Readable version of argument access types and mask
[unix-history] / usr / src / bin / ln / ln.c
CommitLineData
8fb84ebd
BJ
1static 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
12struct stat stbuf;
13
14int fflag; /* force flag set? */
15
16char _sobuf[BUFSIZ];
17
18main(argc, argv)
19register int argc;
20register 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);
43usage:
44 fprintf(stderr, "Usage: ln: f1 f2; or ln f1 ... fn d2\n");
45 exit(1);
46}
47
48linkit(from, to)
49register 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}