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--; 38 argv++; 39 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 return (1); 72 } 73 74 int 75 linkit(char *from, char *to) 76 { 77 char destname[MAXPATHLEN + 1]; 78 char *tail; 79 int (*linkf)() = sflag ? symlink : link; 80 char *strrchr(); 81 82 /* is target a directory? */ 83 if (sflag == 0 && fflag == 0 && stat(from, &stb) >= 0 && 84 (stb.st_mode&S_IFMT) == S_IFDIR) { 85 printf("%s is a directory\n", from); 86 return (1); 87 } 88 if (stat(to, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) { 89 tail = strrchr(from, '/'); 90 if (tail == 0) 91 tail = from; 92 else 93 tail++; 94 if (strlen(to) + strlen(tail) >= sizeof (destname) - 1) { 95 (void) fprintf(stderr, "ln: %s/%s: Name too long\n", 96 to, tail); 97 return (1); 98 } 99 (void) sprintf(destname, "%s/%s", to, tail); 100 to = destname; 101 } 102 if ((*linkf)(from, to) < 0) { 103 if (errno == EEXIST || sflag) 104 Perror(to); 105 else if (access(from, 0) < 0) 106 Perror(from); 107 else 108 Perror(to); 109 return (1); 110 } 111 return (0); 112 } 113 114 void 115 Perror(char *s) 116 { 117 (void) fprintf(stderr, "ln: "); 118 perror(s); 119 } 120