Mercurial > hg > toybox
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 } |