#ifndef lint static char sccsid[] = "@(#)ln.c 4.1 10/1/80"; #endif /* * ln */ #include #include #include #include #include struct stat stb; int fflag; /* force flag set? */ int sflag; char name[BUFSIZ]; char *rindex(); extern int errno; main(argc, argv) int argc; register char **argv; { register int i, r; argc--, argv++; if (argc && strcmp(argv[0], "-f") == 0) { fflag++; argv++; argc--; } #ifdef UCB_SYMLINKS if (argc && strcmp(argv[0], "-s") == 0) { sflag++; argv++; argc--; } #endif if (argc == 0) goto usage; else if (argc == 1) { argv[argc] = "."; argc++; } if (sflag == 0 && argc > 2) { if (stat(argv[argc-1], &stb) < 0) goto usage; if ((stb.st_mode&S_IFMT) != S_IFDIR) goto usage; } r = 0; for(i = 0; i < argc-1; i++) r |= linkit(argv[i], argv[argc-1]); exit(r); usage: #ifdef UCB_SYMLINKS fprintf(stderr, "Usage: ln [ -s ] f1\nor: ln [ -s ] f1 f2\nln [ -s ] f1 ... fn d2\n"); #else fprintf(stderr, "Usage: ln f1\nor: ln f1 f2\nln f1 ... fn d2\n"); #endif exit(1); } int link(); #ifdef UCB_SYMLINKS int symlink(); #endif linkit(from, to) char *from, *to; { char *tail; #ifdef UCB_SYMLINKS int (*linkf)() = sflag ? symlink : link; #else int (*linkf)() = link; #endif /* is target a directory? */ if (sflag == 0 && fflag == 0 && stat(from, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) { printf("%s is a directory\n", from); return (1); } if (stat(to, &stb) >=0 && (stb.st_mode&S_IFMT) == S_IFDIR) { tail = rindex(from, '/'); if (tail == 0) tail = from; else tail++; sprintf(name, "%s/%s", to, tail); to = name; } if ((*linkf)(from, to) < 0) { if (errno == EEXIST) perror(to); else perror(from); return (1); } return(0); }