Magellan Linux

Annotation of /trunk/mkinitrd-magellan/busybox/coreutils/ln.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 984 - (hide annotations) (download)
Sun May 30 11:32:42 2010 UTC (13 years, 11 months ago) by niro
File MIME type: text/plain
File size: 2434 byte(s)
-updated to busybox-1.16.1 and enabled blkid/uuid support in default config
1 niro 532 /* vi: set sw=4 ts=4: */
2     /*
3     * Mini ln implementation for busybox
4     *
5     * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6     *
7     * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8     */
9    
10     /* BB_AUDIT SUSv3 compliant */
11     /* BB_AUDIT GNU options missing: -d, -F, -i, and -v. */
12     /* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
13    
14 niro 816 #include "libbb.h"
15 niro 532
16 niro 816 /* This is a NOEXEC applet. Be very careful! */
17    
18    
19 niro 532 #define LN_SYMLINK 1
20     #define LN_FORCE 2
21     #define LN_NODEREFERENCE 4
22     #define LN_BACKUP 8
23     #define LN_SUFFIX 16
24    
25 niro 816 int ln_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
26 niro 532 int ln_main(int argc, char **argv)
27     {
28     int status = EXIT_SUCCESS;
29 niro 984 int opts;
30 niro 532 char *last;
31     char *src_name;
32     char *src;
33 niro 816 char *suffix = (char*)"~";
34 niro 532 struct stat statbuf;
35     int (*link_func)(const char *, const char *);
36    
37 niro 984 opt_complementary = "-1"; /* min one arg */
38     opts = getopt32(argv, "sfnbS:", &suffix);
39 niro 532
40     last = argv[argc - 1];
41     argv += optind;
42    
43     if (argc == optind + 1) {
44     *--argv = last;
45 niro 816 last = bb_get_last_path_component_strip(xstrdup(last));
46 niro 532 }
47    
48     do {
49     src_name = NULL;
50     src = last;
51    
52     if (is_directory(src,
53 niro 984 (opts & LN_NODEREFERENCE) ^ LN_NODEREFERENCE,
54 niro 816 NULL)
55     ) {
56 niro 532 src_name = xstrdup(*argv);
57 niro 816 src = concat_path_file(src, bb_get_last_path_component_strip(src_name));
58 niro 532 free(src_name);
59     src_name = src;
60     }
61 niro 984 if (!(opts & LN_SYMLINK) && stat(*argv, &statbuf)) {
62 niro 532 // coreutils: "ln dangling_symlink new_hardlink" works
63     if (lstat(*argv, &statbuf) || !S_ISLNK(statbuf.st_mode)) {
64 niro 816 bb_simple_perror_msg(*argv);
65 niro 532 status = EXIT_FAILURE;
66     free(src_name);
67     continue;
68     }
69     }
70    
71 niro 984 if (opts & LN_BACKUP) {
72 niro 532 char *backup;
73     backup = xasprintf("%s%s", src, suffix);
74     if (rename(src, backup) < 0 && errno != ENOENT) {
75 niro 816 bb_simple_perror_msg(src);
76 niro 532 status = EXIT_FAILURE;
77     free(backup);
78     continue;
79     }
80     free(backup);
81     /*
82     * When the source and dest are both hard links to the same
83     * inode, a rename may succeed even though nothing happened.
84     * Therefore, always unlink().
85     */
86     unlink(src);
87 niro 984 } else if (opts & LN_FORCE) {
88 niro 532 unlink(src);
89     }
90    
91     link_func = link;
92 niro 984 if (opts & LN_SYMLINK) {
93 niro 532 link_func = symlink;
94     }
95    
96     if (link_func(*argv, src) != 0) {
97 niro 816 bb_simple_perror_msg(src);
98 niro 532 status = EXIT_FAILURE;
99     }
100    
101     free(src_name);
102    
103     } while ((++argv)[1]);
104    
105     return status;
106     }