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