diff options
Diffstat (limited to 'busybox/libbb')
-rw-r--r-- | busybox/libbb/.cvsignore | 1 | ||||
-rw-r--r-- | busybox/libbb/Makefile.in | 2 | ||||
-rw-r--r-- | busybox/libbb/concat_path_file.c | 4 | ||||
-rw-r--r-- | busybox/libbb/copyfd.c | 78 | ||||
-rw-r--r-- | busybox/libbb/getopt_ulflags.c | 356 | ||||
-rw-r--r-- | busybox/libbb/interface.c | 32 | ||||
-rw-r--r-- | busybox/libbb/messages.c | 3 | ||||
-rw-r--r-- | busybox/libbb/syscalls.c | 61 |
8 files changed, 344 insertions, 193 deletions
diff --git a/busybox/libbb/.cvsignore b/busybox/libbb/.cvsignore deleted file mode 100644 index 2bbe016..0000000 --- a/busybox/libbb/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -loop.h diff --git a/busybox/libbb/Makefile.in b/busybox/libbb/Makefile.in index 85d4a96..d4c5ec1 100644 --- a/busybox/libbb/Makefile.in +++ b/busybox/libbb/Makefile.in @@ -53,7 +53,7 @@ LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC)) LIBBB_MSRC0:=$(srcdir)/messages.c LIBBB_MOBJ0:=full_version.o \ memory_exhausted.o invalid_date.o io_error.o \ - write_error.o name_longer_than_foo.o unknown.o \ + read_error.o write_error.o name_longer_than_foo.o unknown.o \ can_not_create_raw_socket.o perm_denied_are_you_root.o \ shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o \ securetty_file.o motd_file.o \ diff --git a/busybox/libbb/concat_path_file.c b/busybox/libbb/concat_path_file.c index 77c0545..00233ad 100644 --- a/busybox/libbb/concat_path_file.c +++ b/busybox/libbb/concat_path_file.c @@ -34,11 +34,11 @@ extern char *concat_path_file(const char *path, const char *filename) char *lc; if (!path) - path=""; + path = ""; lc = last_char_is(path, '/'); while (*filename == '/') filename++; - bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename); + bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL ? "/" : ""), filename); return outbuf; } diff --git a/busybox/libbb/copyfd.c b/busybox/libbb/copyfd.c index bf0a390..27d65a4 100644 --- a/busybox/libbb/copyfd.c +++ b/busybox/libbb/copyfd.c @@ -2,7 +2,7 @@ /* * Utility routines. * - * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> + * Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> * * 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 @@ -25,6 +25,7 @@ #include <unistd.h> #include "busybox.h" +#include "libbb.h" #if BUFSIZ < 4096 @@ -33,46 +34,59 @@ #endif -/* If size is 0 copy until EOF */ -static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size) +static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size2) { - size_t read_total = 0; - RESERVE_CONFIG_BUFFER(buffer,BUFSIZ); + int status; + size_t xread, wrote, total, size = size2; - while ((size == 0) || (read_total < size)) { - size_t read_try; - ssize_t read_actual; + if (src_fd < 0) { + return -1; + } - if ((size == 0) || (size - read_total > BUFSIZ)) { - read_try = BUFSIZ; - } else { - read_try = size - read_total; - } + if (size == 0) { + /* If size is 0 copy until EOF */ + size = ULONG_MAX; + } - read_actual = safe_read(src_fd, buffer, read_try); - if (read_actual > 0) { - if ((dst_fd >= 0) && (bb_full_write(dst_fd, buffer, (size_t) read_actual) != read_actual)) { - bb_perror_msg(bb_msg_write_error); /* match Read error below */ + { + RESERVE_CONFIG_BUFFER(buffer,BUFSIZ); + total = 0; + wrote = 0; + status = -1; + while (total < size) + { + xread = BUFSIZ; + if (size < (total + BUFSIZ)) + xread = size - total; + xread = bb_full_read(src_fd, buffer, xread); + if (xread > 0) { + if (dst_fd < 0) { + /* A -1 dst_fd means we need to fake it... */ + wrote = xread; + } else { + wrote = bb_full_write(dst_fd, buffer, xread); + } + if (wrote < xread) { + bb_perror_msg(bb_msg_write_error); + break; + } + total += wrote; + } else if (xread < 0) { + bb_perror_msg(bb_msg_read_error); + break; + } else if (xread == 0) { + /* All done. */ + status = 0; break; } } - else if (read_actual == 0) { - if (size) { - bb_error_msg("Unable to read all data"); - } - break; - } else { - /* read_actual < 0 */ - bb_perror_msg("Read error"); - break; - } - - read_total += read_actual; + RELEASE_CONFIG_BUFFER(buffer); } - RELEASE_CONFIG_BUFFER(buffer); - - return(read_total); + if (status == 0 || total) + return total; + /* Some sortof error occured */ + return -1; } diff --git a/busybox/libbb/getopt_ulflags.c b/busybox/libbb/getopt_ulflags.c index 39a7d1d..6197e8d 100644 --- a/busybox/libbb/getopt_ulflags.c +++ b/busybox/libbb/getopt_ulflags.c @@ -26,146 +26,270 @@ #include <stdlib.h> #include "libbb.h" -/* -You can set bb_opt_complementaly as string with one or more -complementaly or incongruously options. -If sequential founded option haved from this string -then your incongruously pairs unsets and complementaly make add sets. -Format: -one char - option for check, -chars - complementaly option for add sets. -- chars - option triggered for unsets. -~ chars - option incongruously. -* - option list, called add_to_list(*ptr_from_usaged, optarg) -: - separator. -Example: du applet can have options "-s" and "-d size" -If getopt found -s then -d option flag unset or if found -d then -s unset. -For this result you must set bb_opt_complementaly = "s-d:d-s". -Result have last option flag only from called arguments. -Warning! You can check returned flag, pointer to "d:" argument seted -to own optarg always. -Example two: cut applet must only one type of list may be specified, -and -b, -c and -f incongruously option, overwited option is error also. -You must set bb_opt_complementaly = "b~cf:c~bf:f~bc". -If called have more one specified, return value have error flag - -high bite set (0x80000000UL). -Example three: grep applet can have one or more "-e pattern" arguments. -You should use bb_getopt_ulflags() as -llist_t *paterns; -bb_opt_complementaly = "e*"; -bb_getopt_ulflags (argc, argv, "e:", &paterns); +/* Documentation ! + +unsigned long +bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) + + The command line options must be declared in const char + *applet_opts as a string of chars, for example: + + flags = bb_getopt_ulflags(argc, argv, "rnug"); + + If one of the given options is found, a flag value is added to + the return value (an unsigned long). + + The flag value is determined by the position of the char in + applet_opts string. For example, in the above case: + + flags = bb_getopt_ulflags(argc, argv, "rnug"); + + "r" will add 1 (bit 1 : 0x01) + "n" will add 2 (bit 2 : 0x02) + "u will add 4 (bit 3 : 0x03) + "g" will add 8 (bit 4 : 0x04) + + and so on. You can also look at the return value as a bit + field and each option sets one of bits. + + ":" If one of the options requires an argument, then add a ":" + after the char in applet_opts and provide a pointer to store + the argument. For example: + + char *pointer_to_arg_for_a; + char *pointer_to_arg_for_b; + char *pointer_to_arg_for_c; + char *pointer_to_arg_for_d; + + flags = bb_getopt_ulflags(argc, argv, "a:b:c:d:", + &pointer_to_arg_for_a, &pointer_to_arg_for_b, + &pointer_to_arg_for_c, &pointer_to_arg_for_d); + + The type of the pointer (char* or llist_t *) may be controlled + by the "*" special character that is set in the external string + bb_opt_complementaly (see below for more info). + +static const struct option bb_default_long_options[] + + This struct allows you to define long options. The syntax for + declaring the array is just like that of getopt's longopts. + + static const struct option applet_long_options[] = { + { "verbose", 0, 0, "v" }, + { 0, 0, 0, 0 } + }; + bb_applet_long_options = applet_long_options; + + The first parameter is the long option name that you would pass + to the applet (without the dashes). + + The second field determines whether the option has an argument. + You can set this to 0, 1, or 2, or you can use the long named + defines of no_argument, required_argument, and optional_argument. + + The third argument is used only when the long option does not + have a corresponding short option. In that case, it should be + an integer pointer. Otherwise (and normally), it should just + bet set to NULL. + + The last argument is the corresponding short option (if there + is one of course). + + Note: a good applet will make long options configurable via the + config process and not a required feature. The current standard + is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS. + +const char *bb_opt_complementaly + + ":" The colon (":") is used to separate groups of two or more chars + and/or groups of chars and special characters (stating some + conditions to be checked). + + "abc" If groups of two or more chars are specified, the first char + is the main option and the other chars are secondary options. + Their flags will be turned on if the main option is found even + if they are not specifed on the command line. For example: + + bb_opt_complementaly = "abc"; + + flags = bb_getopt_ulflags(argc, argv, "abcd") + + If getopt() finds "-a" on the command line, then + bb_getopt_ulflags's return value will be as if "-a -b -c" were + found. + +Special characters: + + "-" A dash between two options causes the second of the two + to be unset (and ignored) if it is given on the command line. + + For example: + The du applet has the options "-s" and "-d depth". If + bb_getopt_ulflags finds -s, then -d is unset or if it finds -d + then -s is unset. (Note: busybox implements the GNU + "--max-depth" option as "-d".) To obtain this behavior, you + set bb_opt_complementaly = "s-d:d-s". Only one flag value is + added to bb_getopt_ulflags's return value depending on the + position of the options on the command line. If one of the + two options requires an argument pointer (":" in applet_opts + as in "d:") optarg is set accordingly. + + char *smax_print_depth; + + bb_opt_complementaly = "s-d:d-s"; + opt = bb_getopt_ulflags(argc, argv, "sd:", &smax_print_depth); + + if (opt & 2) { + max_print_depth = bb_xgetularg10_bnd(smax_print_depth, + 0, INT_MAX); + } + + "~" A tilde between two options, or between an option and a group + of options, means that they are mutually exclusive. Unlike + the "-" case above, an error will be forced if the options + are used together. + + For example: + The cut applet must have only one type of list specified, so + -b, -c and -f are mutally exclusive and should raise an error + if specified together. In this case you must set + bb_opt_complementaly = "b~cf:c~bf:f~bc". If two of the + mutually exclusive options are found, bb_getopt_ulflags's + return value will have the error flag set (BB_GETOPT_ERROR) so + that we can check for it: + + if (flags & BB_GETOPT_ERROR) + bb_show_usage(); + + "*" A star after a char in bb_opt_complementaly means that the + option can occur multiple times: + + For example: + The grep applet can have one or more "-e pattern" arguments. + In this case you should use bb_getopt_ulflags() as follows: + + llist_t *patterns = NULL; + + (this pointer must be initializated to NULL if the list is empty + as required by *llist_add_to(llist_t *old_head, char *new_item).) + + bb_opt_complementaly = "e*"; + + bb_getopt_ulflags(argc, argv, "e:", &patterns); + $ grep -e user -e root /etc/passwd + root:x:0:0:root:/root:/bin/bash + user:x:500:500::/home/user:/bin/bash + */ const char *bb_opt_complementaly; -typedef struct -{ +typedef struct { unsigned char opt; char list_flg; unsigned long switch_on; unsigned long switch_off; unsigned long incongruously; - void **optarg; /* char **optarg or llist_t **optarg */ + void **optarg; /* char **optarg or llist_t **optarg */ } t_complementaly; /* You can set bb_applet_long_options for parse called long options */ static const struct option bb_default_long_options[] = { - /* { "help", 0, NULL, '?' }, */ +/* { "help", 0, NULL, '?' }, */ { 0, 0, 0, 0 } }; const struct option *bb_applet_long_options = bb_default_long_options; - unsigned long bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...) { - unsigned long flags = 0; - t_complementaly complementaly[sizeof(flags) * 8 + 1]; - int c; - const unsigned char *s; - t_complementaly *on_off; - va_list p; - - va_start (p, applet_opts); - - /* skip GNU extension */ - s = applet_opts; - if(*s == '+' || *s == '-') - s++; - - c = 0; - on_off = complementaly; - for (; *s; s++) { - if(c >= (sizeof(flags)*8)) - break; - on_off->opt = *s; - on_off->switch_on = (1 << c); - on_off->list_flg = 0; - on_off->switch_off = 0; - on_off->incongruously = 0; - on_off->optarg = NULL; - if (s[1] == ':') { - on_off->optarg = va_arg (p, void **); - do + unsigned long flags = 0; + t_complementaly complementaly[sizeof(flags) * 8 + 1]; + int c; + const unsigned char *s; + t_complementaly *on_off; + va_list p; + + va_start (p, applet_opts); + + /* skip GNU extension */ + s = applet_opts; + if(*s == '+' || *s == '-') s++; - while (s[1] == ':'); + + c = 0; + on_off = complementaly; + for (; *s; s++) { + if(c >= (sizeof(flags)*8)) + break; + on_off->opt = *s; + on_off->switch_on = (1 << c); + on_off->list_flg = 0; + on_off->switch_off = 0; + on_off->incongruously = 0; + on_off->optarg = NULL; + if (s[1] == ':') { + on_off->optarg = va_arg (p, void **); + do + s++; + while (s[1] == ':'); + } + on_off++; + c++; } - on_off++; - c++; - } - on_off->opt = 0; - c = 0; - for (s = bb_opt_complementaly; s && *s; s++) { - t_complementaly *pair; - - if (*s == ':') { - c = 0; - continue; - } - if (c) - continue; - for (on_off = complementaly; on_off->opt; on_off++) - if (on_off->opt == *s) - break; - pair = on_off; - for(s++; *s && *s != ':'; s++) { - if (*s == '-' || *s == '~') { - c = *s; - } else if(*s == '*') { - pair->list_flg++; - } else { - unsigned long *pair_switch = &(pair->switch_on); - - if(c) - pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); - for (on_off = complementaly; on_off->opt; on_off++) - if (on_off->opt == *s) { - *pair_switch |= on_off->switch_on; - break; - } - } - } - s--; - } - - while ((c = getopt_long (argc, argv, applet_opts, - bb_applet_long_options, NULL)) > 0) { - for (on_off = complementaly; on_off->opt != c; on_off++) { - if(!on_off->opt) - bb_show_usage (); + on_off->opt = 0; + c = 0; + for (s = bb_opt_complementaly; s && *s; s++) { + t_complementaly *pair; + + if (*s == ':') { + c = 0; + continue; + } + if (c) + continue; + for (on_off = complementaly; on_off->opt; on_off++) + if (on_off->opt == *s) + break; + pair = on_off; + for(s++; *s && *s != ':'; s++) { + if (*s == '-' || *s == '~') { + c = *s; + } else if(*s == '*') { + pair->list_flg++; + } else { + unsigned long *pair_switch = &(pair->switch_on); + if(c) + pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously); + for (on_off = complementaly; on_off->opt; on_off++) + if (on_off->opt == *s) { + *pair_switch |= on_off->switch_on; + break; + } + } + } + s--; } - if(flags & on_off->incongruously) - flags |= 0x80000000UL; - flags &= ~on_off->switch_off; - flags |= on_off->switch_on; - if(on_off->list_flg) { - *(llist_t **)(on_off->optarg) = - llist_add_to(*(llist_t **)(on_off->optarg), optarg); - } else if (on_off->optarg) { - *(char **)(on_off->optarg) = optarg; + + while ((c = getopt_long (argc, argv, applet_opts, + bb_applet_long_options, NULL)) > 0) { + for (on_off = complementaly; on_off->opt != c; on_off++) { + if(!on_off->opt) + bb_show_usage (); + } + if(flags & on_off->incongruously) + flags |= BB_GETOPT_ERROR; + flags &= ~on_off->switch_off; + flags |= on_off->switch_on; + if(on_off->list_flg) { + *(llist_t **)(on_off->optarg) = + llist_add_to(*(llist_t **)(on_off->optarg), optarg); + } else if (on_off->optarg) { + *(char **)(on_off->optarg) = optarg; + } } - } - return flags; + + return flags; } diff --git a/busybox/libbb/interface.c b/busybox/libbb/interface.c index fe2d0b4..c4aa032 100644 --- a/busybox/libbb/interface.c +++ b/busybox/libbb/interface.c @@ -888,6 +888,20 @@ static int sockets_open(int family) return sfd; } +#ifdef CONFIG_FEATURE_CLEAN_UP +static void sockets_close(void) +{ + struct aftype **aft; + for (aft = aftypes; *aft != NULL; aft++) { + struct aftype *af = *aft; + if( af->fd != -1 ) { + close(af->fd); + af->fd = -1; + } + } +} +#endif + /* like strcmp(), but knows about numbers */ static int nstrcmp(const char *a, const char *b) { @@ -1223,17 +1237,13 @@ static int if_fetch(struct interface *ife) } #endif +#ifdef SIOCGIFMAP strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) - memset(&ife->map, 0, sizeof(struct ifmap)); + if (ioctl(skfd, SIOCGIFMAP, &ifr) == 0) + ife->map = ifr.ifr_map; else - memcpy(&ife->map, &ifr.ifr_map, sizeof(struct ifmap)); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) +#endif memset(&ife->map, 0, sizeof(struct ifmap)); - else - ife->map = ifr.ifr_map; #ifdef HAVE_TXQUEUELEN strcpy(ifr.ifr_name, ifname); @@ -1374,7 +1384,7 @@ static struct hwtype loop_hwtype = { #if HAVE_HWETHER #include <net/if_arp.h> -#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1 +#if (__GLIBC__ >=2 && __GLIBC_MINOR >= 1) || defined(_NEWLIB_VERSION) #include <net/ethernet.h> #else #include <linux/if_ether.h> @@ -2078,6 +2088,8 @@ int display_interfaces(char *ifname) /* Do we have to show the current setup? */ status = if_print(ifname); - close(skfd); +#ifdef CONFIG_FEATURE_CLEAN_UP + sockets_close(); +#endif exit(status < 0); } diff --git a/busybox/libbb/messages.c b/busybox/libbb/messages.c index 671c452..c3f307e 100644 --- a/busybox/libbb/messages.c +++ b/busybox/libbb/messages.c @@ -36,6 +36,9 @@ #ifdef L_write_error const char * const bb_msg_write_error = "Write Error"; #endif +#ifdef L_read_error + const char * const bb_msg_read_error = "Read Error"; +#endif #ifdef L_name_longer_than_foo const char * const bb_msg_name_longer_than_foo = "Names longer than %d chars not supported."; #endif diff --git a/busybox/libbb/syscalls.c b/busybox/libbb/syscalls.c index 9e89dbd..dac90e2 100644 --- a/busybox/libbb/syscalls.c +++ b/busybox/libbb/syscalls.c @@ -29,7 +29,7 @@ #include <sys/syscall.h> #include "libbb.h" -int sysfs( int option, unsigned int fs_index, char * buf) +int sysfs(int option, unsigned int fs_index, char * buf) { return(syscall(__NR_sysfs, option, fs_index, buf)); } @@ -39,60 +39,59 @@ int pivot_root(const char * new_root,const char * put_old) #ifndef __NR_pivot_root #warning This kernel does not support the pivot_root syscall #warning -> The pivot_root system call is being stubbed out... - /* BusyBox was compiled against a kernel that did not support - * the pivot_root system call. To make this application work, - * you will need to recompile with a kernel supporting the - * pivot_root system call. - */ - bb_error_msg("\n\nTo make this application work, you will need to recompile\n" - "BusyBox with a kernel supporting the pivot_root system call.\n"); - errno=ENOSYS; - return -1; + /* BusyBox was compiled against a kernel that did not support + * the pivot_root system call. To make this application work, + * you will need to recompile with a kernel supporting the + * pivot_root system call. + */ + bb_error_msg("\n\nTo make this application work, you will need to recompile\n" + "BusyBox with a kernel supporting the pivot_root system call.\n"); + errno = ENOSYS; + return -1; #else - return(syscall(__NR_pivot_root, new_root, put_old)); -#endif + return(syscall(__NR_pivot_root, new_root, put_old)); +#endif /* __NR_pivot_root */ } - -/* These syscalls are not included in ancient glibc versions */ +/* These syscalls are not included in ancient glibc versions, + so we have to define them ourselves, whee ! */ #if ((__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1)) int bdflush(int func, int data) { - return(syscall(__NR_bdflush, func, data)); + return(syscall(__NR_bdflush, func, data)); } #ifndef __alpha__ # define __NR_klogctl __NR_syslog int klogctl(int type, char *b, int len) { - return(syscall(__NR_klogctl, type, b, len)); + return(syscall(__NR_klogctl, type, b, len)); } -#endif +#endif /* __alpha__ */ int umount2(const char * special_file, int flags) { -#ifndef __NR_pivot_root +#ifndef __NR_umount2 #warning This kernel does not support the umount2 syscall #warning -> The umount2 system call is being stubbed out... - /* BusyBox was compiled against a kernel that did not support - * the umount2 system call. To make this application work, - * you will need to recompile with a kernel supporting the - * umount2 system call. - */ - bb_error_msg("\n\nTo make this application work, you will need to recompile\n" - "BusyBox with a kernel supporting the umount2 system call.\n"); - errno=ENOSYS; - return -1; + /* BusyBox was compiled against a kernel that did not support + * the umount2 system call. To make this application work, + * you will need to recompile with a kernel supporting the + * umount2 system call. + */ + bb_error_msg("\n\nTo make this application work, you will need to recompile\n" + "BusyBox with a kernel supporting the umount2 system call.\n"); + errno = ENOSYS; + return -1; #else - return(syscall(__NR_umount2, special_file, flags)); -#endif + return(syscall(__NR_umount2, special_file, flags)); +#endif /* __NR_pivot_root */ } - -#endif +#endif /* old glibc check */ /* END CODE */ |