xref: /titanic_52/usr/src/ucbcmd/ln/ln.c (revision bdfc6d18da790deeec2e0eb09c625902defe2498)
1 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
2 /*	  All Rights Reserved  	*/
3 
4 
5 /*
6  * Copyright (c) 1980 Regents of the University of California.
7  * All rights reserved. The Berkeley software License Agreement
8  * specifies the terms and conditions for redistribution.
9  */
10 
11 /*
12  * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc.
13  * All Rights Reserved.
14  */
15 
16 #ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.1	*/
17 
18 /*
19  * ln
20  */
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/param.h>
24 #include <sys/stat.h>
25 #include <errno.h>
26 
27 struct	stat stb;
28 int	fflag;		/* force flag set? */
29 int	sflag;
30 extern	int errno;
31 
32 main(argc, argv)
33 	int argc;
34 	register char **argv;
35 {
36 	register int i, r;
37 
38 	argc--, argv++;
39 again:
40 	if (argc && strcmp(argv[0], "-f") == 0) {
41 		fflag++;
42 		argv++;
43 		argc--;
44 	}
45 	if (argc && strcmp(argv[0], "-s") == 0) {
46 		sflag++;
47 		argv++;
48 		argc--;
49 	}
50 	if (argc == 0)
51 		goto usage;
52 	else if (argc == 1) {
53 		argv[argc] = ".";
54 		argc++;
55 	}
56 	if (argc > 2) {
57 		if (stat(argv[argc-1], &stb) < 0)
58 			goto usage;
59 		if ((stb.st_mode&S_IFMT) != S_IFDIR)
60 			goto usage;
61 	}
62 	r = 0;
63 	for(i = 0; i < argc-1; i++)
64 		r |= linkit(argv[i], argv[argc-1]);
65 	exit(r);
66 usage:
67 	(void) fprintf(stderr,
68 	    "Usage: ln [-f] [-s] f1\n\
69        ln [-f] [-s] f1 f2\n\
70        ln [-f] [-s] f1 ... fn d1\n");
71 	exit(1);
72 }
73 
74 int	link(), symlink();
75 
76 linkit(from, to)
77 	char *from, *to;
78 {
79 	char destname[MAXPATHLEN + 1];
80 	char *tail;
81 	int (*linkf)() = sflag ? symlink : link;
82 	char *strrchr();
83 
84 	/* is target a directory? */
85 	if (sflag == 0 && fflag == 0 && stat(from, &stb) >= 0
86 	    && (stb.st_mode&S_IFMT) == S_IFDIR) {
87 		printf("%s is a directory\n", from);
88 		return (1);
89 	}
90 	if (stat(to, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) {
91 		tail = strrchr(from, '/');
92 		if (tail == 0)
93 			tail = from;
94 		else
95 			tail++;
96 		if (strlen(to) + strlen(tail) >= sizeof destname - 1) {
97 			(void) fprintf(stderr, "ln: %s/%s: Name too long\n",
98 			    to, tail);
99 			return (1);
100 		}
101 		(void) sprintf(destname, "%s/%s", to, tail);
102 		to = destname;
103 	}
104 	if ((*linkf)(from, to) < 0) {
105 		if (errno == EEXIST || sflag)
106 			Perror(to);
107 		else if (access(from, 0) < 0)
108 			Perror(from);
109 		else
110 			Perror(to);
111 		return (1);
112 	}
113 	return (0);
114 }
115 
116 Perror(s)
117 	char *s;
118 {
119 
120 	(void) fprintf(stderr, "ln: ");
121 	perror(s);
122 }
123