comparison toys/ln.c @ 462:3947b397c328

Teach ln about multiple arguments.
author Rob Landley <rob@landley.net>
date Mon, 13 Feb 2012 23:43:33 -0600
parents ca74293f87f1
children 94a2905dd325
comparison
equal deleted inserted replaced
461:ca74293f87f1 462:3947b397c328
4 * 4 *
5 * Copyright 2012 Andre Renaud <andre@bluewatersys.com> 5 * Copyright 2012 Andre Renaud <andre@bluewatersys.com>
6 * 6 *
7 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ln.html 7 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ln.html
8 8
9 USE_LN(NEWTOY(ln, "fs", TOYFLAG_BIN)) 9 USE_LN(NEWTOY(ln, "<1fs", TOYFLAG_BIN))
10 10
11 config LN 11 config LN
12 bool "ln" 12 bool "ln"
13 default n 13 default y
14 help 14 help
15 usage: ln [-s] [-f] file1 file2 15 usage: ln [-sf] [FROM...] TO
16 16
17 Create a link from file2 to file1 17 Create a link between FROM and TO.
18 With only one argument, create link in current directory.
18 19
19 -s Create a symbolic link 20 -s Create a symbolic link
20 -f Force the creation of the link, even if file2 already exists 21 -f Force the creation of the link, even if TO already exists
21 */ 22 */
22 23
23 #include "toys.h" 24 #include "toys.h"
24 25
25 #define FLAG_s 1 26 #define FLAG_s 1
26 #define FLAG_f 2 27 #define FLAG_f 2
27 28
28 void ln_main(void) 29 void ln_main(void)
29 { 30 {
30 char *file1 = toys.optargs[0], *file2 = toys.optargs[1]; 31 char *dest = toys.optargs[--toys.optc], *new;
32 struct stat buf;
33 int i;
31 34
32 /* FIXME: How do we print out the usage info? */ 35 // With one argument, create link in current directory.
33 if (!file1 || !file2) 36 if (!toys.optc) {
34 perror_exit("Usage: ln [-s] [-f] file1 file2"); 37 toys.optc++;
35 /* Silently unlink the existing target. If it doesn't exist, 38 dest=".";
36 * then we just move on */ 39 }
37 if (toys.optflags & FLAG_f) 40
38 unlink(file2); 41 // Is destination a directory?
39 if (toys.optflags & FLAG_s) { 42 if (stat(dest, &buf) || !S_ISDIR(buf.st_mode)) {
40 if (symlink(file1, file2)) 43 if (toys.optc>1) error_exit("'%s' not a directory");
41 perror_exit("cannot create symbolic link from %s to %s", 44 buf.st_mode = 0;
42 file1, file2); 45 }
43 } else { 46
44 if (link(file1, file2)) 47 for (i=0; i<toys.optc; i++) {
45 perror_exit("cannot create hard link from %s to %s", 48 int rc;
46 file1, file2); 49 char *try = toys.optargs[i];
50
51 if (S_ISDIR(buf.st_mode)) {
52 new = strrchr(try, '/');
53 if (!new) new = try;
54 new = xmsprintf("%s/%s", dest, new);
55 } else new = dest;
56 /* Silently unlink the existing target. If it doesn't exist,
57 * then we just move on */
58 if (toys.optflags & FLAG_f) unlink(new);
59
60
61 rc = (toys.optflags & FLAG_s) ? symlink(try, new) : link(try, new);
62 if (rc)
63 perror_exit("cannot create %s link from '%s' to '%s'",
64 (toys.optflags & FLAG_s) ? "symbolic" : "hard", try, new);
65 if (new != dest) free(new);
47 } 66 }
48 } 67 }