Annotation of /trunk/mkinitrd-magellan/busybox/coreutils/install.c
Parent Directory | Revision Log
Revision 532 -
(hide annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 3738 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 3738 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | niro | 532 | /* vi: set sw=4 ts=4: */ |
2 | /* | ||
3 | * Copyright (C) 2003 by Glenn McGrath <bug1@iinet.net.au> | ||
4 | * | ||
5 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
6 | * | ||
7 | * TODO: -d option, need a way of recursively making directories and changing | ||
8 | * owner/group, will probably modify bb_make_directory(...) | ||
9 | */ | ||
10 | |||
11 | #include "busybox.h" | ||
12 | #include "libcoreutils/coreutils.h" | ||
13 | #include <libgen.h> | ||
14 | #include <getopt.h> /* struct option */ | ||
15 | |||
16 | #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS | ||
17 | static const struct option install_long_options[] = { | ||
18 | { "directory", 0, NULL, 'd' }, | ||
19 | { "preserve-timestamps", 0, NULL, 'p' }, | ||
20 | { "strip", 0, NULL, 's' }, | ||
21 | { "group", 0, NULL, 'g' }, | ||
22 | { "mode", 0, NULL, 'm' }, | ||
23 | { "owner", 0, NULL, 'o' }, | ||
24 | { 0, 0, 0, 0 } | ||
25 | }; | ||
26 | #endif | ||
27 | |||
28 | int install_main(int argc, char **argv) | ||
29 | { | ||
30 | struct stat statbuf; | ||
31 | mode_t mode; | ||
32 | uid_t uid; | ||
33 | gid_t gid; | ||
34 | const char *gid_str; | ||
35 | const char *uid_str; | ||
36 | const char *mode_str; | ||
37 | int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; | ||
38 | int ret = EXIT_SUCCESS, flags, i, isdir; | ||
39 | |||
40 | enum { | ||
41 | OPT_CMD = 0x1, | ||
42 | OPT_DIRECTORY = 0x2, | ||
43 | OPT_PRESERVE_TIME = 0x4, | ||
44 | OPT_STRIP = 0x8, | ||
45 | OPT_GROUP = 0x10, | ||
46 | OPT_MODE = 0x20, | ||
47 | OPT_OWNER = 0x40, | ||
48 | }; | ||
49 | |||
50 | #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS | ||
51 | applet_long_options = install_long_options; | ||
52 | #endif | ||
53 | opt_complementary = "?:s--d:d--s"; | ||
54 | /* -c exists for backwards compatibility, its needed */ | ||
55 | flags = getopt32(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); | ||
56 | |||
57 | /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ | ||
58 | if (flags & OPT_PRESERVE_TIME) { | ||
59 | copy_flags |= FILEUTILS_PRESERVE_STATUS; | ||
60 | } | ||
61 | mode = 0666; | ||
62 | if (flags & OPT_MODE) bb_parse_mode(mode_str, &mode); | ||
63 | uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); | ||
64 | gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); | ||
65 | if (flags & (OPT_OWNER|OPT_GROUP)) umask(0); | ||
66 | |||
67 | /* Create directories | ||
68 | * don't use bb_make_directory() as it can't change uid or gid | ||
69 | * perhaps bb_make_directory() should be improved. | ||
70 | */ | ||
71 | if (flags & OPT_DIRECTORY) { | ||
72 | for (argv += optind; *argv; argv++) { | ||
73 | char *old_argv_ptr = *argv + 1; | ||
74 | char *argv_ptr; | ||
75 | do { | ||
76 | argv_ptr = strchr(old_argv_ptr, '/'); | ||
77 | old_argv_ptr = argv_ptr; | ||
78 | if (argv_ptr) { | ||
79 | *argv_ptr = '\0'; | ||
80 | old_argv_ptr++; | ||
81 | } | ||
82 | if (mkdir(*argv, mode | 0111) == -1) { | ||
83 | if (errno != EEXIST) { | ||
84 | bb_perror_msg("cannot create %s", *argv); | ||
85 | ret = EXIT_FAILURE; | ||
86 | break; | ||
87 | } | ||
88 | } | ||
89 | if ((flags & (OPT_OWNER|OPT_GROUP)) | ||
90 | && lchown(*argv, uid, gid) == -1 | ||
91 | ) { | ||
92 | bb_perror_msg("cannot change ownership of %s", *argv); | ||
93 | ret = EXIT_FAILURE; | ||
94 | break; | ||
95 | } | ||
96 | if (argv_ptr) { | ||
97 | *argv_ptr = '/'; | ||
98 | } | ||
99 | } while (old_argv_ptr); | ||
100 | } | ||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | isdir = lstat(argv[argc - 1], &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); | ||
105 | |||
106 | for (i = optind; i < argc - 1; i++) { | ||
107 | char *dest; | ||
108 | |||
109 | dest = argv[argc - 1]; | ||
110 | if (isdir) | ||
111 | dest = concat_path_file(argv[argc - 1], basename(argv[i])); | ||
112 | ret |= copy_file(argv[i], dest, copy_flags); | ||
113 | |||
114 | /* Set the file mode */ | ||
115 | if ((flags & OPT_MODE) && chmod(dest, mode) == -1) { | ||
116 | bb_perror_msg("cannot change permissions of %s", dest); | ||
117 | ret = EXIT_FAILURE; | ||
118 | } | ||
119 | |||
120 | /* Set the user and group id */ | ||
121 | if ((flags & (OPT_OWNER|OPT_GROUP)) | ||
122 | && lchown(dest, uid, gid) == -1 | ||
123 | ) { | ||
124 | bb_perror_msg("cannot change ownership of %s", dest); | ||
125 | ret = EXIT_FAILURE; | ||
126 | } | ||
127 | if (flags & OPT_STRIP) { | ||
128 | if (execlp("strip", "strip", dest, NULL) == -1) { | ||
129 | bb_perror_msg("strip"); | ||
130 | ret = EXIT_FAILURE; | ||
131 | } | ||
132 | } | ||
133 | if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); | ||
134 | } | ||
135 | |||
136 | return ret; | ||
137 | } |