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