morpheus-base

morpheus base system
git clone git://git.2f30.org/morpheus-base.git
Log | Files | Refs

ln.c (1410B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include <errno.h>
      3 #include <fcntl.h>
      4 #include <libgen.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <sys/stat.h>
      9 #include <unistd.h>
     10 
     11 #include "util.h"
     12 
     13 static void
     14 usage(void)
     15 {
     16 	eprintf("usage: %1$s [-LPfs] target [linkname]\n"
     17 	        "       %1$s [-LPfs] target... directory\n", argv0);
     18 }
     19 
     20 int
     21 main(int argc, char *argv[])
     22 {
     23 	char *fname, *to;
     24 	int sflag = 0;
     25 	int fflag = 0;
     26 	int hasto = 0;
     27 	int dirfd = AT_FDCWD;
     28 	int flags = AT_SYMLINK_FOLLOW;
     29 	struct stat st;
     30 
     31 	ARGBEGIN {
     32 	case 'f':
     33 		fflag = 1;
     34 		break;
     35 	case 's':
     36 		sflag = 1;
     37 		break;
     38 	case 'L':
     39 		flags |= AT_SYMLINK_FOLLOW;
     40 		break;
     41 	case 'P':
     42 		flags &= ~AT_SYMLINK_FOLLOW;
     43 		break;
     44 	default:
     45 		usage();
     46 	} ARGEND;
     47 
     48 	if (argc == 0)
     49 		usage();
     50 
     51 	fname = sflag ? "symlink" : "link";
     52 
     53 	if (argc >= 2) {
     54 		if (stat(argv[argc - 1], &st) == 0 && S_ISDIR(st.st_mode)) {
     55 			if ((dirfd = open(argv[argc - 1], O_RDONLY)) < 0)
     56 				eprintf("open:");
     57 		} else if (argc == 2) {
     58 			to = argv[1];
     59 			hasto = 1;
     60 		} else {
     61 			eprintf("destination is not a directory\n");
     62 		}
     63 		argc--;
     64 	}
     65 
     66 	for (; argc > 0; argc--, argv++) {
     67 		if (!hasto)
     68 			to = basename(argv[0]);
     69 		if (fflag)
     70 			remove(to);
     71 		if ((!sflag ? linkat(AT_FDCWD, argv[0], dirfd, to, flags)
     72 		            : symlinkat(argv[0], dirfd, to)) < 0) {
     73 			eprintf("%s %s <- %s:", fname, argv[0], to);
     74 		}
     75 	}
     76 
     77 	return 0;
     78 }