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