|
|
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.