aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-11-27 22:40:08 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-11-27 22:40:08 +0000
commit11e69471be27de28aefef931ec26912a6da7bed7 (patch)
tree4c47bc6390056460d87dda39c45e45b3d542b378
parente39ee01821d537b3b249b0c136bb150734016c35 (diff)
downloadbusybox-w32-11e69471be27de28aefef931ec26912a6da7bed7.tar.gz
busybox-w32-11e69471be27de28aefef931ec26912a6da7bed7.tar.bz2
busybox-w32-11e69471be27de28aefef931ec26912a6da7bed7.zip
Fix a bug, ignore the source path when installing to a directory.
We may be installing symlinks, so use lstat/lchown. Make use of bb_getopt_ulflags and cp_mv_stat2, save 100 bytes.
-rw-r--r--coreutils/install.c86
1 files changed, 41 insertions, 45 deletions
diff --git a/coreutils/install.c b/coreutils/install.c
index 95bb59463..9a1306746 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -18,8 +18,6 @@
18 * 18 *
19 * TODO: -d option, need a way of recursively making directories and changing 19 * TODO: -d option, need a way of recursively making directories and changing
20 * owner/group, will probably modify bb_make_directory(...) 20 * owner/group, will probably modify bb_make_directory(...)
21 * Use bb_getopt_ulflags(...) ?
22 *
23 */ 21 */
24 22
25#include <sys/stat.h> 23#include <sys/stat.h>
@@ -30,50 +28,51 @@
30#include <string.h> 28#include <string.h>
31#include <unistd.h> 29#include <unistd.h>
32 30
33#include "libbb.h" 31#include "busybox.h"
32#include "libcoreutils/coreutils.h"
33
34#define INSTALL_OPT_CMD 1
35#define INSTALL_OPT_DIRECTORY 2
36#define INSTALL_OPT_PRESERVE_TIME 4
37#define INSTALL_OPT_STRIP 8
38#define INSTALL_OPT_GROUP 16
39#define INSTALL_OPT_MODE 32
40#define INSTALL_OPT_OWNER 64
34 41
35extern int install_main(int argc, char **argv) 42extern int install_main(int argc, char **argv)
36{ 43{
37 struct stat statbuf; 44 struct stat statbuf;
38 int i; 45 mode_t mode = 0755;
39 int ret = EXIT_SUCCESS;
40 uid_t uid = -1; 46 uid_t uid = -1;
41 gid_t gid = -1; 47 gid_t gid = -1;
42 int copy_flags = 0; 48 char *gid_str;
43 int strip_flag = 0; 49 char *uid_str;
44 int dir_flag = 0; 50 char *mode_str;
45 mode_t mode = 0755; 51 int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
52 int ret = EXIT_SUCCESS;
53 int flags;
54 int i;
46 55
47 /* -c exists for backwards compatability, its needed */ 56 /* -c exists for backwards compatability, its needed */
48 while ((i = getopt(argc, argv, "cdg:m:o:ps")) != -1) { 57 flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* 'a' must be 2nd */
49 switch (i) { 58
50 case 'd': /* Create directories */ 59 /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */
51 dir_flag = 1; 60 if (flags & INSTALL_OPT_PRESERVE_TIME) {
52 break; 61 copy_flags |= FILEUTILS_PRESERVE_STATUS;
53 case 'g': /* group */ 62 }
54 gid = get_ug_id(optarg, my_getgrnam); 63 if (flags & INSTALL_OPT_GROUP) {
55 break; 64 gid = get_ug_id(gid_str, my_getgrnam);
56 case 'm': /* mode */ 65 }
57 bb_parse_mode(optarg, &mode); 66 if (flags & INSTALL_OPT_MODE) {
58 break; 67 bb_parse_mode(mode_str, &mode);
59 case 'o': /* owner */ 68 }
60 uid = get_ug_id(optarg, my_getpwnam); 69 if (flags & INSTALL_OPT_OWNER) {
61 break; 70 uid = get_ug_id(uid_str, my_getpwnam);
62 case 'p': /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */
63 copy_flags |= FILEUTILS_PRESERVE_STATUS;
64 break;
65 case 's': /* Strip binaries */
66 strip_flag = 1;
67 /* Fall through */
68 case 'c':
69 /* do nothing */
70 break;
71 default:
72 bb_show_usage();
73 }
74 } 71 }
75 72
76 if (dir_flag) { 73 /* Create directories */
74 if (flags & INSTALL_OPT_DIRECTORY) {
75
77 for (argv += optind; *argv; argv++) { 76 for (argv += optind; *argv; argv++) {
78 unsigned char *dir_name = *argv; 77 unsigned char *dir_name = *argv;
79 unsigned char *argv_ptr; 78 unsigned char *argv_ptr;
@@ -86,7 +85,7 @@ extern int install_main(int argc, char **argv)
86 if ((dir_name[0] == '.') && ((dir_name[1] == '\0') || ((dir_name[1] == '.') && (dir_name[2] == '\0')))) { 85 if ((dir_name[0] == '.') && ((dir_name[1] == '\0') || ((dir_name[1] == '.') && (dir_name[2] == '\0')))) {
87 break; 86 break;
88 } 87 }
89 if (chown(dir_name, uid, gid) == -1) { 88 if (lchown(dir_name, uid, gid) == -1) {
90 bb_perror_msg("cannot change ownership of %s", argv_ptr); 89 bb_perror_msg("cannot change ownership of %s", argv_ptr);
91 ret |= EXIT_FAILURE; 90 ret |= EXIT_FAILURE;
92 } 91 }
@@ -97,16 +96,13 @@ extern int install_main(int argc, char **argv)
97 } 96 }
98 return(ret); 97 return(ret);
99 } 98 }
100 99
101 if ((stat(argv[argc - 1], &statbuf) == -1) && (errno != ENOENT)) { 100 cp_mv_stat2(argv[argc - 1], &statbuf, lstat);
102 bb_perror_msg_and_die("stat failed for %s: ", argv[argc - 1]);
103 }
104
105 for (i = optind; i < argc - 1; i++) { 101 for (i = optind; i < argc - 1; i++) {
106 unsigned char *dest; 102 unsigned char *dest;
107 103
108 if (S_ISDIR(statbuf.st_mode)) { 104 if (S_ISDIR(statbuf.st_mode)) {
109 dest = concat_path_file(argv[argc - 1], argv[i]); 105 dest = concat_path_file(argv[argc - 1], basename(argv[i]));
110 } else { 106 } else {
111 dest = argv[argc - 1]; 107 dest = argv[argc - 1];
112 } 108 }
@@ -119,11 +115,11 @@ extern int install_main(int argc, char **argv)
119 } 115 }
120 116
121 /* Set the user and group id */ 117 /* Set the user and group id */
122 if (chown(dest, uid, gid) == -1) { 118 if (lchown(dest, uid, gid) == -1) {
123 bb_perror_msg("cannot change ownership of %s", dest); 119 bb_perror_msg("cannot change ownership of %s", dest);
124 ret |= EXIT_FAILURE; 120 ret |= EXIT_FAILURE;
125 } 121 }
126 if (strip_flag) { 122 if (flags & INSTALL_OPT_STRIP) {
127 if (execlp("strip", "strip", dest, NULL) == -1) { 123 if (execlp("strip", "strip", dest, NULL) == -1) {
128 bb_error_msg("strip failed"); 124 bb_error_msg("strip failed");
129 ret |= EXIT_FAILURE; 125 ret |= EXIT_FAILURE;