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