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