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