symbolic links
[unix-history] / usr / src / bin / ln / ln.c
CommitLineData
a3954b4f 1static char sccsid[] = "@(#)ln.c 4.2 %G%";
8fb84ebd 2/*
1bfeaa36 3 * ln
8fb84ebd 4 */
8fb84ebd
BJ
5#include <stdio.h>
6#include <sys/types.h>
7#include <sys/stat.h>
8
1bfeaa36
BJ
9struct stat stb;
10int fflag; /* force flag set? */
a3954b4f 11int sflag;
1bfeaa36
BJ
12char name[BUFSIZ];
13char *rindex();
8fb84ebd
BJ
14
15main(argc, argv)
1bfeaa36
BJ
16 int argc;
17 register char **argv;
8fb84ebd 18{
1bfeaa36 19 register int i, r;
8fb84ebd 20
1bfeaa36 21 argc--, argv++;
a3954b4f 22again:
1bfeaa36 23 if (argc && strcmp(argv[0], "-f") == 0) {
8fb84ebd
BJ
24 fflag++;
25 argv++;
26 argc--;
27 }
a3954b4f
BJ
28 if (argc && strcmp(argv[0], "-s") == 0) {
29 sflag++;
30 argv++;
31 argc--;
32 }
1bfeaa36 33 if (argc == 0)
8fb84ebd 34 goto usage;
1bfeaa36 35 else if (argc == 1) {
8fb84ebd 36 argv[argc] = ".";
1bfeaa36
BJ
37 argc++;
38 }
a3954b4f
BJ
39 if (sflag == 0 && argc > 2) {
40 if (lstat(argv[argc-1], &stb) < 0)
8fb84ebd 41 goto usage;
1bfeaa36 42 if ((stb.st_mode&S_IFMT) != S_IFDIR)
8fb84ebd
BJ
43 goto usage;
44 }
45 r = 0;
1bfeaa36 46 for(i = 0; i < argc-1; i++)
8fb84ebd
BJ
47 r |= linkit(argv[i], argv[argc-1]);
48 exit(r);
49usage:
a3954b4f 50 fprintf(stderr, "Usage: ln [ -s ] f1\nor: ln [ -s ] f1 f2\nln [ -s ] f1 ... fn d2\n");
8fb84ebd
BJ
51 exit(1);
52}
53
a3954b4f
BJ
54int link(), symlink();
55
8fb84ebd 56linkit(from, to)
1bfeaa36 57 char *from, *to;
8fb84ebd 58{
1bfeaa36 59 char *tail;
a3954b4f 60 int (*linkf)() = sflag ? symlink : link;
8fb84ebd
BJ
61
62 /* is target a directory? */
a3954b4f 63 if (sflag == 0 && fflag == 0 && lstat(from, &stb) >= 0
1bfeaa36 64 && (stb.st_mode&S_IFMT) == S_IFDIR) {
8fb84ebd 65 printf("%s is a directory\n", from);
1bfeaa36 66 return (1);
8fb84ebd 67 }
a3954b4f 68 if (lstat(to, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) {
1bfeaa36
BJ
69 tail = rindex(from, '/');
70 if (tail == 0)
71 tail = from;
72 else
73 tail++;
74 sprintf(name, "%s/%s", to, tail);
75 to = name;
8fb84ebd 76 }
a3954b4f 77 if ((*linkf)(from, to) < 0) {
8fb84ebd 78 perror(from);
1bfeaa36 79 return (1);
8fb84ebd 80 }
a3954b4f 81 return (0);
8fb84ebd 82}