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