Add the "install" applet, move get_ug_id to libbb as its used by chown, chgrp and install.
No binary (build failed)
—
(log yok)
| @@ -218,6 +218,12 @@ config CONFIG_ID | |
| help | |
| id displays the current user and group ID names. | |
| + | config CONFIG_INSTALL |
| + | bool "install" |
| + | default n |
| + | help |
| + | Copy files and set attributes. |
| + | |
| config CONFIG_LENGTH | |
| bool "length" | |
| default n | |
| @@ -47,6 +47,7 @@ COREUTILS-$(CONFIG_FOLD) += fold.o | |
| COREUTILS-$(CONFIG_HEAD) += head.o | |
| COREUTILS-$(CONFIG_HOSTID) += hostid.o | |
| COREUTILS-$(CONFIG_ID) += id.o | |
| + | COREUTILS-$(CONFIG_INSTALL) += install.o |
| COREUTILS-$(CONFIG_LENGTH) += length.o | |
| COREUTILS-$(CONFIG_LN) += ln.o | |
| COREUTILS-$(CONFIG_LOGNAME) += logname.o | |
| @@ -59,10 +59,7 @@ int chgrp_main(int argc, char **argv) | |
| argv += optind; | |
| /* Find the selected group */ | |
| - | gid = strtoul(*argv, &p, 10); /* maybe it's already numeric */ |
| - | if (*p || (p == *argv)) { /* trailing chars or nonnumeric */ |
| - | gid = my_getgrnam(*argv); |
| - | } |
| + | gid = get_ug_id(*argv, my_getgrnam); |
| ++argv; | |
| /* Ok, ready to do the deed now */ | |
| @@ -53,19 +53,6 @@ static int fileAction(const char *fileName, struct stat *statbuf, void* junk) | |
| #define FLAG_R 1 | |
| #define FLAG_h 2 | |
| - | static unsigned long get_ug_id(const char *s, long (*my_getxxnam)(const char *)) |
| - | { |
| - | unsigned long r; |
| - | char *p; |
| - | |
| - | r = strtoul(s, &p, 10); |
| - | if (*p || (s == p)) { |
| - | r = my_getxxnam(s); |
| - | } |
| - | |
| - | return r; |
| - | } |
| - | |
| int chown_main(int argc, char **argv) | |
| { | |
| int flags; | |
| @@ -0,0 +1,102 @@ | |
| + | /* |
| + | * Copyright (C) 2003 by Glenn McGrath <[email protected]> |
| + | * |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | * |
| + | * |
| + | * TODO: -d option, need a way of recursively making directories and changing |
| + | * owner/group, will probably modify bb_make_directory(...) |
| + | * Use bb_getopt_ulflags(...) ? |
| + | * |
| + | */ |
| + | |
| + | #include <sys/stat.h> |
| + | #include <sys/types.h> |
| + | #include <errno.h> |
| + | #include <getopt.h> |
| + | #include <stdlib.h> |
| + | #include <unistd.h> |
| + | |
| + | #include "libbb.h" |
| + | |
| + | extern int install_main(int argc, char **argv) |
| + | { |
| + | struct stat statbuf; |
| + | int i; |
| + | int ret = EXIT_SUCCESS; |
| + | uid_t uid = -1; |
| + | gid_t gid = -1; |
| + | int copy_flags = 0; |
| + | int strip_flag = 0; |
| + | mode_t mode = 0755; |
| + | |
| + | /* -c exists for backwards compatability, its needed */ |
| + | while ((i = getopt(argc, argv, "cg:m:o:ps")) != -1) { |
| + | switch (i) { |
| + | case 'g': /* group */ |
| + | gid = get_ug_id(optarg, my_getgrnam); |
| + | break; |
| + | case 'm': /* mode */ |
| + | bb_parse_mode(optarg, &mode); |
| + | break; |
| + | case 'o': /* owner */ |
| + | uid = get_ug_id(optarg, my_getpwnam); |
| + | break; |
| + | case 'p': /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ |
| + | copy_flags |= FILEUTILS_PRESERVE_STATUS; |
| + | break; |
| + | case 's': /* Strip binaries */ |
| + | strip_flag = 1; |
| + | break; |
| + | default: |
| + | bb_show_usage(); |
| + | } |
| + | } |
| + | |
| + | if ((stat(argv[argc - 1], &statbuf) == -1) && (errno != ENOENT)) { |
| + | bb_perror_msg_and_die("stat failed for %s: ", argv[argc - 1]); |
| + | } |
| + | |
| + | for (i = optind; i < argc - 1; i++) { |
| + | unsigned char *dest; |
| + | |
| + | if (S_ISDIR(statbuf.st_mode)) { |
| + | dest = concat_path_file(argv[argc - 1], argv[i]); |
| + | } else { |
| + | dest = argv[argc - 1]; |
| + | } |
| + | ret |= copy_file(argv[i], dest, copy_flags); |
| + | |
| + | /* Set the file mode */ |
| + | if (chmod(dest, mode) == -1) { |
| + | bb_perror_msg("cannot change permissions of %s", dest); |
| + | ret |= EXIT_FAILURE; |
| + | } |
| + | |
| + | /* Set the user and group id */ |
| + | if (chown(dest, uid, gid) == -1) { |
| + | bb_perror_msg("cannot change ownership of %s", dest); |
| + | ret |= EXIT_FAILURE; |
| + | } |
| + | if (strip_flag) { |
| + | if (execlp("strip", "strip", dest, NULL) == -1) { |
| + | bb_error_msg("strip failed"); |
| + | ret |= EXIT_FAILURE; |
| + | } |
| + | } |
| + | } |
| + | |
| + | return(ret); |
| + | } |
| @@ -283,6 +283,9 @@ | |
| #ifdef CONFIG_INSMOD | |
| APPLET(insmod, insmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER) | |
| #endif | |
| + | #ifdef CONFIG_INSTALL |
| + | APPLET(install, install_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) |
| + | #endif |
| #ifdef CONFIG_IP | |
| APPLET(ip, ip_main, _BB_DIR_BIN, _BB_SUID_NEVER) | |
| #endif | |
| @@ -467,5 +467,6 @@ extern void print_login_prompt(void); | |
| extern void vfork_daemon_rexec(int argc, char **argv, char *foreground_opt); | |
| extern void get_terminal_width_height(int fd, int *width, int *height); | |
| + | extern unsigned long get_ug_id(const char *s, long (*my_getxxnam)(const char *)); |
| #endif /* __LIBCONFIG_H__ */ | |
| @@ -1239,6 +1239,18 @@ | |
| USAGE_INSMOD_MAP("\t-m\tOutput load map to stdout") \ | |
| "\t-x\tdo not export externs\n" | |
| + | #define install_trivial_usage \ |
| + | "[cgmops] [sources] <dest|directory>" |
| + | #define install_full_usage \ |
| + | "copy files and set attributes\n\n" \ |
| + | "Options:\n" \ |
| + | "\t-c\tcopy the file, default\n" \ |
| + | "\t-g\tset group ownership\n" \ |
| + | "\t-m\tset permission modes\n" \ |
| + | "\t-o\tset ownership\n" \ |
| + | "\t-p\tpreserve date\n" \ |
| + | "\t-s\tstrip symbol tables\n" |
| + | |
| #define ip_trivial_usage \ | |
| "[ OPTIONS ] { address | link | route | tunnel } { COMMAND | help }" | |
| #define ip_full_usage \ | |
| @@ -30,7 +30,7 @@ LIBBB_SRC:= \ | |
| create_icmp6_socket.c device_open.c dump.c error_msg.c \ | |
| error_msg_and_die.c find_mount_point.c find_pid_by_name.c \ | |
| find_root_device.c fgets_str.c full_read.c full_write.c get_console.c \ | |
| - | get_last_path_component.c get_line_from_file.c \ |
| + | get_last_path_component.c get_line_from_file.c get_ug_id.c \ |
| get_terminal_width_height.c herror_msg.c herror_msg_and_die.c \ | |
| human_readable.c inet_common.c inode_hash.c interface.c isdirectory.c \ | |
| kernel_version.c last_char_is.c llist_add_to.c login.c loop.c \ | |
| @@ -0,0 +1,28 @@ | |
| + | /* |
| + | * This program is free software; you can redistribute it and/or modify |
| + | * it under the terms of the GNU General Public License as published by |
| + | * the Free Software Foundation; either version 2 of the License, or |
| + | * (at your option) any later version. |
| + | * |
| + | * This program is distributed in the hope that it will be useful, |
| + | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| + | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| + | * GNU Library General Public License for more details. |
| + | * |
| + | * You should have received a copy of the GNU General Public License |
| + | * along with this program; if not, write to the Free Software |
| + | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| + | */ |
| + | |
| + | extern unsigned long get_ug_id(const char *s, long (*my_getxxnam)(const char *)) |
| + | { |
| + | unsigned long r; |
| + | char *p; |
| + | |
| + | r = strtoul(s, &p, 10); |
| + | if (*p || (s == p)) { |
| + | r = my_getxxnam(s); |
| + | } |
| + | |
| + | return r; |
| + | } |