Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/libbb
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (16 years ago)
- Location:
- branches/2.2.5/mindi-busybox/libbb
- Files:
-
- 20 added
- 27 deleted
- 81 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/libbb/Config.in
r821 r1765 6 6 menu "Busybox Library Tuning" 7 7 8 config CONFIG_MD5_SIZE_VS_SPEED 8 config PASSWORD_MINLEN 9 int "Minimum password length" 10 default 6 11 range 5 32 12 help 13 Minimum allowable password length. 14 15 config MD5_SIZE_VS_SPEED 9 16 int " MD5: Trade Bytes for Speed" 10 17 default 2 … … 20 27 3 (smallest) 5.1 4912 21 28 29 config FEATURE_FAST_TOP 30 bool "Faster /proc scanning code (+100 bytes)" 31 default n 32 help 33 This option makes top (and ps) ~20% faster (or 20% less CPU hungry), 34 but code size is slightly bigger. 35 36 config FEATURE_ETC_NETWORKS 37 bool "Support for /etc/networks" 38 default n 39 help 40 Enable support for network names in /etc/networks. This is 41 a rarely used feature which allows you to use names 42 instead of IP/mask pairs in route command. 43 44 config FEATURE_EDITING 45 bool "Command line editing" 46 default n 47 help 48 Enable line editing (mainly for shell command line). 49 50 config FEATURE_EDITING_MAX_LEN 51 int "Maximum length of input" 52 range 128 8192 53 default 1024 54 depends on FEATURE_EDITING 55 help 56 Line editing code uses on-stack buffers for storage. 57 You may want to decrease this parameter if your target machine 58 benefits from smaller stack usage. 59 60 config FEATURE_EDITING_FANCY_KEYS 61 bool "Additional editing keys" 62 default n 63 depends on FEATURE_EDITING 64 help 65 Enable additonal editing keys (Ctrl-E, Ctrl-U etc). 66 Arrow keys, Home/End/Delete and Ctrl-W work even without this option. 67 68 config FEATURE_EDITING_VI 69 bool "vi-style line editing commands" 70 default n 71 depends on FEATURE_EDITING 72 help 73 Enable vi-style line editing. In shells, this mode can be 74 turned on and off with "set -o vi" and "set +o vi". 75 76 config FEATURE_EDITING_HISTORY 77 int "History size" 78 range 0 99999 79 default 15 80 depends on FEATURE_EDITING 81 help 82 Specify command history size. 83 84 config FEATURE_EDITING_SAVEHISTORY 85 bool "History saving" 86 default n 87 depends on ASH && FEATURE_EDITING 88 help 89 Enable history saving in ash shell. 90 91 config FEATURE_TAB_COMPLETION 92 bool "Tab completion" 93 default n 94 depends on FEATURE_EDITING 95 help 96 Enable tab completion. 97 98 config FEATURE_USERNAME_COMPLETION 99 bool "Username completion" 100 default n 101 depends on FEATURE_TAB_COMPLETION 102 help 103 Enable username completion. 104 105 config FEATURE_EDITING_FANCY_PROMPT 106 bool "Fancy shell prompts" 107 default n 108 depends on FEATURE_EDITING 109 help 110 Setting this option allows for prompts to use things like \w and 111 \$ and escape codes. 112 113 config MONOTONIC_SYSCALL 114 bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" 115 default y 116 help 117 Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring 118 time intervals (time, ping, traceroute etc need this). 119 Probably requires Linux 2.6+. If not selected, gettimeofday 120 will be used instead (which gives wrong results if date/time 121 is reset). 122 123 config IOCTL_HEX2STR_ERROR 124 bool "Use ioctl names rather than hex values in error messages" 125 default y 126 help 127 Use ioctl names rather than hex values in error messages 128 (e.g. VT_DISALLOCATE rather than 0x5608). If disabled this 129 saves about 1400 bytes. 22 130 endmenu -
branches/2.2.5/mindi-busybox/libbb/ask_confirmation.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 25 12 */ 26 13 27 #include <stdio.h>28 #include <ctype.h>29 14 #include "libbb.h" 30 15 -
branches/2.2.5/mindi-busybox/libbb/bb_askpass.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h>12 #include <string.h>13 #include <unistd.h>14 #include <fcntl.h>15 #include <signal.h>16 11 #include <termios.h> 17 #include <sys/ioctl.h>18 12 19 13 #include "libbb.h" 20 #define PWD_BUFFER_SIZE 25621 22 14 23 15 /* do nothing signal handler */ … … 28 20 char *bb_askpass(int timeout, const char * prompt) 29 21 { 22 /* Was static char[BIGNUM] */ 23 enum { sizeof_passwd = 128 }; 24 static char *passwd; 25 30 26 char *ret; 31 int i , size;27 int i; 32 28 struct sigaction sa; 33 29 struct termios old, new; 34 static char passwd[PWD_BUFFER_SIZE]; 30 31 if (!passwd) 32 passwd = xmalloc(sizeof_passwd); 33 memset(passwd, 0, sizeof_passwd); 35 34 36 35 tcgetattr(STDIN_FILENO, &old); 37 36 tcflush(STDIN_FILENO, TCIFLUSH); 38 39 size = sizeof(passwd);40 ret = passwd;41 memset(passwd, 0, size);42 37 43 38 fputs(prompt, stdout); … … 56 51 } 57 52 58 if (read(STDIN_FILENO, passwd, size-1) <= 0) { 59 ret = NULL; 60 } else { 61 for(i = 0; i < size && passwd[i]; i++) { 62 if (passwd[i]== '\r' || passwd[i] == '\n') { 63 passwd[i]= 0; 64 break; 65 } 66 } 53 ret = NULL; 54 /* On timeout, read will hopefully be interrupted by SIGALRM, 55 * and we return NULL */ 56 if (read(STDIN_FILENO, passwd, sizeof_passwd-1) > 0) { 57 ret = passwd; 58 i = 0; 59 /* Last byte is guaranteed to be 0 60 (read did not overwrite it) */ 61 do { 62 if (passwd[i] == '\r' || passwd[i] == '\n') 63 passwd[i] = '\0'; 64 } while (passwd[i++]); 67 65 } 68 66 … … 72 70 73 71 tcsetattr(STDIN_FILENO, TCSANOW, &old); 74 fputs("\n", stdout);72 putchar('\n'); 75 73 fflush(stdout); 76 74 return ret; 77 75 } 78 -
branches/2.2.5/mindi-busybox/libbb/bb_do_delay.c
r821 r1765 8 8 */ 9 9 10 #include <time.h>11 #include <unistd.h>12 10 #include "libbb.h" 13 11 -
branches/2.2.5/mindi-busybox/libbb/bb_pwd.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under the GPL v2 , see the file LICENSE in this tarball.7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 8 8 */ 9 9 10 #include "libbb.h" 10 11 11 #ifdef L_bb_getgrgid 12 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more 13 * flexible : 14 * 15 * if bufsize is > 0 char *group cannot be set to NULL. 16 * On success groupname is written on static allocated buffer 17 * group (and a pointer to it is returned). 18 * On failure gid as string is written to static allocated 19 * buffer group and NULL is returned. 20 * if bufsize is = 0 char *group can be set to NULL. 21 * On success groupname is returned. 22 * On failure NULL is returned. 23 * if bufsize is < 0 char *group can be set to NULL. 24 * On success groupname is returned. 25 * On failure an error message is printed and 26 * the program exits. 27 */ 12 #define assert(x) ((void)0) 28 13 29 #include "libbb.h" 30 #include "grp_.h" 14 /* internal function for bb_getpwuid and bb_getgrgid */ 15 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more 16 * flexible: 17 * 18 * bufsize > 0: If idname is not NULL it is copied to buffer, 19 * and buffer is returned. Else id as string is written 20 * to buffer, and NULL is returned. 21 * 22 * bufsize == 0: idname is returned. 23 * 24 * bufsize < 0: If idname is not NULL it is returned. 25 * Else an error message is printed and the program exits. 26 */ 27 static char* bb_getug(char *buffer, int bufsize, char *idname, long id, char prefix) 28 { 29 if (bufsize > 0) { 30 assert(buffer != NULL); 31 if (idname) { 32 return safe_strncpy(buffer, idname, bufsize); 33 } 34 snprintf(buffer, bufsize, "%ld", id); 35 } else if (bufsize < 0 && !idname) { 36 bb_error_msg_and_die("unknown %cid %ld", prefix, id); 37 } 38 return idname; 39 } 31 40 41 /* bb_getpwuid, bb_getgrgid: 42 * bb_getXXXid(buf, bufsz, id) - copy user/group name or id 43 * as a string to buf, return user/group name or NULL 44 * bb_getXXXid(NULL, 0, id) - return user/group name or NULL 45 * bb_getXXXid(NULL, -1, id) - return user/group name or exit 46 */ 47 /* gets a username given a uid */ 48 char* bb_getpwuid(char *name, int bufsize, long uid) 49 { 50 struct passwd *myuser = getpwuid(uid); 51 52 return bb_getug(name, bufsize, 53 (myuser ? myuser->pw_name : (char*)myuser), 54 uid, 'u'); 55 } 32 56 /* gets a groupname given a gid */ 33 char * bb_getgrgid(char *group, long gid, int bufsize)57 char* bb_getgrgid(char *group, int bufsize, long gid) 34 58 { 35 59 struct group *mygroup = getgrgid(gid); 36 60 37 return bb_getug(group, (mygroup) ? 38 mygroup->gr_name : (char *)mygroup, gid, bufsize, 'g'); 61 return bb_getug(group, bufsize, 62 (mygroup ? mygroup->gr_name : (char*)mygroup), 63 gid, 'g'); 39 64 } 40 #endif /* L_bb_getgrgid */41 42 #ifdef L_bb_xgetgrnam43 #include <stdio.h>44 #include <string.h>45 #include "libbb.h"46 #include "pwd_.h"47 #include "grp_.h"48 49 65 50 66 /* returns a gid given a group name */ 51 long bb_xgetgrnam(const char *name)67 long xgroup2gid(const char *name) 52 68 { 53 69 struct group *mygroup; 54 70 55 mygroup 56 if (mygroup ==NULL)71 mygroup = getgrnam(name); 72 if (mygroup == NULL) 57 73 bb_error_msg_and_die("unknown group name: %s", name); 58 74 59 return (mygroup->gr_gid);75 return mygroup->gr_gid; 60 76 } 61 #endif /* L_bb_xgetgrnam */62 63 #ifdef L_bb_xgetpwnam64 #include <stdio.h>65 #include <string.h>66 #include "libbb.h"67 #include "pwd_.h"68 #include "grp_.h"69 70 77 71 78 /* returns a uid given a username */ 72 long bb_xgetpwnam(const char *name)79 long xuname2uid(const char *name) 73 80 { 74 81 struct passwd *myuser; 75 82 76 myuser 77 if (myuser ==NULL)83 myuser = getpwnam(name); 84 if (myuser == NULL) 78 85 bb_error_msg_and_die("unknown user name: %s", name); 79 86 80 87 return myuser->pw_uid; 81 88 } 82 #endif /* L_bb_xgetpwnam */83 84 #ifdef L_bb_getpwuid85 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more86 * flexible :87 *88 * if bufsize is > 0 char *name can not be set to NULL.89 * On success username is written on the static allocated90 * buffer name (and a pointer to it is returned).91 * On failure uid as string is written to the static92 * allocated buffer name and NULL is returned.93 * if bufsize is = 0 char *name can be set to NULL.94 * On success username is returned.95 * On failure NULL is returned.96 * if bufsize is < 0 char *name can be set to NULL97 * On success username is returned.98 * On failure an error message is printed and99 * the program exits.100 */101 102 #include "libbb.h"103 #include "pwd_.h"104 105 /* gets a username given a uid */106 char * bb_getpwuid(char *name, long uid, int bufsize)107 {108 struct passwd *myuser = getpwuid(uid);109 110 return bb_getug(name, (myuser) ?111 myuser->pw_name : (char *)myuser , uid, bufsize, 'u');112 }113 #endif /* L_bb_getpwuid */114 115 #ifdef L_bb_getug116 /*117 * if bufsize is > 0 char *buffer can not be set to NULL.118 * If idname is not NULL it is written on the static119 * allocated buffer (and a pointer to it is returned).120 * if idname is NULL, id as string is written to the static121 * allocated buffer and NULL is returned.122 * if bufsize is = 0 char *buffer can be set to NULL.123 * If idname exists a pointer to it is returned,124 * else NULL is returned.125 * if bufsize is < 0 char *buffer can be set to NULL.126 * If idname exists a pointer to it is returned,127 * else an error message is printed and the program exits.128 */129 130 #include <stdio.h>131 #include <assert.h>132 #include "libbb.h"133 134 135 /* internal function for bb_getpwuid and bb_getgrgid */136 char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix)137 {138 if(bufsize > 0 ) {139 assert(buffer!=NULL);140 if(idname) {141 return safe_strncpy(buffer, idname, bufsize);142 }143 snprintf(buffer, bufsize, "%ld", id);144 } else if(bufsize < 0 && !idname) {145 bb_error_msg_and_die("unknown %cid %ld", prefix, id);146 }147 return idname;148 }149 #endif /* L_bb_getug */150 151 152 #ifdef L_get_ug_id153 /* indirect dispatcher for pwd helpers. */154 #include <stdlib.h>155 #include "libbb.h"156 89 157 90 unsigned long get_ug_id(const char *s, 158 long (* __bb_getxxnam)(const char *))91 long (*xname2id)(const char *)) 159 92 { 160 93 unsigned long r; 161 char *p;162 94 163 r = strtoul(s, &p, 10); 164 if (*p || (s == p)) { 165 r = __bb_getxxnam(s); 166 } 167 95 r = bb_strtoul(s, NULL, 10); 96 if (errno) 97 return xname2id(s); 168 98 return r; 169 99 } 170 #endif /* L_get_ug_id */ -
branches/2.2.5/mindi-busybox/libbb/change_identity.c
r821 r1765 29 29 */ 30 30 31 #include <stdio.h>32 #include <errno.h>33 #include <unistd.h>34 #include <string.h>35 #include <stdlib.h>36 #include <syslog.h>37 #include <ctype.h>38 39 31 #include "libbb.h" 40 32 41 33 42 34 /* Become the user and group(s) specified by PW. */ 43 const char *change_identity_e2str ( const struct passwd *pw)35 const char *change_identity_e2str(const struct passwd *pw) 44 36 { 45 if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1)37 if (initgroups(pw->pw_name, pw->pw_gid) == -1) 46 38 return "cannot set groups"; 47 endgrent ( ); 48 49 if ( setgid ( pw-> pw_gid )) 50 return "cannot set group id"; 51 if ( setuid ( pw->pw_uid )) 52 return "cannot set user id"; 39 endgrent(); /* ?? */ 40 xsetgid(pw->pw_gid); 41 xsetuid(pw->pw_uid); 53 42 return NULL; 54 43 } 55 44 56 void change_identity ( const struct passwd *pw)45 void change_identity(const struct passwd *pw) 57 46 { 58 47 const char *err_msg = change_identity_e2str(pw); 59 48 60 if (err_msg)61 bb_perror_msg_and_die ( "%s", err_msg);49 if (err_msg) 50 bb_perror_msg_and_die("%s", err_msg); 62 51 } -
branches/2.2.5/mindi-busybox/libbb/chomp.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h>12 #include <string.h>13 11 #include "libbb.h" 14 15 12 16 13 void chomp(char *s) … … 18 15 char *lc = last_char_is(s, '\n'); 19 16 20 if (lc)21 *lc = 0;17 if (lc) 18 *lc = '\0'; 22 19 } -
branches/2.2.5/mindi-busybox/libbb/compare_string_array.c
r821 r1765 1 /* vi: set ts=4:*/1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 4 4 */ 5 5 6 #include <string.h>7 6 #include "libbb.h" 8 7 9 /* returns the array number of the string */ 10 int compare_string_array(const char * const string_array[], const char *key) 8 /* returns the array index of the string */ 9 /* (index of first match is returned, or -1) */ 10 int index_in_str_array(const char *const string_array[], const char *key) 11 11 { 12 12 int i; … … 17 17 } 18 18 } 19 return - i;19 return -1; 20 20 } 21 21 22 int index_in_strings(const char *strings, const char *key) 23 { 24 int idx = 0; 25 26 while (strings[0]) { 27 if (strcmp(strings, key) == 0) { 28 return idx; 29 } 30 strings += strlen(strings) + 1; /* skip NUL */ 31 idx++; 32 } 33 return -1; 34 } 35 36 /* returns the array index of the string, even if it matches only a beginning */ 37 /* (index of first match is returned, or -1) */ 38 #ifdef UNUSED 39 int index_in_substr_array(const char *const string_array[], const char *key) 40 { 41 int i; 42 int len = strlen(key); 43 if (len) { 44 for (i = 0; string_array[i] != 0; i++) { 45 if (strncmp(string_array[i], key, len) == 0) { 46 return i; 47 } 48 } 49 } 50 return -1; 51 } 52 #endif 53 54 int index_in_substrings(const char *strings, const char *key) 55 { 56 int len = strlen(key); 57 58 if (len) { 59 int idx = 0; 60 while (strings[0]) { 61 if (strncmp(strings, key, len) == 0) { 62 return idx; 63 } 64 strings += strlen(strings) + 1; /* skip NUL */ 65 idx++; 66 } 67 } 68 return -1; 69 } -
branches/2.2.5/mindi-busybox/libbb/concat_path_file.c
r821 r1765 6 6 * If you wrote this, please acknowledge your work. 7 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 * USA 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 22 9 */ 23 10 24 11 /* concatenate path and file name to new allocation buffer, 25 * not addi tion '/' if path name already have'/'12 * not adding '/' if path name already has '/' 26 13 */ 27 14 28 #include <string.h>29 15 #include "libbb.h" 30 16 … … 38 24 while (*filename == '/') 39 25 filename++; 40 return bb_xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename);26 return xasprintf("%s%s%s", path, (lc==NULL ? "/" : ""), filename); 41 27 } -
branches/2.2.5/mindi-busybox/libbb/concat_subpath_file.c
r821 r1765 5 5 * Copyright (C) (C) 2003 Vladimir Oleynik <dzo@simtreas.ru> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 20 * USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 This function make special for recursive actions with usage 25 12 concat_path_file(path, filename) 26 and skip ing "." and ".." directory entries13 and skipping "." and ".." directory entries 27 14 */ 28 15 … … 31 18 char *concat_subpath_file(const char *path, const char *f) 32 19 { 33 if (f && *f == '.' && (!f[1] || (f[1] == '.' && !f[2])))20 if (f && DOT_OR_DOTDOT(f)) 34 21 return NULL; 35 22 return concat_path_file(path, f); -
branches/2.2.5/mindi-busybox/libbb/copy_file.c
r821 r1765 4 4 * 5 5 * Copyright (C) 2001 by Matt Kraai <kraai@alumni.carnegiemellon.edu> 6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> 6 7 * 7 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. … … 10 11 11 12 #include "libbb.h" 12 #include <utime.h> 13 #include <errno.h> 14 13 14 // POSIX: if exists and -i, ask (w/o -i assume yes). 15 // Then open w/o EXCL (yes, not unlink!). 16 // If open still fails and -f, try unlink, then try open again. 17 // Result: a mess: 18 // If dest is a softlink, we overwrite softlink's destination! 19 // (or fail, if it points to dir/nonexistent location/etc). 20 // This is strange, but POSIX-correct. 21 // coreutils cp has --remove-destination to override this... 22 // 23 // NB: we have special code which still allows for "cp file /dev/node" 24 // to work POSIX-ly (the only realistic case where it makes sense) 25 26 #define DO_POSIX_CP 0 /* 1 - POSIX behavior, 0 - safe behavior */ 27 28 // errno must be set to relevant value ("why we cannot create dest?") 29 // for POSIX mode to give reasonable error message 30 static int ask_and_unlink(const char *dest, int flags) 31 { 32 #if DO_POSIX_CP 33 if (!(flags & (FILEUTILS_FORCE|FILEUTILS_INTERACTIVE))) { 34 // Either it exists, or the *path* doesnt exist 35 bb_perror_msg("cannot create '%s'", dest); 36 return -1; 37 } 38 #endif 39 // If !DO_POSIX_CP, act as if -f is always in effect - we don't want 40 // "cannot create" msg, we want unlink to be done (silently unless -i). 41 42 // TODO: maybe we should do it only if ctty is present? 43 if (flags & FILEUTILS_INTERACTIVE) { 44 // We would not do POSIX insanity. -i asks, 45 // then _unlinks_ the offender. Presto. 46 // (No "opening without O_EXCL", no "unlink only if -f") 47 // Or else we will end up having 3 open()s! 48 fprintf(stderr, "%s: overwrite '%s'? ", applet_name, dest); 49 if (!bb_ask_confirmation()) 50 return 0; // not allowed to overwrite 51 } 52 if (unlink(dest) < 0) { 53 bb_perror_msg("cannot remove '%s'", dest); 54 return -1; // error 55 } 56 return 1; // ok (to try again) 57 } 58 59 /* Return: 60 * -1 error, copy not made 61 * 0 copy is made or user answered "no" in interactive mode 62 * (failures to preserve mode/owner/times are not reported in exit code) 63 */ 15 64 int copy_file(const char *source, const char *dest, int flags) 16 65 { 66 /* This is a recursive function, try to minimize stack usage */ 67 /* NB: each struct stat is ~100 bytes */ 17 68 struct stat source_stat; 18 69 struct stat dest_stat; 19 int dest_exists = 0; 20 int status = 0; 21 22 if ((!(flags & FILEUTILS_DEREFERENCE) && 23 lstat(source, &source_stat) < 0) || 24 ((flags & FILEUTILS_DEREFERENCE) && 25 stat(source, &source_stat) < 0)) { 26 bb_perror_msg("%s", source); 70 signed char retval = 0; 71 signed char dest_exists = 0; 72 signed char ovr; 73 74 #define FLAGS_DEREF (flags & FILEUTILS_DEREFERENCE) 75 76 if ((FLAGS_DEREF ? stat : lstat)(source, &source_stat) < 0) { 77 // This may be a dangling symlink. 78 // Making [sym]links to dangling symlinks works, so... 79 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) 80 goto make_links; 81 bb_perror_msg("cannot stat '%s'", source); 27 82 return -1; 28 83 } … … 30 85 if (lstat(dest, &dest_stat) < 0) { 31 86 if (errno != ENOENT) { 32 bb_perror_msg(" unable to stat `%s'", dest);87 bb_perror_msg("cannot stat '%s'", dest); 33 88 return -1; 34 89 } 35 90 } else { 36 if (source_stat.st_dev == dest_stat.st_dev &&37 source_stat.st_ino == dest_stat.st_ino)38 {39 bb_error_msg(" `%s' and `%s' are the same file", source, dest);91 if (source_stat.st_dev == dest_stat.st_dev 92 && source_stat.st_ino == dest_stat.st_ino 93 ) { 94 bb_error_msg("'%s' and '%s' are the same file", source, dest); 40 95 return -1; 41 96 } 42 97 dest_exists = 1; 43 98 } 99 100 #if ENABLE_SELINUX 101 if ((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) && is_selinux_enabled() > 0) { 102 security_context_t con; 103 if (lgetfilecon(source, &con) >= 0) { 104 if (setfscreatecon(con) < 0) { 105 bb_perror_msg("cannot set setfscreatecon %s", con); 106 freecon(con); 107 return -1; 108 } 109 } else if (errno == ENOTSUP || errno == ENODATA) { 110 setfscreatecon_or_die(NULL); 111 } else { 112 bb_perror_msg("cannot lgetfilecon %s", source); 113 return -1; 114 } 115 } 116 #endif 44 117 45 118 if (S_ISDIR(source_stat.st_mode)) { 46 119 DIR *dp; 120 const char *tp; 47 121 struct dirent *d; 48 122 mode_t saved_umask = 0; 49 123 50 124 if (!(flags & FILEUTILS_RECUR)) { 51 bb_error_msg("%s: omitting directory", source); 52 return -1; 53 } 54 55 /* Create DEST. */ 125 bb_error_msg("omitting directory '%s'", source); 126 return -1; 127 } 128 129 /* Did we ever create source ourself before? */ 130 tp = is_in_ino_dev_hashtable(&source_stat); 131 if (tp) { 132 /* We did! it's a recursion! man the lifeboats... */ 133 bb_error_msg("recursion detected, omitting directory '%s'", 134 source); 135 return -1; 136 } 137 138 /* Create DEST */ 56 139 if (dest_exists) { 57 140 if (!S_ISDIR(dest_stat.st_mode)) { 58 bb_error_msg("`%s' is not a directory", dest); 59 return -1; 60 } 141 bb_error_msg("target '%s' is not a directory", dest); 142 return -1; 143 } 144 /* race here: user can substitute a symlink between 145 * this check and actual creation of files inside dest */ 61 146 } else { 62 147 mode_t mode; … … 66 151 if (!(flags & FILEUTILS_PRESERVE_STATUS)) 67 152 mode = source_stat.st_mode & ~saved_umask; 153 /* Allow owner to access new dir (at least for now) */ 68 154 mode |= S_IRWXU; 69 70 155 if (mkdir(dest, mode) < 0) { 71 156 umask(saved_umask); 72 bb_perror_msg("cannot create directory `%s'", dest); 73 return -1; 74 } 75 157 bb_perror_msg("cannot create directory '%s'", dest); 158 return -1; 159 } 76 160 umask(saved_umask); 77 } 78 79 /* Recursively copy files in SOURCE. */ 80 if ((dp = bb_opendir(source)) == NULL) { 81 status = -1; 82 goto preserve_status; 161 /* need stat info for add_to_ino_dev_hashtable */ 162 if (lstat(dest, &dest_stat) < 0) { 163 bb_perror_msg("cannot stat '%s'", dest); 164 return -1; 165 } 166 } 167 /* remember (dev,inode) of each created dir. 168 * NULL: name is not remembered */ 169 add_to_ino_dev_hashtable(&dest_stat, NULL); 170 171 /* Recursively copy files in SOURCE */ 172 dp = opendir(source); 173 if (dp == NULL) { 174 retval = -1; 175 goto preserve_mode_ugid_time; 83 176 } 84 177 … … 87 180 88 181 new_source = concat_subpath_file(source, d->d_name); 89 if (new_source == NULL)182 if (new_source == NULL) 90 183 continue; 91 184 new_dest = concat_path_file(dest, d->d_name); 92 185 if (copy_file(new_source, new_dest, flags) < 0) 93 status= -1;186 retval = -1; 94 187 free(new_source); 95 188 free(new_dest); 96 189 } 97 /* closedir have only EBADF error, but "dp" not changes */98 190 closedir(dp); 99 191 100 if (!dest_exists && 101 chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { 102 bb_perror_msg("unable to change permissions of `%s'", dest); 103 status = -1; 104 } 105 } else if (S_ISREG(source_stat.st_mode) || 106 (S_ISLNK(source_stat.st_mode) && (flags & FILEUTILS_DEREFERENCE))) 107 { 192 if (!dest_exists 193 && chmod(dest, source_stat.st_mode & ~saved_umask) < 0 194 ) { 195 bb_perror_msg("cannot preserve %s of '%s'", "permissions", dest); 196 /* retval = -1; - WRONG! copy *WAS* made */ 197 } 198 goto preserve_mode_ugid_time; 199 } 200 201 if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { 202 int (*lf)(const char *oldpath, const char *newpath); 203 make_links: 204 // Hmm... maybe 205 // if (DEREF && MAKE_SOFTLINK) source = realpath(source) ? 206 // (but realpath returns NULL on dangling symlinks...) 207 lf = (flags & FILEUTILS_MAKE_SOFTLINK) ? symlink : link; 208 if (lf(source, dest) < 0) { 209 ovr = ask_and_unlink(dest, flags); 210 if (ovr <= 0) 211 return ovr; 212 if (lf(source, dest) < 0) { 213 bb_perror_msg("cannot create link '%s'", dest); 214 return -1; 215 } 216 } 217 /* _Not_ jumping to preserve_mode_ugid_time: 218 * hard/softlinks don't have those */ 219 return 0; 220 } 221 222 if (S_ISREG(source_stat.st_mode) 223 /* DEREF uses stat, which never returns S_ISLNK() == true. */ 224 /* || (FLAGS_DEREF && S_ISLNK(source_stat.st_mode)) */ 225 ) { 108 226 int src_fd; 109 227 int dst_fd; 110 if (ENABLE_FEATURE_PRESERVE_HARDLINKS) { 111 char *link_name; 112 113 if (!(flags & FILEUTILS_DEREFERENCE) && 114 is_in_ino_dev_hashtable(&source_stat, &link_name)) { 115 if (link(link_name, dest) < 0) { 116 bb_perror_msg("unable to link `%s'", dest); 228 229 if (ENABLE_FEATURE_PRESERVE_HARDLINKS && !FLAGS_DEREF) { 230 const char *link_target; 231 link_target = is_in_ino_dev_hashtable(&source_stat); 232 if (link_target) { 233 if (link(link_target, dest) < 0) { 234 ovr = ask_and_unlink(dest, flags); 235 if (ovr <= 0) 236 return ovr; 237 if (link(link_target, dest) < 0) { 238 bb_perror_msg("cannot create link '%s'", dest); 239 return -1; 240 } 241 } 242 return 0; 243 } 244 add_to_ino_dev_hashtable(&source_stat, dest); 245 } 246 247 src_fd = open_or_warn(source, O_RDONLY); 248 if (src_fd < 0) 249 return -1; 250 251 /* POSIX way is a security problem versus symlink attacks, 252 * we do it only for non-symlinks, and only for non-recursive, 253 * non-interactive cp. NB: it is still racy 254 * for "cp file /home/bad_user/file" case 255 * (user can rm file and create a link to /etc/passwd) */ 256 if (DO_POSIX_CP 257 || (dest_exists && !(flags & (FILEUTILS_RECUR|FILEUTILS_INTERACTIVE)) 258 && !S_ISLNK(dest_stat.st_mode)) 259 ) { 260 dst_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, source_stat.st_mode); 261 } else /* safe way: */ 262 dst_fd = open(dest, O_WRONLY|O_CREAT|O_EXCL, source_stat.st_mode); 263 if (dst_fd == -1) { 264 ovr = ask_and_unlink(dest, flags); 265 if (ovr <= 0) { 266 close(src_fd); 267 return ovr; 268 } 269 /* It shouldn't exist. If it exists, do not open (symlink attack?) */ 270 dst_fd = open3_or_warn(dest, O_WRONLY|O_CREAT|O_EXCL, source_stat.st_mode); 271 if (dst_fd < 0) { 272 close(src_fd); 273 return -1; 274 } 275 } 276 277 #if ENABLE_SELINUX 278 if (((flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) 279 || (flags & FILEUTILS_SET_SECURITY_CONTEXT)) 280 && is_selinux_enabled() > 0 281 ) { 282 security_context_t con; 283 if (getfscreatecon(&con) == -1) { 284 bb_perror_msg("getfscreatecon"); 285 return -1; 286 } 287 if (con) { 288 if (setfilecon(dest, con) == -1) { 289 bb_perror_msg("setfilecon:%s,%s", dest, con); 290 freecon(con); 117 291 return -1; 118 292 } 119 120 return 0; 121 } 122 add_to_ino_dev_hashtable(&source_stat, dest); 123 } 124 src_fd = open(source, O_RDONLY); 125 if (src_fd == -1) { 126 bb_perror_msg("unable to open `%s'", source); 127 return(-1); 128 } 129 130 if (dest_exists) { 131 if (flags & FILEUTILS_INTERACTIVE) { 132 fprintf(stderr, "%s: overwrite `%s'? ", bb_applet_name, dest); 133 if (!bb_ask_confirmation()) { 134 close (src_fd); 135 return 0; 136 } 137 } 138 139 dst_fd = open(dest, O_WRONLY|O_TRUNC); 140 if (dst_fd == -1) { 141 if (!(flags & FILEUTILS_FORCE)) { 142 bb_perror_msg("unable to open `%s'", dest); 143 close(src_fd); 144 return -1; 145 } 146 147 if (unlink(dest) < 0) { 148 bb_perror_msg("unable to remove `%s'", dest); 149 close(src_fd); 150 return -1; 151 } 152 153 goto dest_removed; 154 } 155 } else { 156 dest_removed: 157 dst_fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode); 158 if (dst_fd == -1) { 159 bb_perror_msg("unable to open `%s'", dest); 160 close(src_fd); 161 return(-1); 162 } 163 } 164 293 freecon(con); 294 } 295 } 296 #endif 165 297 if (bb_copyfd_eof(src_fd, dst_fd) == -1) 166 status= -1;167 298 retval = -1; 299 /* Ok, writing side I can understand... */ 168 300 if (close(dst_fd) < 0) { 169 bb_perror_msg("unable to close `%s'", dest); 170 status = -1; 171 } 172 173 if (close(src_fd) < 0) { 174 bb_perror_msg("unable to close `%s'", source); 175 status = -1; 176 } 177 } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) || 178 S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) || 179 S_ISLNK(source_stat.st_mode)) { 180 181 if (dest_exists) { 182 if((flags & FILEUTILS_FORCE) == 0) { 183 fprintf(stderr, "`%s' exists\n", dest); 184 return -1; 185 } 186 if(unlink(dest) < 0) { 187 bb_perror_msg("unable to remove `%s'", dest); 188 return -1; 189 } 190 } 191 if (S_ISFIFO(source_stat.st_mode)) { 192 if (mkfifo(dest, source_stat.st_mode) < 0) { 193 bb_perror_msg("cannot create fifo `%s'", dest); 194 return -1; 195 } 196 } else if (S_ISLNK(source_stat.st_mode)) { 197 char *lpath; 198 199 lpath = xreadlink(source); 200 if (symlink(lpath, dest) < 0) { 201 bb_perror_msg("cannot create symlink `%s'", dest); 202 return -1; 203 } 301 bb_perror_msg("cannot close '%s'", dest); 302 retval = -1; 303 } 304 /* ...but read size is already checked by bb_copyfd_eof */ 305 close(src_fd); 306 goto preserve_mode_ugid_time; 307 } 308 309 /* Source is a symlink or a special file */ 310 /* We are lazy here, a bit lax with races... */ 311 if (dest_exists) { 312 errno = EEXIST; 313 ovr = ask_and_unlink(dest, flags); 314 if (ovr <= 0) 315 return ovr; 316 } 317 if (S_ISLNK(source_stat.st_mode)) { 318 char *lpath = xmalloc_readlink_or_warn(source); 319 if (lpath) { 320 int r = symlink(lpath, dest); 204 321 free(lpath); 205 322 if (r < 0) { 323 bb_perror_msg("cannot create symlink '%s'", dest); 324 return -1; 325 } 206 326 if (flags & FILEUTILS_PRESERVE_STATUS) 207 327 if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0) 208 bb_perror_msg("unable to preserve ownership of `%s'", dest); 209 210 return 0; 211 212 } else { 213 if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { 214 bb_perror_msg("unable to create `%s'", dest); 215 return -1; 216 } 328 bb_perror_msg("cannot preserve %s of '%s'", "ownership", dest); 329 } 330 /* _Not_ jumping to preserve_mode_ugid_time: 331 * symlinks don't have those */ 332 return 0; 333 } 334 if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) 335 || S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) 336 ) { 337 if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { 338 bb_perror_msg("cannot create '%s'", dest); 339 return -1; 217 340 } 218 341 } else { 219 bb_error_msg(" internal error: unrecognized file type");342 bb_error_msg("unrecognized file '%s' with mode %x", source, source_stat.st_mode); 220 343 return -1; 221 344 } 222 345 223 preserve_status: 224 225 if (flags & FILEUTILS_PRESERVE_STATUS) { 346 preserve_mode_ugid_time: 347 348 if (flags & FILEUTILS_PRESERVE_STATUS 349 /* Cannot happen: */ 350 /* && !(flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) */ 351 ) { 226 352 struct utimbuf times; 227 char *msg="unable to preserve %s of `%s'";228 353 229 354 times.actime = source_stat.st_atime; 230 355 times.modtime = source_stat.st_mtime; 356 /* BTW, utimes sets usec-precision time - just FYI */ 231 357 if (utime(dest, ×) < 0) 232 bb_perror_msg( msg, "times", dest);358 bb_perror_msg("cannot preserve %s of '%s'", "times", dest); 233 359 if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { 234 360 source_stat.st_mode &= ~(S_ISUID | S_ISGID); 235 bb_perror_msg( msg, "ownership", dest);361 bb_perror_msg("cannot preserve %s of '%s'", "ownership", dest); 236 362 } 237 363 if (chmod(dest, source_stat.st_mode) < 0) 238 bb_perror_msg( msg, "permissions", dest);239 } 240 241 return status;364 bb_perror_msg("cannot preserve %s of '%s'", "permissions", dest); 365 } 366 367 return retval; 242 368 } -
branches/2.2.5/mindi-busybox/libbb/copyfd.c
r821 r1765 8 8 */ 9 9 10 #include <errno.h>11 #include <stdlib.h>12 #include <string.h>13 #include <unistd.h>14 15 10 #include "libbb.h" 16 17 11 18 12 #if BUFSIZ < 4096 … … 21 15 #endif 22 16 17 /* Used by NOFORK applets (e.g. cat) - must not use xmalloc */ 23 18 24 static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size)19 static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) 25 20 { 26 21 int status = -1; 27 size_t total = 0;28 RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);22 off_t total = 0; 23 char buffer[BUFSIZ]; 29 24 30 if (src_fd < 0) goto out; 31 while (!size || total < size) 32 { 33 ssize_t wrote, xread; 25 if (src_fd < 0) 26 goto out; 34 27 35 xread = safe_read(src_fd, buffer, 36 (!size || size - total > BUFSIZ) ? BUFSIZ : size - total); 28 if (!size) { 29 size = BUFSIZ; 30 status = 1; /* copy until eof */ 31 } 37 32 38 if (xread > 0) { 39 /* A -1 dst_fd means we need to fake it... */ 40 wrote = (dst_fd < 0) ? xread : bb_full_write(dst_fd, buffer, xread); 41 if (wrote < xread) { 33 while (1) { 34 ssize_t rd; 35 36 rd = safe_read(src_fd, buffer, size > BUFSIZ ? BUFSIZ : size); 37 38 if (!rd) { /* eof - all done */ 39 status = 0; 40 break; 41 } 42 if (rd < 0) { 43 bb_perror_msg(bb_msg_read_error); 44 break; 45 } 46 /* dst_fd == -1 is a fake, else... */ 47 if (dst_fd >= 0) { 48 ssize_t wr = full_write(dst_fd, buffer, rd); 49 if (wr < rd) { 42 50 bb_perror_msg(bb_msg_write_error); 43 51 break; 44 52 } 45 total += wrote;46 if (total == size) status = 0;47 } else if (xread < 0) {48 bb_perror_msg(bb_msg_read_error);49 break;50 } else if (xread == 0) {51 /* All done. */52 status = 0;53 break;53 } 54 total += rd; 55 if (status < 0) { /* if we aren't copying till EOF... */ 56 size -= rd; 57 if (!size) { 58 /* 'size' bytes copied - all done */ 59 status = 0; 60 break; 61 } 54 62 } 55 63 } 56 57 out: 58 RELEASE_CONFIG_BUFFER(buffer); 59 60 return status ? status : (ssize_t)total; 64 out: 65 return status ? -1 : total; 61 66 } 62 67 63 68 64 int bb_copyfd_size(int fd1, int fd2, const off_t size) 69 #if 0 70 void complain_copyfd_and_die(off_t sz) 71 { 72 if (sz != -1) 73 bb_error_msg_and_die("short read"); 74 /* if sz == -1, bb_copyfd_XX already complained */ 75 xfunc_die(); 76 } 77 #endif 78 79 off_t bb_copyfd_size(int fd1, int fd2, off_t size) 65 80 { 66 81 if (size) { 67 return (bb_full_fd_action(fd1, fd2, size));82 return bb_full_fd_action(fd1, fd2, size); 68 83 } 69 return (0);84 return 0; 70 85 } 71 86 72 int bb_copyfd_eof(int fd1, int fd2)87 void bb_copyfd_exact_size(int fd1, int fd2, off_t size) 73 88 { 74 return(bb_full_fd_action(fd1, fd2, 0)); 89 off_t sz = bb_copyfd_size(fd1, fd2, size); 90 if (sz == size) 91 return; 92 if (sz != -1) 93 bb_error_msg_and_die("short read"); 94 /* if sz == -1, bb_copyfd_XX already complained */ 95 xfunc_die(); 75 96 } 97 98 off_t bb_copyfd_eof(int fd1, int fd2) 99 { 100 return bb_full_fd_action(fd1, fd2, 0); 101 } -
branches/2.2.5/mindi-busybox/libbb/correct_password.c
r821 r1765 29 29 */ 30 30 31 #include <stdio.h>32 #include <errno.h>33 #include <unistd.h>34 #include <string.h>35 #include <stdlib.h>36 #include <syslog.h>37 #include <ctype.h>38 #include <crypt.h>39 40 31 #include "libbb.h" 41 32 33 /* Ask the user for a password. 34 * Return 1 if the user gives the correct password for entry PW, 35 * 0 if not. Return 1 without asking if PW has an empty password. 36 * 37 * NULL pw means "just fake it for login with bad username" */ 42 38 39 int correct_password(const struct passwd *pw) 40 { 41 char *unencrypted, *encrypted; 42 const char *correct; 43 43 44 /* Ask the user for a password. 45 Return 1 if the user gives the correct password for entry PW, 46 0 if not. Return 1 without asking for a password if run by UID 0 47 or if PW has an empty password. */ 44 /* fake salt. crypt() can choke otherwise. */ 45 correct = "aa"; 46 if (!pw) { 47 /* "aa" will never match */ 48 goto fake_it; 49 } 50 correct = pw->pw_passwd; 51 #if ENABLE_FEATURE_SHADOWPASSWDS 52 if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) { 53 /* Using _r function to avoid pulling in static buffers */ 54 struct spwd spw; 55 struct spwd *result; 56 char buffer[256]; 57 correct = (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)) ? "aa" : spw.sp_pwdp; 58 } 59 #endif 48 60 49 int correct_password ( const struct passwd *pw ) 50 { 51 char *unencrypted, *encrypted, *correct; 52 53 #ifdef CONFIG_FEATURE_SHADOWPASSWDS 54 if (( strcmp ( pw-> pw_passwd, "x" ) == 0 ) || ( strcmp ( pw-> pw_passwd, "*" ) == 0 )) { 55 struct spwd *sp = getspnam ( pw-> pw_name ); 56 57 if ( !sp ) 58 bb_error_msg_and_die ( "\nno valid shadow password" ); 59 60 correct = sp-> sp_pwdp; 61 } 62 else 63 #endif 64 correct = pw-> pw_passwd; 65 66 if ( correct == 0 || correct[0] == '\0' ) 61 if (!correct[0]) /* empty password field? */ 67 62 return 1; 68 63 69 unencrypted = bb_askpass ( 0, "Password: " ); 70 if ( !unencrypted )71 {64 fake_it: 65 unencrypted = bb_askpass(0, "Password: "); 66 if (!unencrypted) { 72 67 return 0; 73 68 } 74 encrypted = crypt ( unencrypted, correct);75 memset ( unencrypted, 0, strlen ( unencrypted));76 return ( strcmp ( encrypted, correct ) == 0 ) ? 1 :0;69 encrypted = crypt(unencrypted, correct); 70 memset(unencrypted, 0, strlen(unencrypted)); 71 return strcmp(encrypted, correct) == 0; 77 72 } -
branches/2.2.5/mindi-busybox/libbb/crc32.c
r821 r1765 7 7 * 8 8 * The following function creates a CRC32 table depending on whether 9 * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is 9 * a big-endian (0x04c11db7) or little-endian (0xedb88320) CRC32 is 10 10 * required. Admittedly, there are other CRC32 polynomials floating 11 11 * around, but Busybox doesn't use them. … … 15 15 */ 16 16 17 #include <stdio.h>18 #include <stdlib.h>19 17 #include "libbb.h" 20 18 21 uint32_t *bb_crc32_filltable (int endian) { 22 23 uint32_t *crc_table = xmalloc(256 * sizeof(uint32_t)); 19 uint32_t *crc32_filltable(uint32_t *crc_table, int endian) 20 { 24 21 uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; 25 22 uint32_t c; 26 23 int i, j; 27 24 25 if (!crc_table) 26 crc_table = xmalloc(256 * sizeof(uint32_t)); 27 28 28 for (i = 0; i < 256; i++) { 29 29 c = endian ? (i << 24) : i; -
branches/2.2.5/mindi-busybox/libbb/create_icmp6_socket.c
r821 r1765 8 8 */ 9 9 10 #include <sys/types.h> 11 #include <netdb.h> 12 #include <sys/socket.h> 13 #include <errno.h> 14 #include <unistd.h> 10 //#include <sys/types.h> 11 //#include <netdb.h> 12 //#include <sys/socket.h> 15 13 #include "libbb.h" 16 14 17 #if def CONFIG_FEATURE_IPV615 #if ENABLE_FEATURE_IPV6 18 16 int create_icmp6_socket(void) 19 17 { … … 24 22 /* if getprotobyname failed, just silently force 25 23 * proto->p_proto to have the correct value for "ipv6-icmp" */ 26 if ((sock = socket(AF_INET6, SOCK_RAW, 27 (proto ? proto->p_proto : IPPROTO_ICMPV6))) < 0) { 24 sock = socket(AF_INET6, SOCK_RAW, 25 (proto ? proto->p_proto : IPPROTO_ICMPV6)); 26 if (sock < 0) { 28 27 if (errno == EPERM) 29 28 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 30 else 31 bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); 29 bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); 32 30 } 33 31 34 32 /* drop root privs if running setuid */ 35 setuid(getuid());33 xsetuid(getuid()); 36 34 37 35 return sock; -
branches/2.2.5/mindi-busybox/libbb/create_icmp_socket.c
r821 r1765 8 8 */ 9 9 10 #include <sys/types.h> 11 #include <netdb.h> 12 #include <sys/socket.h> 13 #include <errno.h> 14 #include <unistd.h> 10 //#include <sys/types.h> 11 //#include <netdb.h> 12 //#include <sys/socket.h> 15 13 #include "libbb.h" 16 14 … … 23 21 /* if getprotobyname failed, just silently force 24 22 * proto->p_proto to have the correct value for "icmp" */ 25 if ((sock = socket(AF_INET, SOCK_RAW, 26 (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */ 23 sock = socket(AF_INET, SOCK_RAW, 24 (proto ? proto->p_proto : 1)); /* 1 == ICMP */ 25 if (sock < 0) { 27 26 if (errno == EPERM) 28 27 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 29 else 30 bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); 28 bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); 31 29 } 32 30 33 31 /* drop root privs if running setuid */ 34 setuid(getuid());32 xsetuid(getuid()); 35 33 36 34 return sock; -
branches/2.2.5/mindi-busybox/libbb/default_error_retval.c
r821 r1765 3 3 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 4 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 19 6 */ 20 7 … … 27 14 */ 28 15 29 #include <stdlib.h>30 16 #include "libbb.h" 31 17 32 int bb_default_error_retval = EXIT_FAILURE;18 int xfunc_error_retval = EXIT_FAILURE; -
branches/2.2.5/mindi-busybox/libbb/device_open.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <fcntl.h>12 10 #include "libbb.h" 13 14 11 15 12 /* try to open up the specified device */ … … 21 18 22 19 /* Retry up to 5 times */ 20 /* TODO: explain why it can't be considered insane */ 23 21 for (f = 0; f < 5; f++) 24 22 if ((fd = open(device, m, 0600)) >= 0) -
branches/2.2.5/mindi-busybox/libbb/dump.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Support code for the hexdump and od applets, … … 12 13 13 14 #include "libbb.h" 14 #include <string.h>15 #include <unistd.h>16 #include <ctype.h> /* for isdigit() */17 15 #include "dump.h" 18 16 … … 29 27 int bb_dump_length = -1; /* max bytes to read */ 30 28 31 static const char index_str[] = ".#-+ 0123456789";32 33 static const char size_conv_str[] =29 static const char index_str[] ALIGN1 = ".#-+ 0123456789"; 30 31 static const char size_conv_str[] ALIGN1 = 34 32 "\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; 35 33 36 static const char lcc[] = "diouxX";34 static const char lcc[] ALIGN1 = "diouxX"; 37 35 38 36 int bb_dump_size(FS * fs) 39 37 { 40 registerFU *fu;41 registerint bcnt, cur_size;42 registerchar *fmt;38 FU *fu; 39 int bcnt, cur_size; 40 char *fmt; 43 41 const char *p; 44 42 int prec; … … 77 75 cur_size += bcnt * fu->reps; 78 76 } 79 return (cur_size);77 return cur_size; 80 78 } 81 79 … … 156 154 /* Unlike the original, output the remainder of the format string. */ 157 155 if (!*byte_count_str) { 158 bb_error_msg_and_die("bad byte count for conversion character %s .", p1);156 bb_error_msg_and_die("bad byte count for conversion character %s", p1); 159 157 } 160 158 pr->bcnt = *byte_count_str; … … 189 187 pr->bcnt = prec; 190 188 } else { /* NOTOKAY */ 191 bb_error_msg_and_die("%%s requires a precision or a byte count .");189 bb_error_msg_and_die("%%s requires a precision or a byte count"); 192 190 } 193 191 } else if (*p1 == '_') { … … 223 221 } else { 224 222 DO_BAD_CONV_CHAR: 225 bb_error_msg_and_die("bad conversion character %%%s .\n", p1);223 bb_error_msg_and_die("bad conversion character %%%s", p1); 226 224 } 227 225 … … 232 230 savech = *p2; 233 231 p1[1] = '\0'; 234 pr->fmt = bb_xstrdup(fmtp);232 pr->fmt = xstrdup(fmtp); 235 233 *p2 = savech; 236 234 pr->cchar = pr->fmt + (p1 - fmtp); … … 256 254 /* only one conversion character if byte count */ 257 255 if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) { 258 bb_error_msg_and_die("byte count with multiple conversion characters .\n");256 bb_error_msg_and_die("byte count with multiple conversion characters"); 259 257 } 260 258 } … … 294 292 } 295 293 296 static void do_skip(c har *fname, int statok)294 static void do_skip(const char *fname, int statok) 297 295 { 298 296 struct stat sbuf; … … 320 318 static int next(char **argv) 321 319 { 322 static int done; 320 static smallint done; 321 323 322 int statok; 324 323 325 324 if (argv) { 326 325 _argv = argv; 327 return (1);326 return 1; 328 327 } 329 328 for (;;) { … … 335 334 continue; 336 335 } 337 statok = done= 1;336 done = statok = 1; 338 337 } else { 339 if (done++) 340 return (0); 338 if (done) 339 return 0; 340 done = 1; 341 341 statok = 0; 342 342 } … … 346 346 ++_argv; 347 347 if (!bb_dump_skip) 348 return (1);348 return 1; 349 349 } 350 350 /* NOTREACHED */ … … 353 353 static unsigned char *get(void) 354 354 { 355 static int ateof = 1; 356 static unsigned char *curp=NULL, *savp; /*DBU:[dave@cray.com]initialize curp */ 357 register int n; 355 static smallint ateof = 1; 356 static unsigned char *curp = NULL, *savp; /*DBU:[dave@cray.com]initialize curp */ 357 358 int n; 358 359 int need, nread; 359 360 unsigned char *tmpp; … … 361 362 if (!curp) { 362 363 address = (off_t)0; /*DBU:[dave@cray.com] initialize,initialize..*/ 363 curp = (unsigned char *)xmalloc(bb_dump_blocksize);364 savp = (unsigned char *)xmalloc(bb_dump_blocksize);364 curp = xmalloc(bb_dump_blocksize); 365 savp = xmalloc(bb_dump_blocksize); 365 366 } else { 366 367 tmpp = curp; … … 377 378 if (!bb_dump_length || (ateof && !next((char **) NULL))) { 378 379 if (need == bb_dump_blocksize) { 379 return ((unsigned char *) NULL);380 return NULL; 380 381 } 381 382 if (bb_dump_vflag != ALL && !memcmp(curp, savp, nread)) { 382 383 if (bb_dump_vflag != DUP) { 383 p rintf("*\n");384 } 385 return ((unsigned char *) NULL);384 puts("*"); 385 } 386 return NULL; 386 387 } 387 388 memset((char *) curp + nread, 0, need); 388 389 eaddress = address + nread; 389 return (curp);390 return curp; 390 391 } 391 392 n = fread((char *) curp + nread, sizeof(unsigned char), … … 402 403 bb_dump_length -= n; 403 404 } 404 if (!(need -= n)) { 405 need -= n; 406 if (!need) { 405 407 if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST 406 408 || memcmp(curp, savp, bb_dump_blocksize)) { … … 408 410 bb_dump_vflag = WAIT; 409 411 } 410 return (curp);412 return curp; 411 413 } 412 414 if (bb_dump_vflag == WAIT) { 413 p rintf("*\n");415 puts("*"); 414 416 } 415 417 bb_dump_vflag = DUP; … … 439 441 } 440 442 441 static const char conv_str[] =443 static const char conv_str[] ALIGN1 = 442 444 "\0\\0\0" 443 445 "\007\\a\0" /* \a */ … … 448 450 "\t\\t\0" 449 451 "\v\\v\0" 450 "\0";452 ; 451 453 452 454 … … 478 480 static void conv_u(PR * pr, unsigned char * p) 479 481 { 480 static const char list[] =482 static const char list[] ALIGN1 = 481 483 "nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0" 482 484 "bs\0_ht\0_lf\0_vt\0_ff\0_cr\0_so\0_si\0_" … … 503 505 { 504 506 /* extern FU *endfu; */ 505 registerFS *fs;506 registerFU *fu;507 registerPR *pr;508 registerint cnt;509 registerunsigned char *bp;507 FS *fs; 508 FU *fu; 509 PR *pr; 510 int cnt; 511 unsigned char *bp; 510 512 511 513 off_t saveaddress; … … 651 653 int bb_dump_dump(char **argv) 652 654 { 653 registerFS *tfs;655 FS *tfs; 654 656 655 657 /* figure out the data block bb_dump_size */ … … 668 670 display(); 669 671 670 return (exitval);672 return exitval; 671 673 } 672 674 … … 727 729 /* byte count */ 728 730 if (isdigit(*p)) { 729 for (savep = p; isdigit(*p); ++p); 731 // TODO: use bb_strtou 732 savep = p; 733 do p++; while (isdigit(*p)); 730 734 if (!isspace(*p)) { 731 735 bb_error_msg_and_die("bad format {%s}", fmt); -
branches/2.2.5/mindi-busybox/libbb/error_msg.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <errno.h>12 #include <string.h>13 #include <stdlib.h>14 10 #include "libbb.h" 15 11 … … 19 15 20 16 va_start(p, s); 21 bb_verror_msg(s, p );17 bb_verror_msg(s, p, NULL); 22 18 va_end(p); 23 putc('\n', stderr);24 19 } -
branches/2.2.5/mindi-busybox/libbb/error_msg_and_die.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <errno.h>12 #include <string.h>13 #include <stdlib.h>14 10 #include "libbb.h" 11 12 int die_sleep; 13 #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH 14 jmp_buf die_jmp; 15 #endif 16 17 void xfunc_die(void) 18 { 19 if (die_sleep) { 20 if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) 21 && die_sleep < 0 22 ) { 23 /* Special case. We arrive here if NOFORK applet 24 * calls xfunc, which then decides to die. 25 * We don't die, but jump instead back to caller. 26 * NOFORK applets still cannot carelessly call xfuncs: 27 * p = xmalloc(10); 28 * q = xmalloc(10); // BUG! if this dies, we leak p! 29 */ 30 /* -2222 means "zero" (longjmp can't pass 0) 31 * run_nofork_applet() catches -2222. */ 32 longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); 33 } 34 sleep(die_sleep); 35 } 36 exit(xfunc_error_retval); 37 } 15 38 16 39 void bb_error_msg_and_die(const char *s, ...) … … 19 42 20 43 va_start(p, s); 21 bb_verror_msg(s, p );44 bb_verror_msg(s, p, NULL); 22 45 va_end(p); 23 putc('\n', stderr); 24 exit(bb_default_error_retval); 46 xfunc_die(); 25 47 } -
branches/2.2.5/mindi-busybox/libbb/fclose_nonstdin.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 26 13 */ 27 14 28 #include <stdio.h> 29 #include <libbb.h> 15 #include "libbb.h" 30 16 31 int bb_fclose_nonstdin(FILE *f)17 int fclose_if_not_stdin(FILE *f) 32 18 { 33 19 if (f != stdin) { -
branches/2.2.5/mindi-busybox/libbb/fflush_stdout_and_exit.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 25 12 */ 26 13 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <libbb.h> 14 #include "libbb.h" 30 15 31 void bb_fflush_stdout_and_exit(int retval)16 void fflush_stdout_and_exit(int retval) 32 17 { 33 if (fflush(stdout)) { 34 retval = bb_default_error_retval; 18 if (fflush(stdout)) 19 bb_perror_msg_and_die(bb_msg_standard_output); 20 21 if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { 22 /* We are in NOFORK applet. Do not exit() directly, 23 * but use xfunc_die() */ 24 xfunc_error_retval = retval; 25 xfunc_die(); 35 26 } 27 36 28 exit(retval); 37 29 } -
branches/2.2.5/mindi-busybox/libbb/fgets_str.c
r821 r1765 6 6 * If you wrote this, please acknowledge your work. 7 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 9 */ 22 23 24 #include <stdio.h>25 #include <stdlib.h>26 #include <string.h>27 10 28 11 #include "libbb.h" … … 31 14 * Return NULL on EOF. */ 32 15 33 char * fgets_str(FILE *file, const char *terminating_string)16 char *xmalloc_fgets_str(FILE *file, const char *terminating_string) 34 17 { 35 18 char *linebuf = NULL; … … 49 32 /* grow the line buffer as necessary */ 50 33 while (idx > linebufsz - 2) { 51 linebuf = xrealloc(linebuf, linebufsz += 1000); 34 linebufsz += 200; 35 linebuf = xrealloc(linebuf, linebufsz); 52 36 } 53 37 … … 57 41 /* Check for terminating string */ 58 42 end_string_offset = idx - term_length; 59 if ((end_string_offset > 0) && (memcmp(&linebuf[end_string_offset], terminating_string, term_length) == 0)) { 43 if (end_string_offset > 0 44 && memcmp(&linebuf[end_string_offset], terminating_string, term_length) == 0 45 ) { 60 46 idx -= term_length; 61 47 break; 62 48 } 63 49 } 50 linebuf = xrealloc(linebuf, idx + 1); 64 51 linebuf[idx] = '\0'; 65 return (linebuf);52 return linebuf; 66 53 } 67 -
branches/2.2.5/mindi-busybox/libbb/find_mount_point.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <string.h>12 10 #include "libbb.h" 11 #include <mntent.h> 13 12 14 15 #include <mntent.h>16 13 /* 17 14 * Given a block device, find the mount table entry if that block device … … 37 34 38 35 39 if ((mountTable = setmntent(table ? table : bb_path_mtab_file, "r")) == 0) 36 mountTable = setmntent(table ? table : bb_path_mtab_file, "r"); 37 if (!mountTable) 40 38 return 0; 41 39 42 40 while ((mountEntry = getmntent(mountTable)) != 0) { 43 44 if(strcmp(name, mountEntry->mnt_dir) == 045 || strcmp(name, mountEntry->mnt_fsname) == 0)/* String match. */41 if (strcmp(name, mountEntry->mnt_dir) == 0 42 || strcmp(name, mountEntry->mnt_fsname) == 0 43 ) { /* String match. */ 46 44 break; 45 } 47 46 if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */ 48 47 break; -
branches/2.2.5/mindi-busybox/libbb/find_pid_by_name.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under the GPL v2 , see the file LICENSE in this tarball.7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 8 8 */ 9 9 10 #include <stdio.h>11 #include <ctype.h>12 #include <string.h>13 #include <stdlib.h>14 10 #include "libbb.h" 11 12 /* 13 In Linux we have three ways to determine "process name": 14 1. /proc/PID/stat has "...(name)...", among other things. It's so-called "comm" field. 15 2. /proc/PID/cmdline's first NUL-terminated string. It's argv[0] from exec syscall. 16 3. /proc/PID/exe symlink. Points to the running executable file. 17 18 kernel threads: 19 comm: thread name 20 cmdline: empty 21 exe: <readlink fails> 22 23 executable 24 comm: first 15 chars of base name 25 (if executable is a symlink, then first 15 chars of symlink name are used) 26 cmdline: argv[0] from exec syscall 27 exe: points to executable (resolves symlink, unlike comm) 28 29 script (an executable with #!/path/to/interpreter): 30 comm: first 15 chars of script's base name (symlinks are not resolved) 31 cmdline: /path/to/interpreter (symlinks are not resolved) 32 (script name is in argv[1], args are pushed into argv[2] etc) 33 exe: points to interpreter's executable (symlinks are resolved) 34 35 If FEATURE_PREFER_APPLETS=y (and more so if FEATURE_SH_STANDALONE=y), 36 some commands started from busybox shell, xargs or find are started by 37 execXXX("/proc/self/exe", applet_name, params....) 38 and therefore comm field contains "exe". 39 */ 15 40 16 41 /* find_pid_by_name() … … 24 49 * It is the caller's duty to free the returned pidlist. 25 50 */ 26 long* find_pid_by_name( const char* pidName)51 pid_t* find_pid_by_name(const char* procName) 27 52 { 28 long* pidList;29 int i =0;30 procps_status_t * p;53 pid_t* pidList; 54 int i = 0; 55 procps_status_t* p = NULL; 31 56 32 pidList = xmalloc(sizeof(long)); 33 while ((p = procps_scan(0)) != 0) 34 { 35 if (strncmp(p->short_cmd, pidName, COMM_LEN-1) == 0) { 36 pidList=xrealloc( pidList, sizeof(long) * (i+2)); 37 pidList[i++]=p->pid; 57 pidList = xmalloc(sizeof(*pidList)); 58 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_COMM|PSSCAN_ARGV0))) { 59 if ( 60 /* we require comm to match and to not be truncated */ 61 /* in Linux, if comm is 15 chars, it may be a truncated 62 * name, so we don't allow that to match */ 63 (!p->comm[sizeof(p->comm)-2] && strcmp(p->comm, procName) == 0) 64 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ 65 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) 66 /* TOOD: we can also try exe, do we want that? */ 67 ) { 68 pidList = xrealloc(pidList, sizeof(*pidList) * (i+2)); 69 pidList[i++] = p->pid; 38 70 } 39 71 } 40 72 41 pidList[i] = i==0 ? -1 :0;73 pidList[i] = 0; 42 74 return pidList; 43 75 } 44 76 45 long *pidlist_reverse(long*pidList)77 pid_t *pidlist_reverse(pid_t *pidList) 46 78 { 47 int i=0; 48 while (pidList[i] > 0 && ++i); 49 if ( i-- > 0) { 50 long k; 79 int i = 0; 80 while (pidList[i]) 81 i++; 82 if (--i >= 0) { 83 pid_t k; 51 84 int j; 52 85 for (j = 0; i > j; i--, j++) { -
branches/2.2.5/mindi-busybox/libbb/find_root_device.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 */ 21 9 22 #include <limits.h>23 #include <stdio.h>24 #include <string.h>25 #include <dirent.h>26 #include <stdlib.h>27 10 #include "libbb.h" 28 11 29 char *find_block_device(char *path) 12 /* Find block device /dev/XXX which contains specified file 13 * We handle /dev/dir/dir/dir too, at a cost of ~80 more bytes code */ 14 15 /* Do not reallocate all this stuff on each recursion */ 16 enum { DEVNAME_MAX = 256 }; 17 struct arena { 18 struct stat st; 19 dev_t dev; 20 /* Was PATH_MAX, but we recurse _/dev_. We can assume 21 * people are not crazy enough to have mega-deep tree there */ 22 char devpath[DEVNAME_MAX]; 23 }; 24 25 static char *find_block_device_in_dir(struct arena *ap) 30 26 { 31 27 DIR *dir; 32 28 struct dirent *entry; 33 struct stat st; 34 dev_t dev; 35 char *retpath=NULL; 29 char *retpath = NULL; 30 int len, rem; 36 31 37 if(stat(path, &st) || !(dir = opendir("/dev"))) return NULL; 38 dev = (st.st_mode & S_IFMT) == S_IFBLK ? st.st_rdev : st.st_dev; 39 while((entry = readdir(dir)) != NULL) { 40 char devpath[PATH_MAX]; 41 sprintf(devpath,"/dev/%s", entry->d_name); 42 if(!stat(devpath, &st) && S_ISBLK(st.st_mode) && st.st_rdev == dev) { 43 retpath = bb_xstrdup(devpath); 32 dir = opendir(ap->devpath); 33 if (!dir) 34 return NULL; 35 36 len = strlen(ap->devpath); 37 rem = DEVNAME_MAX-2 - len; 38 if (rem <= 0) 39 return NULL; 40 ap->devpath[len++] = '/'; 41 42 while ((entry = readdir(dir)) != NULL) { 43 safe_strncpy(ap->devpath + len, entry->d_name, rem); 44 /* lstat: do not follow links */ 45 if (lstat(ap->devpath, &ap->st) != 0) 46 continue; 47 if (S_ISBLK(ap->st.st_mode) && ap->st.st_rdev == ap->dev) { 48 retpath = xstrdup(ap->devpath); 44 49 break; 50 } 51 if (S_ISDIR(ap->st.st_mode)) { 52 /* Do not recurse for '.' and '..' */ 53 if (DOT_OR_DOTDOT(entry->d_name)) 54 continue; 55 retpath = find_block_device_in_dir(ap); 56 if (retpath) 57 break; 45 58 } 46 59 } … … 49 62 return retpath; 50 63 } 64 65 char *find_block_device(const char *path) 66 { 67 struct arena a; 68 69 if (stat(path, &a.st) != 0) 70 return NULL; 71 a.dev = S_ISBLK(a.st.st_mode) ? a.st.st_rdev : a.st.st_dev; 72 strcpy(a.devpath, "/dev"); 73 return find_block_device_in_dir(&a); 74 } -
branches/2.2.5/mindi-busybox/libbb/full_write.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <unistd.h>12 10 #include "libbb.h" 13 11 … … 17 15 * Returns the amount written, or -1 on an error. 18 16 */ 19 ssize_t bb_full_write(int fd, const void *buf, size_t len)17 ssize_t full_write(int fd, const void *buf, size_t len) 20 18 { 21 19 ssize_t cc; … … 24 22 total = 0; 25 23 26 while (len > 0) {24 while (len) { 27 25 cc = safe_write(fd, buf, len); 28 26 29 27 if (cc < 0) 30 return cc; 28 return cc; /* write() returns -1 on failure. */ 31 29 32 30 total += cc; -
branches/2.2.5/mindi-busybox/libbb/get_console.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h> 12 #include <errno.h> 13 #include <fcntl.h> 14 #include <unistd.h> 15 #include <sys/ioctl.h> 11 //#include <sys/ioctl.h> 16 12 #include "libbb.h" 17 18 13 19 14 … … 48 43 int get_console_fd(void) 49 44 { 45 static const char *const console_names[] = { 46 DEV_CONSOLE, CURRENT_VC, CURRENT_TTY 47 }; 48 50 49 int fd; 51 52 static const char * const choise_console_names[] = {53 CONSOLE_DEV, CURRENT_VC, CURRENT_TTY54 };55 50 56 51 for (fd = 2; fd >= 0; fd--) { 57 52 int fd4name; 58 int choi se_fd;53 int choice_fd; 59 54 char arg; 60 55 61 fd4name = open_a_console(c hoise_console_names[fd]);62 63 choi se_fd = fd4name >= 0 ? fd4name : fd;56 fd4name = open_a_console(console_names[fd]); 57 chk_std: 58 choice_fd = (fd4name >= 0 ? fd4name : fd); 64 59 65 60 arg = 0; 66 if (ioctl(choi se_fd, KDGKBTYPE, &arg) == 0)67 return choi se_fd;68 if (fd4name >= 0) {61 if (ioctl(choice_fd, KDGKBTYPE, &arg) == 0) 62 return choice_fd; 63 if (fd4name >= 0) { 69 64 close(fd4name); 70 65 fd4name = -1; … … 73 68 } 74 69 75 bb_error_msg(" Couldn't get a file descriptor referring to theconsole");70 bb_error_msg("cannot get file descriptor referring to console"); 76 71 return fd; /* total failure */ 77 72 } -
branches/2.2.5/mindi-busybox/libbb/get_last_path_component.c
r821 r1765 27 27 last = first; 28 28 } 29 last[1] = 0;29 last[1] = '\0'; 30 30 31 31 return first; -
branches/2.2.5/mindi-busybox/libbb/get_line_from_file.c
r821 r1765 10 10 */ 11 11 12 #include <stdio.h>13 #include <stdlib.h>14 12 #include "libbb.h" 15 13 16 /* get_line_from_file() - This function reads an entire line from a text file, 17 * up to a newline or NUL byte. It returns a malloc'ed char * which must be 18 * stored and free'ed by the caller. If end is null '\n' isn't considered 19 * and of line. If end isn't null, length of the chunk read is stored in it. */ 14 /* This function reads an entire line from a text file, up to a newline 15 * or NUL byte, inclusive. It returns a malloc'ed char * which must be 16 * stored and free'ed by the caller. If end is NULL '\n' isn't considered 17 * end of line. If end isn't NULL, length of the chunk read is stored in it. 18 * Return NULL if EOF/error */ 20 19 21 char *bb_get_chunk_from_file(FILE * 20 char *bb_get_chunk_from_file(FILE *file, int *end) 22 21 { 23 22 int ch; … … 28 27 while ((ch = getc(file)) != EOF) { 29 28 /* grow the line buffer as necessary */ 30 if (idx > linebufsz - 2) { 31 linebuf = xrealloc(linebuf, linebufsz += 80); 29 if (idx >= linebufsz) { 30 linebufsz += 80; 31 linebuf = xrealloc(linebuf, linebufsz); 32 32 } 33 33 linebuf[idx++] = (char) ch; … … 38 38 *end = idx; 39 39 if (linebuf) { 40 if (ferror(file)) { 41 free(linebuf); 42 return NULL; 43 } 44 linebuf[idx] = 0; 40 // huh, does fgets discard prior data on error like this? 41 // I don't think so.... 42 //if (ferror(file)) { 43 // free(linebuf); 44 // return NULL; 45 //} 46 linebuf = xrealloc(linebuf, idx+1); 47 linebuf[idx] = '\0'; 45 48 } 46 49 return linebuf; 47 50 } 48 51 49 /* Get line, including trailing /n if any */50 char * bb_get_line_from_file(FILE *file)52 /* Get line, including trailing \n if any */ 53 char *xmalloc_fgets(FILE *file) 51 54 { 52 55 int i; … … 55 58 } 56 59 57 /* Get line. Remove trailing /n */58 char * bb_get_chomped_line_from_file(FILE *file)60 /* Get line. Remove trailing \n */ 61 char *xmalloc_getline(FILE *file) 59 62 { 60 63 int i; … … 62 65 63 66 if (i && c[--i] == '\n') 64 c[i] = 0;67 c[i] = '\0'; 65 68 66 69 return c; -
branches/2.2.5/mindi-busybox/libbb/herror_msg.c
r821 r1765 8 8 */ 9 9 10 #include <stdarg.h>11 #include <stdlib.h>12 13 10 #include "libbb.h" 14 11 … … 18 15 19 16 va_start(p, s); 20 bb_v herror_msg(s, p);17 bb_verror_msg(s, p, hstrerror(h_errno)); 21 18 va_end(p); 22 19 } -
branches/2.2.5/mindi-busybox/libbb/herror_msg_and_die.c
r821 r1765 8 8 */ 9 9 10 #include <stdarg.h>11 #include <stdlib.h>12 13 10 #include "libbb.h" 14 11 … … 18 15 19 16 va_start(p, s); 20 bb_v herror_msg(s, p);17 bb_verror_msg(s, p, hstrerror(h_errno)); 21 18 va_end(p); 22 exit(bb_default_error_retval);19 xfunc_die(); 23 20 } -
branches/2.2.5/mindi-busybox/libbb/human_readable.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * June 30, 2001 Manuel Novoa III … … 26 27 */ 27 28 28 #include <stdio.h>29 29 #include "libbb.h" 30 30 … … 32 32 unsigned long block_size, unsigned long display_unit) 33 33 { 34 /* The code will adjust for additional (appended) units .*/35 static const char zero_and_units[] = { '0', 0, 'k', 'M', 'G', 'T' };36 static const char fmt[] = "%llu";37 static const char fmt_tenths[] = "%llu.%d%c";34 /* The code will adjust for additional (appended) units */ 35 static const char zero_and_units[] ALIGN1 = { '0', 0, 'k', 'M', 'G', 'T' }; 36 static const char fmt[] ALIGN1 = "%llu"; 37 static const char fmt_tenths[] ALIGN1 = "%llu.%d%c"; 38 38 39 static char str[21] ; /* Sufficient for 64 bit unsigned integers.*/39 static char str[21] ALIGN1; /* Sufficient for 64 bit unsigned integers */ 40 40 41 41 unsigned long long val; … … 54 54 55 55 if (display_unit) { 56 val += display_unit/2; /* Deal with rounding .*/56 val += display_unit/2; /* Deal with rounding */ 57 57 val /= display_unit; /* Don't combine with the line above!!! */ 58 58 } else { 59 59 ++u; 60 while ((val >= KILOBYTE) 61 && (u < zero_and_units + sizeof(zero_and_units) - 1)) { 60 while ((val >= 1024) 61 && (u < zero_and_units + sizeof(zero_and_units) - 1) 62 ) { 62 63 f = fmt_tenths; 63 64 ++u; 64 frac = ((( (int)(val % KILOBYTE)) * 10) + (KILOBYTE/2)) / KILOBYTE;65 val /= KILOBYTE;65 frac = (((int)(val % 1024)) * 10 + 1024/2) / 1024; 66 val /= 1024; 66 67 } 67 68 if (frac >= 10) { /* We need to round up here. */ … … 71 72 #if 0 72 73 /* Sample code to omit decimal point and tenths digit. */ 73 if ( /* no_tenths */ 1) {74 if ( frac >= 5) {74 if (/* no_tenths */ 1) { 75 if (frac >= 5) { 75 76 ++val; 76 77 } 77 f = "%llu%*c" /* fmt_no_tenths */ 78 f = "%llu%*c" /* fmt_no_tenths */; 78 79 frac = 1; 79 80 } -
branches/2.2.5/mindi-busybox/libbb/inet_common.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * stolen from net-tools-1.59 and stripped down for busybox by … … 5 6 * Heavily modified by Manuel Novoa III Mar 12, 2001 6 7 * 7 * Version: $Id: inet_common.c,v 1.8 2004/03/10 07:42:38 mjn3 Exp $8 8 * 9 9 */ … … 11 11 #include "libbb.h" 12 12 #include "inet_common.h" 13 #include <stdio.h>14 #include <errno.h>15 #include <stdlib.h>16 #include <string.h>17 #include <unistd.h>18 19 #ifdef DEBUG20 # include <resolv.h>21 #endif22 23 24 const char bb_INET_default[] = "default";25 13 26 14 int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst) 27 15 { 28 16 struct hostent *hp; 17 #if ENABLE_FEATURE_ETC_NETWORKS 29 18 struct netent *np; 19 #endif 30 20 31 21 /* Grmpf. -FvK */ … … 34 24 35 25 /* Default is special, meaning 0.0.0.0. */ 36 if (!strcmp(name, bb_ INET_default)) {26 if (!strcmp(name, bb_str_default)) { 37 27 s_in->sin_addr.s_addr = INADDR_ANY; 38 return (1);28 return 1; 39 29 } 40 30 /* Look to see if it's a dotted quad. */ … … 45 35 #ifdef DEBUG 46 36 if (hostfirst) { 47 bb_error_msg("gethostbyname (%s)", name); 48 } 49 #endif 50 if (hostfirst && (hp = gethostbyname(name)) != (struct hostent *) NULL) { 51 memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0], 52 sizeof(struct in_addr)); 53 return 0; 54 } 37 bb_error_msg("gethostbyname(%s)", name); 38 } 39 #endif 40 if (hostfirst) { 41 hp = gethostbyname(name); 42 if (hp != NULL) { 43 memcpy(&s_in->sin_addr, hp->h_addr_list[0], 44 sizeof(struct in_addr)); 45 return 0; 46 } 47 } 48 #if ENABLE_FEATURE_ETC_NETWORKS 55 49 /* Try the NETWORKS database to see if this is a known network. */ 56 50 #ifdef DEBUG 57 bb_error_msg("getnetbyname (%s)", name); 58 #endif 59 if ((np = getnetbyname(name)) != (struct netent *) NULL) { 51 bb_error_msg("getnetbyname(%s)", name); 52 #endif 53 np = getnetbyname(name); 54 if (np != NULL) { 60 55 s_in->sin_addr.s_addr = htonl(np->n_net); 61 56 return 1; 62 57 } 58 #endif 63 59 if (hostfirst) { 64 60 /* Don't try again */ … … 71 67 72 68 #ifdef DEBUG 73 bb_error_msg("gethostbyname (%s)", name); 74 #endif 75 if ((hp = gethostbyname(name)) == (struct hostent *) NULL) { 69 bb_error_msg("gethostbyname(%s)", name); 70 #endif 71 hp = gethostbyname(name); 72 if (hp == NULL) { 76 73 return -1; 77 74 } 78 memcpy((char *) &s_in->sin_addr, (char *) hp->h_addr_list[0], 79 sizeof(struct in_addr)); 80 75 memcpy(&s_in->sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); 81 76 return 0; 82 77 } 83 78 84 /* cache */85 struct addr {86 struct sockaddr_in addr;87 char *name;88 int host;89 struct addr *next;90 };91 92 static struct addr *INET_nn = NULL; /* addr-to-name cache */93 79 94 80 /* numeric: & 0x8000: default instead of *, … … 96 82 * & 0x0fff: don't resolve 97 83 */ 98 int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in, 99 int numeric, unsigned int netmask) 100 { 101 struct hostent *ent; 102 struct netent *np; 84 char *INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t netmask) 85 { 86 /* addr-to-name cache */ 87 struct addr { 88 struct addr *next; 89 struct sockaddr_in addr; 90 int host; 91 char name[1]; 92 }; 93 static struct addr *cache = NULL; 94 103 95 struct addr *pn; 104 unsigned long ad, host_ad; 96 char *name; 97 uint32_t ad, host_ad; 105 98 int host = 0; 106 99 … … 108 101 if (s_in->sin_family != AF_INET) { 109 102 #ifdef DEBUG 110 bb_error_msg("rresolve: unsupport address family %d!",103 bb_error_msg("rresolve: unsupported address family %d!", 111 104 s_in->sin_family); 112 105 #endif 113 106 errno = EAFNOSUPPORT; 114 return (-1);115 } 116 ad = (unsigned long)s_in->sin_addr.s_addr;117 #ifdef DEBUG 118 bb_error_msg("rresolve: %08 lx, mask %08x, num %08x",ad, netmask, numeric);107 return NULL; 108 } 109 ad = s_in->sin_addr.s_addr; 110 #ifdef DEBUG 111 bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric); 119 112 #endif 120 113 if (ad == INADDR_ANY) { 121 114 if ((numeric & 0x0FFF) == 0) { 122 115 if (numeric & 0x8000) 123 safe_strncpy(name, bb_INET_default, len); 124 else 125 safe_strncpy(name, "*", len); 126 return (0); 116 return xstrdup(bb_str_default); 117 return xstrdup("*"); 127 118 } 128 119 } 129 if (numeric & 0x0FFF) { 130 safe_strncpy(name, inet_ntoa(s_in->sin_addr), len); 131 return (0); 132 } 120 if (numeric & 0x0FFF) 121 return xstrdup(inet_ntoa(s_in->sin_addr)); 133 122 134 123 if ((ad & (~netmask)) != 0 || (numeric & 0x4000)) 135 124 host = 1; 136 #if 0 137 INET_nn = NULL; 138 #endif 139 pn = INET_nn; 140 while (pn != NULL) { 125 pn = cache; 126 while (pn) { 141 127 if (pn->addr.sin_addr.s_addr == ad && pn->host == host) { 142 safe_strncpy(name, pn->name, len); 143 #ifdef DEBUG 144 bb_error_msg("rresolve: found %s %08lx in cache", 145 (host ? "host" : "net"), ad); 146 #endif 147 return (0); 128 #ifdef DEBUG 129 bb_error_msg("rresolve: found %s %08x in cache", 130 (host ? "host" : "net"), (unsigned)ad); 131 #endif 132 return xstrdup(pn->name); 148 133 } 149 134 pn = pn->next; … … 151 136 152 137 host_ad = ntohl(ad); 153 np = NULL; 154 ent = NULL; 138 name = NULL; 155 139 if (host) { 156 #ifdef DEBUG 157 bb_error_msg("gethostbyaddr (%08lx)", ad); 140 struct hostent *ent; 141 #ifdef DEBUG 142 bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad); 158 143 #endif 159 144 ent = gethostbyaddr((char *) &ad, 4, AF_INET); 160 if (ent != NULL) {161 safe_strncpy(name, ent->h_name, len);162 }163 } else {164 #ifdef DEBUG 165 bb_error_msg("getnetbyaddr (%08 lx)",host_ad);145 if (ent) 146 name = xstrdup(ent->h_name); 147 } else if (ENABLE_FEATURE_ETC_NETWORKS) { 148 struct netent *np; 149 #ifdef DEBUG 150 bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad); 166 151 #endif 167 152 np = getnetbyaddr(host_ad, AF_INET); 168 if (np != NULL) { 169 safe_strncpy(name, np->n_name, len); 170 } 171 } 172 if ((ent == NULL) && (np == NULL)) { 173 safe_strncpy(name, inet_ntoa(s_in->sin_addr), len); 174 } 175 pn = (struct addr *) xmalloc(sizeof(struct addr)); 153 if (np) 154 name = xstrdup(np->n_name); 155 } 156 if (!name) 157 name = xstrdup(inet_ntoa(s_in->sin_addr)); 158 pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */ 159 pn->next = cache; 176 160 pn->addr = *s_in; 177 pn->next = INET_nn;178 161 pn->host = host; 179 pn->name = bb_xstrdup(name); 180 INET_nn = pn; 181 182 return (0); 183 } 184 185 #ifdef CONFIG_FEATURE_IPV6 162 strcpy(pn->name, name); 163 cache = pn; 164 return name; 165 } 166 167 #if ENABLE_FEATURE_IPV6 186 168 187 169 int INET6_resolve(const char *name, struct sockaddr_in6 *sin6) … … 192 174 memset(&req, '\0', sizeof req); 193 175 req.ai_family = AF_INET6; 194 if ((s = getaddrinfo(name, NULL, &req, &ai))) { 176 s = getaddrinfo(name, NULL, &req, &ai); 177 if (s) { 195 178 bb_error_msg("getaddrinfo: %s: %d", name, s); 196 179 return -1; 197 180 } 198 181 memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6)); 199 200 182 freeaddrinfo(ai); 201 202 return (0); 183 return 0; 203 184 } 204 185 … … 210 191 211 192 212 int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, 213 int numeric) 214 { 193 char *INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) 194 { 195 char name[128]; 215 196 int s; 216 197 … … 218 199 if (sin6->sin6_family != AF_INET6) { 219 200 #ifdef DEBUG 220 bb_error_msg( _("rresolve: unsupport address family %d !\n"),201 bb_error_msg("rresolve: unsupport address family %d!", 221 202 sin6->sin6_family); 222 203 #endif 223 204 errno = EAFNOSUPPORT; 224 return (-1);205 return NULL; 225 206 } 226 207 if (numeric & 0x7FFF) { 227 inet_ntop(AF_INET6, &sin6->sin6_addr, name, len);228 return (0);208 inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name)); 209 return xstrdup(name); 229 210 } 230 211 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 231 if (numeric & 0x8000) { 232 strcpy(name, "default"); 233 } else { 234 strcpy(name, "*"); 235 } 236 return (0); 237 } 238 239 s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), name, len, NULL, 0, 0); 212 if (numeric & 0x8000) 213 return xstrdup(bb_str_default); 214 return xstrdup("*"); 215 } 216 217 s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), 218 name, sizeof(name), NULL, 0, 0); 240 219 if (s) { 241 220 bb_error_msg("getnameinfo failed"); 242 return -1;243 } 244 return (0);221 return NULL; 222 } 223 return xstrdup(name); 245 224 } 246 225 -
branches/2.2.5/mindi-busybox/libbb/inode_hash.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h>12 #include <stdlib.h>13 #include <string.h>14 11 #include "libbb.h" 12 13 typedef struct ino_dev_hash_bucket_struct { 14 struct ino_dev_hash_bucket_struct *next; 15 ino_t ino; 16 dev_t dev; 17 char name[1]; 18 } ino_dev_hashtable_bucket_t; 15 19 16 20 #define HASH_SIZE 311 /* Should be prime */ 17 21 #define hash_inode(i) ((i) % HASH_SIZE) 18 22 19 typedef struct ino_dev_hash_bucket_struct { 20 struct ino_dev_hash_bucket_struct *next; 21 ino_t ino; 22 dev_t dev; 23 char name[1]; 24 } ino_dev_hashtable_bucket_t; 25 26 static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE]; 23 /* array of [HASH_SIZE] elements */ 24 static ino_dev_hashtable_bucket_t **ino_dev_hashtable; 27 25 28 26 /* 29 * Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in 30 * `ino_dev_hashtable', else return 0 31 * 32 * If NAME is a non-NULL pointer to a character pointer, and there is 33 * a match, then set *NAME to the value of the name slot in that 34 * bucket. 27 * Return name if statbuf->st_ino && statbuf->st_dev are recorded in 28 * ino_dev_hashtable, else return NULL 35 29 */ 36 int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)30 char *is_in_ino_dev_hashtable(const struct stat *statbuf) 37 31 { 38 32 ino_dev_hashtable_bucket_t *bucket; 39 33 34 if (!ino_dev_hashtable) 35 return NULL; 36 40 37 bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)]; 41 38 while (bucket != NULL) { 42 if ((bucket->ino == statbuf->st_ino) && 43 (bucket->dev == statbuf->st_dev)) 44 { 45 if (name) *name = bucket->name; 46 return 1; 47 } 48 bucket = bucket->next; 39 if ((bucket->ino == statbuf->st_ino) 40 && (bucket->dev == statbuf->st_dev) 41 ) { 42 return bucket->name; 43 } 44 bucket = bucket->next; 49 45 } 50 return 0;46 return NULL; 51 47 } 52 48 … … 55 51 { 56 52 int i; 57 size_t s;58 53 ino_dev_hashtable_bucket_t *bucket; 59 54 60 55 i = hash_inode(statbuf->st_ino); 61 s = name ? strlen(name) : 0; 62 bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + s); 56 if (!name) 57 name = ""; 58 bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + strlen(name)); 63 59 bucket->ino = statbuf->st_ino; 64 60 bucket->dev = statbuf->st_dev; 65 if (name) 66 strcpy(bucket->name, name); 67 else 68 bucket->name[0] = '\0'; 61 strcpy(bucket->name, name); 62 63 if (!ino_dev_hashtable) 64 ino_dev_hashtable = xzalloc(HASH_SIZE * sizeof(*ino_dev_hashtable)); 65 69 66 bucket->next = ino_dev_hashtable[i]; 70 67 ino_dev_hashtable[i] = bucket; 71 68 } 72 69 73 #if def CONFIG_FEATURE_CLEAN_UP70 #if ENABLE_FEATURE_CLEAN_UP 74 71 /* Clear statbuf hash table */ 75 72 void reset_ino_dev_hashtable(void) … … 78 75 ino_dev_hashtable_bucket_t *bucket; 79 76 80 for (i = 0; i < HASH_SIZE; i++) {77 for (i = 0; ino_dev_hashtable && i < HASH_SIZE; i++) { 81 78 while (ino_dev_hashtable[i] != NULL) { 82 79 bucket = ino_dev_hashtable[i]->next; … … 85 82 } 86 83 } 84 free(ino_dev_hashtable); 85 ino_dev_hashtable = NULL; 87 86 } 87 #else 88 void reset_ino_dev_hashtable(void); 88 89 #endif -
branches/2.2.5/mindi-busybox/libbb/kernel_version.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <string.h>12 #include <stdlib.h>13 10 #include <sys/utsname.h> /* for uname(2) */ 14 11 … … 28 25 if (uname(&name) == -1) { 29 26 bb_perror_msg("cannot get system information"); 30 return (0);27 return 0; 31 28 } 32 29 33 30 s = name.release; 34 31 r = 0; 35 for (i =0 ; i<3; i++) {32 for (i = 0; i < 3; i++) { 36 33 r = r * 256 + atoi(strtok(s, ".")); 37 34 s = NULL; -
branches/2.2.5/mindi-busybox/libbb/last_char_is.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * busybox library eXtended function … … 4 5 * Copyright (C) 2001 Larry Doolittle, <ldoolitt@recycle.lbl.gov> 5 6 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 */ 21 9 22 #include <string.h>23 10 #include "libbb.h" 24 11 25 /* Find out if the last character of a string matches the one given Don't 26 * underrun the buffer if the string length is 0. Also avoids a possible 27 * space-hogging inline of strlen() per usage. 12 /* Find out if the last character of a string matches the one given. 13 * Don't underrun the buffer if the string length is 0. 28 14 */ 29 char 15 char* last_char_is(const char *s, int c) 30 16 { 31 char *sret = (char *)s;32 if (sret) {33 s ret = strrchr(sret, c);34 if (sret != NULL && *(sret+1) != 0)35 sret = NULL;17 if (s && *s) { 18 size_t sz = strlen(s) - 1; 19 s += sz; 20 if ( (unsigned char)*s == c) 21 return (char*)s; 36 22 } 37 return sret;23 return NULL; 38 24 } -
branches/2.2.5/mindi-busybox/libbb/llist.c
r821 r1765 8 8 * Copyright (C) 2006 Rob Landley <rob@landley.net> 9 9 * 10 * Licensed under the GPL v2 , see the file LICENSE in this tarball.10 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 11 11 */ 12 #include <stdlib.h> 12 13 13 #include "libbb.h" 14 14 15 #ifdef L_llist_add_to16 15 /* Add data to the start of the linked list. */ 17 16 void llist_add_to(llist_t **old_head, void *data) 18 17 { 19 18 llist_t *new_head = xmalloc(sizeof(llist_t)); 19 20 20 new_head->data = data; 21 21 new_head->link = *old_head; 22 22 *old_head = new_head; 23 23 } 24 #endif25 24 26 #ifdef L_llist_add_to_end27 25 /* Add data to the end of the linked list. */ 28 26 void llist_add_to_end(llist_t **list_head, void *data) 29 27 { 30 28 llist_t *new_item = xmalloc(sizeof(llist_t)); 29 31 30 new_item->data = data; 32 31 new_item->link = NULL; 33 32 34 if (!*list_head) *list_head = new_item; 33 if (!*list_head) 34 *list_head = new_item; 35 35 else { 36 36 llist_t *tail = *list_head; 37 while (tail->link) tail = tail->link; 37 38 while (tail->link) 39 tail = tail->link; 38 40 tail->link = new_item; 39 41 } 40 42 } 41 #endif42 43 43 #ifdef L_llist_pop44 44 /* Remove first element from the list and return it */ 45 45 void *llist_pop(llist_t **head) 46 46 { 47 void *data ;47 void *data, *next; 48 48 49 if (!*head) data = *head;50 else {51 void *next = (*head)->link; 52 53 free(*head);54 *head = next;55 }49 if (!*head) 50 return NULL; 51 52 data = (*head)->data; 53 next = (*head)->link; 54 free(*head); 55 *head = next; 56 56 57 57 return data; 58 58 } 59 #endif60 59 61 #ifdef L_llist_free 60 /* Unlink arbitrary given element from the list */ 61 void llist_unlink(llist_t **head, llist_t *elm) 62 { 63 llist_t *crt; 64 65 if (!(elm && *head)) 66 return; 67 68 if (elm == *head) { 69 *head = (*head)->link; 70 return; 71 } 72 73 for (crt = *head; crt; crt = crt->link) { 74 if (crt->link == elm) { 75 crt->link = elm->link; 76 return; 77 } 78 } 79 } 80 62 81 /* Recursively free all elements in the linked list. If freeit != NULL 63 82 * call it on each datum in the list */ 64 void llist_free(llist_t *elm, void (*freeit) (void *data))83 void llist_free(llist_t *elm, void (*freeit) (void *data)) 65 84 { 66 85 while (elm) { 67 86 void *data = llist_pop(&elm); 68 if (freeit) freeit(data); 87 88 if (freeit) 89 freeit(data); 69 90 } 70 91 } 92 93 #ifdef UNUSED 94 /* Reverse list order. */ 95 llist_t *llist_rev(llist_t *list) 96 { 97 llist_t *rev = NULL; 98 99 while (list) { 100 llist_t *next = list->link; 101 102 list->link = rev; 103 rev = list; 104 list = next; 105 } 106 return rev; 107 } 71 108 #endif -
branches/2.2.5/mindi-busybox/libbb/login.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * issue.c: issue printing code … … 4 5 * Copyright (C) 2003 Bastian Blank <waldi@tuxbox.org> 5 6 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 7 * Optimize and correcting OCRNL by Vladimir Oleynik <dzo@simtreas.ru> 10 8 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 20 * Optimize and correcting OCRNL by Vladimir Oleynik <dzo@simtreas.ru> 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 10 */ 22 11 23 12 #include <sys/param.h> /* MAXHOSTNAMELEN */ 24 #include <stdio.h> 25 #include <unistd.h> 13 #include <sys/utsname.h> 26 14 #include "libbb.h" 27 28 #include <sys/utsname.h>29 #include <time.h>30 15 31 16 #define LOGIN " login: " 32 17 33 static const char fmtstr_d[] = "%A, %d %B %Y";34 static const char fmtstr_t[] = "%H:%M:%S";18 static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y"; 19 static const char fmtstr_t[] ALIGN1 = "%H:%M:%S"; 35 20 36 21 void print_login_issue(const char *issue_file, const char *tty) … … 48 33 puts("\r"); /* start a new line */ 49 34 50 if ((fd = fopen(issue_file, "r"))) { 51 while ((c = fgetc(fd)) != EOF) { 52 outbuf = buf; 53 buf[0] = c; 54 if(c == '\n') { 55 buf[1] = '\r'; 56 buf[2] = 0; 57 } else { 58 buf[1] = 0; 35 fd = fopen(issue_file, "r"); 36 if (!fd) 37 return; 38 while ((c = fgetc(fd)) != EOF) { 39 outbuf = buf; 40 buf[0] = c; 41 buf[1] = '\0'; 42 if (c == '\n') { 43 buf[1] = '\r'; 44 buf[2] = '\0'; 45 } 46 if (c == '\\' || c == '%') { 47 c = fgetc(fd); 48 switch (c) { 49 case 's': 50 outbuf = uts.sysname; 51 break; 52 case 'n': 53 outbuf = uts.nodename; 54 break; 55 case 'r': 56 outbuf = uts.release; 57 break; 58 case 'v': 59 outbuf = uts.version; 60 break; 61 case 'm': 62 outbuf = uts.machine; 63 break; 64 case 'D': 65 case 'o': 66 c = getdomainname(buf, sizeof(buf) - 1); 67 buf[c >= 0 ? c : 0] = '\0'; 68 break; 69 case 'd': 70 strftime(buf, sizeof(buf), fmtstr_d, localtime(&t)); 71 break; 72 case 't': 73 strftime(buf, sizeof(buf), fmtstr_t, localtime(&t)); 74 break; 75 case 'h': 76 gethostname(buf, sizeof(buf) - 1); 77 buf[sizeof(buf) - 1] = '\0'; 78 break; 79 case 'l': 80 outbuf = tty; 81 break; 82 default: 83 buf[0] = c; 59 84 } 60 if (c == '\\' || c == '%') {61 c = fgetc(fd);62 switch (c) {63 case 's':64 outbuf = uts.sysname;65 break;66 67 case 'n':68 outbuf = uts.nodename;69 break;70 71 case 'r':72 outbuf = uts.release;73 break;74 75 case 'v':76 outbuf = uts.version;77 break;78 79 case 'm':80 outbuf = uts.machine;81 break;82 83 case 'D':84 case 'o':85 c = getdomainname(buf, sizeof(buf) - 1);86 buf[c >= 0 ? c : 0] = '\0';87 break;88 89 case 'd':90 strftime(buf, sizeof(buf), fmtstr_d, localtime(&t));91 break;92 93 case 't':94 strftime(buf, sizeof(buf), fmtstr_t, localtime(&t));95 break;96 97 case 'h':98 gethostname(buf, sizeof(buf) - 1);99 buf[sizeof(buf) - 1] = '\0';100 break;101 102 case 'l':103 outbuf = tty;104 break;105 106 default:107 buf[0] = c;108 }109 }110 fputs(outbuf, stdout);111 85 } 112 113 fclose(fd); 114 115 fflush(stdout); 86 fputs(outbuf, stdout); 116 87 } 88 fclose(fd); 89 fflush(stdout); 117 90 } 118 91 … … 121 94 char buf[MAXHOSTNAMELEN+1]; 122 95 123 if (gethostname(buf, MAXHOSTNAMELEN) == 0)96 if (gethostname(buf, MAXHOSTNAMELEN) == 0) 124 97 fputs(buf, stdout); 125 98 … … 127 100 fflush(stdout); 128 101 } 129 -
branches/2.2.5/mindi-busybox/libbb/loop.c
r821 r1765 4 4 * 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * Copyright (C) 2005 by Rob Landley <rob@landley.net> 6 7 * 7 8 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 8 9 */ 9 10 10 11 #include <features.h>12 #include <stdio.h>13 #include <errno.h>14 #include <fcntl.h>15 #include <string.h>16 #include <unistd.h>17 #include <sys/ioctl.h>18 11 #include "libbb.h" 19 12 … … 56 49 int fd; 57 50 bb_loop_info loopinfo; 58 char *dev =0;51 char *dev = 0; 59 52 60 if ((fd = open(device, O_RDONLY)) < 0) return 0; 53 fd = open(device, O_RDONLY); 54 if (fd < 0) return 0; 61 55 if (!ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo)) 62 dev =bb_xasprintf("%ld %s", (long) loopinfo.lo_offset,56 dev = xasprintf("%ld %s", (long) loopinfo.lo_offset, 63 57 (char *)loopinfo.lo_file_name); 64 58 close(fd); … … 72 66 int fd, rc; 73 67 74 if ((fd = open(device, O_RDONLY)) < 0) return 1; 75 rc=ioctl(fd, LOOP_CLR_FD, 0); 68 fd = open(device, O_RDONLY); 69 if (fd < 0) return 1; 70 rc = ioctl(fd, LOOP_CLR_FD, 0); 76 71 close(fd); 77 72 … … 85 80 file/offset if it finds one. 86 81 */ 87 int set_loop(char **device, const char *file, intoffset)82 int set_loop(char **device, const char *file, unsigned long long offset) 88 83 { 89 char dev[20], *try; 84 char dev[LOOP_NAMESIZE]; 85 char *try; 90 86 bb_loop_info loopinfo; 91 87 struct stat statbuf; 92 int i, dfd, ffd, mode, rc =-1;93 88 int i, dfd, ffd, mode, rc = -1; 89 94 90 /* Open the file. Barf if this doesn't work. */ 95 if((ffd = open(file, mode=O_RDWR))<0 && (ffd = open(file,mode=O_RDONLY))<0) 96 return -errno; 91 mode = O_RDWR; 92 ffd = open(file, mode); 93 if (ffd < 0) { 94 mode = O_RDONLY; 95 ffd = open(file, mode); 96 if (ffd < 0) 97 return -errno; 98 } 97 99 98 100 /* Find a loop device. */ 99 try =*device ? : dev;100 for (i=0;rc;i++) {101 try = *device ? : dev; 102 for (i = 0; rc; i++) { 101 103 sprintf(dev, LOOP_FORMAT, i); 102 104 103 105 /* Ran out of block devices, return failure. */ 104 if (stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) {105 rc =-ENOENT;106 if (stat(try, &statbuf) || !S_ISBLK(statbuf.st_mode)) { 107 rc = -ENOENT; 106 108 break; 107 109 } 108 110 /* Open the sucker and check its loopiness. */ 109 if((dfd=open(try, mode))<0 && errno==EROFS) 110 dfd=open(try, mode = O_RDONLY); 111 if(dfd<0) goto try_again; 111 dfd = open(try, mode); 112 if (dfd < 0 && errno == EROFS) { 113 mode = O_RDONLY; 114 dfd = open(try, mode); 115 } 116 if (dfd < 0) 117 goto try_again; 112 118 113 rc =ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo);119 rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); 114 120 115 /* If device free, claim it. */116 if (rc && errno==ENXIO) {121 /* If device is free, claim it. */ 122 if (rc && errno == ENXIO) { 117 123 memset(&loopinfo, 0, sizeof(loopinfo)); 118 124 safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); 119 125 loopinfo.lo_offset = offset; 120 126 /* Associate free loop device with file. */ 121 if(!ioctl(dfd, LOOP_SET_FD, ffd)) { 122 if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) rc=0; 123 else ioctl(dfd, LOOP_CLR_FD, 0); 127 if (!ioctl(dfd, LOOP_SET_FD, ffd)) { 128 if (!ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo)) 129 rc = 0; 130 else 131 ioctl(dfd, LOOP_CLR_FD, 0); 124 132 } 125 133 … … 129 137 without using losetup manually is problematic.) 130 138 */ 131 } else if(strcmp(file,(char *)loopinfo.lo_file_name) 132 || offset!=loopinfo.lo_offset) rc=-1; 139 } else if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 140 || offset != loopinfo.lo_offset) { 141 rc = -1; 142 } 133 143 close(dfd); 134 try_again:135 if (*device) break;144 try_again: 145 if (*device) break; 136 146 } 137 147 close(ffd); 138 if(!rc) { 139 if(!*device) *device=strdup(dev); 140 return mode==O_RDONLY ? 1 : 0; 141 } else return rc; 148 if (!rc) { 149 if (!*device) 150 *device = xstrdup(dev); 151 return (mode == O_RDONLY); /* 1:ro, 0:rw */ 152 } 153 return rc; 142 154 } -
branches/2.2.5/mindi-busybox/libbb/make_directory.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 36 23 */ 37 24 38 #include <errno.h>39 #include <unistd.h>40 #include <sys/stat.h>41 25 #include "libbb.h" 26 27 /* This function is used from NOFORK applets. It must not allocate anything */ 42 28 43 29 int bb_make_directory (char *path, long mode, int flags) … … 113 99 } while (1); 114 100 115 bb_perror_msg ("Cannot %s directory `%s'", fail_msg, path);101 bb_perror_msg("cannot %s directory '%s'", fail_msg, path); 116 102 return -1; 117 103 } -
branches/2.2.5/mindi-busybox/libbb/md5.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * md5.c - Compute MD5 checksum of strings according to the … … 12 13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 13 14 */ 14 #include <fcntl.h>15 #include <limits.h>16 #include <stdio.h>17 #include <stdint.h>18 #include <stdlib.h>19 #include <string.h>20 #include <unistd.h>21 15 22 16 #include "libbb.h" 23 17 24 # 18 #if CONFIG_MD5_SIZE_VS_SPEED < 0 || CONFIG_MD5_SIZE_VS_SPEED > 3 25 19 # define MD5_SIZE_VS_SPEED 2 26 # 20 #else 27 21 # define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED 28 # 22 #endif 29 23 30 24 /* Initialize structure containing state of computation. … … 82 76 }; 83 77 84 static const char P_array[] = {78 static const char P_array[] ALIGN1 = { 85 79 # if MD5_SIZE_VS_SPEED > 1 86 80 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ … … 92 86 93 87 # if MD5_SIZE_VS_SPEED > 1 94 static const char S_array[] = {88 static const char S_array[] ALIGN1 = { 95 89 7, 12, 17, 22, 96 90 5, 9, 14, 20, … … 439 433 if (buf != ctx->buffer) md5_hash_block(ctx->buffer, ctx); 440 434 md5_hash_block(buf, ctx); 441 435 442 436 /* Put result from CTX in first 16 bytes following RESBUF. The result is 443 437 * always in little endian byte order, so that a byte-wise output yields -
branches/2.2.5/mindi-busybox/libbb/messages.c
r821 r1765 4 4 * 5 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 6 *7 6 */ 8 7 9 8 #include "libbb.h" 10 9 11 #ifdef L_full_version12 10 #ifndef BB_EXTRA_VERSION 13 #define LIBBB_BANNER "BusyBox's libraryv" BB_VER " (" BB_BT ")"11 #define BANNER "BusyBox v" BB_VER " (" BB_BT ")" 14 12 #else 15 #define LIBBB_BANNER "BusyBox's libraryv" BB_VER " (" BB_EXTRA_VERSION ")"13 #define BANNER "BusyBox v" BB_VER " (" BB_EXTRA_VERSION ")" 16 14 #endif 17 const char * const libbb_msg_full_version = LIBBB_BANNER; 18 #endif 19 #ifdef L_memory_exhausted 20 const char * const bb_msg_memory_exhausted = "memory exhausted"; 21 #endif 22 #ifdef L_invalid_date 23 const char * const bb_msg_invalid_date = "invalid date `%s'"; 24 #endif 25 #ifdef L_io_error 26 const char * const bb_msg_io_error = "%s: input/output error -- %m"; 27 #endif 28 #ifdef L_write_error 29 const char * const bb_msg_write_error = "Write Error"; 30 #endif 31 #ifdef L_read_error 32 const char * const bb_msg_read_error = "Read Error"; 33 #endif 34 #ifdef L_name_longer_than_foo 35 const char * const bb_msg_name_longer_than_foo = "Names longer than %d chars not supported."; 36 #endif 37 #ifdef L_unknown 38 const char * const bb_msg_unknown = "(unknown)"; 39 #endif 40 #ifdef L_can_not_create_raw_socket 41 const char * const bb_msg_can_not_create_raw_socket = "can't create raw socket"; 42 #endif 43 #ifdef L_perm_denied_are_you_root 44 const char * const bb_msg_perm_denied_are_you_root = "permission denied. (are you root?)"; 45 #endif 46 #ifdef L_msg_requires_arg 47 const char * const bb_msg_requires_arg = "%s requires an argument"; 48 #endif 49 #ifdef L_msg_invalid_arg 50 const char * const bb_msg_invalid_arg = "invalid argument `%s' to `%s'"; 51 #endif 52 #ifdef L_msg_standard_input 53 const char * const bb_msg_standard_input = "standard input"; 54 #endif 55 #ifdef L_msg_standard_output 56 const char * const bb_msg_standard_output = "standard output"; 57 #endif 15 const char bb_banner[] ALIGN1 = BANNER; 58 16 59 #ifdef L_passwd_file 60 #define PASSWD_FILE "/etc/passwd" 61 const char * const bb_path_passwd_file = PASSWD_FILE; 62 #endif 17 const char bb_msg_memory_exhausted[] ALIGN1 = "memory exhausted"; 18 const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'"; 19 const char bb_msg_write_error[] ALIGN1 = "write error"; 20 const char bb_msg_read_error[] ALIGN1 = "read error"; 21 const char bb_msg_unknown[] ALIGN1 = "(unknown)"; 22 const char bb_msg_can_not_create_raw_socket[] ALIGN1 = "can't create raw socket"; 23 const char bb_msg_perm_denied_are_you_root[] ALIGN1 = "permission denied. (are you root?)"; 24 const char bb_msg_requires_arg[] ALIGN1 = "%s requires an argument"; 25 const char bb_msg_invalid_arg[] ALIGN1 = "invalid argument '%s' to '%s'"; 26 const char bb_msg_standard_input[] ALIGN1 = "standard input"; 27 const char bb_msg_standard_output[] ALIGN1 = "standard output"; 63 28 64 #ifdef L_shadow_file 65 #define SHADOW_FILE "/etc/shadow" 66 const char * const bb_path_shadow_file = SHADOW_FILE; 67 #endif 29 const char bb_str_default[] ALIGN1 = "default"; 30 const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF"; 68 31 69 #ifdef L_group_file 70 #define GROUP_FILE "/etc/group" 71 const char * const bb_path_group_file = GROUP_FILE; 72 #endif 32 const char bb_path_passwd_file[] ALIGN1 = "/etc/passwd"; 33 const char bb_path_shadow_file[] ALIGN1 = "/etc/shadow"; 34 const char bb_path_group_file[] ALIGN1 = "/etc/group"; 35 const char bb_path_gshadow_file[] ALIGN1 = "/etc/gshadow"; 36 const char bb_path_motd_file[] ALIGN1 = "/etc/motd"; 37 const char bb_dev_null[] ALIGN1 = "/dev/null"; 38 const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH; 39 const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; 40 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, 41 * but I want to save a few bytes here. Check libbb.h before changing! */ 42 const char bb_PATH_root_path[] ALIGN1 = "PATH=/sbin:/usr/sbin:/bin:/usr/bin"; 73 43 74 #ifdef L_gshadow_file75 #define GSHADOW_FILE "/etc/gshadow"76 const char * const bb_path_gshadow_file = GSHADOW_FILE;77 #endif78 44 79 #ifdef L_nologin_file 80 #define NOLOGIN_FILE "/etc/nologin" 81 const char * const bb_path_nologin_file = NOLOGIN_FILE; 82 #endif 45 const int const_int_0; 46 const int const_int_1 = 1; 83 47 84 #ifdef L_securetty_file85 #define SECURETTY_FILE "/etc/securetty"86 const char * const bb_path_securetty_file = SECURETTY_FILE;87 #endif88 89 #ifdef L_motd_file90 #define MOTD_FILE "/etc/motd"91 const char * const bb_path_motd_file = MOTD_FILE;92 #endif93 94 #ifdef L_shell_file95 const char * const bb_default_login_shell = LIBBB_DEFAULT_LOGIN_SHELL;96 #endif97 98 #ifdef L_bb_dev_null99 const char * const bb_dev_null = "/dev/null";100 #endif101 102 #ifdef L_bb_path_wtmp_file103 48 #include <utmp.h> 104 49 /* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */ 105 const char * const bb_path_wtmp_file=50 const char bb_path_wtmp_file[] ALIGN1 = 106 51 #if defined _PATH_WTMP 107 52 _PATH_WTMP; … … 111 56 # error unknown path to wtmp file 112 57 #endif 113 #endif114 58 59 char bb_common_bufsiz1[COMMON_BUFSIZE]; 115 60 116 #ifdef L_bb_common_bufsiz1 117 char bb_common_bufsiz1[BUFSIZ+1]; 118 #endif 61 struct globals; 62 /* Make it reside in R/W memory: */ 63 struct globals *const ptr_to_globals __attribute__ ((section (".data"))); -
branches/2.2.5/mindi-busybox/libbb/mode_string.c
r821 r1765 6 6 * 7 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 *9 8 */ 10 9 … … 49 48 /* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', 50 49 * and 'B' types don't appear to be available on linux. So I removed them. */ 51 static const char type_chars[16] = "?pc?d?b?-?l?s???";50 static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???"; 52 51 /* 0123456789abcdef */ 53 static const char mode_chars[7] = "rwxSTst";52 static const char mode_chars[7] ALIGN1 = "rwxSTst"; 54 53 55 const char *bb_mode_string( int mode)54 const char *bb_mode_string(mode_t mode) 56 55 { 57 56 static char buf[12]; … … 93 92 static const char mode_chars[7] = "rwxSTst"; 94 93 95 const char *bb_mode_string( int mode)94 const char *bb_mode_string(mode_t mode) 96 95 { 97 96 static char buf[12]; -
branches/2.2.5/mindi-busybox/libbb/mtab.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 */ 21 9 22 #include <stdlib.h>23 #include <unistd.h>24 #include <errno.h>25 #include <string.h>26 #include <stdio.h>27 10 #include <mntent.h> 28 11 #include "libbb.h" 29 12 30 #define MTAB_MAX_ENTRIES 40 31 32 #ifdef CONFIG_FEATURE_MTAB_SUPPORT 13 #if ENABLE_FEATURE_MTAB_SUPPORT 33 14 void erase_mtab(const char *name) 34 15 { 35 struct mntent entries[MTAB_MAX_ENTRIES];36 int count = 0;37 FILE *mountTable = setmntent(bb_path_mtab_file, "r");16 struct mntent *entries = NULL; 17 int i, count = 0; 18 FILE *mountTable; 38 19 struct mntent *m; 39 20 40 /* Check if reading the mtab file failed */41 if (mountTable == 042 /* Bummer. fall back on trying the /proc filesystem */43 && (mountTable = setmntent("/proc/mounts", "r")) == 0) {21 mountTable = setmntent(bb_path_mtab_file, "r"); 22 /* Bummer. Fall back on trying the /proc filesystem */ 23 if (!mountTable) mountTable = setmntent("/proc/mounts", "r"); 24 if (!mountTable) { 44 25 bb_perror_msg(bb_path_mtab_file); 45 26 return; 46 27 } 47 28 48 while (( (m = getmntent(mountTable)) != 0) && (count < MTAB_MAX_ENTRIES))49 {50 entries [count].mnt_fsname = strdup(m->mnt_fsname);51 entries[ count].mnt_dir = strdup(m->mnt_dir);52 entries[ count].mnt_type = strdup(m->mnt_type);53 entries[ count].mnt_opts = strdup(m->mnt_opts);54 entries[ count].mnt_freq = m->mnt_freq;55 entries[ count].mnt_passno = m->mnt_passno;56 count++;29 while ((m = getmntent(mountTable)) != 0) { 30 i = count++; 31 entries = xrealloc(entries, count * sizeof(entries[0])); 32 entries[i].mnt_fsname = xstrdup(m->mnt_fsname); 33 entries[i].mnt_dir = xstrdup(m->mnt_dir); 34 entries[i].mnt_type = xstrdup(m->mnt_type); 35 entries[i].mnt_opts = xstrdup(m->mnt_opts); 36 entries[i].mnt_freq = m->mnt_freq; 37 entries[i].mnt_passno = m->mnt_passno; 57 38 } 58 39 endmntent(mountTable); 59 if ((mountTable = setmntent(bb_path_mtab_file, "w"))) {60 int i;61 40 41 mountTable = setmntent(bb_path_mtab_file, "w"); 42 if (mountTable) { 62 43 for (i = 0; i < count; i++) { 63 int result = (strcmp(entries[i].mnt_fsname, name) == 0 64 || strcmp(entries[i].mnt_dir, name) == 0); 65 66 if (result) 67 continue; 68 else 44 if (strcmp(entries[i].mnt_fsname, name) != 0 45 && strcmp(entries[i].mnt_dir, name) != 0) 69 46 addmntent(mountTable, &entries[i]); 70 47 } -
branches/2.2.5/mindi-busybox/libbb/mtab_file.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 10 #include "libbb.h" 12 13 11 14 12 /* Busybox mount uses either /proc/mounts or /etc/mtab to 15 13 * get the list of currently mounted filesystems */ 16 #if defined(CONFIG_FEATURE_MTAB_SUPPORT) 17 const char bb_path_mtab_file[] = "/etc/mtab"; 18 #else 19 const char bb_path_mtab_file[] = "/proc/mounts"; 20 #endif 14 const char bb_path_mtab_file[] ALIGN1 = 15 USE_FEATURE_MTAB_SUPPORT("/etc/mtab")SKIP_FEATURE_MTAB_SUPPORT("/proc/mounts"); -
branches/2.2.5/mindi-busybox/libbb/obscure.c
r821 r1765 40 40 */ 41 41 42 #include <ctype.h>43 #include <unistd.h>44 #include <string.h>45 #include <strings.h>46 47 42 #include "libbb.h" 48 49 50 /* passwords should consist of 6 (to 8 characters) */51 #define MINLEN 652 53 43 54 44 static int string_checker_helper(const char *p1, const char *p2) __attribute__ ((__pure__)); … … 72 62 int ret = string_checker_helper(p1, p2); 73 63 /* Make our own copy */ 74 char *p = bb_xstrdup(p1);64 char *p = xstrdup(p1); 75 65 /* reverse string */ 76 66 size = strlen(p); … … 101 91 int length; 102 92 int mixed = 0; 103 /* Add 1for each type of characters to the minlen of password */104 int size = MINLEN + 8;93 /* Add 2 for each type of characters to the minlen of password */ 94 int size = CONFIG_PASSWORD_MINLEN + 8; 105 95 const char *p; 106 96 char hostname[255]; 107 97 108 98 /* size */ 109 if (!new_p || (length = strlen(new_p)) < MINLEN)110 return ("too short");99 if (!new_p || (length = strlen(new_p)) < CONFIG_PASSWORD_MINLEN) 100 return "too short"; 111 101 112 102 /* no username as-is, as sub-string, reversed, capitalized, doubled */ … … 168 158 } 169 159 170 int obscure(const char *old, const char *newval, const struct passwd *pw dp)160 int obscure(const char *old, const char *newval, const struct passwd *pw) 171 161 { 172 162 const char *msg; 173 163 174 if ((msg = obscure_msg(old, newval, pwdp))) {175 printf("Bad password: %s.\n", msg);176 /* If user is root warn only */177 return (getuid())? 1 : 0;164 msg = obscure_msg(old, newval, pw); 165 if (msg) { 166 printf("Bad password: %s\n", msg); 167 return 1; 178 168 } 179 169 return 0; -
branches/2.2.5/mindi-busybox/libbb/parse_mode.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 10 /* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */ 24 11 25 #include <stdlib.h>26 #include <assert.h>27 #include <sys/stat.h>28 12 #include "libbb.h" 29 13 30 #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 14 /* This function is used from NOFORK applets. It must not allocate anything */ 15 16 #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 31 17 32 18 int bb_parse_mode(const char *s, mode_t *current_mode) … … 34 20 static const mode_t who_mask[] = { 35 21 S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ 36 S_ISUID | S_IRWXU, 37 S_ISGID | S_IRWXG, 38 S_IRWXO 22 S_ISUID | S_IRWXU, /* u */ 23 S_ISGID | S_IRWXG, /* g */ 24 S_IRWXO /* o */ 39 25 }; 40 41 26 static const mode_t perm_mask[] = { 42 27 S_IRUSR | S_IRGRP | S_IROTH, /* r */ … … 44 29 S_IXUSR | S_IXGRP | S_IXOTH, /* x */ 45 30 S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */ 46 S_ISUID | S_ISGID, 47 S_ISVTX 31 S_ISUID | S_ISGID, /* s */ 32 S_ISVTX /* t */ 48 33 }; 49 50 static const char who_chars[] = "augo"; 51 static const char perm_chars[] = "rwxXst"; 34 static const char who_chars[] ALIGN1 = "augo"; 35 static const char perm_chars[] ALIGN1 = "rwxXst"; 52 36 53 37 const char *p; 54 55 38 mode_t wholist; 56 39 mode_t permlist; 57 mode_t mask;58 40 mode_t new_mode; 59 41 char op; 60 61 assert(s);62 42 63 43 if (((unsigned int)(*s - '0')) < 8) { … … 65 45 char *e; 66 46 67 tmp = strto l(s, &e, 8);47 tmp = strtoul(s, &e, 8); 68 48 if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ 69 49 return 0; … … 73 53 } 74 54 75 mask = umask(0);76 umask(mask);77 78 55 new_mode = *current_mode; 79 56 80 /* Note: We allow empty clauses, and hence empty modes.57 /* Note: we allow empty clauses, and hence empty modes. 81 58 * We treat an empty mode as no change to perms. */ 82 59 83 60 while (*s) { /* Process clauses. */ 84 85 61 if (*s == ',') { /* We allow empty clauses. */ 86 62 ++s; … … 90 66 /* Get a wholist. */ 91 67 wholist = 0; 92 93 WHO_LIST: 68 WHO_LIST: 94 69 p = who_chars; 95 70 do { … … 109 84 } 110 85 /* Since op is '=', clear all bits corresponding to the 111 * wholist, o fall file bits if wholist is empty. */86 * wholist, or all file bits if wholist is empty. */ 112 87 permlist = ~FILEMODEBITS; 113 88 if (wholist) { … … 138 113 /* It was not a permcopy, so get a permlist. */ 139 114 permlist = 0; 140 141 PERM_LIST: 115 PERM_LIST: 142 116 p = perm_chars; 143 117 do { 144 118 if (*p == *s) { 145 119 if ((*p != 'X') 146 120 || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH)) 147 121 ) { 148 122 permlist |= perm_mask[(int)(p-perm_chars)]; … … 154 128 } 155 129 } while (*++p); 156 157 GOT_ACTION: 130 GOT_ACTION: 158 131 if (permlist) { /* The permlist was nonempty. */ 159 mode_t tmp = ~mask; 160 if (wholist) { 161 tmp = wholist; 132 mode_t tmp = wholist; 133 if (!wholist) { 134 mode_t u_mask = umask(0); 135 umask(u_mask); 136 tmp = ~u_mask; 162 137 } 163 138 permlist &= tmp; 164 165 139 if (op == '-') { 166 140 new_mode &= ~permlist; … … 173 147 174 148 *current_mode = new_mode; 175 176 149 return 1; 177 150 } -
branches/2.2.5/mindi-busybox/libbb/perror_msg.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <errno.h>12 #include <string.h>13 #include <stdlib.h>14 10 #include "libbb.h" 15 11 … … 19 15 20 16 va_start(p, s); 21 bb_vperror_msg(s, p); 17 /* Guard against "<error message>: Success" */ 18 bb_verror_msg(s, p, errno ? strerror(errno) : NULL); 22 19 va_end(p); 23 20 } -
branches/2.2.5/mindi-busybox/libbb/perror_msg_and_die.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <errno.h>12 #include <string.h>13 #include <stdlib.h>14 10 #include "libbb.h" 15 11 … … 19 15 20 16 va_start(p, s); 21 bb_vperror_msg(s, p); 17 /* Guard against "<error message>: Success" */ 18 bb_verror_msg(s, p, errno ? strerror(errno) : NULL); 22 19 va_end(p); 23 exit(bb_default_error_retval);20 xfunc_die(); 24 21 } -
branches/2.2.5/mindi-busybox/libbb/perror_nomsg.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <stddef.h> 24 #include <libbb.h> 10 /* gcc warns about a null format string, therefore we provide 11 * modified definition without "attribute (format)" 12 * instead of including libbb.h */ 13 //#include "libbb.h" 14 extern void bb_perror_msg(const char *s, ...); 25 15 16 /* suppress gcc "no previous prototype" warning */ 17 void bb_perror_nomsg(void); 26 18 void bb_perror_nomsg(void) 27 19 { 28 /* Ignore the gcc warning about a null format string. */ 29 bb_perror_msg(NULL); 20 bb_perror_msg(0); 30 21 } -
branches/2.2.5/mindi-busybox/libbb/perror_nomsg_and_die.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <stddef.h> 24 #include "libbb.h" 10 /* gcc warns about a null format string, therefore we provide 11 * modified definition without "attribute (format)" 12 * instead of including libbb.h */ 13 //#include "libbb.h" 14 extern void bb_perror_msg_and_die(const char *s, ...); 25 15 16 /* suppress gcc "no previous prototype" warning */ 17 void bb_perror_nomsg_and_die(void); 26 18 void bb_perror_nomsg_and_die(void) 27 19 { 28 /* Ignore the gcc warning about a null format string. */ 29 bb_perror_msg_and_die(NULL); 20 bb_perror_msg_and_die(0); 30 21 } -
branches/2.2.5/mindi-busybox/libbb/process_escape_sequence.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h>12 #include <limits.h>13 #include <ctype.h>14 11 #include "libbb.h" 15 12 … … 22 19 char bb_process_escape_sequence(const char **ptr) 23 20 { 24 static const char charmap[] = {21 static const char charmap[] ALIGN1 = { 25 22 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0, 26 23 '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' }; … … 47 44 48 45 do { 49 d = (unsigned int)(*q - '0');46 d = (unsigned char)(*q) - '0'; 50 47 #ifdef WANT_HEX_ESCAPES 51 48 if (d >= 10) { 52 d = ( (unsigned int)(_tolower(*q) - 'a'))+ 10;49 d = (unsigned char)(_tolower(*q)) - 'a' + 10; 53 50 } 54 51 #endif … … 81 78 } 82 79 } while (*++p); 83 n = *(p +(sizeof(charmap)/2));80 n = *(p + (sizeof(charmap)/2)); 84 81 } 85 82 -
branches/2.2.5/mindi-busybox/libbb/procps.c
r821 r1765 5 5 * Copyright 1998 by Albert Cahalan; all rights reserved. 6 6 * Copyright (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru> 7 * SELinux support: (c) 2007 by Yuichi Nakamura <ynakam@hitachisoft.jp> 7 8 * 8 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 9 10 */ 10 11 11 #include <dirent.h>12 #include <string.h>13 #include <stdlib.h>14 #include <sys/param.h>15 #include <unistd.h>16 #include <fcntl.h>17 18 12 #include "libbb.h" 19 13 20 14 15 typedef struct unsigned_to_name_map_t { 16 unsigned id; 17 char name[USERNAME_MAX_SIZE]; 18 } unsigned_to_name_map_t; 19 20 typedef struct cache_t { 21 unsigned_to_name_map_t *cache; 22 int size; 23 } cache_t; 24 25 static cache_t username, groupname; 26 27 static void clear_cache(cache_t *cp) 28 { 29 free(cp->cache); 30 cp->cache = NULL; 31 cp->size = 0; 32 } 33 void clear_username_cache(void) 34 { 35 clear_cache(&username); 36 clear_cache(&groupname); 37 } 38 39 #if 0 /* more generic, but we don't need that yet */ 40 /* Returns -N-1 if not found. */ 41 /* cp->cache[N] is allocated and must be filled in this case */ 42 static int get_cached(cache_t *cp, unsigned id) 43 { 44 int i; 45 for (i = 0; i < cp->size; i++) 46 if (cp->cache[i].id == id) 47 return i; 48 i = cp->size++; 49 cp->cache = xrealloc(cp->cache, cp->size * sizeof(*cp->cache)); 50 cp->cache[i++].id = id; 51 return -i; 52 } 53 #endif 54 55 typedef char* ug_func(char *name, int bufsize, long uid); 56 static char* get_cached(cache_t *cp, unsigned id, ug_func* fp) 57 { 58 int i; 59 for (i = 0; i < cp->size; i++) 60 if (cp->cache[i].id == id) 61 return cp->cache[i].name; 62 i = cp->size++; 63 cp->cache = xrealloc(cp->cache, cp->size * sizeof(*cp->cache)); 64 cp->cache[i].id = id; 65 /* Never fails. Generates numeric string if name isn't found */ 66 fp(cp->cache[i].name, sizeof(cp->cache[i].name), id); 67 return cp->cache[i].name; 68 } 69 const char* get_cached_username(uid_t uid) 70 { 71 return get_cached(&username, uid, bb_getpwuid); 72 } 73 const char* get_cached_groupname(gid_t gid) 74 { 75 return get_cached(&groupname, gid, bb_getgrgid); 76 } 77 78 21 79 #define PROCPS_BUFSIZE 1024 22 80 … … 24 82 { 25 83 int fd; 26 ssize_t ret; 27 84 /* open_read_close() would do two reads, checking for EOF. 85 * When you have 10000 /proc/$NUM/stat to read, it isn't desirable */ 86 ssize_t ret = -1; 28 87 fd = open(filename, O_RDONLY); 29 if (fd < 0)30 ret urn -1;31 ret = read(fd, buf, PROCPS_BUFSIZE-1);32 ((char *)buf)[ret > 0 ? ret : 0] = 0;33 close(fd);88 if (fd >= 0) { 89 ret = read(fd, buf, PROCPS_BUFSIZE-1); 90 close(fd); 91 } 92 ((char *)buf)[ret > 0 ? ret : 0] = '\0'; 34 93 return ret; 35 94 } 36 95 37 38 procps_status_t * procps_scan(int save_user_arg0) 39 { 40 static DIR *dir; 96 procps_status_t *alloc_procps_scan(int flags) 97 { 98 procps_status_t* sp = xzalloc(sizeof(procps_status_t)); 99 sp->dir = xopendir("/proc"); 100 return sp; 101 } 102 103 void free_procps_scan(procps_status_t* sp) 104 { 105 closedir(sp->dir); 106 free(sp->argv0); 107 USE_SELINUX(free(sp->context);) 108 free(sp); 109 } 110 111 #if ENABLE_FEATURE_FAST_TOP 112 /* We cut a lot of corners here for speed */ 113 static unsigned long fast_strtoul_10(char **endptr) 114 { 115 char c; 116 char *str = *endptr; 117 unsigned long n = *str - '0'; 118 119 while ((c = *++str) != ' ') 120 n = n*10 + (c - '0'); 121 122 *endptr = str + 1; /* We skip trailing space! */ 123 return n; 124 } 125 static char *skip_fields(char *str, int count) 126 { 127 do { 128 while (*str++ != ' ') 129 continue; 130 /* we found a space char, str points after it */ 131 } while (--count); 132 return str; 133 } 134 #endif 135 136 void BUG_comm_size(void); 137 procps_status_t *procps_scan(procps_status_t* sp, int flags) 138 { 41 139 struct dirent *entry; 42 static procps_status_t ret_status; 43 char *name; 140 char buf[PROCPS_BUFSIZE]; 141 char filename[sizeof("/proc//cmdline") + sizeof(int)*3]; 142 char *filename_tail; 143 long tasknice; 144 unsigned pid; 44 145 int n; 45 char status[32];46 char *status_tail;47 char buf[PROCPS_BUFSIZE];48 procps_status_t curstatus;49 int pid;50 long tasknice;51 146 struct stat sb; 52 147 53 if (!dir) { 54 dir = bb_xopendir("/proc"); 148 if (!sp) 149 sp = alloc_procps_scan(flags); 150 151 for (;;) { 152 entry = readdir(sp->dir); 153 if (entry == NULL) { 154 free_procps_scan(sp); 155 return NULL; 156 } 157 pid = bb_strtou(entry->d_name, NULL, 10); 158 if (errno) 159 continue; 160 161 /* After this point we have to break, not continue 162 * ("continue" would mean that current /proc/NNN 163 * is not a valid process info) */ 164 165 memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); 166 167 sp->pid = pid; 168 if (!(flags & ~PSSCAN_PID)) break; 169 170 #if ENABLE_SELINUX 171 if (flags & PSSCAN_CONTEXT) { 172 if (getpidcon(sp->pid, &sp->context) < 0) 173 sp->context = NULL; 174 } 175 #endif 176 177 filename_tail = filename + sprintf(filename, "/proc/%d", pid); 178 179 if (flags & PSSCAN_UIDGID) { 180 if (stat(filename, &sb)) 181 break; 182 /* Need comment - is this effective or real UID/GID? */ 183 sp->uid = sb.st_uid; 184 sp->gid = sb.st_gid; 185 } 186 187 if (flags & PSSCAN_STAT) { 188 char *cp, *comm1; 189 int tty; 190 #if !ENABLE_FEATURE_FAST_TOP 191 unsigned long vsz, rss; 192 #endif 193 194 /* see proc(5) for some details on this */ 195 strcpy(filename_tail, "/stat"); 196 n = read_to_buf(filename, buf); 197 if (n < 0) 198 break; 199 cp = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */ 200 /*if (!cp || cp[1] != ' ') 201 break;*/ 202 cp[0] = '\0'; 203 if (sizeof(sp->comm) < 16) 204 BUG_comm_size(); 205 comm1 = strchr(buf, '('); 206 /*if (comm1)*/ 207 safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm)); 208 209 #if !ENABLE_FEATURE_FAST_TOP 210 n = sscanf(cp+2, 211 "%c %u " /* state, ppid */ 212 "%u %u %d %*s " /* pgid, sid, tty, tpgid */ 213 "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */ 214 "%lu %lu " /* utime, stime */ 215 "%*s %*s %*s " /* cutime, cstime, priority */ 216 "%ld " /* nice */ 217 "%*s %*s %*s " /* timeout, it_real_value, start_time */ 218 "%lu " /* vsize */ 219 "%lu " /* rss */ 220 /* "%lu %lu %lu %lu %lu %lu " rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ 221 /* "%u %u %u %u " signal, blocked, sigignore, sigcatch */ 222 /* "%lu %lu %lu" wchan, nswap, cnswap */ 223 , 224 sp->state, &sp->ppid, 225 &sp->pgid, &sp->sid, &tty, 226 &sp->utime, &sp->stime, 227 &tasknice, 228 &vsz, 229 &rss); 230 if (n != 10) 231 break; 232 sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */ 233 sp->rss = rss >> 10; 234 sp->tty_major = (tty >> 8) & 0xfff; 235 sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00); 236 #else 237 /* This costs ~100 bytes more but makes top faster by 20% 238 * If you run 10000 processes, this may be important for you */ 239 sp->state[0] = cp[2]; 240 cp += 4; 241 sp->ppid = fast_strtoul_10(&cp); 242 sp->pgid = fast_strtoul_10(&cp); 243 sp->sid = fast_strtoul_10(&cp); 244 tty = fast_strtoul_10(&cp); 245 sp->tty_major = (tty >> 8) & 0xfff; 246 sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00); 247 cp = skip_fields(cp, 6); /* tpgid, flags, min_flt, cmin_flt, maj_flt, cmaj_flt */ 248 sp->utime = fast_strtoul_10(&cp); 249 sp->stime = fast_strtoul_10(&cp); 250 cp = skip_fields(cp, 3); /* cutime, cstime, priority */ 251 tasknice = fast_strtoul_10(&cp); 252 cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */ 253 sp->vsz = fast_strtoul_10(&cp) >> 10; /* vsize is in bytes and we want kb */ 254 sp->rss = fast_strtoul_10(&cp) >> 10; 255 #endif 256 257 if (sp->vsz == 0 && sp->state[0] != 'Z') 258 sp->state[1] = 'W'; 259 else 260 sp->state[1] = ' '; 261 if (tasknice < 0) 262 sp->state[2] = '<'; 263 else if (tasknice) /* > 0 */ 264 sp->state[2] = 'N'; 265 else 266 sp->state[2] = ' '; 267 268 } 269 270 #if 0 /* PSSCAN_CMD is not used */ 271 if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) { 272 if (sp->argv0) { 273 free(sp->argv0); 274 sp->argv0 = NULL; 275 } 276 if (sp->cmd) { 277 free(sp->cmd); 278 sp->cmd = NULL; 279 } 280 strcpy(filename_tail, "/cmdline"); 281 /* TODO: to get rid of size limits, read into malloc buf, 282 * then realloc it down to real size. */ 283 n = read_to_buf(filename, buf); 284 if (n <= 0) 285 break; 286 if (flags & PSSCAN_ARGV0) 287 sp->argv0 = xstrdup(buf); 288 if (flags & PSSCAN_CMD) { 289 do { 290 n--; 291 if ((unsigned char)(buf[n]) < ' ') 292 buf[n] = ' '; 293 } while (n); 294 sp->cmd = xstrdup(buf); 295 } 296 } 297 #else 298 if (flags & PSSCAN_ARGV0) { 299 if (sp->argv0) { 300 free(sp->argv0); 301 sp->argv0 = NULL; 302 } 303 strcpy(filename_tail, "/cmdline"); 304 n = read_to_buf(filename, buf); 305 if (n <= 0) 306 break; 307 if (flags & PSSCAN_ARGV0) 308 sp->argv0 = xstrdup(buf); 309 } 310 #endif 311 break; 55 312 } 56 for(;;) { 57 if((entry = readdir(dir)) == NULL) { 58 closedir(dir); 59 dir = 0; 60 return 0; 61 } 62 name = entry->d_name; 63 if (!(*name >= '0' && *name <= '9')) 64 continue; 65 66 memset(&curstatus, 0, sizeof(procps_status_t)); 67 pid = atoi(name); 68 curstatus.pid = pid; 69 70 status_tail = status + sprintf(status, "/proc/%d", pid); 71 if(stat(status, &sb)) 72 continue; 73 bb_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user)); 74 75 /* see proc(5) for some details on this */ 76 strcpy(status_tail, "/stat"); 77 n = read_to_buf(status, buf); 78 if(n < 0) 79 continue; 80 name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */ 81 if(name == 0 || name[1] != ' ') 82 continue; 83 *name = 0; 84 sscanf(buf, "%*s (%15c", curstatus.short_cmd); 85 n = sscanf(name+2, 86 "%c %d " 87 "%*s %*s %*s %*s " /* pgrp, session, tty, tpgid */ 88 "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */ 89 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 90 "%lu %lu " /* utime, stime */ 91 #else 92 "%*s %*s " /* utime, stime */ 93 #endif 94 "%*s %*s %*s " /* cutime, cstime, priority */ 95 "%ld " /* nice */ 96 "%*s %*s %*s " /* timeout, it_real_value, start_time */ 97 "%*s " /* vsize */ 98 "%ld", /* rss */ 99 curstatus.state, &curstatus.ppid, 100 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 101 &curstatus.utime, &curstatus.stime, 102 #endif 103 &tasknice, 104 &curstatus.rss); 105 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 106 if(n != 6) 107 #else 108 if(n != 4) 109 #endif 110 continue; 111 112 if (curstatus.rss == 0 && curstatus.state[0] != 'Z') 113 curstatus.state[1] = 'W'; 114 else 115 curstatus.state[1] = ' '; 116 if (tasknice < 0) 117 curstatus.state[2] = '<'; 118 else if (tasknice > 0) 119 curstatus.state[2] = 'N'; 120 else 121 curstatus.state[2] = ' '; 122 123 #ifdef PAGE_SHIFT 124 curstatus.rss <<= (PAGE_SHIFT - 10); /* 2**10 = 1kb */ 125 #else 126 curstatus.rss *= (getpagesize() >> 10); /* 2**10 = 1kb */ 127 #endif 128 129 if(save_user_arg0) { 130 strcpy(status_tail, "/cmdline"); 131 n = read_to_buf(status, buf); 132 if(n > 0) { 133 if(buf[n-1]=='\n') 134 buf[--n] = 0; 135 name = buf; 136 while(n) { 137 if(((unsigned char)*name) < ' ') 138 *name = ' '; 139 name++; 140 n--; 141 } 142 *name = 0; 143 if(buf[0]) 144 curstatus.cmd = strdup(buf); 145 /* if NULL it work true also */ 146 } 147 } 148 return memcpy(&ret_status, &curstatus, sizeof(procps_status_t)); 313 return sp; 314 } 315 316 void read_cmdline(char *buf, int col, unsigned pid, const char *comm) 317 { 318 ssize_t sz; 319 char filename[sizeof("/proc//cmdline") + sizeof(int)*3]; 320 321 sprintf(filename, "/proc/%u/cmdline", pid); 322 sz = open_read_close(filename, buf, col); 323 if (sz > 0) { 324 buf[sz] = '\0'; 325 while (--sz >= 0) 326 if ((unsigned char)(buf[sz]) < ' ') 327 buf[sz] = ' '; 328 } else { 329 snprintf(buf, col, "[%s]", comm); 149 330 } 150 331 } 332 333 /* from kernel: 334 // pid comm S ppid pgid sid tty_nr tty_pgrp flg 335 sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \ 336 %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ 337 %lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu %llu\n", 338 task->pid, 339 tcomm, 340 state, 341 ppid, 342 pgid, 343 sid, 344 tty_nr, 345 tty_pgrp, 346 task->flags, 347 min_flt, 348 cmin_flt, 349 maj_flt, 350 cmaj_flt, 351 cputime_to_clock_t(utime), 352 cputime_to_clock_t(stime), 353 cputime_to_clock_t(cutime), 354 cputime_to_clock_t(cstime), 355 priority, 356 nice, 357 num_threads, 358 // 0, 359 start_time, 360 vsize, 361 mm ? get_mm_rss(mm) : 0, 362 rsslim, 363 mm ? mm->start_code : 0, 364 mm ? mm->end_code : 0, 365 mm ? mm->start_stack : 0, 366 esp, 367 eip, 368 the rest is some obsolete cruft 369 */ -
branches/2.2.5/mindi-busybox/libbb/pw_encrypt.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 10 #include "libbb.h" 24 #include <string.h>25 11 #include <crypt.h> 26 27 12 28 13 char *pw_encrypt(const char *clear, const char *salt) 29 14 { 30 static char cipher[128];31 char *cp;15 /* Was static char[BIGNUM]. Malloced thing works as well */ 16 static char *cipher; 32 17 33 #if def CONFIG_FEATURE_SHA1_PASSWORDS18 #if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */ 34 19 if (strncmp(salt, "$2$", 3) == 0) { 35 20 return sha1_crypt(clear); 36 21 } 37 22 #endif 38 cp = (char *) crypt(clear, salt); 39 /* if crypt (a nonstandard crypt) returns a string too large, 40 truncate it so we don't overrun buffers and hope there is 41 enough security in what's left */ 42 safe_strncpy(cipher, cp, sizeof(cipher)); 23 24 free(cipher); 25 cipher = xstrdup(crypt(clear, salt)); 43 26 return cipher; 44 27 } 45 -
branches/2.2.5/mindi-busybox/libbb/recursive_action.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <string.h>12 #include <dirent.h>13 #include <sys/stat.h>14 #include <stdlib.h> /* free() */15 10 #include "libbb.h" 16 11 17 12 #undef DEBUG_RECURS_ACTION 18 19 13 20 14 /* … … 28 22 * is so stinking huge. 29 23 */ 24 25 static int true_action(const char *fileName, struct stat *statbuf, 26 void* userData, int depth) 27 { 28 return TRUE; 29 } 30 31 /* fileAction return value of 0 on any file in directory will make 32 * recursive_action() return 0, but it doesn't stop directory traversal 33 * (fileAction/dirAction will be called on each file). 34 * 35 * if !depthFirst, dirAction return value of 0 (FALSE) or 2 (SKIP) 36 * prevents recursion into that directory, instead 37 * recursive_action() returns 0 (if FALSE) or 1 (if SKIP). 38 * 39 * followLinks=0/1 differs mainly in handling of links to dirs. 40 * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. 41 * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. 42 */ 43 30 44 int recursive_action(const char *fileName, 31 int recurse, int followLinks, int depthFirst, 32 int (*fileAction) (const char *fileName, 33 struct stat * statbuf, 34 void* userData), 35 int (*dirAction) (const char *fileName, 36 struct stat * statbuf, 37 void* userData), 38 void* userData) 45 unsigned flags, 46 int (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth), 47 int (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth), 48 void* userData, 49 unsigned depth) 39 50 { 51 struct stat statbuf; 40 52 int status; 41 struct stat statbuf;53 DIR *dir; 42 54 struct dirent *next; 43 55 44 if (followLinks) 45 status = stat(fileName, &statbuf); 46 else 47 status = lstat(fileName, &statbuf); 56 if (!fileAction) fileAction = true_action; 57 if (!dirAction) dirAction = true_action; 48 58 59 status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */ 60 if (!depth) status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0; 61 status = ((flags & status) ? stat : lstat)(fileName, &statbuf); 49 62 if (status < 0) { 50 63 #ifdef DEBUG_RECURS_ACTION 51 bb_error_msg("status=%d followLinks=%d TRUE=%d", 52 status, followLinks, TRUE); 64 bb_error_msg("status=%d flags=%x", status, flags); 53 65 #endif 54 bb_perror_msg("%s", fileName); 55 return FALSE; 66 goto done_nak_warn; 56 67 } 57 68 58 if (! followLinks && (S_ISLNK(statbuf.st_mode))) { 59 if (fileAction == NULL) 60 return TRUE; 61 else 62 return fileAction(fileName, &statbuf, userData); 69 /* If S_ISLNK(m), then we know that !S_ISDIR(m). 70 * Then we can skip checking first part: if it is true, then 71 * (!dir) is also true! */ 72 if ( /* (!(flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */ 73 !S_ISDIR(statbuf.st_mode) 74 ) { 75 return fileAction(fileName, &statbuf, userData, depth); 63 76 } 64 77 65 if (! recurse) { 66 if (S_ISDIR(statbuf.st_mode)) { 67 if (dirAction != NULL) 68 return (dirAction(fileName, &statbuf, userData)); 69 else 70 return TRUE; 71 } 78 /* It's a directory (or a link to one, and followLinks is set) */ 79 80 if (!(flags & ACTION_RECURSE)) { 81 return dirAction(fileName, &statbuf, userData, depth); 72 82 } 73 83 74 if (S_ISDIR(statbuf.st_mode)) { 75 DIR *dir; 84 if (!(flags & ACTION_DEPTHFIRST)) { 85 status = dirAction(fileName, &statbuf, userData, depth); 86 if (!status) 87 goto done_nak_warn; 88 if (status == SKIP) 89 return TRUE; 90 } 76 91 77 if (dirAction != NULL && ! depthFirst) { 78 status = dirAction(fileName, &statbuf, userData); 79 if (! status) { 80 bb_perror_msg("%s", fileName); 81 return FALSE; 82 } else if (status == SKIP) 83 return TRUE; 84 } 85 dir = bb_opendir(fileName); 86 if (!dir) { 87 return FALSE; 88 } 89 status = TRUE; 90 while ((next = readdir(dir)) != NULL) { 91 char *nextFile; 92 dir = opendir(fileName); 93 if (!dir) { 94 /* findutils-4.1.20 reports this */ 95 /* (i.e. it doesn't silently return with exit code 1) */ 96 /* To trigger: "find -exec rm -rf {} \;" */ 97 goto done_nak_warn; 98 } 99 status = TRUE; 100 while ((next = readdir(dir)) != NULL) { 101 char *nextFile; 92 102 93 nextFile = concat_subpath_file(fileName, next->d_name); 94 if(nextFile == NULL) 95 continue; 96 if (! recursive_action(nextFile, TRUE, followLinks, depthFirst, 97 fileAction, dirAction, userData)) { 98 status = FALSE; 99 } 100 free(nextFile); 101 } 102 closedir(dir); 103 if (dirAction != NULL && depthFirst) { 104 if (! dirAction(fileName, &statbuf, userData)) { 105 bb_perror_msg("%s", fileName); 106 return FALSE; 107 } 108 } 109 if (! status) 110 return FALSE; 111 } else { 112 if (fileAction == NULL) 113 return TRUE; 114 else 115 return fileAction(fileName, &statbuf, userData); 103 nextFile = concat_subpath_file(fileName, next->d_name); 104 if (nextFile == NULL) 105 continue; 106 /* now descend into it (NB: ACTION_RECURSE is set in flags) */ 107 if (!recursive_action(nextFile, flags, fileAction, dirAction, userData, depth+1)) 108 status = FALSE; 109 free(nextFile); 116 110 } 111 closedir(dir); 112 113 if (flags & ACTION_DEPTHFIRST) { 114 if (!dirAction(fileName, &statbuf, userData, depth)) 115 goto done_nak_warn; 116 } 117 118 if (!status) 119 return FALSE; 117 120 return TRUE; 121 122 done_nak_warn: 123 bb_perror_msg("%s", fileName); 124 return FALSE; 118 125 } -
branches/2.2.5/mindi-busybox/libbb/remove_file.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <time.h>12 #include <utime.h>13 #include <dirent.h>14 #include <errno.h>15 #include <unistd.h>16 #include <stdlib.h>17 #include <string.h>18 #include <getopt.h>19 10 #include "libbb.h" 11 12 /* Used from NOFORK applets. Must not allocate anything */ 20 13 21 14 int remove_file(const char *path, int flags) 22 15 { 23 16 struct stat path_stat; 24 int path_exists = 1;25 17 26 18 if (lstat(path, &path_stat) < 0) { 27 19 if (errno != ENOENT) { 28 bb_perror_msg(" unable to stat `%s'", path);20 bb_perror_msg("cannot stat '%s'", path); 29 21 return -1; 30 22 } 31 32 path_exists = 0;33 }34 35 if (!path_exists) {36 23 if (!(flags & FILEUTILS_FORCE)) { 37 bb_perror_msg("cannot remove `%s'", path);24 bb_perror_msg("cannot remove '%s'", path); 38 25 return -1; 39 26 } … … 51 38 } 52 39 53 if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 && 54 isatty(0)) ||55 (flags & FILEUTILS_INTERACTIVE)) {56 fprintf(stderr, "%s: descend into directory `%s'? ", bb_applet_name,40 if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 && isatty(0)) 41 || (flags & FILEUTILS_INTERACTIVE) 42 ) { 43 fprintf(stderr, "%s: descend into directory '%s'? ", applet_name, 57 44 path); 58 45 if (!bb_ask_confirmation()) … … 60 47 } 61 48 62 if ((dp = bb_opendir(path)) == NULL) { 49 dp = opendir(path); 50 if (dp == NULL) { 63 51 return -1; 64 52 } … … 68 56 69 57 new_path = concat_subpath_file(path, d->d_name); 70 if (new_path == NULL)58 if (new_path == NULL) 71 59 continue; 72 60 if (remove_file(new_path, flags) < 0) … … 76 64 77 65 if (closedir(dp) < 0) { 78 bb_perror_msg(" unable to close `%s'", path);66 bb_perror_msg("cannot close '%s'", path); 79 67 return -1; 80 68 } 81 69 82 70 if (flags & FILEUTILS_INTERACTIVE) { 83 fprintf(stderr, "%s: remove directory `%s'? ", bb_applet_name, path);71 fprintf(stderr, "%s: remove directory '%s'? ", applet_name, path); 84 72 if (!bb_ask_confirmation()) 85 73 return status; … … 87 75 88 76 if (rmdir(path) < 0) { 89 bb_perror_msg(" unable to remove `%s'", path);77 bb_perror_msg("cannot remove '%s'", path); 90 78 return -1; 91 79 } 92 80 93 81 return status; 94 } else { 95 if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 && 96 !S_ISLNK(path_stat.st_mode) && 97 isatty(0)) || 98 (flags & FILEUTILS_INTERACTIVE)) { 99 fprintf(stderr, "%s: remove `%s'? ", bb_applet_name, path); 100 if (!bb_ask_confirmation()) 101 return 0; 102 } 82 } 103 83 104 if (unlink(path) < 0) { 105 bb_perror_msg("unable to remove `%s'", path); 106 return -1; 107 } 84 /* !ISDIR */ 85 if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 86 && !S_ISLNK(path_stat.st_mode) && isatty(0)) 87 || (flags & FILEUTILS_INTERACTIVE) 88 ) { 89 fprintf(stderr, "%s: remove '%s'? ", applet_name, path); 90 if (!bb_ask_confirmation()) 91 return 0; 92 } 108 93 109 return 0; 94 if (unlink(path) < 0) { 95 bb_perror_msg("cannot remove '%s'", path); 96 return -1; 110 97 } 98 99 return 0; 111 100 } -
branches/2.2.5/mindi-busybox/libbb/restricted_shell.c
r821 r1765 29 29 */ 30 30 31 #include <stdio.h>32 #include <errno.h>33 #include <unistd.h>34 #include <string.h>35 #include <stdlib.h>36 #include <syslog.h>37 #include <ctype.h>38 31 #include "libbb.h" 39 40 41 32 42 33 /* Return 1 if SHELL is a restricted shell (one not returned by 43 34 getusershell), else 0, meaning it is a standard shell. */ 44 45 int restricted_shell ( const char *shell ) 35 int restricted_shell(const char *shell) 46 36 { 47 37 char *line; 48 38 49 setusershell ();50 while (( line = getusershell ())) {51 if ( ( *line != '#' ) && ( strcmp ( line, shell ) == 0 ))52 break;39 setusershell(); 40 while ((line = getusershell())) { 41 if (*line != '#' && strcmp(line, shell) == 0) 42 return 0; 53 43 } 54 endusershell ();55 return line ? 0 :1;44 endusershell(); 45 return 1; 56 46 } 57 -
branches/2.2.5/mindi-busybox/libbb/run_shell.c
r821 r1765 29 29 */ 30 30 31 #include <stdio.h>32 #include <errno.h>33 #include <unistd.h>34 #include <string.h>35 #include <stdlib.h>36 #include <syslog.h>37 #include <ctype.h>38 31 #include "libbb.h" 39 #if def CONFIG_SELINUX32 #if ENABLE_SELINUX 40 33 #include <selinux/selinux.h> /* for setexeccon */ 41 34 #endif 42 35 43 #if def CONFIG_SELINUX44 static security_context_t current_sid =NULL;36 #if ENABLE_SELINUX 37 static security_context_t current_sid; 45 38 46 39 void 47 40 renew_current_security_context(void) 48 41 { 49 if (current_sid) 50 freecon(current_sid); /* Release old context */ 51 52 getcon(¤t_sid); /* update */ 53 54 return; 42 if (current_sid) 43 freecon(current_sid); /* Release old context */ 44 getcon(¤t_sid); /* update */ 55 45 } 56 46 void 57 47 set_current_security_context(security_context_t sid) 58 48 { 59 if (current_sid) 60 freecon(current_sid); /* Release old context */ 61 62 current_sid=sid; 63 64 return; 49 if (current_sid) 50 freecon(current_sid); /* Release old context */ 51 current_sid = sid; 65 52 } 66 53 … … 72 59 arguments. */ 73 60 74 void run_shell (const char *shell, int loginshell, const char *command, const char **additional_args)61 void run_shell(const char *shell, int loginshell, const char *command, const char **additional_args) 75 62 { 76 63 const char **args; … … 78 65 int additional_args_cnt = 0; 79 66 80 for ( args = additional_args; args && *args; args++)67 for (args = additional_args; args && *args; args++) 81 68 additional_args_cnt++; 82 69 83 args = (const char **) xmalloc (sizeof (char *) * ( 4 + additional_args_cnt));70 args = xmalloc(sizeof(char*) * (4 + additional_args_cnt)); 84 71 85 args [0] = bb_get_last_path_component ( bb_xstrdup ( shell));72 args[0] = bb_get_last_path_component(xstrdup(shell)); 86 73 87 if ( loginshell)88 args [0] = bb_xasprintf ("-%s", args[0]);74 if (loginshell) 75 args[0] = xasprintf("-%s", args[0]); 89 76 90 if ( command) {91 args 92 args 77 if (command) { 78 args[argno++] = "-c"; 79 args[argno++] = command; 93 80 } 94 if ( additional_args) {95 for ( ; *additional_args; ++additional_args)96 args 81 if (additional_args) { 82 for (; *additional_args; ++additional_args) 83 args[argno++] = *additional_args; 97 84 } 98 args [argno] = 0;99 #if def CONFIG_SELINUX100 if ( (current_sid) && (!setexeccon(current_sid))) {101 102 85 args[argno] = NULL; 86 #if ENABLE_SELINUX 87 if (current_sid && !setexeccon(current_sid)) { 88 freecon(current_sid); 89 execve(shell, (char **) args, environ); 103 90 } else 104 91 #endif 105 execv ( shell, (char **) args);106 bb_perror_msg_and_die ( "cannot run %s", shell);92 execv(shell, (char **) args); 93 bb_perror_msg_and_die("cannot run %s", shell); 107 94 } -
branches/2.2.5/mindi-busybox/libbb/safe_strncpy.c
r821 r1765 8 8 */ 9 9 10 #include <string.h>11 10 #include "libbb.h" 12 13 14 11 15 12 /* Like strncpy but make sure the resulting string is always 0 terminated. */ 16 13 char * safe_strncpy(char *dst, const char *src, size_t size) 17 14 { 18 dst[size-1] = '\0'; 19 return strncpy(dst, src, size-1); 15 if (!size) return dst; 16 dst[--size] = '\0'; 17 return strncpy(dst, src, size); 20 18 } -
branches/2.2.5/mindi-busybox/libbb/safe_write.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <errno.h>12 #include <unistd.h>13 10 #include "libbb.h" 14 15 16 11 17 12 ssize_t safe_write(int fd, const void *buf, size_t count) -
branches/2.2.5/mindi-busybox/libbb/setup_environment.c
r821 r1765 29 29 */ 30 30 31 #include <stdio.h>32 #include <errno.h>33 #include <unistd.h>34 #include <string.h>35 #include <stdlib.h>36 #include <syslog.h>37 #include <ctype.h>38 31 #include "libbb.h" 39 32 40 41 42 #define DEFAULT_LOGIN_PATH "/bin:/usr/bin" 43 #define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin" 44 45 static void xsetenv ( const char *key, const char *value ) 33 void setup_environment(const char *shell, int loginshell, int changeenv, const struct passwd *pw) 46 34 { 47 if ( setenv ( key, value, 1 )) 48 bb_error_msg_and_die (bb_msg_memory_exhausted); 49 } 50 51 void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw ) 52 { 53 if ( loginshell ) { 35 if (loginshell) { 54 36 const char *term; 55 37 … … 60 42 * Some systems default to HOME=/ 61 43 */ 62 if ( chdir ( pw-> pw_dir )) { 63 if ( chdir ( "/" )) { 64 syslog ( LOG_WARNING, "unable to cd to %s' for user %s'\n", pw-> pw_dir, pw-> pw_name ); 65 bb_error_msg_and_die ( "cannot cd to home directory or /" ); 66 } 67 fputs ( "warning: cannot change to home directory\n", stderr ); 44 if (chdir(pw->pw_dir)) { 45 xchdir("/"); 46 fputs("warning: cannot change to home directory\n", stderr); 68 47 } 69 48 70 49 /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. 71 50 Unset all other environment variables. */ 72 term = getenv 73 clearenv ();74 if ( term)75 xsetenv ( "TERM", term);76 xsetenv ( "HOME", pw-> pw_dir);77 xsetenv ( "SHELL", shell);78 xsetenv ( "USER", pw-> pw_name);79 xsetenv ( "LOGNAME", pw-> pw_name);80 xsetenv ( "PATH", ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH));51 term = getenv("TERM"); 52 clearenv(); 53 if (term) 54 xsetenv("TERM", term); 55 xsetenv("HOME", pw->pw_dir); 56 xsetenv("SHELL", shell); 57 xsetenv("USER", pw->pw_name); 58 xsetenv("LOGNAME", pw->pw_name); 59 xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path)); 81 60 } 82 else if ( changeenv) {61 else if (changeenv) { 83 62 /* Set HOME, SHELL, and if not becoming a super-user, 84 63 USER and LOGNAME. */ 85 xsetenv ( "HOME", pw-> pw_dir);86 xsetenv ( "SHELL", shell);87 if ( pw-> pw_uid) {88 xsetenv ( "USER", pw-> pw_name);89 xsetenv ( "LOGNAME", pw-> pw_name);64 xsetenv("HOME", pw->pw_dir); 65 xsetenv("SHELL", shell); 66 if (pw->pw_uid) { 67 xsetenv("USER", pw->pw_name); 68 xsetenv("LOGNAME", pw->pw_name); 90 69 } 91 70 } 92 71 } 93 -
branches/2.2.5/mindi-busybox/libbb/sha1.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Based on shasum from http://www.netsw.org/crypto/hash/ … … 6 7 * Copyright (C) 2003 Glenn L. McGrath 7 8 * Copyright (C) 2003 Erik Andersen 8 *9 * LICENSE TERMS10 9 * 11 * The free distribution and use of this software in both source and binary 12 * form is allowed (with or without changes) provided that: 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 13 11 * 14 * 1. distributions of this source code include the above copyright15 * notice, this list of conditions and the following disclaimer;16 *17 * 2. distributions in binary form include the above copyright18 * notice, this list of conditions and the following disclaimer19 * in the documentation and/or other associated materials;20 *21 * 3. the copyright holder's name is not used to endorse products22 * built using this software without specific written permission.23 *24 * ALTERNATIVELY, provided that this notice is retained in full, this product25 * may be distributed under the terms of the GNU General Public License (GPL),26 * in which case the provisions of the GPL apply INSTEAD OF those given above.27 *28 * DISCLAIMER29 *30 * This software is provided 'as is' with no explicit or implied warranties31 * in respect of its properties, including, but not limited to, correctness32 * and/or fitness for purpose.33 12 * --------------------------------------------------------------------------- 34 13 * Issue Date: 10/11/2002 … … 38 17 */ 39 18 40 #include <fcntl.h>41 #include <limits.h>42 #include <stdio.h>43 #include <stdint.h>44 #include <stdlib.h>45 #include <string.h>46 #include <unistd.h>47 48 19 #include "libbb.h" 49 20 50 # 51 # 52 # 53 # 54 # 21 #define SHA1_BLOCK_SIZE 64 22 #define SHA1_DIGEST_SIZE 20 23 #define SHA1_HASH_SIZE SHA1_DIGEST_SIZE 24 #define SHA2_GOOD 0 25 #define SHA2_BAD 1 55 26 56 # define rotl32(x,n)(((x) << n) | ((x) >> (32 - n)))27 #define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) 57 28 58 # define SHA1_MASK(SHA1_BLOCK_SIZE - 1)29 #define SHA1_MASK (SHA1_BLOCK_SIZE - 1) 59 30 60 31 /* reverse byte order in 32-bit words */ 61 #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))62 #define parity(x,y,z) ((x) ^ (y) ^ (z))63 #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))32 #define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) 33 #define parity(x,y,z) ((x) ^ (y) ^ (z)) 34 #define maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) 64 35 65 36 /* A normal version as set out in the FIPS. This version uses */ 66 37 /* partial loop unrolling and is optimised for the Pentium 4 */ 67 # define rnd(f,k) \ 68 t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \ 69 e = d; d = c; c = rotl32(b, 30); b = t 70 38 #define rnd(f,k) \ 39 do { \ 40 t = a; a = rotl32(a,5) + f(b,c,d) + e + k + w[i]; \ 41 e = d; d = c; c = rotl32(b, 30); b = t; \ 42 } while (0) 71 43 72 44 static void sha1_compile(sha1_ctx_t *ctx) … … 182 154 183 155 /* assemble the eight byte counter in the buffer in big-endian */ 184 /* format */156 /* format */ 185 157 186 158 ctx->wbuf[14] = htonl((ctx->count[1] << 3) | (ctx->count[0] >> 29)); … … 194 166 for (i = 0; i < SHA1_DIGEST_SIZE; ++i) 195 167 hval[i] = (unsigned char) (ctx->hash[i >> 2] >> 8 * (~i & 3)); 196 168 197 169 return resbuf; 198 170 } 199 200 -
branches/2.2.5/mindi-busybox/libbb/simplify_path.c
r821 r1765 5 5 * Copyright (C) 2001 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <stdlib.h>24 10 #include "libbb.h" 25 11 … … 29 15 30 16 if (path[0] == '/') 31 start = bb_xstrdup(path);17 start = xstrdup(path); 32 18 else { 33 s = x getcwd(NULL);19 s = xrealloc_getcwd_or_warn(NULL); 34 20 start = concat_path_file(s, path); 35 21 free(s); … … 41 27 if (*s == '/') { /* skip duplicate (or initial) slash */ 42 28 continue; 43 } else if (*s == '.') { 44 if (s[1] == '/' || s[1] == 0) { /* remove extra '.' */ 29 } 30 if (*s == '.') { 31 if (s[1] == '/' || !s[1]) { /* remove extra '.' */ 45 32 continue; 46 } else if ((s[1] == '.') && (s[2] == '/' || s[2] == 0)) { 33 } 34 if ((s[1] == '.') && (s[2] == '/' || !s[2])) { 47 35 ++s; 48 36 if (p > start) { 49 while (*--p != '/'); /* omit previous dir */ 37 while (*--p != '/') /* omit previous dir */ 38 continue; 50 39 } 51 40 continue; -
branches/2.2.5/mindi-busybox/libbb/skip_whitespace.c
r821 r1765 8 8 */ 9 9 10 #include <ctype.h>11 10 #include "libbb.h" 12 11 13 12 char *skip_whitespace(const char *s) 14 13 { 14 /* NB: isspace('0') returns 0 */ 15 15 while (isspace(*s)) ++s; 16 16 17 17 return (char *) s; 18 18 } 19 20 char *skip_non_whitespace(const char *s) 21 { 22 while (*s && !isspace(*s)) ++s; 23 24 return (char *) s; 25 } -
branches/2.2.5/mindi-busybox/libbb/speed_table.c
r821 r1765 55 55 }; 56 56 57 enum { NUM_SPEEDS = (sizeof(speeds) / sizeof(struct speed_map)) };57 enum { NUM_SPEEDS = ARRAY_SIZE(speeds) }; 58 58 59 59 unsigned int tty_baud_to_value(speed_t speed) … … 95 95 speed_t s; 96 96 97 for (v = 0 ; v < 500000 97 for (v = 0 ; v < 500000; v++) { 98 98 s = tty_value_to_baud(v); 99 99 if (s == (speed_t) -1) { … … 105 105 printf("-------------------------------\n"); 106 106 107 for (s = 0 ; s < 010017+1 107 for (s = 0 ; s < 010017+1; s++) { 108 108 v = tty_baud_to_value(s); 109 109 if (!v) { -
branches/2.2.5/mindi-busybox/libbb/trim.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h>12 #include <string.h>13 #include <ctype.h>14 11 #include "libbb.h" 15 16 12 17 13 void trim(char *s) … … 24 20 25 21 /* trim leading whitespace */ 26 if (len) {22 if (len) { 27 23 lws = strspn(s, " \n\r\t\v"); 28 24 memmove(s, s + lws, len -= lws); 29 25 } 30 s[len] = 0;26 s[len] = '\0'; 31 27 } -
branches/2.2.5/mindi-busybox/libbb/u_signal_names.c
r821 r1765 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * Utilityroutines.3 * Signal name/number conversion routines. 4 4 * 5 * Copyright (C) many different people. 6 * If you wrote this, please acknowledge your work. 5 * Copyright 2006 Rob Landley <rob@landley.net> 7 6 * 8 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 9 8 */ 10 9 11 #include <signal.h>12 #include <ctype.h>13 #include <string.h>14 #include <strings.h>15 #include <stdlib.h>16 #include <stdio.h>17 18 10 #include "libbb.h" 19 11 20 struct signal_name { 21 const char *name; 22 int number; 12 static const char signals[32][7] = { 13 // SUSv3 says kill must support these, and specifies the numerical values, 14 // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html 15 // TODO: "[SIG]EXIT" shouldn't work for kill, right? 16 // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"}, 17 // {6, "ABRT"}, {9, "KILL"}, {14, "ALRM"}, {15, "TERM"} 18 // And Posix adds the following: 19 // {SIGILL, "ILL"}, {SIGTRAP, "TRAP"}, {SIGFPE, "FPE"}, {SIGUSR1, "USR1"}, 20 // {SIGSEGV, "SEGV"}, {SIGUSR2, "USR2"}, {SIGPIPE, "PIPE"}, {SIGCHLD, "CHLD"}, 21 // {SIGCONT, "CONT"}, {SIGSTOP, "STOP"}, {SIGTSTP, "TSTP"}, {SIGTTIN, "TTIN"}, 22 // {SIGTTOU, "TTOU"} 23 [0] = "EXIT", 24 #ifdef SIGHUP 25 [SIGHUP ] = "HUP", 26 #endif 27 #ifdef SIGINT 28 [SIGINT ] = "INT", 29 #endif 30 #ifdef SIGQUIT 31 [SIGQUIT ] = "QUIT", 32 #endif 33 #ifdef SIGILL 34 [SIGILL ] = "ILL", 35 #endif 36 #ifdef SIGTRAP 37 [SIGTRAP ] = "TRAP", 38 #endif 39 #ifdef SIGABRT 40 [SIGABRT ] = "ABRT", 41 #endif 42 #ifdef SIGBUS 43 [SIGBUS ] = "BUS", 44 #endif 45 #ifdef SIGFPE 46 [SIGFPE ] = "FPE", 47 #endif 48 #ifdef SIGKILL 49 [SIGKILL ] = "KILL", 50 #endif 51 #ifdef SIGUSR1 52 [SIGUSR1 ] = "USR1", 53 #endif 54 #ifdef SIGSEGV 55 [SIGSEGV ] = "SEGV", 56 #endif 57 #ifdef SIGUSR2 58 [SIGUSR2 ] = "USR2", 59 #endif 60 #ifdef SIGPIPE 61 [SIGPIPE ] = "PIPE", 62 #endif 63 #ifdef SIGALRM 64 [SIGALRM ] = "ALRM", 65 #endif 66 #ifdef SIGTERM 67 [SIGTERM ] = "TERM", 68 #endif 69 #ifdef SIGSTKFLT 70 [SIGSTKFLT] = "STKFLT", 71 #endif 72 #ifdef SIGCHLD 73 [SIGCHLD ] = "CHLD", 74 #endif 75 #ifdef SIGCONT 76 [SIGCONT ] = "CONT", 77 #endif 78 #ifdef SIGSTOP 79 [SIGSTOP ] = "STOP", 80 #endif 81 #ifdef SIGTSTP 82 [SIGTSTP ] = "TSTP", 83 #endif 84 #ifdef SIGTTIN 85 [SIGTTIN ] = "TTIN", 86 #endif 87 #ifdef SIGTTOU 88 [SIGTTOU ] = "TTOU", 89 #endif 90 #ifdef SIGURG 91 [SIGURG ] = "URG", 92 #endif 93 #ifdef SIGXCPU 94 [SIGXCPU ] = "XCPU", 95 #endif 96 #ifdef SIGXFSZ 97 [SIGXFSZ ] = "XFSZ", 98 #endif 99 #ifdef SIGVTALRM 100 [SIGVTALRM] = "VTALRM", 101 #endif 102 #ifdef SIGPROF 103 [SIGPROF ] = "PROF", 104 #endif 105 #ifdef SIGWINCH 106 [SIGWINCH ] = "WINCH", 107 #endif 108 #ifdef SIGPOLL 109 [SIGPOLL ] = "POLL", 110 #endif 111 #ifdef SIGPWR 112 [SIGPWR ] = "PWR", 113 #endif 114 #ifdef SIGSYS 115 [SIGSYS ] = "SYS", 116 #endif 23 117 }; 24 118 25 static const struct signal_name signames[] = { 26 /* POSIX signals */ 27 { "EXIT", 0 }, /* 0 */ 28 { "HUP", SIGHUP }, /* 1 */ 29 { "INT", SIGINT }, /* 2 */ 30 { "QUIT", SIGQUIT }, /* 3 */ 31 { "ILL", SIGILL }, /* 4 */ 32 { "ABRT", SIGABRT }, /* 6 */ 33 { "FPE", SIGFPE }, /* 8 */ 34 { "KILL", SIGKILL }, /* 9 */ 35 { "SEGV", SIGSEGV }, /* 11 */ 36 { "PIPE", SIGPIPE }, /* 13 */ 37 { "ALRM", SIGALRM }, /* 14 */ 38 { "TERM", SIGTERM }, /* 15 */ 39 { "USR1", SIGUSR1 }, /* 10 (arm,i386,m68k,ppc), 30 (alpha,sparc*), 16 (mips) */ 40 { "USR2", SIGUSR2 }, /* 12 (arm,i386,m68k,ppc), 31 (alpha,sparc*), 17 (mips) */ 41 { "CHLD", SIGCHLD }, /* 17 (arm,i386,m68k,ppc), 20 (alpha,sparc*), 18 (mips) */ 42 { "CONT", SIGCONT }, /* 18 (arm,i386,m68k,ppc), 19 (alpha,sparc*), 25 (mips) */ 43 { "STOP", SIGSTOP }, /* 19 (arm,i386,m68k,ppc), 17 (alpha,sparc*), 23 (mips) */ 44 { "TSTP", SIGTSTP }, /* 20 (arm,i386,m68k,ppc), 18 (alpha,sparc*), 24 (mips) */ 45 { "TTIN", SIGTTIN }, /* 21 (arm,i386,m68k,ppc,alpha,sparc*), 26 (mips) */ 46 { "TTOU", SIGTTOU }, /* 22 (arm,i386,m68k,ppc,alpha,sparc*), 27 (mips) */ 47 /* Miscellaneous other signals */ 48 #ifdef SIGTRAP 49 { "TRAP", SIGTRAP }, /* 5 */ 119 // Convert signal name to number. 120 121 int get_signum(const char *name) 122 { 123 int i; 124 125 i = bb_strtou(name, NULL, 10); 126 if (!errno) 127 return i; 128 if (strncasecmp(name, "SIG", 3) == 0) 129 name += 3; 130 for (i = 0; i < ARRAY_SIZE(signals); i++) 131 if (strcasecmp(name, signals[i]) == 0) 132 return i; 133 134 #if ENABLE_DESKTOP && (defined(SIGIOT) || defined(SIGIO)) 135 /* These are aliased to other names */ 136 if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') { 137 #ifdef SIGIO 138 if (!name[2]) 139 return SIGIO; 50 140 #endif 51 141 #ifdef SIGIOT 52 { "IOT", SIGIOT }, /* 6, same as SIGABRT */ 142 if ((name[2] | 0x20) == 't' && !name[3]) 143 return SIGIOT; 53 144 #endif 54 #ifdef SIGEMT 55 { "EMT", SIGEMT }, /* 7 (mips,alpha,sparc*) */ 145 } 56 146 #endif 57 #ifdef SIGBUS58 { "BUS", SIGBUS }, /* 7 (arm,i386,m68k,ppc), 10 (mips,alpha,sparc*) */59 #endif60 #ifdef SIGSYS61 { "SYS", SIGSYS }, /* 12 (mips,alpha,sparc*) */62 #endif63 #ifdef SIGSTKFLT64 { "STKFLT", SIGSTKFLT }, /* 16 (arm,i386,m68k,ppc) */65 #endif66 #ifdef SIGURG67 { "URG", SIGURG }, /* 23 (arm,i386,m68k,ppc), 16 (alpha,sparc*), 21 (mips) */68 #endif69 #ifdef SIGIO70 { "IO", SIGIO }, /* 29 (arm,i386,m68k,ppc), 23 (alpha,sparc*), 22 (mips) */71 #endif72 #ifdef SIGPOLL73 { "POLL", SIGPOLL }, /* same as SIGIO */74 #endif75 #ifdef SIGCLD76 { "CLD", SIGCLD }, /* same as SIGCHLD (mips) */77 #endif78 #ifdef SIGXCPU79 { "XCPU", SIGXCPU }, /* 24 (arm,i386,m68k,ppc,alpha,sparc*), 30 (mips) */80 #endif81 #ifdef SIGXFSZ82 { "XFSZ", SIGXFSZ }, /* 25 (arm,i386,m68k,ppc,alpha,sparc*), 31 (mips) */83 #endif84 #ifdef SIGVTALRM85 { "VTALRM", SIGVTALRM }, /* 26 (arm,i386,m68k,ppc,alpha,sparc*), 28 (mips) */86 #endif87 #ifdef SIGPROF88 { "PROF", SIGPROF }, /* 27 (arm,i386,m68k,ppc,alpha,sparc*), 29 (mips) */89 #endif90 #ifdef SIGPWR91 { "PWR", SIGPWR }, /* 30 (arm,i386,m68k,ppc), 29 (alpha,sparc*), 19 (mips) */92 #endif93 #ifdef SIGINFO94 { "INFO", SIGINFO }, /* 29 (alpha) */95 #endif96 #ifdef SIGLOST97 { "LOST", SIGLOST }, /* 29 (arm,i386,m68k,ppc,sparc*) */98 #endif99 #ifdef SIGWINCH100 { "WINCH", SIGWINCH }, /* 28 (arm,i386,m68k,ppc,alpha,sparc*), 20 (mips) */101 #endif102 #ifdef SIGUNUSED103 { "UNUSED", SIGUNUSED }, /* 31 (arm,i386,m68k,ppc) */104 #endif105 {0, 0}106 };107 147 108 /* 109 if str_sig == NULL returned signal name [*signo], 110 if str_sig != NULL - set *signo from signal_name, 111 findings with digit number or with or without SIG-prefix name 148 return -1; 149 } 112 150 113 if startnum=0 flag for support finding zero signal, 114 but str_sig="0" always found, (hmm - standart or realize?) 115 if startnum<0 returned reverse signal_number <-> signal_name 116 if found error - returned NULL 151 // Convert signal number to name 117 152 118 */ 153 const char *get_signame(int number) 154 { 155 if ((unsigned)number < ARRAY_SIZE(signals)) { 156 if (signals[number][0]) /* if it's not an empty str */ 157 return signals[number]; 158 } 119 159 120 const char * 121 u_signal_names(const char *str_sig, int *signo, int startnum) 122 { 123 static char retstr[16]; 124 const struct signal_name *s = signames; 125 static const char prefix[] = "SIG"; 126 const char *sptr; 127 128 if(startnum) 129 s++; 130 if(str_sig==NULL) { 131 while (s->name != 0) { 132 if(s->number == *signo) 133 break; 134 s++; 135 } 136 } else { 137 if (isdigit(((unsigned char)*str_sig))) { 138 char *endp; 139 long int sn = strtol(str_sig, &endp, 10); 140 /* test correct and overflow */ 141 if(*endp == 0 && sn >= 0 && sn < NSIG) { 142 *signo = (int)sn; 143 /* test for unnamed */ 144 sptr = u_signal_names(0, signo, 0); 145 if(sptr==NULL) 146 return NULL; 147 if(sn!=0) 148 sptr += 3; 149 return sptr; 150 } 151 } else { 152 sptr = str_sig; 153 while (s->name != 0) { 154 if (strcasecmp(s->name, sptr) == 0) { 155 *signo = s->number; 156 if(startnum<0) { 157 sprintf(retstr, "%d", *signo); 158 return retstr; 159 } 160 break; 161 } 162 if(s!=signames && sptr == str_sig && 163 strncasecmp(sptr, prefix, 3) == 0) { 164 sptr += 3; /* strlen(prefix) */ 165 continue; 166 } 167 sptr = str_sig; 168 s++; 169 } 170 } 171 } 172 if(s->name==0) 173 return NULL; 174 if(s!=signames) 175 strcpy(retstr, prefix); 176 else 177 retstr[0] = 0; 178 return strcat(retstr, s->name); 160 return itoa(number); 179 161 } -
branches/2.2.5/mindi-busybox/libbb/vdprintf.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <unistd.h>12 10 #include "libbb.h" 13 11 14 15 16 #if (__GLIBC__ < 2) 12 #if defined(__GLIBC__) && __GLIBC__ < 2 17 13 int vdprintf(int d, const char *format, va_list ap) 18 14 { … … 20 16 int len; 21 17 22 len = vs printf(buf, format, ap);18 len = vsnprintf(buf, BUF_SIZE, format, ap); 23 19 return write(d, buf, len); 24 20 } -
branches/2.2.5/mindi-busybox/libbb/verror_msg.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h> 11 #include <errno.h> 12 #include <string.h> 13 #include <stdlib.h> 10 #include <syslog.h> 14 11 #include "libbb.h" 15 12 16 void bb_verror_msg(const char *s, va_list p) 13 smallint logmode = LOGMODE_STDIO; 14 const char *msg_eol = "\n"; 15 16 void bb_verror_msg(const char *s, va_list p, const char* strerr) 17 17 { 18 fflush(stdout); 19 fprintf(stderr, "%s: ", bb_applet_name); 20 vfprintf(stderr, s, p); 18 char *msg; 19 int applet_len, strerr_len, msgeol_len, used; 20 21 if (!logmode) 22 return; 23 24 if (!s) /* nomsg[_and_die] uses NULL fmt */ 25 s = ""; /* some libc don't like printf(NULL) */ 26 27 used = vasprintf(&msg, s, p); 28 if (used < 0) 29 return; 30 31 /* This is ugly and costs +60 bytes compared to multiple 32 * fprintf's, but is guaranteed to do a single write. 33 * This is needed for e.g. httpd logging, when multiple 34 * children can produce log messages simultaneously. */ 35 36 applet_len = strlen(applet_name) + 2; /* "applet: " */ 37 strerr_len = strerr ? strlen(strerr) : 0; 38 msgeol_len = strlen(msg_eol); 39 /* +3 is for ": " before strerr and for terminating NUL */ 40 msg = xrealloc(msg, applet_len + used + strerr_len + msgeol_len + 3); 41 /* TODO: maybe use writev instead of memmoving? Need full_writev? */ 42 memmove(msg + applet_len, msg, used); 43 used += applet_len; 44 strcpy(msg, applet_name); 45 msg[applet_len - 2] = ':'; 46 msg[applet_len - 1] = ' '; 47 if (strerr) { 48 msg[used++] = ':'; 49 msg[used++] = ' '; 50 strcpy(&msg[used], strerr); 51 used += strerr_len; 52 } 53 strcpy(&msg[used], msg_eol); 54 55 if (logmode & LOGMODE_STDIO) { 56 fflush(stdout); 57 full_write(2, msg, used + msgeol_len); 58 } 59 if (logmode & LOGMODE_SYSLOG) { 60 syslog(LOG_ERR, "%s", msg + applet_len); 61 } 62 free(msg); 21 63 } 64 65 66 #ifdef VERSION_WITH_WRITEV 67 68 /* Code size is approximately the same, but currently it's the only user 69 * of writev in entire bbox. __libc_writev in uclibc is ~50 bytes. */ 70 71 void bb_verror_msg(const char *s, va_list p, const char* strerr) 72 { 73 int strerr_len, msgeol_len; 74 struct iovec iov[3]; 75 76 #define used (iov[2].iov_len) 77 #define msgv (iov[2].iov_base) 78 #define msgc ((char*)(iov[2].iov_base)) 79 #define msgptr (&(iov[2].iov_base)) 80 81 if (!logmode) 82 return; 83 84 if (!s) /* nomsg[_and_die] uses NULL fmt */ 85 s = ""; /* some libc don't like printf(NULL) */ 86 87 /* Prevent "derefing type-punned ptr will break aliasing rules" */ 88 used = vasprintf((char**)(void*)msgptr, s, p); 89 if (used < 0) 90 return; 91 92 /* This is ugly and costs +60 bytes compared to multiple 93 * fprintf's, but is guaranteed to do a single write. 94 * This is needed for e.g. httpd logging, when multiple 95 * children can produce log messages simultaneously. */ 96 97 strerr_len = strerr ? strlen(strerr) : 0; 98 msgeol_len = strlen(msg_eol); 99 /* +3 is for ": " before strerr and for terminating NUL */ 100 msgv = xrealloc(msgv, used + strerr_len + msgeol_len + 3); 101 if (strerr) { 102 msgc[used++] = ':'; 103 msgc[used++] = ' '; 104 strcpy(msgc + used, strerr); 105 used += strerr_len; 106 } 107 strcpy(msgc + used, msg_eol); 108 used += msgeol_len; 109 110 if (logmode & LOGMODE_STDIO) { 111 iov[0].iov_base = (char*)applet_name; 112 iov[0].iov_len = strlen(applet_name); 113 iov[1].iov_base = (char*)": "; 114 iov[1].iov_len = 2; 115 /*iov[2].iov_base = msgc;*/ 116 /*iov[2].iov_len = used;*/ 117 fflush(stdout); 118 writev(2, iov, 3); 119 } 120 if (logmode & LOGMODE_SYSLOG) { 121 syslog(LOG_ERR, "%s", msgc); 122 } 123 free(msgc); 124 } 125 #endif -
branches/2.2.5/mindi-busybox/libbb/vfork_daemon_rexec.c
r821 r1765 16 16 */ 17 17 18 #include <unistd.h>19 #include <stdio.h>20 #include <fcntl.h>21 18 #include <paths.h> 22 #include "libbb.h" 23 24 25 #ifdef BB_NOMMU 26 void vfork_daemon_rexec(int nochdir, int noclose, 27 int argc, char **argv, char *foreground_opt) 19 #include "busybox.h" /* for struct bb_applet */ 20 21 /* This does a fork/exec in one call, using vfork(). Returns PID of new child, 22 * -1 for failure. Runs argv[0], searching path if that has no / in it. */ 23 pid_t spawn(char **argv) 24 { 25 /* Compiler should not optimize stores here */ 26 volatile int failed; 27 pid_t pid; 28 29 // Ain't it a good place to fflush(NULL)? 30 31 /* Be nice to nommu machines. */ 32 failed = 0; 33 pid = vfork(); 34 if (pid < 0) /* error */ 35 return pid; 36 if (!pid) { /* child */ 37 /* This macro is ok - it doesn't do NOEXEC/NOFORK tricks */ 38 BB_EXECVP(argv[0], argv); 39 40 /* We are (maybe) sharing a stack with blocked parent, 41 * let parent know we failed and then exit to unblock parent 42 * (but don't run atexit() stuff, which would screw up parent.) 43 */ 44 failed = errno; 45 _exit(111); 46 } 47 /* parent */ 48 /* Unfortunately, this is not reliable: according to standards 49 * vfork() can be equivalent to fork() and we won't see value 50 * of 'failed'. 51 * Interested party can wait on pid and learn exit code. 52 * If 111 - then it (most probably) failed to exec */ 53 if (failed) { 54 errno = failed; 55 return -1; 56 } 57 return pid; 58 } 59 60 /* Die with an error message if we can't spawn a child process. */ 61 pid_t xspawn(char **argv) 62 { 63 pid_t pid = spawn(argv); 64 if (pid < 0) 65 bb_perror_msg_and_die("%s", *argv); 66 return pid; 67 } 68 69 // Wait for the specified child PID to exit, returning child's error return. 70 int wait4pid(int pid) 71 { 72 int status; 73 74 if (pid <= 0) { 75 /*errno = ECHILD; -- wrong. */ 76 /* we expect errno to be already set from failed [v]fork/exec */ 77 return -1; 78 } 79 if (waitpid(pid, &status, 0) == -1) 80 return -1; 81 if (WIFEXITED(status)) 82 return WEXITSTATUS(status); 83 if (WIFSIGNALED(status)) 84 return WTERMSIG(status) + 1000; 85 return 0; 86 } 87 88 int wait_nohang(int *wstat) 89 { 90 return waitpid(-1, wstat, WNOHANG); 91 } 92 93 int wait_pid(int *wstat, int pid) 94 { 95 int r; 96 97 do 98 r = waitpid(pid, wstat, 0); 99 while ((r == -1) && (errno == EINTR)); 100 return r; 101 } 102 103 #if ENABLE_FEATURE_PREFER_APPLETS 104 void save_nofork_data(struct nofork_save_area *save) 105 { 106 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); 107 save->current_applet = current_applet; 108 save->xfunc_error_retval = xfunc_error_retval; 109 save->option_mask32 = option_mask32; 110 save->die_sleep = die_sleep; 111 save->saved = 1; 112 } 113 114 void restore_nofork_data(struct nofork_save_area *save) 115 { 116 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); 117 current_applet = save->current_applet; 118 xfunc_error_retval = save->xfunc_error_retval; 119 option_mask32 = save->option_mask32; 120 die_sleep = save->die_sleep; 121 122 applet_name = current_applet->name; 123 } 124 125 int run_nofork_applet_prime(struct nofork_save_area *old, const struct bb_applet *a, char **argv) 126 { 127 int rc, argc; 128 129 current_applet = a; 130 applet_name = a->name; 131 xfunc_error_retval = EXIT_FAILURE; 132 /*option_mask32 = 0; - not needed */ 133 /* special flag for xfunc_die(). If xfunc will "die" 134 * in NOFORK applet, xfunc_die() sees negative 135 * die_sleep and longjmp here instead. */ 136 die_sleep = -1; 137 138 argc = 1; 139 while (argv[argc]) 140 argc++; 141 142 rc = setjmp(die_jmp); 143 if (!rc) { 144 /* Some callers (xargs) 145 * need argv untouched because they free argv[i]! */ 146 char *tmp_argv[argc+1]; 147 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); 148 /* Finally we can call NOFORK applet's main() */ 149 rc = a->main(argc, tmp_argv); 150 } else { /* xfunc died in NOFORK applet */ 151 /* in case they meant to return 0... */ 152 if (rc == -2222) 153 rc = 0; 154 } 155 156 /* Restoring globals */ 157 restore_nofork_data(old); 158 return rc; 159 } 160 161 int run_nofork_applet(const struct bb_applet *a, char **argv) 162 { 163 struct nofork_save_area old; 164 165 /* Saving globals */ 166 save_nofork_data(&old); 167 return run_nofork_applet_prime(&old, a, argv); 168 } 169 #endif /* FEATURE_PREFER_APPLETS */ 170 171 int spawn_and_wait(char **argv) 172 { 173 int rc; 174 #if ENABLE_FEATURE_PREFER_APPLETS 175 const struct bb_applet *a = find_applet_by_name(argv[0]); 176 177 if (a && (a->nofork 178 #if BB_MMU 179 || a->noexec /* NOEXEC trick needs fork() */ 180 #endif 181 )) { 182 #if BB_MMU 183 if (a->nofork) 184 #endif 185 { 186 return run_nofork_applet(a, argv); 187 } 188 #if BB_MMU 189 /* MMU only */ 190 /* a->noexec is true */ 191 rc = fork(); 192 if (rc) /* parent or error */ 193 return wait4pid(rc); 194 /* child */ 195 xfunc_error_retval = EXIT_FAILURE; 196 current_applet = a; 197 run_current_applet_and_exit(argv); 198 #endif 199 } 200 #endif /* FEATURE_PREFER_APPLETS */ 201 rc = spawn(argv); 202 return wait4pid(rc); 203 } 204 205 #if !BB_MMU 206 void re_exec(char **argv) 207 { 208 /* high-order bit of first char in argv[0] is a hidden 209 * "we have (already) re-execed, don't do it again" flag */ 210 argv[0][0] |= 0x80; 211 execv(bb_busybox_exec_path, argv); 212 bb_perror_msg_and_die("exec %s", bb_busybox_exec_path); 213 } 214 215 void forkexit_or_rexec(char **argv) 216 { 217 pid_t pid; 218 /* Maybe we are already re-execed and come here again? */ 219 if (re_execed) 220 return; 221 222 pid = vfork(); 223 if (pid < 0) /* wtf? */ 224 bb_perror_msg_and_die("vfork"); 225 if (pid) /* parent */ 226 exit(0); 227 /* child - re-exec ourself */ 228 re_exec(argv); 229 } 230 #else 231 /* Dance around (void)...*/ 232 #undef forkexit_or_rexec 233 void forkexit_or_rexec(void) 234 { 235 pid_t pid; 236 pid = fork(); 237 if (pid < 0) /* wtf? */ 238 bb_perror_msg_and_die("fork"); 239 if (pid) /* parent */ 240 exit(0); 241 /* child */ 242 } 243 #define forkexit_or_rexec(argv) forkexit_or_rexec() 244 #endif 245 246 /* Due to a #define in libbb.h on MMU systems we actually have 1 argument - 247 * char **argv "vanishes" */ 248 void bb_daemonize_or_rexec(int flags, char **argv) 28 249 { 29 250 int fd; 30 char **vfork_args; 31 int a = 0; 32 33 setsid(); 34 35 if (!nochdir) 36 chdir("/"); 37 38 if (!noclose && (fd = open(bb_dev_null, O_RDWR, 0)) != -1) { 39 dup2(fd, STDIN_FILENO); 40 dup2(fd, STDOUT_FILENO); 41 dup2(fd, STDERR_FILENO); 42 if (fd > 2) 43 close(fd); 44 } 45 46 vfork_args = xcalloc(sizeof(char *), argc + 3); 47 vfork_args[a++] = "/bin/busybox"; 48 while(*argv) { 49 vfork_args[a++] = *argv; 50 argv++; 51 } 52 vfork_args[a] = foreground_opt; 53 switch (vfork()) { 54 case 0: /* child */ 55 /* Make certain we are not a session leader, or else we 56 * might reacquire a controlling terminal */ 57 if (vfork()) 58 _exit(0); 59 execv(vfork_args[0], vfork_args); 60 bb_perror_msg_and_die("execv %s", vfork_args[0]); 61 case -1: /* error */ 62 bb_perror_msg_and_die("vfork"); 63 default: /* parent */ 64 exit(0); 65 } 66 } 67 #endif /* BB_NOMMU */ 251 252 if (flags & DAEMON_CHDIR_ROOT) 253 xchdir("/"); 254 255 if (flags & DAEMON_DEVNULL_STDIO) { 256 close(0); 257 close(1); 258 close(2); 259 } 260 261 fd = xopen(bb_dev_null, O_RDWR); 262 263 while ((unsigned)fd < 2) 264 fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ 265 266 if (!(flags & DAEMON_ONLY_SANITIZE)) { 267 forkexit_or_rexec(argv); 268 /* if daemonizing, make sure we detach from stdio & ctty */ 269 setsid(); 270 dup2(fd, 0); 271 dup2(fd, 1); 272 dup2(fd, 2); 273 } 274 while (fd > 2) { 275 close(fd--); 276 if (!(flags & DAEMON_CLOSE_EXTRA_FDS)) 277 return; 278 /* else close everything after fd#2 */ 279 } 280 } 281 282 void bb_sanitize_stdio(void) 283 { 284 bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE, NULL); 285 } -
branches/2.2.5/mindi-busybox/libbb/warn_ignoring_args.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <libbb.h>10 #include "libbb.h" 24 11 25 12 void bb_warn_ignoring_args(int n) 26 13 { 27 14 if (n) { 28 bb_ perror_msg("ignoring all arguments");15 bb_error_msg("ignoring all arguments"); 29 16 } 30 17 } -
branches/2.2.5/mindi-busybox/libbb/wfopen.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h>11 #include <errno.h>12 10 #include "libbb.h" 13 11 14 FILE * bb_wfopen(const char *path, const char *mode)12 FILE *fopen_or_warn(const char *path, const char *mode) 15 13 { 16 FILE *fp ;17 if ( (fp = fopen(path, mode)) == NULL) {14 FILE *fp = fopen(path, mode); 15 if (!fp) { 18 16 bb_perror_msg("%s", path); 19 17 errno = 0; -
branches/2.2.5/mindi-busybox/libbb/wfopen_input.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 25 12 * we avoid testing everywhere by consolidating things in this routine. 26 13 * 27 * Note: We also consider "" to main stdin (for 'cmp' at least).14 * Note: we also consider "" to mean stdin (for 'cmp' at least). 28 15 */ 29 16 30 #include <stdio.h> 31 #include <sys/stat.h> 32 #include <libbb.h> 17 #include "libbb.h" 33 18 34 FILE * bb_wfopen_input(const char *filename)19 FILE *fopen_or_warn_stdin(const char *filename) 35 20 { 36 21 FILE *fp = stdin; 37 22 38 if ((filename != bb_msg_standard_input) 39 && filename[0] && ((filename[0] != '-') || filename[1]) 23 if (filename != bb_msg_standard_input 24 && filename[0] 25 && NOT_LONE_DASH(filename) 40 26 ) { 41 fp = bb_wfopen(filename, "r");27 fp = fopen_or_warn(filename, "r"); 42 28 } 43 29 -
branches/2.2.5/mindi-busybox/libbb/xconnect.c
r821 r1765 7 7 */ 8 8 9 #include <unistd.h>10 #include <string.h>11 #include <stdlib.h>12 #include <sys/types.h>13 #include <sys/socket.h>14 #include <errno.h>15 #include <netdb.h>16 #include <sys/socket.h>17 9 #include <netinet/in.h> 18 #include <arpa/inet.h>19 10 #include "libbb.h" 20 11 21 /* Return network byte ordered port number for a service. 12 void setsockopt_reuseaddr(int fd) 13 { 14 setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1)); 15 } 16 int setsockopt_broadcast(int fd) 17 { 18 return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); 19 } 20 21 void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) 22 { 23 if (connect(s, s_addr, addrlen) < 0) { 24 if (ENABLE_FEATURE_CLEAN_UP) 25 close(s); 26 if (s_addr->sa_family == AF_INET) 27 bb_perror_msg_and_die("%s (%s)", 28 "cannot connect to remote host", 29 inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr)); 30 bb_perror_msg_and_die("cannot connect to remote host"); 31 } 32 } 33 34 /* Return port number for a service. 22 35 * If "port" is a number use it as the port. 23 36 * If "port" is a name it is looked up in /etc/services, if it isnt found return 24 * default_port 25 */ 26 unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port) 27 { 28 unsigned short port_nr = htons(default_port); 37 * default_port */ 38 unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) 39 { 40 unsigned port_nr = default_port; 29 41 if (port) { 30 char *endptr;31 42 int old_errno; 32 long port_long;33 43 34 44 /* Since this is a lib function, we're not allowed to reset errno to 0. 35 45 * Doing so could break an app that is deferring checking of errno. */ 36 46 old_errno = errno; 37 errno = 0; 38 port_long = strtol(port, &endptr, 10); 39 if (errno != 0 || *endptr!='\0' || endptr==port || port_long < 0 || port_long > 65535) { 47 port_nr = bb_strtou(port, NULL, 10); 48 if (errno || port_nr > 65535) { 40 49 struct servent *tserv = getservbyname(port, protocol); 41 if (tserv) { 42 port_nr = tserv->s_port; 43 } 44 } else { 45 port_nr = htons(port_long); 50 port_nr = default_port; 51 if (tserv) 52 port_nr = ntohs(tserv->s_port); 46 53 } 47 54 errno = old_errno; 48 55 } 49 return port_nr; 50 } 51 56 return (uint16_t)port_nr; 57 } 58 59 60 /* "Old" networking API - only IPv4 */ 61 62 /* 52 63 void bb_lookup_host(struct sockaddr_in *s_in, const char *host) 53 64 { … … 60 71 } 61 72 62 int xconnect(struct sockaddr_in *s_addr) 63 { 64 int s = bb_xsocket(AF_INET, SOCK_STREAM, 0); 65 if (connect(s, (struct sockaddr *)s_addr, sizeof(struct sockaddr_in)) < 0) 66 { 67 if (ENABLE_FEATURE_CLEAN_UP) close(s); 68 bb_perror_msg_and_die("Unable to connect to remote host (%s)", 69 inet_ntoa(s_addr->sin_addr)); 70 } 73 74 int xconnect_tcp_v4(struct sockaddr_in *s_addr) 75 { 76 int s = xsocket(AF_INET, SOCK_STREAM, 0); 77 xconnect(s, (struct sockaddr*) s_addr, sizeof(*s_addr)); 71 78 return s; 72 79 } 80 */ 81 82 /* "New" networking API */ 83 84 85 int get_nport(const struct sockaddr *sa) 86 { 87 #if ENABLE_FEATURE_IPV6 88 if (sa->sa_family == AF_INET6) { 89 return ((struct sockaddr_in6*)sa)->sin6_port; 90 } 91 #endif 92 if (sa->sa_family == AF_INET) { 93 return ((struct sockaddr_in*)sa)->sin_port; 94 } 95 /* What? UNIX socket? IPX?? :) */ 96 return -1; 97 } 98 99 void set_nport(len_and_sockaddr *lsa, unsigned port) 100 { 101 #if ENABLE_FEATURE_IPV6 102 if (lsa->sa.sa_family == AF_INET6) { 103 lsa->sin6.sin6_port = port; 104 return; 105 } 106 #endif 107 if (lsa->sa.sa_family == AF_INET) { 108 lsa->sin.sin_port = port; 109 return; 110 } 111 /* What? UNIX socket? IPX?? :) */ 112 } 113 114 /* We hijack this constant to mean something else */ 115 /* It doesn't hurt because we will remove this bit anyway */ 116 #define DIE_ON_ERROR AI_CANONNAME 117 118 /* host: "1.2.3.4[:port]", "www.google.com[:port]" 119 * port: if neither of above specifies port # */ 120 static len_and_sockaddr* str2sockaddr( 121 const char *host, int port, 122 USE_FEATURE_IPV6(sa_family_t af,) 123 int ai_flags) 124 { 125 int rc; 126 len_and_sockaddr *r = NULL; 127 struct addrinfo *result = NULL; 128 const char *org_host = host; /* only for error msg */ 129 const char *cp; 130 struct addrinfo hint; 131 132 /* Ugly parsing of host:addr */ 133 if (ENABLE_FEATURE_IPV6 && host[0] == '[') { 134 host++; 135 cp = strchr(host, ']'); 136 if (!cp || cp[1] != ':') /* Malformed: must have [xx]:nn */ 137 bb_error_msg_and_die("bad address '%s'", org_host); 138 //return r; /* return NULL */ 139 } else { 140 cp = strrchr(host, ':'); 141 if (ENABLE_FEATURE_IPV6 && cp && strchr(host, ':') != cp) { 142 /* There is more than one ':' (e.g. "::1") */ 143 cp = NULL; /* it's not a port spec */ 144 } 145 } 146 if (cp) { 147 int sz = cp - host + 1; 148 host = safe_strncpy(alloca(sz), host, sz); 149 if (ENABLE_FEATURE_IPV6 && *cp != ':') 150 cp++; /* skip ']' */ 151 cp++; /* skip ':' */ 152 port = xatou16(cp); 153 } 154 155 memset(&hint, 0 , sizeof(hint)); 156 #if !ENABLE_FEATURE_IPV6 157 hint.ai_family = AF_INET; /* do not try to find IPv6 */ 158 #else 159 hint.ai_family = af; 160 #endif 161 /* Needed. Or else we will get each address thrice (or more) 162 * for each possible socket type (tcp,udp,raw...): */ 163 hint.ai_socktype = SOCK_STREAM; 164 hint.ai_flags = ai_flags & ~DIE_ON_ERROR; 165 rc = getaddrinfo(host, NULL, &hint, &result); 166 if (rc || !result) { 167 bb_error_msg("bad address '%s'", org_host); 168 if (ai_flags & DIE_ON_ERROR) 169 xfunc_die(); 170 goto ret; 171 } 172 r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); 173 r->len = result->ai_addrlen; 174 memcpy(&r->sa, result->ai_addr, result->ai_addrlen); 175 set_nport(r, htons(port)); 176 ret: 177 freeaddrinfo(result); 178 return r; 179 } 180 #if !ENABLE_FEATURE_IPV6 181 #define str2sockaddr(host, port, af, ai_flags) str2sockaddr(host, port, ai_flags) 182 #endif 183 184 #if ENABLE_FEATURE_IPV6 185 len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) 186 { 187 return str2sockaddr(host, port, af, 0); 188 } 189 190 len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) 191 { 192 return str2sockaddr(host, port, af, DIE_ON_ERROR); 193 } 194 #endif 195 196 len_and_sockaddr* host2sockaddr(const char *host, int port) 197 { 198 return str2sockaddr(host, port, AF_UNSPEC, 0); 199 } 200 201 len_and_sockaddr* xhost2sockaddr(const char *host, int port) 202 { 203 return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR); 204 } 205 206 len_and_sockaddr* xdotted2sockaddr(const char *host, int port) 207 { 208 return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); 209 } 210 211 int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int family,) int sock_type) 212 { 213 SKIP_FEATURE_IPV6(enum { family = AF_INET };) 214 len_and_sockaddr *lsa; 215 int fd; 216 int len; 217 218 #if ENABLE_FEATURE_IPV6 219 if (family == AF_UNSPEC) { 220 fd = socket(AF_INET6, sock_type, 0); 221 if (fd >= 0) { 222 family = AF_INET6; 223 goto done; 224 } 225 family = AF_INET; 226 } 227 #endif 228 fd = xsocket(family, sock_type, 0); 229 len = sizeof(struct sockaddr_in); 230 #if ENABLE_FEATURE_IPV6 231 if (family == AF_INET6) { 232 done: 233 len = sizeof(struct sockaddr_in6); 234 } 235 #endif 236 lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len); 237 lsa->len = len; 238 lsa->sa.sa_family = family; 239 *lsap = lsa; 240 return fd; 241 } 242 243 int xsocket_stream(len_and_sockaddr **lsap) 244 { 245 return xsocket_type(lsap, USE_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM); 246 } 247 248 static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) 249 { 250 int fd; 251 len_and_sockaddr *lsa; 252 253 if (bindaddr && bindaddr[0]) { 254 lsa = xdotted2sockaddr(bindaddr, port); 255 /* user specified bind addr dictates family */ 256 fd = xsocket(lsa->sa.sa_family, sock_type, 0); 257 } else { 258 fd = xsocket_type(&lsa, USE_FEATURE_IPV6(AF_UNSPEC,) sock_type); 259 set_nport(lsa, htons(port)); 260 } 261 setsockopt_reuseaddr(fd); 262 xbind(fd, &lsa->sa, lsa->len); 263 free(lsa); 264 return fd; 265 } 266 267 int create_and_bind_stream_or_die(const char *bindaddr, int port) 268 { 269 return create_and_bind_or_die(bindaddr, port, SOCK_STREAM); 270 } 271 272 int create_and_bind_dgram_or_die(const char *bindaddr, int port) 273 { 274 return create_and_bind_or_die(bindaddr, port, SOCK_DGRAM); 275 } 276 277 278 int create_and_connect_stream_or_die(const char *peer, int port) 279 { 280 int fd; 281 len_and_sockaddr *lsa; 282 283 lsa = xhost2sockaddr(peer, port); 284 fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); 285 setsockopt_reuseaddr(fd); 286 xconnect(fd, &lsa->sa, lsa->len); 287 free(lsa); 288 return fd; 289 } 290 291 int xconnect_stream(const len_and_sockaddr *lsa) 292 { 293 int fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); 294 xconnect(fd, &lsa->sa, lsa->len); 295 return fd; 296 } 297 298 /* We hijack this constant to mean something else */ 299 /* It doesn't hurt because we will add this bit anyway */ 300 #define IGNORE_PORT NI_NUMERICSERV 301 static char* sockaddr2str(const struct sockaddr *sa, int flags) 302 { 303 char host[128]; 304 char serv[16]; 305 int rc; 306 socklen_t salen; 307 308 salen = LSA_SIZEOF_SA; 309 #if ENABLE_FEATURE_IPV6 310 if (sa->sa_family == AF_INET) 311 salen = sizeof(struct sockaddr_in); 312 if (sa->sa_family == AF_INET6) 313 salen = sizeof(struct sockaddr_in6); 314 #endif 315 rc = getnameinfo(sa, salen, 316 host, sizeof(host), 317 /* can do ((flags & IGNORE_PORT) ? NULL : serv) but why bother? */ 318 serv, sizeof(serv), 319 /* do not resolve port# into service _name_ */ 320 flags | NI_NUMERICSERV 321 ); 322 if (rc) 323 return NULL; 324 if (flags & IGNORE_PORT) 325 return xstrdup(host); 326 #if ENABLE_FEATURE_IPV6 327 if (sa->sa_family == AF_INET6) { 328 if (strchr(host, ':')) /* heh, it's not a resolved hostname */ 329 return xasprintf("[%s]:%s", host, serv); 330 /*return xasprintf("%s:%s", host, serv);*/ 331 /* - fall through instead */ 332 } 333 #endif 334 /* For now we don't support anything else, so it has to be INET */ 335 /*if (sa->sa_family == AF_INET)*/ 336 return xasprintf("%s:%s", host, serv); 337 /*return xstrdup(host);*/ 338 } 339 340 char* xmalloc_sockaddr2host(const struct sockaddr *sa) 341 { 342 return sockaddr2str(sa, 0); 343 } 344 345 char* xmalloc_sockaddr2host_noport(const struct sockaddr *sa) 346 { 347 return sockaddr2str(sa, IGNORE_PORT); 348 } 349 350 char* xmalloc_sockaddr2hostonly_noport(const struct sockaddr *sa) 351 { 352 return sockaddr2str(sa, NI_NAMEREQD | IGNORE_PORT); 353 } 354 char* xmalloc_sockaddr2dotted(const struct sockaddr *sa) 355 { 356 return sockaddr2str(sa, NI_NUMERICHOST); 357 } 358 359 char* xmalloc_sockaddr2dotted_noport(const struct sockaddr *sa) 360 { 361 return sockaddr2str(sa, NI_NUMERICHOST | IGNORE_PORT); 362 } -
branches/2.2.5/mindi-busybox/libbb/xfuncs.c
r821 r1765 4 4 * 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * Copyright (C) 2006 Rob Landley 7 * Copyright (C) 2006 Denis Vlasenko 6 8 * 7 * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPL version 2, see file LICENSE in this tarball for details. 8 10 */ 9 11 10 #include <sys/types.h> 11 #include <sys/stat.h> 12 #include <sys/wait.h> 13 #include <stdio.h> 14 #include <string.h> 15 #include <stdlib.h> 16 #include <unistd.h> 17 #include <fcntl.h> 18 #include "busybox.h" 12 #include "libbb.h" 13 14 /* All the functions starting with "x" call bb_error_msg_and_die() if they 15 * fail, so callers never need to check for errors. If it returned, it 16 * succeeded. */ 19 17 20 18 #ifndef DMALLOC 21 #ifdef L_xmalloc 19 /* dmalloc provides variants of these that do abort() on failure. 20 * Since dmalloc's prototypes overwrite the impls here as they are 21 * included after these prototypes in libbb.h, all is well. 22 */ 23 // Warn if we can't allocate size bytes of memory. 24 void *malloc_or_warn(size_t size) 25 { 26 void *ptr = malloc(size); 27 if (ptr == NULL && size != 0) 28 bb_error_msg(bb_msg_memory_exhausted); 29 return ptr; 30 } 31 32 // Die if we can't allocate size bytes of memory. 22 33 void *xmalloc(size_t size) 23 34 { … … 27 38 return ptr; 28 39 } 29 #endif 30 31 #ifdef L_xrealloc 40 41 // Die if we can't resize previously allocated memory. (This returns a pointer 42 // to the new memory, which may or may not be the same as the old memory. 43 // It'll copy the contents to a new chunk and free the old one if necessary.) 32 44 void *xrealloc(void *ptr, size_t size) 33 45 { … … 37 49 return ptr; 38 50 } 39 #endif 40 41 #ifdef L_xzalloc 51 #endif /* DMALLOC */ 52 53 // Die if we can't allocate and zero size bytes of memory. 42 54 void *xzalloc(size_t size) 43 55 { … … 46 58 return ptr; 47 59 } 48 #endif 49 50 #ifdef L_xcalloc 51 void *xcalloc(size_t nmemb, size_t size) 52 { 53 void *ptr = calloc(nmemb, size); 54 if (ptr == NULL && nmemb != 0 && size != 0) 55 bb_error_msg_and_die(bb_msg_memory_exhausted); 56 return ptr; 57 } 58 #endif 59 #endif /* DMALLOC */ 60 61 #ifdef L_xstrdup 62 char * bb_xstrdup (const char *s) 60 61 // Die if we can't copy a string to freshly allocated memory. 62 char * xstrdup(const char *s) 63 63 { 64 64 char *t; … … 67 67 return NULL; 68 68 69 t = strdup 69 t = strdup(s); 70 70 71 71 if (t == NULL) … … 74 74 return t; 75 75 } 76 #endif 77 78 #ifdef L_xstrndup 79 char * bb_xstrndup (const char *s, int n) 80 { 76 77 // Die if we can't allocate n+1 bytes (space for the null terminator) and copy 78 // the (possibly truncated to length n) string into it. 79 char * xstrndup(const char *s, int n) 80 { 81 int m; 81 82 char *t; 82 83 83 84 if (ENABLE_DEBUG && s == NULL) 84 bb_error_msg_and_die("bb_xstrndup bug"); 85 86 t = xmalloc(++n); 87 88 return safe_strncpy(t,s,n); 89 } 90 #endif 91 92 #ifdef L_xfopen 93 FILE *bb_xfopen(const char *path, const char *mode) 94 { 95 FILE *fp; 96 if ((fp = fopen(path, mode)) == NULL) 97 bb_perror_msg_and_die("%s", path); 85 bb_error_msg_and_die("xstrndup bug"); 86 87 /* We can just xmalloc(n+1) and strncpy into it, */ 88 /* but think about xstrndup("abc", 10000) wastage! */ 89 m = n; 90 t = (char*) s; 91 while (m) { 92 if (!*t) break; 93 m--; 94 t++; 95 } 96 n -= m; 97 t = xmalloc(n + 1); 98 t[n] = '\0'; 99 100 return memcpy(t, s, n); 101 } 102 103 // Die if we can't open a file and return a FILE * to it. 104 // Notice we haven't got xfread(), This is for use with fscanf() and friends. 105 FILE *xfopen(const char *path, const char *mode) 106 { 107 FILE *fp = fopen(path, mode); 108 if (fp == NULL) 109 bb_perror_msg_and_die("can't open '%s'", path); 98 110 return fp; 99 111 } 100 #endif 101 102 #ifdef L_xopen 103 int bb_xopen(const char *pathname, int flags) 104 { 105 return bb_xopen3(pathname, flags, 0777); 106 } 107 #endif 108 109 #ifdef L_xopen3 110 int bb_xopen3(const char *pathname, int flags, int mode) 112 113 // Die if we can't open a file and return a fd. 114 int xopen3(const char *pathname, int flags, int mode) 111 115 { 112 116 int ret; … … 114 118 ret = open(pathname, flags, mode); 115 119 if (ret < 0) { 116 bb_perror_msg_and_die(" %s", pathname);120 bb_perror_msg_and_die("can't open '%s'", pathname); 117 121 } 118 122 return ret; 119 123 } 120 #endif 121 122 #ifdef L_xread 123 ssize_t bb_xread(int fd, void *buf, size_t count) 124 { 125 ssize_t size; 126 127 size = read(fd, buf, count); 128 if (size < 0) { 129 bb_perror_msg_and_die(bb_msg_read_error); 130 } 131 return(size); 132 } 133 #endif 134 135 #ifdef L_xread_all 136 void bb_xread_all(int fd, void *buf, size_t count) 137 { 138 ssize_t size; 139 140 while (count) { 141 if ((size = bb_xread(fd, buf, count)) == 0) { /* EOF */ 142 bb_error_msg_and_die("Short read"); 143 } 144 count -= size; 145 buf = ((char *) buf) + size; 146 } 147 return; 148 } 149 #endif 150 151 #ifdef L_xread_char 152 unsigned char bb_xread_char(int fd) 153 { 154 char tmp; 155 156 bb_xread_all(fd, &tmp, 1); 157 158 return(tmp); 159 } 160 #endif 161 162 #ifdef L_xferror 163 void bb_xferror(FILE *fp, const char *fn) 124 125 // Die if we can't open an existing file and return a fd. 126 int xopen(const char *pathname, int flags) 127 { 128 return xopen3(pathname, flags, 0666); 129 } 130 131 // Warn if we can't open a file and return a fd. 132 int open3_or_warn(const char *pathname, int flags, int mode) 133 { 134 int ret; 135 136 ret = open(pathname, flags, mode); 137 if (ret < 0) { 138 bb_perror_msg("can't open '%s'", pathname); 139 } 140 return ret; 141 } 142 143 // Warn if we can't open a file and return a fd. 144 int open_or_warn(const char *pathname, int flags) 145 { 146 return open3_or_warn(pathname, flags, 0666); 147 } 148 149 void xpipe(int filedes[2]) 150 { 151 if (pipe(filedes)) 152 bb_perror_msg_and_die("can't create pipe"); 153 } 154 155 void xunlink(const char *pathname) 156 { 157 if (unlink(pathname)) 158 bb_perror_msg_and_die("can't remove file '%s'", pathname); 159 } 160 161 // Turn on nonblocking I/O on a fd 162 int ndelay_on(int fd) 163 { 164 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) | O_NONBLOCK); 165 } 166 167 int ndelay_off(int fd) 168 { 169 return fcntl(fd, F_SETFL, fcntl(fd,F_GETFL) & ~O_NONBLOCK); 170 } 171 172 void xdup2(int from, int to) 173 { 174 if (dup2(from, to) != to) 175 bb_perror_msg_and_die("can't duplicate file descriptor"); 176 } 177 178 // "Renumber" opened fd 179 void xmove_fd(int from, int to) 180 { 181 if (from == to) 182 return; 183 xdup2(from, to); 184 close(from); 185 } 186 187 // Die with an error message if we can't write the entire buffer. 188 void xwrite(int fd, const void *buf, size_t count) 189 { 190 if (count) { 191 ssize_t size = full_write(fd, buf, count); 192 if (size != count) 193 bb_error_msg_and_die("short write"); 194 } 195 } 196 197 // Die with an error message if we can't lseek to the right spot. 198 off_t xlseek(int fd, off_t offset, int whence) 199 { 200 off_t off = lseek(fd, offset, whence); 201 if (off == (off_t)-1) { 202 if (whence == SEEK_SET) 203 bb_perror_msg_and_die("lseek(%"OFF_FMT"u)", offset); 204 bb_perror_msg_and_die("lseek"); 205 } 206 return off; 207 } 208 209 // Die with supplied filename if this FILE * has ferror set. 210 void die_if_ferror(FILE *fp, const char *fn) 164 211 { 165 212 if (ferror(fp)) { 166 bb_error_msg_and_die("%s", fn); 167 } 168 } 169 #endif 170 171 #ifdef L_xferror_stdout 172 void bb_xferror_stdout(void) 173 { 174 bb_xferror(stdout, bb_msg_standard_output); 175 } 176 #endif 177 178 #ifdef L_xfflush_stdout 179 void bb_xfflush_stdout(void) 213 /* ferror doesn't set useful errno */ 214 bb_error_msg_and_die("%s: I/O error", fn); 215 } 216 } 217 218 // Die with an error message if stdout has ferror set. 219 void die_if_ferror_stdout(void) 220 { 221 die_if_ferror(stdout, bb_msg_standard_output); 222 } 223 224 // Die with an error message if we have trouble flushing stdout. 225 void xfflush_stdout(void) 180 226 { 181 227 if (fflush(stdout)) { … … 183 229 } 184 230 } 231 232 void sig_block(int sig) 233 { 234 sigset_t ss; 235 sigemptyset(&ss); 236 sigaddset(&ss, sig); 237 sigprocmask(SIG_BLOCK, &ss, NULL); 238 } 239 240 void sig_unblock(int sig) 241 { 242 sigset_t ss; 243 sigemptyset(&ss); 244 sigaddset(&ss, sig); 245 sigprocmask(SIG_UNBLOCK, &ss, NULL); 246 } 247 248 #if 0 249 void sig_blocknone(void) 250 { 251 sigset_t ss; 252 sigemptyset(&ss); 253 sigprocmask(SIG_SETMASK, &ss, NULL); 254 } 185 255 #endif 186 256 187 #ifdef L_spawn 188 // This does a fork/exec in one call, using vfork(). 189 pid_t bb_spawn(char **argv) 190 { 191 static int failed; 192 pid_t pid; 193 void *app = find_applet_by_name(argv[0]); 194 195 // Be nice to nommu machines. 196 failed = 0; 197 pid = vfork(); 198 if (pid < 0) return pid; 199 if (!pid) { 200 execvp(app ? CONFIG_BUSYBOX_EXEC_PATH : *argv, argv); 201 202 // We're sharing a stack with blocked parent, let parent know we failed 203 // and then exit to unblock parent (but don't run atexit() stuff, which 204 // would screw up parent.) 205 206 failed = -1; 207 _exit(0); 208 } 209 return failed ? failed : pid; 210 } 257 void sig_catch(int sig, void (*f)(int)) 258 { 259 struct sigaction sa; 260 sa.sa_handler = f; 261 sa.sa_flags = 0; 262 sigemptyset(&sa.sa_mask); 263 sigaction(sig, &sa, NULL); 264 } 265 266 void sig_pause(void) 267 { 268 sigset_t ss; 269 sigemptyset(&ss); 270 sigsuspend(&ss); 271 } 272 273 274 void xsetenv(const char *key, const char *value) 275 { 276 if (setenv(key, value, 1)) 277 bb_error_msg_and_die(bb_msg_memory_exhausted); 278 } 279 280 // Converts unsigned long long value into compact 4-char 281 // representation. Examples: "1234", "1.2k", " 27M", "123T" 282 // Fifth char is always '\0' 283 void smart_ulltoa5(unsigned long long ul, char buf[5]) 284 { 285 const char *fmt; 286 char c; 287 unsigned v,idx = 0; 288 ul *= 10; 289 if (ul > 9999*10) { // do not scale if 9999 or less 290 while (ul >= 10000) { 291 ul /= 1024; 292 idx++; 293 } 294 } 295 v = ul; // ullong divisions are expensive, avoid them 296 297 fmt = " 123456789"; 298 if (!idx) { // 9999 or less: use 1234 format 299 c = buf[0] = " 123456789"[v/10000]; 300 if (c != ' ') fmt = "0123456789"; 301 c = buf[1] = fmt[v/1000%10]; 302 if (c != ' ') fmt = "0123456789"; 303 buf[2] = fmt[v/100%10]; 304 buf[3] = "0123456789"[v/10%10]; 305 } else { 306 if (v >= 10*10) { // scaled value is >=10: use 123M format 307 c = buf[0] = " 123456789"[v/1000]; 308 if (c != ' ') fmt = "0123456789"; 309 buf[1] = fmt[v/100%10]; 310 buf[2] = "0123456789"[v/10%10]; 311 } else { // scaled value is <10: use 1.2M format 312 buf[0] = "0123456789"[v/10]; 313 buf[1] = '.'; 314 buf[2] = "0123456789"[v%10]; 315 } 316 // see http://en.wikipedia.org/wiki/Tera 317 buf[3] = " kMGTPEZY"[idx]; 318 } 319 buf[4] = '\0'; 320 } 321 322 // Convert unsigned integer to ascii, writing into supplied buffer. 323 // A truncated result contains the first few digits of the result ala strncpy. 324 // Returns a pointer past last generated digit, does _not_ store NUL. 325 void BUG_sizeof_unsigned_not_4(void); 326 char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) 327 { 328 unsigned i, out, res; 329 if (sizeof(unsigned) != 4) 330 BUG_sizeof_unsigned_not_4(); 331 if (buflen) { 332 out = 0; 333 for (i = 1000000000; i; i /= 10) { 334 res = n / i; 335 if (res || out || i == 1) { 336 if (!--buflen) break; 337 out++; 338 n -= res*i; 339 *buf++ = '0' + res; 340 } 341 } 342 } 343 return buf; 344 } 345 346 // Convert signed integer to ascii, like utoa_to_buf() 347 char *itoa_to_buf(int n, char *buf, unsigned buflen) 348 { 349 if (buflen && n<0) { 350 n = -n; 351 *buf++ = '-'; 352 buflen--; 353 } 354 return utoa_to_buf((unsigned)n, buf, buflen); 355 } 356 357 // The following two functions use a static buffer, so calling either one a 358 // second time will overwrite previous results. 359 // 360 // The largest 32 bit integer is -2 billion plus null terminator, or 12 bytes. 361 // Int should always be 32 bits on any remotely Unix-like system, see 362 // http://www.unix.org/whitepapers/64bit.html for the reasons why. 363 364 static char local_buf[12]; 365 366 // Convert unsigned integer to ascii using a static buffer (returned). 367 char *utoa(unsigned n) 368 { 369 *(utoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0'; 370 371 return local_buf; 372 } 373 374 // Convert signed integer to ascii using a static buffer (returned). 375 char *itoa(int n) 376 { 377 *(itoa_to_buf(n, local_buf, sizeof(local_buf))) = '\0'; 378 379 return local_buf; 380 } 381 382 // Emit a string of hex representation of bytes 383 char *bin2hex(char *p, const char *cp, int count) 384 { 385 while (count) { 386 unsigned char c = *cp++; 387 /* put lowercase hex digits */ 388 *p++ = 0x20 | bb_hexdigits_upcase[c >> 4]; 389 *p++ = 0x20 | bb_hexdigits_upcase[c & 0xf]; 390 count--; 391 } 392 return p; 393 } 394 395 // Die with an error message if we can't set gid. (Because resource limits may 396 // limit this user to a given number of processes, and if that fills up the 397 // setgid() will fail and we'll _still_be_root_, which is bad.) 398 void xsetgid(gid_t gid) 399 { 400 if (setgid(gid)) bb_perror_msg_and_die("setgid"); 401 } 402 403 // Die with an error message if we can't set uid. (See xsetgid() for why.) 404 void xsetuid(uid_t uid) 405 { 406 if (setuid(uid)) bb_perror_msg_and_die("setuid"); 407 } 408 409 // Return how long the file at fd is, if there's any way to determine it. 410 off_t fdlength(int fd) 411 { 412 off_t bottom = 0, top = 0, pos; 413 long size; 414 415 // If the ioctl works for this, return it. 416 417 if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512; 418 419 // FIXME: explain why lseek(SEEK_END) is not used here! 420 421 // If not, do a binary search for the last location we can read. (Some 422 // block devices don't do BLKGETSIZE right.) 423 424 do { 425 char temp; 426 427 pos = bottom + (top - bottom) / 2; 428 429 // If we can read from the current location, it's bigger. 430 431 if (lseek(fd, pos, SEEK_SET)>=0 && safe_read(fd, &temp, 1)==1) { 432 if (bottom == top) bottom = top = (top+1) * 2; 433 else bottom = pos; 434 435 // If we can't, it's smaller. 436 437 } else { 438 if (bottom == top) { 439 if (!top) return 0; 440 bottom = top/2; 441 } 442 else top = pos; 443 } 444 } while (bottom + 1 != top); 445 446 return pos + 1; 447 } 448 449 // Die with an error message if we can't malloc() enough space and do an 450 // sprintf() into that space. 451 char *xasprintf(const char *format, ...) 452 { 453 va_list p; 454 int r; 455 char *string_ptr; 456 457 #if 1 458 // GNU extension 459 va_start(p, format); 460 r = vasprintf(&string_ptr, format, p); 461 va_end(p); 462 #else 463 // Bloat for systems that haven't got the GNU extension. 464 va_start(p, format); 465 r = vsnprintf(NULL, 0, format, p); 466 va_end(p); 467 string_ptr = xmalloc(r+1); 468 va_start(p, format); 469 r = vsnprintf(string_ptr, r+1, format, p); 470 va_end(p); 211 471 #endif 212 472 213 #ifdef L_xspawn 214 pid_t bb_xspawn(char **argv) 215 { 216 pid_t pid = bb_spawn(argv); 217 if (pid < 0) bb_perror_msg_and_die("%s", *argv); 218 return pid; 219 } 473 if (r < 0) bb_error_msg_and_die(bb_msg_memory_exhausted); 474 return string_ptr; 475 } 476 477 #if 0 /* If we will ever meet a libc which hasn't [f]dprintf... */ 478 int fdprintf(int fd, const char *format, ...) 479 { 480 va_list p; 481 int r; 482 char *string_ptr; 483 484 #if 1 485 // GNU extension 486 va_start(p, format); 487 r = vasprintf(&string_ptr, format, p); 488 va_end(p); 489 #else 490 // Bloat for systems that haven't got the GNU extension. 491 va_start(p, format); 492 r = vsnprintf(NULL, 0, format, p) + 1; 493 va_end(p); 494 string_ptr = malloc(r); 495 if (string_ptr) { 496 va_start(p, format); 497 r = vsnprintf(string_ptr, r, format, p); 498 va_end(p); 499 } 220 500 #endif 221 501 222 #ifdef L_wait4 223 int wait4pid(int pid) 224 { 225 int status; 226 227 if (pid == -1 || waitpid(pid, &status, 0) == -1) return -1; 228 if (WIFEXITED(status)) return WEXITSTATUS(status); 229 if (WIFSIGNALED(status)) return WTERMSIG(status); 230 return 0; 231 } 232 #endif 233 234 #ifdef L_setuid 235 void xsetgid(gid_t gid) 236 { 237 if (setgid(gid)) bb_error_msg_and_die("setgid"); 238 } 239 240 void xsetuid(uid_t uid) 241 { 242 if (setuid(uid)) bb_error_msg_and_die("setuid"); 502 if (r >= 0) { 503 full_write(fd, string_ptr, r); 504 free(string_ptr); 505 } 506 return r; 243 507 } 244 508 #endif 509 510 // Die with an error message if we can't copy an entire FILE * to stdout, then 511 // close that file. 512 void xprint_and_close_file(FILE *file) 513 { 514 fflush(stdout); 515 // copyfd outputs error messages for us. 516 if (bb_copyfd_eof(fileno(file), 1) == -1) 517 xfunc_die(); 518 519 fclose(file); 520 } 521 522 // Die if we can't chdir to a new path. 523 void xchdir(const char *path) 524 { 525 if (chdir(path)) 526 bb_perror_msg_and_die("chdir(%s)", path); 527 } 528 529 // Print a warning message if opendir() fails, but don't die. 530 DIR *warn_opendir(const char *path) 531 { 532 DIR *dp; 533 534 dp = opendir(path); 535 if (!dp) 536 bb_perror_msg("can't open '%s'", path); 537 return dp; 538 } 539 540 // Die with an error message if opendir() fails. 541 DIR *xopendir(const char *path) 542 { 543 DIR *dp; 544 545 dp = opendir(path); 546 if (!dp) 547 bb_perror_msg_and_die("can't open '%s'", path); 548 return dp; 549 } 550 551 // Die with an error message if we can't open a new socket. 552 int xsocket(int domain, int type, int protocol) 553 { 554 int r = socket(domain, type, protocol); 555 556 if (r < 0) { 557 /* Hijack vaguely related config option */ 558 #if ENABLE_VERBOSE_RESOLUTION_ERRORS 559 const char *s = "INET"; 560 if (domain == AF_PACKET) s = "PACKET"; 561 if (domain == AF_NETLINK) s = "NETLINK"; 562 USE_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) 563 bb_perror_msg_and_die("socket(AF_%s)", s); 564 #else 565 bb_perror_msg_and_die("socket"); 566 #endif 567 } 568 569 return r; 570 } 571 572 // Die with an error message if we can't bind a socket to an address. 573 void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) 574 { 575 if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); 576 } 577 578 // Die with an error message if we can't listen for connections on a socket. 579 void xlisten(int s, int backlog) 580 { 581 if (listen(s, backlog)) bb_perror_msg_and_die("listen"); 582 } 583 584 /* Die with an error message if sendto failed. 585 * Return bytes sent otherwise */ 586 ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, 587 socklen_t tolen) 588 { 589 ssize_t ret = sendto(s, buf, len, 0, to, tolen); 590 if (ret < 0) { 591 if (ENABLE_FEATURE_CLEAN_UP) 592 close(s); 593 bb_perror_msg_and_die("sendto"); 594 } 595 return ret; 596 } 597 598 // xstat() - a stat() which dies on failure with meaningful error message 599 void xstat(const char *name, struct stat *stat_buf) 600 { 601 if (stat(name, stat_buf)) 602 bb_perror_msg_and_die("can't stat '%s'", name); 603 } 604 605 // selinux_or_die() - die if SELinux is disabled. 606 void selinux_or_die(void) 607 { 608 #if ENABLE_SELINUX 609 int rc = is_selinux_enabled(); 610 if (rc == 0) { 611 bb_error_msg_and_die("SELinux is disabled"); 612 } else if (rc < 0) { 613 bb_error_msg_and_die("is_selinux_enabled() failed"); 614 } 615 #else 616 bb_error_msg_and_die("SELinux support is disabled"); 617 #endif 618 } 619 620 /* It is perfectly ok to pass in a NULL for either width or for 621 * height, in which case that value will not be set. */ 622 int get_terminal_width_height(int fd, int *width, int *height) 623 { 624 struct winsize win = { 0, 0, 0, 0 }; 625 int ret = ioctl(fd, TIOCGWINSZ, &win); 626 627 if (height) { 628 if (!win.ws_row) { 629 char *s = getenv("LINES"); 630 if (s) win.ws_row = atoi(s); 631 } 632 if (win.ws_row <= 1 || win.ws_row >= 30000) 633 win.ws_row = 24; 634 *height = (int) win.ws_row; 635 } 636 637 if (width) { 638 if (!win.ws_col) { 639 char *s = getenv("COLUMNS"); 640 if (s) win.ws_col = atoi(s); 641 } 642 if (win.ws_col <= 1 || win.ws_col >= 30000) 643 win.ws_col = 80; 644 *width = (int) win.ws_col; 645 } 646 647 return ret; 648 } 649 650 void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) 651 { 652 va_list p; 653 654 if (ioctl(fd, request, argp) < 0) { 655 va_start(p, fmt); 656 bb_verror_msg(fmt, p, strerror(errno)); 657 /* xfunc_die can actually longjmp, so be nice */ 658 va_end(p); 659 xfunc_die(); 660 } 661 } 662 663 int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) 664 { 665 va_list p; 666 int ret = ioctl(fd, request, argp); 667 668 if (ret < 0) { 669 va_start(p, fmt); 670 bb_verror_msg(fmt, p, strerror(errno)); 671 va_end(p); 672 } 673 return ret; 674 } 675 676 #if ENABLE_IOCTL_HEX2STR_ERROR 677 int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name) 678 { 679 int ret; 680 681 ret = ioctl(fd, request, argp); 682 if (ret < 0) 683 bb_perror_msg("%s", ioctl_name); 684 return ret; 685 } 686 void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name) 687 { 688 if (ioctl(fd, request, argp) < 0) 689 bb_perror_msg_and_die("%s", ioctl_name); 690 } 691 #else 692 int bb_ioctl_or_warn(int fd, int request, void *argp) 693 { 694 int ret; 695 696 ret = ioctl(fd, request, argp); 697 if (ret < 0) 698 bb_perror_msg("ioctl %#x failed", request); 699 return ret; 700 } 701 void bb_xioctl(int fd, int request, void *argp) 702 { 703 if (ioctl(fd, request, argp) < 0) 704 bb_perror_msg_and_die("ioctl %#x failed", request); 705 } 706 #endif -
branches/2.2.5/mindi-busybox/libbb/xgetcwd.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * xgetcwd.c -- return current directory with unlimited length … … 7 8 */ 8 9 9 #include <stdlib.h>10 #include <errno.h>11 #include <unistd.h>12 #include <limits.h>13 #include <sys/param.h>14 10 #include "libbb.h" 15 11 … … 23 19 24 20 char * 25 x getcwd(char *cwd)21 xrealloc_getcwd_or_warn(char *cwd) 26 22 { 27 28 23 char *ret; 24 unsigned path_max; 29 25 30 31 26 path_max = (unsigned) PATH_MAX; 27 path_max += 2; /* The getcwd docs say to do this. */ 32 28 33 if(cwd==0)34 cwd = xmalloc(path_max);29 if (cwd == NULL) 30 cwd = xmalloc(path_max); 35 31 36 while ((ret = getcwd(cwd, path_max)) == NULL && errno == ERANGE) {37 38 cwd = xrealloc(cwd, path_max);39 32 while ((ret = getcwd(cwd, path_max)) == NULL && errno == ERANGE) { 33 path_max += PATH_INCR; 34 cwd = xrealloc(cwd, path_max); 35 } 40 36 41 42 free(cwd);43 bb_perror_msg("getcwd()");44 45 37 if (ret == NULL) { 38 free(cwd); 39 bb_perror_msg("getcwd"); 40 return NULL; 41 } 46 42 47 43 return cwd; 48 44 } -
branches/2.2.5/mindi-busybox/libbb/xgethostbyname.c
r821 r1765 5 5 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>. 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <netdb.h>10 //#include <netdb.h> 24 11 #include "libbb.h" 25 26 12 27 13 struct hostent *xgethostbyname(const char *name) 28 14 { 29 struct hostent *retval; 30 31 if ((retval = gethostbyname(name)) == NULL) 15 struct hostent *retval = gethostbyname(name); 16 if (!retval) 32 17 bb_herror_msg_and_die("%s", name); 33 34 18 return retval; 35 19 } -
branches/2.2.5/mindi-busybox/libbb/xreadlink.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * xreadlink.c - safe implementation of readlink. … … 4 5 */ 5 6 6 #include <stdio.h>7 #include "libbb.h" 7 8 8 9 /* … … 10 11 * yourself. You have been warned. 11 12 */ 12 13 #include <unistd.h> 14 #include "libbb.h" 15 16 char *xreadlink(const char *path) 13 char *xmalloc_readlink(const char *path) 17 14 { 18 15 enum { GROWBY = 80 }; /* how large we will grow strings by */ … … 23 20 do { 24 21 buf = xrealloc(buf, bufsize += GROWBY); 25 readsize = readlink(path, buf, bufsize); /* 1st try */22 readsize = readlink(path, buf, bufsize); 26 23 if (readsize == -1) { 27 bb_perror_msg("%s", path);28 24 free(buf); 29 25 return NULL; 30 26 } 31 } 32 while (bufsize < readsize + 1); 27 } while (bufsize < readsize + 1); 33 28 34 29 buf[readsize] = '\0'; … … 36 31 return buf; 37 32 } 33 34 char *xmalloc_readlink_or_warn(const char *path) 35 { 36 char *buf = xmalloc_readlink(path); 37 if (!buf) { 38 /* EINVAL => "file: Invalid argument" => puzzled user */ 39 bb_error_msg("%s: cannot read link (not a symlink?)", path); 40 } 41 return buf; 42 } 43 44 /* UNUSED */ 45 #if 0 46 char *xmalloc_realpath(const char *path) 47 { 48 #if defined(__GLIBC__) && !defined(__UCLIBC__) 49 /* glibc provides a non-standard extension */ 50 return realpath(path, NULL); 51 #else 52 char buf[PATH_MAX+1]; 53 54 /* on error returns NULL (xstrdup(NULL) ==NULL) */ 55 return xstrdup(realpath(path, buf)); 56 #endif 57 } 58 #endif -
branches/2.2.5/mindi-busybox/libbb/xregcomp.c
r821 r1765 9 9 */ 10 10 11 #include <stdio.h>12 11 #include "libbb.h" 13 12 #include "xregex.h" 14 13 15 14 char* regcomp_or_errmsg(regex_t *preg, const char *regex, int cflags) 15 { 16 int ret = regcomp(preg, regex, cflags); 17 if (ret) { 18 int errmsgsz = regerror(ret, preg, NULL, 0); 19 char *errmsg = xmalloc(errmsgsz); 20 regerror(ret, preg, errmsg, errmsgsz); 21 return errmsg; 22 } 23 return NULL; 24 } 16 25 17 26 void xregcomp(regex_t *preg, const char *regex, int cflags) 18 27 { 19 int ret; 20 if ((ret = regcomp(preg, regex, cflags)) != 0) { 21 int errmsgsz = regerror(ret, preg, NULL, 0); 22 char *errmsg = xmalloc(errmsgsz); 23 regerror(ret, preg, errmsg, errmsgsz); 28 char *errmsg = regcomp_or_errmsg(preg, regex, cflags); 29 if (errmsg) { 24 30 bb_error_msg_and_die("xregcomp: %s", errmsg); 25 31 }
Note:
See TracChangeset
for help on using the changeset viewer.