|
|
1.1 root 1: /*
2: * Copyright (c) 1987 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: char copyright[] =
20: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
21: All rights reserved.\n";
22: #endif /* not lint */
23:
24: #ifndef lint
25: static char sccsid[] = "@(#)ln.c 4.11 (Berkeley) 6/18/88";
26: #endif /* not lint */
27:
28: #include <sys/param.h>
29: #include <sys/stat.h>
30: #include <stdio.h>
31: #include <errno.h>
32:
33: static int fflag, /* undocumented force flag */
34: sflag, /* symbolic, not hard, link */
35: (*linkf)(); /* system link call */
36:
37: main(argc, argv)
38: int argc;
39: char **argv;
40: {
41: extern int optind;
42: struct stat buf;
43: int ch, exitval, link(), symlink();
44: char *sourcedir;
45:
46: while ((ch = getopt(argc, argv, "fs")) != EOF)
47: switch((char)ch) {
48: case 'f':
49: fflag = 1;
50: break;
51: case 's':
52: sflag = 1;
53: break;
54: case '?':
55: default:
56: usage();
57: }
58:
59: argv += optind;
60: argc -= optind;
61:
62: linkf = sflag ? symlink : link;
63:
64: switch(argc) {
65: case 0:
66: usage();
67: case 1: /* ln target */
68: exit(linkit(argv[0], ".", 1));
69: case 2: /* ln target source */
70: exit(linkit(argv[0], argv[1], 0));
71: default: /* ln target1 target2 directory */
72: sourcedir = argv[argc - 1];
73: if (stat(sourcedir, &buf)) {
74: perror(sourcedir);
75: exit(1);
76: }
77: if ((buf.st_mode & S_IFMT) != S_IFDIR)
78: usage();
79: for (exitval = 0; *argv != sourcedir; ++argv)
80: exitval |= linkit(*argv, sourcedir, 1);
81: exit(exitval);
82: }
83: /*NOTREACHED*/
84: }
85:
86: static
87: linkit(target, source, isdir)
88: char *target, *source;
89: int isdir;
90: {
91: extern int errno;
92: struct stat buf;
93: char path[MAXPATHLEN],
94: *cp, *rindex(), *strcpy();
95:
96: if (!sflag) {
97: /* if target doesn't exist, quit now */
98: if (stat(target, &buf)) {
99: perror(target);
100: return(1);
101: }
102: /* only symbolic links to directories, unless -f option used */
103: if (!fflag && (buf.st_mode & S_IFMT) == S_IFDIR) {
104: printf("%s is a directory.\n", target);
105: return(1);
106: }
107: }
108:
109: /* if the source is a directory, append the target's name */
110: if (isdir || !stat(source, &buf) && (buf.st_mode & S_IFMT) == S_IFDIR) {
111: if (!(cp = rindex(target, '/')))
112: cp = target;
113: else
114: ++cp;
115: (void)sprintf(path, "%s/%s", source, cp);
116: source = path;
117: }
118:
119: if ((*linkf)(target, source)) {
120: perror(source);
121: return(1);
122: }
123: return(0);
124: }
125:
126: static
127: usage()
128: {
129: fputs("usage:\tln [-s] targetname [sourcename]\n\tln [-s] targetname1 targetname2 [... targetnameN] sourcedirectory\n", stderr);
130: exit(1);
131: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.