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 /* 16 * ln 17 */ 18 #include <stdio.h> 19 #include <sys/types.h> 20 #include <sys/param.h> 21 #include <sys/stat.h> 22 #include <errno.h> 23 #include <unistd.h> 24 25 struct stat stb; 26 int fflag; /* force flag set? */ 27 int sflag; 28 29 int linkit(char *, char *); 30 void Perror(char *); 31 32 int 33 main(int argc, char **argv) 34 { 35 int i, r; 36 37 argc--, argv++; 38 again: 39 if (argc && strcmp(argv[0], "-f") == 0) { 40 fflag++; 41 argv++; 42 argc--; 43 } 44 if (argc && strcmp(argv[0], "-s") == 0) { 45 sflag++; 46 argv++; 47 argc--; 48 } 49 if (argc == 0) 50 goto usage; 51 else if (argc == 1) { 52 argv[argc] = "."; 53 argc++; 54 } 55 if (argc > 2) { 56 if (stat(argv[argc-1], &stb) < 0) 57 goto usage; 58 if ((stb.st_mode&S_IFMT) != S_IFDIR) 59 goto usage; 60 } 61 r = 0; 62 for (i = 0; i < argc-1; i++) 63 r |= linkit(argv[i], argv[argc-1]); 64 exit(r); 65 usage: 66 (void) fprintf(stderr, 67 "Usage: ln [-f] [-s] f1\n\ 68 ln [-f] [-s] f1 f2\n\ 69 ln [-f] [-s] f1 ... fn d1\n"); 70 return (1); 71 } 72 73 int 74 linkit(char *from, char *to) 75 { 76 char destname[MAXPATHLEN + 1]; 77 char *tail; 78 int (*linkf)() = sflag ? symlink : link; 79 char *strrchr(); 80 81 /* is target a directory? */ 82 if (sflag == 0 && fflag == 0 && stat(from, &stb) >= 0 && 83 (stb.st_mode&S_IFMT) == S_IFDIR) { 84 printf("%s is a directory\n", from); 85 return (1); 86 } 87 if (stat(to, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) { 88 tail = strrchr(from, '/'); 89 if (tail == 0) 90 tail = from; 91 else 92 tail++; 93 if (strlen(to) + strlen(tail) >= sizeof (destname) - 1) { 94 (void) fprintf(stderr, "ln: %s/%s: Name too long\n", 95 to, tail); 96 return (1); 97 } 98 (void) sprintf(destname, "%s/%s", to, tail); 99 to = destname; 100 } 101 if ((*linkf)(from, to) < 0) { 102 if (errno == EEXIST || sflag) 103 Perror(to); 104 else if (access(from, 0) < 0) 105 Perror(from); 106 else 107 Perror(to); 108 return (1); 109 } 110 return (0); 111 } 112 113 void 114 Perror(char *s) 115 { 116 (void) fprintf(stderr, "ln: "); 117 perror(s); 118 } 119