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