BSD 4 release
[unix-history] / usr / src / cmd / ln.c
index ac6c619..b264368 100644 (file)
@@ -1,56 +1,72 @@
+static char sccsid[] = "@(#)ln.c 4.1 10/1/80";
 /*
 /*
- * ln [ -f ] target [ new name ]
+ * ln
  */
  */
-
+#include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include "stdio.h"
+
+struct stat stb;
+int    fflag;          /* force flag set? */
+char   name[BUFSIZ];
 char   *rindex();
 
 main(argc, argv)
 char   *rindex();
 
 main(argc, argv)
-char **argv;
+       int argc;
+       register char **argv;
 {
 {
-       struct stat statb;
-       register char *np;
-       int fflag = 0;
-       char nb[100], *name=nb, *arg2;
-       int statres;
+       register int i, r;
 
 
-       if (argc >1 && strcmp(argv[1], "-f")==0) {
-               argc--;
-               argv++;
+       argc--, argv++;
+       if (argc && strcmp(argv[0], "-f") == 0) {
                fflag++;
                fflag++;
+               argv++;
+               argc--;
        }
        }
-       if (argc<2 || argc>3) {
-               printf("Usage: ln target [ newname ]\n");
-               exit(1);
+       if (argc == 0) 
+               goto usage;
+       else if (argc == 1) {
+               argv[argc] = ".";
+               argc++;
        }
        }
-       np = rindex(argv[1], '/');
-       if (np==0)
-               np = argv[1];
-       else
-               np++;
-       if (argc==2)
-               arg2 = np;
-       else
-               arg2 = argv[2];
-       statres = stat(argv[1], &statb);
-       if (statres<0) {
-               printf ("ln: %s does not exist\n", argv[1]);
-               exit(1);
+       if (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:
+       fprintf(stderr, "Usage: ln f1\nor: ln f1 f2\nln f1 ... fn d2\n");
+       exit(1);
+}
+
+linkit(from, to)
+       char *from, *to;
+{
+       char *tail;
+
+       /* is target a directory? */
+       if (fflag == 0 && stat(from, &stb) >= 0
+           && (stb.st_mode&S_IFMT) == S_IFDIR) {
+               printf("%s is a directory\n", from);
+               return (1);
        }
        }
-       if (fflag==0 && (statb.st_mode&S_IFMT) == S_IFDIR) {
-               printf("ln: %s is a directory\n", argv[1]);
-               exit(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;
        }
        }
-       statres = stat(arg2, &statb);
-       if (statres>=0 && (statb.st_mode&S_IFMT) == S_IFDIR)
-               sprintf(name, "%s/%s", arg2, np);
-       else
-               name = arg2;
-       if (link(argv[1], name)<0) {
-               perror("ln");
-               exit(1);
+       if (link(from, to) < 0) {
+               perror(from);
+               return (1);
        }
        }
-       exit(0);
+       return(0);
 }
 }