Commit | Line | Data |
---|---|---|
e1e33884 | 1 | static char sccsid[] = "@(#)ln.c 4.5 %G%"; |
8fb84ebd | 2 | /* |
1bfeaa36 | 3 | * ln |
8fb84ebd | 4 | */ |
8fb84ebd BJ |
5 | #include <stdio.h> |
6 | #include <sys/types.h> | |
7 | #include <sys/stat.h> | |
56abc04a | 8 | #include <errno.h> |
8fb84ebd | 9 | |
1bfeaa36 BJ |
10 | struct stat stb; |
11 | int fflag; /* force flag set? */ | |
a3954b4f | 12 | int sflag; |
1bfeaa36 BJ |
13 | char name[BUFSIZ]; |
14 | char *rindex(); | |
56abc04a | 15 | extern int errno; |
8fb84ebd BJ |
16 | |
17 | main(argc, argv) | |
1bfeaa36 BJ |
18 | int argc; |
19 | register char **argv; | |
8fb84ebd | 20 | { |
1bfeaa36 | 21 | register int i, r; |
8fb84ebd | 22 | |
1bfeaa36 | 23 | argc--, argv++; |
a3954b4f | 24 | again: |
1bfeaa36 | 25 | if (argc && strcmp(argv[0], "-f") == 0) { |
8fb84ebd BJ |
26 | fflag++; |
27 | argv++; | |
28 | argc--; | |
29 | } | |
a3954b4f BJ |
30 | if (argc && strcmp(argv[0], "-s") == 0) { |
31 | sflag++; | |
32 | argv++; | |
33 | argc--; | |
34 | } | |
1bfeaa36 | 35 | if (argc == 0) |
8fb84ebd | 36 | goto usage; |
1bfeaa36 | 37 | else if (argc == 1) { |
8fb84ebd | 38 | argv[argc] = "."; |
1bfeaa36 BJ |
39 | argc++; |
40 | } | |
a3954b4f | 41 | if (sflag == 0 && argc > 2) { |
973b1564 | 42 | if (stat(argv[argc-1], &stb) < 0) |
8fb84ebd | 43 | goto usage; |
1bfeaa36 | 44 | if ((stb.st_mode&S_IFMT) != S_IFDIR) |
8fb84ebd BJ |
45 | goto usage; |
46 | } | |
47 | r = 0; | |
1bfeaa36 | 48 | for(i = 0; i < argc-1; i++) |
8fb84ebd BJ |
49 | r |= linkit(argv[i], argv[argc-1]); |
50 | exit(r); | |
51 | usage: | |
a3954b4f | 52 | fprintf(stderr, "Usage: ln [ -s ] f1\nor: ln [ -s ] f1 f2\nln [ -s ] f1 ... fn d2\n"); |
8fb84ebd BJ |
53 | exit(1); |
54 | } | |
55 | ||
a3954b4f BJ |
56 | int link(), symlink(); |
57 | ||
8fb84ebd | 58 | linkit(from, to) |
1bfeaa36 | 59 | char *from, *to; |
8fb84ebd | 60 | { |
1bfeaa36 | 61 | char *tail; |
a3954b4f | 62 | int (*linkf)() = sflag ? symlink : link; |
8fb84ebd BJ |
63 | |
64 | /* is target a directory? */ | |
973b1564 | 65 | if (sflag == 0 && fflag == 0 && stat(from, &stb) >= 0 |
1bfeaa36 | 66 | && (stb.st_mode&S_IFMT) == S_IFDIR) { |
8fb84ebd | 67 | printf("%s is a directory\n", from); |
1bfeaa36 | 68 | return (1); |
8fb84ebd | 69 | } |
973b1564 | 70 | if (stat(to, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) { |
1bfeaa36 BJ |
71 | tail = rindex(from, '/'); |
72 | if (tail == 0) | |
73 | tail = from; | |
74 | else | |
75 | tail++; | |
76 | sprintf(name, "%s/%s", to, tail); | |
77 | to = name; | |
8fb84ebd | 78 | } |
a3954b4f | 79 | if ((*linkf)(from, to) < 0) { |
56abc04a KM |
80 | if (errno == EEXIST) |
81 | perror(to); | |
e1e33884 | 82 | else if (access(from, 0) < 0) |
56abc04a | 83 | perror(from); |
e1e33884 SL |
84 | else |
85 | perror(to); | |
1bfeaa36 | 86 | return (1); |
8fb84ebd | 87 | } |
a3954b4f | 88 | return (0); |
8fb84ebd | 89 | } |