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