Mercurial > hg > toybox
diff toys/posix/ln.c @ 653:2986aa63a021
Move commands into "posix", "lsb", and "other" menus/directories.
author | Rob Landley <rob@landley.net> |
---|---|
date | Sat, 25 Aug 2012 14:25:22 -0500 |
parents | toys/ln.c@94a2905dd325 |
children | 6df4ccc0acbe |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toys/posix/ln.c Sat Aug 25 14:25:22 2012 -0500 @@ -0,0 +1,70 @@ +/* vi: set sw=4 ts=4: + * + * ln.c - Create filesystem links + * + * Copyright 2012 Andre Renaud <andre@bluewatersys.com> + * + * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ln.html + +USE_LN(NEWTOY(ln, "<1nfs", TOYFLAG_BIN)) + +config LN + bool "ln" + default y + help + usage: ln [-sf] [FROM...] TO + + Create a link between FROM and TO. + With only one argument, create link in current directory. + + -s Create a symbolic link + -f Force the creation of the link, even if TO already exists + -n Symlink at destination treated as file +*/ + +#include "toys.h" + +#define FLAG_s 1 +#define FLAG_f 2 +#define FLAG_n 4 + +void ln_main(void) +{ + char *dest = toys.optargs[--toys.optc], *new; + struct stat buf; + int i; + + // With one argument, create link in current directory. + if (!toys.optc) { + toys.optc++; + dest="."; + } + + // Is destination a directory? + if (((toys.optflags&FLAG_n) ? lstat : stat)(dest, &buf) + || !S_ISDIR(buf.st_mode)) + { + if (toys.optc>1) error_exit("'%s' not a directory"); + buf.st_mode = 0; + } + + for (i=0; i<toys.optc; i++) { + int rc; + char *try = toys.optargs[i]; + + if (S_ISDIR(buf.st_mode)) { + new = strrchr(try, '/'); + if (!new) new = try; + new = xmsprintf("%s/%s", dest, new); + } else new = dest; + /* Silently unlink the existing target. If it doesn't exist, + * then we just move on */ + if (toys.optflags & FLAG_f) unlink(new); + + rc = (toys.optflags & FLAG_s) ? symlink(try, new) : link(try, new); + if (rc) + perror_exit("cannot create %s link from '%s' to '%s'", + (toys.optflags & FLAG_s) ? "symbolic" : "hard", try, new); + if (new != dest) free(new); + } +}