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