Commit | Line | Data |
---|---|---|
8fb84ebd BJ |
1 | static char sccsid[] = "@(#)ln.c 3.1 %G%"; |
2 | /* | |
3 | * ln [ -f ] file ... name | |
4 | * | |
5 | * name must be dir if more than one file given | |
6 | */ | |
7 | ||
8 | #include <stdio.h> | |
9 | #include <sys/types.h> | |
10 | #include <sys/stat.h> | |
11 | ||
12 | struct stat stbuf; | |
13 | ||
14 | int fflag; /* force flag set? */ | |
15 | ||
16 | char _sobuf[BUFSIZ]; | |
17 | ||
18 | main(argc, argv) | |
19 | register int argc; | |
20 | register char *argv[]; | |
21 | { | |
22 | register i, r; | |
23 | ||
24 | if (argc > 1 && strcmp(argv[1], "-f") == 0) { | |
25 | fflag++; | |
26 | argv++; | |
27 | argc--; | |
28 | } | |
29 | if (argc < 2) | |
30 | goto usage; | |
31 | else if (argc == 2) | |
32 | argv[argc] = "."; | |
33 | if (argc > 3) { | |
34 | if (stat(argv[argc-1], &stbuf) < 0) | |
35 | goto usage; | |
36 | if ((stbuf.st_mode&S_IFMT) != S_IFDIR) | |
37 | goto usage; | |
38 | } | |
39 | r = 0; | |
40 | for(i=1; i<argc-1;i++) | |
41 | r |= linkit(argv[i], argv[argc-1]); | |
42 | exit(r); | |
43 | usage: | |
44 | fprintf(stderr, "Usage: ln: f1 f2; or ln f1 ... fn d2\n"); | |
45 | exit(1); | |
46 | } | |
47 | ||
48 | linkit(from, to) | |
49 | register char *from, *to; | |
50 | { | |
51 | register char *p1, *p2, *bp; | |
52 | ||
53 | /* is target a directory? */ | |
54 | if (fflag == 0 && stat(from, &stbuf) >= 0 | |
55 | && (stbuf.st_mode&S_IFMT) == S_IFDIR) { | |
56 | printf("%s is a directory\n", from); | |
57 | return 1; | |
58 | } | |
59 | if (stat(to, &stbuf) >=0 && (stbuf.st_mode&S_IFMT) == S_IFDIR) { | |
60 | p1 = from; | |
61 | p2 = to; | |
62 | bp = _sobuf; | |
63 | while(*bp++ = *p2++) | |
64 | continue; | |
65 | bp[-1] = '/'; | |
66 | p2 = bp; | |
67 | while(*bp = *p1++) | |
68 | if (*bp++ == '/') | |
69 | bp = p2; | |
70 | to = _sobuf; | |
71 | } | |
72 | else | |
73 | p1 = NULL; | |
74 | if (link(from, to) < 0) { | |
75 | perror(from); | |
76 | return 1; | |
77 | } | |
78 | return(0); | |
79 | } |