wok-next rev 757
busybox: misc fixes from busybox.net
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu May 08 07:55:34 2008 +0000 (2008-05-08) |
parents | 9c508a04c78d |
children | bc579f419add |
files | busybox/receipt busybox/stuff/busybox-1.10.1-fixes-1.10.1.u |
line diff
1.1 --- a/busybox/receipt Wed May 07 21:18:17 2008 +0000 1.2 +++ b/busybox/receipt Thu May 08 07:55:34 2008 +0000 1.3 @@ -29,6 +29,7 @@ 1.4 $PACKAGE-$VERSION-tar.u 1.5 $PACKAGE-$VERSION-script.u 1.6 $PACKAGE-$VERSION-header_tar.u 1.7 +$PACKAGE-$VERSION-fixes-$VERSION.u 1.8 EOT 1.9 cp ../stuff/$PACKAGE-$VERSION.config .config 1.10 make oldconfig
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/busybox/stuff/busybox-1.10.1-fixes-1.10.1.u Thu May 08 07:55:34 2008 +0000 2.3 @@ -0,0 +1,971 @@ 2.4 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-completion.patch 2.5 +--- busybox-1.10.1/libbb/lineedit.c Sat Apr 19 05:50:33 2008 2.6 ++++ busybox-1.10.1-completion/libbb/lineedit.c Thu Apr 24 06:45:39 2008 2.7 +@@ -518,8 +518,8 @@ 2.8 + 2.9 + for (i = 0; i < npaths; i++) { 2.10 + dir = opendir(paths[i]); 2.11 +- if (!dir) /* Don't print an error */ 2.12 +- continue; 2.13 ++ if (!dir) 2.14 ++ continue; /* don't print an error */ 2.15 + 2.16 + while ((next = readdir(dir)) != NULL) { 2.17 + int len1; 2.18 +@@ -529,18 +529,21 @@ 2.19 + if (strncmp(str_found, pfind, strlen(pfind))) 2.20 + continue; 2.21 + /* not see .name without .match */ 2.22 +- if (*str_found == '.' && *pfind == 0) { 2.23 ++ if (*str_found == '.' && *pfind == '\0') { 2.24 + if (NOT_LONE_CHAR(paths[i], '/') || str_found[1]) 2.25 + continue; 2.26 + str_found = ""; /* only "/" */ 2.27 + } 2.28 + found = concat_path_file(paths[i], str_found); 2.29 +- /* hmm, remover in progress? */ 2.30 +- if (lstat(found, &st) < 0) 2.31 ++ /* hmm, remove in progress? */ 2.32 ++ /* NB: stat() first so that we see is it a directory; 2.33 ++ * but if that fails, use lstat() so that 2.34 ++ * we still match dangling links */ 2.35 ++ if (stat(found, &st) && lstat(found, &st)) 2.36 + goto cont; 2.37 + /* find with dirs? */ 2.38 + if (paths[i] != dirbuf) 2.39 +- strcpy(found, next->d_name); /* only name */ 2.40 ++ strcpy(found, next->d_name); /* only name */ 2.41 + 2.42 + len1 = strlen(found); 2.43 + found = xrealloc(found, len1 + 2); 2.44 +@@ -548,7 +551,7 @@ 2.45 + found[len1+1] = '\0'; 2.46 + 2.47 + if (S_ISDIR(st.st_mode)) { 2.48 +- /* name is directory */ 2.49 ++ /* name is a directory */ 2.50 + if (found[len1-1] != '/') { 2.51 + found[len1] = '/'; 2.52 + } 2.53 +@@ -566,7 +569,7 @@ 2.54 + closedir(dir); 2.55 + } 2.56 + if (paths != path1) { 2.57 +- free(paths[0]); /* allocated memory only in first member */ 2.58 ++ free(paths[0]); /* allocated memory is only in first member */ 2.59 + free(paths); 2.60 + } 2.61 + #undef dirbuf 2.62 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-echo.patch 2.63 +--- busybox-1.10.1/coreutils/echo.c Sat Apr 19 05:50:32 2008 2.64 ++++ busybox-1.10.1-echo/coreutils/echo.c Wed Apr 30 02:37:08 2008 2.65 +@@ -27,10 +27,8 @@ 2.66 + 2.67 + /* This is a NOFORK applet. Be very careful! */ 2.68 + 2.69 +-/* argc is unused, but removing it precludes compiler from 2.70 +- * using call -> jump optimization */ 2.71 ++/* NB: can be used by shell even if not enabled as applet */ 2.72 + 2.73 +-int echo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 2.74 + int echo_main(int argc ATTRIBUTE_UNUSED, char **argv) 2.75 + { 2.76 + const char *arg; 2.77 +@@ -110,15 +108,19 @@ 2.78 + } 2.79 + #if !ENABLE_FEATURE_FANCY_ECHO 2.80 + /* SUSv3 specifies that octal escapes must begin with '0'. */ 2.81 +- if ( (((unsigned char)*arg) - '1') >= 7) 2.82 ++ if ( ((int)(unsigned char)(*arg) - '0') >= 8) /* '8' or bigger */ 2.83 + #endif 2.84 + { 2.85 + /* Since SUSv3 mandates a first digit of 0, 4-digit octals 2.86 + * of the form \0### are accepted. */ 2.87 +- if (*arg == '0' && ((unsigned char)(arg[1]) - '0') < 8) { 2.88 +- arg++; 2.89 ++ if (*arg == '0') { 2.90 ++ /* NB: don't turn "...\0" into "...\" */ 2.91 ++ if (arg[1] && ((unsigned char)(arg[1]) - '0') < 8) { 2.92 ++ arg++; 2.93 ++ } 2.94 + } 2.95 +- /* bb_process_escape_sequence can handle nul correctly */ 2.96 ++ /* bb_process_escape_sequence handles NUL correctly 2.97 ++ * ("...\" case). */ 2.98 + c = bb_process_escape_sequence(&arg); 2.99 + } 2.100 + } 2.101 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-fixes-1.10.1.u 2.102 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-hppa.patch 2.103 +--- busybox-1.10.1/include/libbb.h Sat Apr 19 05:50:36 2008 2.104 ++++ busybox-1.10.1-hppa/include/libbb.h Mon Apr 28 10:34:36 2008 2.105 +@@ -288,20 +288,20 @@ 2.106 + * SIGSYS Bad argument to routine 2.107 + * SIGTRAP Trace/breakpoint trap 2.108 + */ 2.109 +- BB_FATAL_SIGS = 0 2.110 +- + (1 << SIGHUP) 2.111 +- + (1 << SIGINT) 2.112 +- + (1 << SIGTERM) 2.113 +- + (1 << SIGPIPE) // Write to pipe with no readers 2.114 +- + (1 << SIGQUIT) // Quit from keyboard 2.115 +- + (1 << SIGABRT) // Abort signal from abort(3) 2.116 +- + (1 << SIGALRM) // Timer signal from alarm(2) 2.117 +- + (1 << SIGVTALRM) // Virtual alarm clock 2.118 +- + (1 << SIGXCPU) // CPU time limit exceeded 2.119 +- + (1 << SIGXFSZ) // File size limit exceeded 2.120 +- + (1 << SIGUSR1) // Yes kids, these are also fatal! 2.121 +- + (1 << SIGUSR2) 2.122 +- + 0, 2.123 ++ BB_FATAL_SIGS = (int)(0 2.124 ++ + (1LL << SIGHUP) 2.125 ++ + (1LL << SIGINT) 2.126 ++ + (1LL << SIGTERM) 2.127 ++ + (1LL << SIGPIPE) // Write to pipe with no readers 2.128 ++ + (1LL << SIGQUIT) // Quit from keyboard 2.129 ++ + (1LL << SIGABRT) // Abort signal from abort(3) 2.130 ++ + (1LL << SIGALRM) // Timer signal from alarm(2) 2.131 ++ + (1LL << SIGVTALRM) // Virtual alarm clock 2.132 ++ + (1LL << SIGXCPU) // CPU time limit exceeded 2.133 ++ + (1LL << SIGXFSZ) // File size limit exceeded 2.134 ++ + (1LL << SIGUSR1) // Yes kids, these are also fatal! 2.135 ++ + (1LL << SIGUSR2) 2.136 ++ + 0), 2.137 + }; 2.138 + void bb_signals(int sigs, void (*f)(int)); 2.139 + /* Unlike signal() and bb_signals, sets handler with sigaction() 2.140 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-httpd.patch 2.141 +--- busybox-1.10.1/networking/httpd.c Sat Apr 19 05:50:27 2008 2.142 ++++ busybox-1.10.1-httpd/networking/httpd.c Wed May 7 11:19:11 2008 2.143 +@@ -1457,6 +1457,11 @@ 2.144 + } 2.145 + } 2.146 + #endif 2.147 ++ /* restore default signal dispositions for CGI process */ 2.148 ++ signal(SIGCHLD, SIG_DFL); 2.149 ++ signal(SIGPIPE, SIG_DFL); 2.150 ++ signal(SIGHUP, SIG_DFL); 2.151 ++ 2.152 + execv(fullpath, argv); 2.153 + if (verbose) 2.154 + bb_perror_msg("exec %s", fullpath); 2.155 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-ioctl.patch 2.156 +--- busybox-1.10.1/include/libbb.h Sat Apr 19 05:50:36 2008 2.157 ++++ busybox-1.10.1-ioctl/include/libbb.h Thu Apr 24 06:45:03 2008 2.158 +@@ -995,16 +995,16 @@ 2.159 + /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */ 2.160 + int get_terminal_width_height(int fd, int *width, int *height); 2.161 + 2.162 +-int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); 2.163 +-void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); 2.164 ++int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); 2.165 ++void ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); 2.166 + #if ENABLE_IOCTL_HEX2STR_ERROR 2.167 +-int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name); 2.168 +-void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name); 2.169 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name); 2.170 ++void bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name); 2.171 + #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request) 2.172 + #define xioctl(fd,request,argp) bb_xioctl(fd,request,argp,#request) 2.173 + #else 2.174 +-int bb_ioctl_or_warn(int fd, int request, void *argp); 2.175 +-void bb_xioctl(int fd, int request, void *argp); 2.176 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp); 2.177 ++void bb_xioctl(int fd, unsigned request, void *argp); 2.178 + #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp) 2.179 + #define xioctl(fd,request,argp) bb_xioctl(fd,request,argp) 2.180 + #endif 2.181 +--- busybox-1.10.1/libbb/xfuncs.c Sat Apr 19 05:50:33 2008 2.182 ++++ busybox-1.10.1-ioctl/libbb/xfuncs.c Thu Apr 24 06:45:14 2008 2.183 +@@ -704,7 +704,7 @@ 2.184 + return ret; 2.185 + } 2.186 + 2.187 +-void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) 2.188 ++void ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) 2.189 + { 2.190 + va_list p; 2.191 + 2.192 +@@ -717,7 +717,7 @@ 2.193 + } 2.194 + } 2.195 + 2.196 +-int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) 2.197 ++int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) 2.198 + { 2.199 + va_list p; 2.200 + int ret = ioctl(fd, request, argp); 2.201 +@@ -731,7 +731,7 @@ 2.202 + } 2.203 + 2.204 + #if ENABLE_IOCTL_HEX2STR_ERROR 2.205 +-int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name) 2.206 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name) 2.207 + { 2.208 + int ret; 2.209 + 2.210 +@@ -740,13 +740,13 @@ 2.211 + bb_simple_perror_msg(ioctl_name); 2.212 + return ret; 2.213 + } 2.214 +-void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name) 2.215 ++void bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name) 2.216 + { 2.217 + if (ioctl(fd, request, argp) < 0) 2.218 + bb_simple_perror_msg_and_die(ioctl_name); 2.219 + } 2.220 + #else 2.221 +-int bb_ioctl_or_warn(int fd, int request, void *argp) 2.222 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp) 2.223 + { 2.224 + int ret; 2.225 + 2.226 +@@ -755,7 +755,7 @@ 2.227 + bb_perror_msg("ioctl %#x failed", request); 2.228 + return ret; 2.229 + } 2.230 +-void bb_xioctl(int fd, int request, void *argp) 2.231 ++void bb_xioctl(int fd, unsigned request, void *argp) 2.232 + { 2.233 + if (ioctl(fd, request, argp) < 0) 2.234 + bb_perror_msg_and_die("ioctl %#x failed", request); 2.235 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-mdev.patch 2.236 +--- busybox-1.10.1/util-linux/mdev.c Sat Apr 19 05:50:39 2008 2.237 ++++ busybox-1.10.1-mdev/util-linux/mdev.c Fri May 2 14:48:06 2008 2.238 +@@ -12,6 +12,8 @@ 2.239 + #include "libbb.h" 2.240 + #include "xregex.h" 2.241 + 2.242 ++#define ENABLE_FEATURE_MDEV_RENAME_REGEXP 1 2.243 ++ 2.244 + struct globals { 2.245 + int root_major, root_minor; 2.246 + }; 2.247 +@@ -21,7 +23,21 @@ 2.248 + 2.249 + #define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ 2.250 + 2.251 ++/* We use additional 64+ bytes in make_device() */ 2.252 ++#define SCRATCH_SIZE 80 2.253 ++ 2.254 ++static char *next_field(char *s) 2.255 ++{ 2.256 ++ char *end = skip_non_whitespace(s); 2.257 ++ s = skip_whitespace(end); 2.258 ++ *end = '\0'; 2.259 ++ if (*s == '\0') 2.260 ++ s = NULL; 2.261 ++ return s; 2.262 ++} 2.263 ++ 2.264 + /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ 2.265 ++/* NB: "mdev -s" may call us many times, do not leak memory/fds! */ 2.266 + static void make_device(char *path, int delete) 2.267 + { 2.268 + const char *device_name; 2.269 +@@ -29,7 +45,7 @@ 2.270 + int mode = 0660; 2.271 + uid_t uid = 0; 2.272 + gid_t gid = 0; 2.273 +- char *temp = path + strlen(path); 2.274 ++ char *dev_maj_min = path + strlen(path); 2.275 + char *command = NULL; 2.276 + char *alias = NULL; 2.277 + 2.278 +@@ -42,156 +58,178 @@ 2.279 + * also depend on path having writeable space after it. 2.280 + */ 2.281 + if (!delete) { 2.282 +- strcat(path, "/dev"); 2.283 +- len = open_read_close(path, temp + 1, 64); 2.284 +- *temp++ = 0; 2.285 ++ strcpy(dev_maj_min, "/dev"); 2.286 ++ len = open_read_close(path, dev_maj_min + 1, 64); 2.287 ++ *dev_maj_min++ = '\0'; 2.288 + if (len < 1) { 2.289 +- if (ENABLE_FEATURE_MDEV_EXEC) 2.290 +- /* no "dev" file, so just try to run script */ 2.291 +- *temp = 0; 2.292 +- else 2.293 ++ if (!ENABLE_FEATURE_MDEV_EXEC) 2.294 + return; 2.295 ++ /* no "dev" file, so just try to run script */ 2.296 ++ *dev_maj_min = '\0'; 2.297 + } 2.298 + } 2.299 + 2.300 + /* Determine device name, type, major and minor */ 2.301 + device_name = bb_basename(path); 2.302 +- type = (path[5] == 'c' ? S_IFCHR : S_IFBLK); 2.303 ++ /* http://kernel.org/doc/pending/hotplug.txt says that only 2.304 ++ * "/sys/block/..." is for block devices. "sys/bus" etc is not! */ 2.305 ++ type = (strncmp(&path[5], "block/", 6) == 0 ? S_IFBLK : S_IFCHR); 2.306 + 2.307 + if (ENABLE_FEATURE_MDEV_CONF) { 2.308 + FILE *fp; 2.309 +- char *line, *vline; 2.310 ++ char *line, *val, *next; 2.311 + unsigned lineno = 0; 2.312 + 2.313 +- /* If we have a config file, look up the user settings */ 2.314 ++ /* If we have config file, look up user settings */ 2.315 + fp = fopen_or_warn("/etc/mdev.conf", "r"); 2.316 + if (!fp) 2.317 + goto end_parse; 2.318 + 2.319 +- while ((vline = line = xmalloc_getline(fp)) != NULL) { 2.320 +- int field; 2.321 ++ while ((line = xmalloc_getline(fp)) != NULL) { 2.322 ++ regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; 2.323 + 2.324 +- /* A pristine copy for command execution. */ 2.325 +- char *orig_line; 2.326 +- if (ENABLE_FEATURE_MDEV_EXEC) 2.327 +- orig_line = xstrdup(line); 2.328 +- 2.329 + ++lineno; 2.330 ++ trim(line); 2.331 ++ if (!line[0]) 2.332 ++ goto next_line; 2.333 + 2.334 +- /* Three fields: regex, uid:gid, mode */ 2.335 +- for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_RENAME + ENABLE_FEATURE_MDEV_EXEC); ++field) { 2.336 ++ /* Fields: regex uid:gid mode [alias] [cmd] */ 2.337 + 2.338 +- /* Find a non-empty field */ 2.339 +- char *val; 2.340 +- do { 2.341 +- val = strtok(vline, " \t"); 2.342 +- vline = NULL; 2.343 +- } while (val && !*val); 2.344 +- if (!val) { 2.345 +- if (field) 2.346 +- break; 2.347 +- else 2.348 +- goto next_line; 2.349 +- } 2.350 ++ /* 1st field: regex to match this device */ 2.351 ++ next = next_field(line); 2.352 ++ { 2.353 ++ regex_t match; 2.354 ++ int result; 2.355 + 2.356 +- if (field == 0) { 2.357 ++ /* Is this it? */ 2.358 ++ xregcomp(&match, line, REG_EXTENDED); 2.359 ++ result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0); 2.360 ++ regfree(&match); 2.361 + 2.362 +- /* Regex to match this device */ 2.363 +- regex_t match; 2.364 +- regmatch_t off; 2.365 +- int result; 2.366 ++ //bb_error_msg("matches:"); 2.367 ++ //for (int i = 0; i < ARRAY_SIZE(off); i++) { 2.368 ++ // if (off[i].rm_so < 0) continue; 2.369 ++ // bb_error_msg("match %d: '%.*s'\n", i, 2.370 ++ // (int)(off[i].rm_eo - off[i].rm_so), 2.371 ++ // device_name + off[i].rm_so); 2.372 ++ //} 2.373 + 2.374 +- /* Is this it? */ 2.375 +- xregcomp(&match, val, REG_EXTENDED); 2.376 +- result = regexec(&match, device_name, 1, &off, 0); 2.377 +- regfree(&match); 2.378 ++ /* If not this device, skip rest of line */ 2.379 ++ /* (regexec returns whole pattern as "range" 0) */ 2.380 ++ if (result || off[0].rm_so || off[0].rm_eo != strlen(device_name)) 2.381 ++ goto next_line; 2.382 ++ } 2.383 + 2.384 +- /* If not this device, skip rest of line */ 2.385 +- if (result || off.rm_so || off.rm_eo != strlen(device_name)) 2.386 +- goto next_line; 2.387 ++ /* This line matches: stop parsing the file 2.388 ++ * after parsing the rest of fields */ 2.389 + 2.390 +- } else if (field == 1) { 2.391 ++ /* 2nd field: uid:gid - device ownership */ 2.392 ++ if (!next) /* field must exist */ 2.393 ++ bb_error_msg_and_die("bad line %u", lineno); 2.394 ++ val = next; 2.395 ++ next = next_field(val); 2.396 ++ { 2.397 ++ struct passwd *pass; 2.398 ++ struct group *grp; 2.399 ++ char *str_uid = val; 2.400 ++ char *str_gid = strchrnul(val, ':'); 2.401 + 2.402 +- /* uid:gid device ownership */ 2.403 +- struct passwd *pass; 2.404 +- struct group *grp; 2.405 ++ if (*str_gid) 2.406 ++ *str_gid++ = '\0'; 2.407 ++ /* Parse UID */ 2.408 ++ pass = getpwnam(str_uid); 2.409 ++ if (pass) 2.410 ++ uid = pass->pw_uid; 2.411 ++ else 2.412 ++ uid = strtoul(str_uid, NULL, 10); 2.413 ++ /* Parse GID */ 2.414 ++ grp = getgrnam(str_gid); 2.415 ++ if (grp) 2.416 ++ gid = grp->gr_gid; 2.417 ++ else 2.418 ++ gid = strtoul(str_gid, NULL, 10); 2.419 ++ } 2.420 + 2.421 +- char *str_uid = val; 2.422 +- char *str_gid = strchr(val, ':'); 2.423 +- if (str_gid) 2.424 +- *str_gid = '\0', ++str_gid; 2.425 ++ /* 3rd field: mode - device permissions */ 2.426 ++ if (!next) /* field must exist */ 2.427 ++ bb_error_msg_and_die("bad line %u", lineno); 2.428 ++ val = next; 2.429 ++ next = next_field(val); 2.430 ++ mode = strtoul(val, NULL, 8); 2.431 + 2.432 +- /* Parse UID */ 2.433 +- pass = getpwnam(str_uid); 2.434 +- if (pass) 2.435 +- uid = pass->pw_uid; 2.436 +- else 2.437 +- uid = strtoul(str_uid, NULL, 10); 2.438 ++ /* 4th field (opt): >alias */ 2.439 ++ if (ENABLE_FEATURE_MDEV_RENAME) { 2.440 ++ if (!next) 2.441 ++ break; 2.442 ++ if (*next == '>') { 2.443 ++#if ENABLE_FEATURE_MDEV_RENAME_REGEXP 2.444 ++ char *s, *p; 2.445 ++ unsigned i, n; 2.446 ++#endif 2.447 ++ val = next; 2.448 ++ next = next_field(val); 2.449 ++#if ENABLE_FEATURE_MDEV_RENAME_REGEXP 2.450 ++ /* substitute %1..9 with off[1..9], if any */ 2.451 ++ n = 0; 2.452 ++ s = val; 2.453 ++ while (*s && *s++ == '%') 2.454 ++ n++; 2.455 + 2.456 +- /* parse GID */ 2.457 +- grp = getgrnam(str_gid); 2.458 +- if (grp) 2.459 +- gid = grp->gr_gid; 2.460 +- else 2.461 +- gid = strtoul(str_gid, NULL, 10); 2.462 +- 2.463 +- } else if (field == 2) { 2.464 +- 2.465 +- /* Mode device permissions */ 2.466 +- mode = strtoul(val, NULL, 8); 2.467 +- 2.468 +- } else if (ENABLE_FEATURE_MDEV_RENAME && field == 3) { 2.469 +- 2.470 +- if (*val != '>') 2.471 +- ++field; 2.472 +- else 2.473 +- alias = xstrdup(val + 1); 2.474 +- 2.475 ++ p = alias = xzalloc(strlen(val) + n * strlen(device_name)); 2.476 ++ s = val + 1; 2.477 ++ while (*s) { 2.478 ++ *p = *s; 2.479 ++ if ('%' == *s) { 2.480 ++ i = (s[1] - '0'); 2.481 ++ if (i <= 9 && off[i].rm_so >= 0) { 2.482 ++ n = off[i].rm_eo - off[i].rm_so; 2.483 ++ strncpy(p, device_name + off[i].rm_so, n); 2.484 ++ p += n - 1; 2.485 ++ s++; 2.486 ++ } 2.487 ++ } 2.488 ++ p++; 2.489 ++ s++; 2.490 ++ } 2.491 ++#else 2.492 ++ alias = xstrdup(val + 1); 2.493 ++#endif 2.494 + } 2.495 ++ } 2.496 + 2.497 +- if (ENABLE_FEATURE_MDEV_EXEC && field == 3 + ENABLE_FEATURE_MDEV_RENAME) { 2.498 ++ /* The rest (opt): command to run */ 2.499 ++ if (!next) 2.500 ++ break; 2.501 ++ val = next; 2.502 ++ if (ENABLE_FEATURE_MDEV_EXEC) { 2.503 ++ const char *s = "@$*"; 2.504 ++ const char *s2 = strchr(s, *val); 2.505 + 2.506 +- /* Optional command to run */ 2.507 +- const char *s = "@$*"; 2.508 +- const char *s2 = strchr(s, *val); 2.509 ++ if (!s2) 2.510 ++ bb_error_msg_and_die("bad line %u", lineno); 2.511 + 2.512 +- if (!s2) { 2.513 +- /* Force error */ 2.514 +- field = 1; 2.515 +- break; 2.516 +- } 2.517 +- 2.518 +- /* Correlate the position in the "@$*" with the delete 2.519 +- * step so that we get the proper behavior. 2.520 +- */ 2.521 +- if ((s2 - s + 1) & (1 << delete)) 2.522 +- command = xstrdup(orig_line + (val + 1 - line)); 2.523 ++ /* Correlate the position in the "@$*" with the delete 2.524 ++ * step so that we get the proper behavior: 2.525 ++ * @cmd: run on create 2.526 ++ * $cmd: run on delete 2.527 ++ * *cmd: run on both 2.528 ++ */ 2.529 ++ if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) { 2.530 ++ command = xstrdup(val + 1); 2.531 + } 2.532 + } 2.533 +- 2.534 +- /* Did everything parse happily? */ 2.535 +- if (field <= 2) 2.536 +- bb_error_msg_and_die("bad line %u", lineno); 2.537 +- 2.538 ++ /* end of field parsing */ 2.539 ++ break; /* we found matching line, stop */ 2.540 + next_line: 2.541 + free(line); 2.542 +- if (ENABLE_FEATURE_MDEV_EXEC) 2.543 +- free(orig_line); 2.544 +- } 2.545 ++ } /* end of "while line is read from /etc/mdev.conf" */ 2.546 + 2.547 +- if (ENABLE_FEATURE_CLEAN_UP) 2.548 +- fclose(fp); 2.549 +- 2.550 +- end_parse: /* nothing */ ; 2.551 ++ free(line); /* in case we used "break" to get here */ 2.552 ++ fclose(fp); 2.553 + } 2.554 ++ end_parse: 2.555 + 2.556 +- if (!delete) { 2.557 +- if (sscanf(temp, "%d:%d", &major, &minor) != 2) { 2.558 +- if (ENABLE_FEATURE_MDEV_EXEC) 2.559 +- goto skip_creation; 2.560 +- else 2.561 +- return; 2.562 +- } 2.563 ++ if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) { 2.564 + 2.565 + if (ENABLE_FEATURE_MDEV_RENAME) 2.566 + unlink(device_name); 2.567 +@@ -208,39 +246,44 @@ 2.568 + if (ENABLE_FEATURE_MDEV_RENAME && alias) { 2.569 + char *dest; 2.570 + 2.571 +- temp = strrchr(alias, '/'); 2.572 +- if (temp) { 2.573 +- if (temp[1] != '\0') 2.574 +- /* given a file name, so rename it */ 2.575 +- *temp = '\0'; 2.576 ++ /* ">bar/": rename to bar/device_name */ 2.577 ++ /* ">bar[/]baz": rename to bar[/]baz */ 2.578 ++ dest = strrchr(alias, '/'); 2.579 ++ if (dest) { /* ">bar/[baz]" ? */ 2.580 ++ *dest = '\0'; /* mkdir bar */ 2.581 + bb_make_directory(alias, 0755, FILEUTILS_RECUR); 2.582 +- dest = concat_path_file(alias, device_name); 2.583 +- } else 2.584 +- dest = alias; 2.585 ++ *dest = '/'; 2.586 ++ if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */ 2.587 ++ dest = alias; 2.588 ++ alias = concat_path_file(alias, device_name); 2.589 ++ free(dest); 2.590 ++ } 2.591 ++ } 2.592 + 2.593 +- rename(device_name, dest); // TODO: xrename? 2.594 +- symlink(dest, device_name); 2.595 ++ /* recreate device_name as a symlink to moved device node */ 2.596 ++ if (rename(device_name, alias) == 0) { 2.597 ++ symlink(alias, device_name); 2.598 ++ } 2.599 + 2.600 +- if (alias != dest) 2.601 +- free(alias); 2.602 +- free(dest); 2.603 ++ free(alias); 2.604 + } 2.605 + } 2.606 +- skip_creation: /* nothing */ ; 2.607 + } 2.608 ++ 2.609 + if (ENABLE_FEATURE_MDEV_EXEC && command) { 2.610 +- /* setenv will leak memory, so use putenv */ 2.611 ++ /* setenv will leak memory, use putenv/unsetenv/free */ 2.612 + char *s = xasprintf("MDEV=%s", device_name); 2.613 + putenv(s); 2.614 + if (system(command) == -1) 2.615 +- bb_perror_msg_and_die("cannot run %s", command); 2.616 ++ bb_perror_msg_and_die("can't run '%s'", command); 2.617 + s[4] = '\0'; 2.618 + unsetenv(s); 2.619 + free(s); 2.620 + free(command); 2.621 + } 2.622 ++ 2.623 + if (delete) 2.624 +- remove_file(device_name, FILEUTILS_FORCE); 2.625 ++ unlink(device_name); 2.626 + } 2.627 + 2.628 + /* File callback for /sys/ traversal */ 2.629 +@@ -249,14 +292,15 @@ 2.630 + void *userData, 2.631 + int depth ATTRIBUTE_UNUSED) 2.632 + { 2.633 +- size_t len = strlen(fileName) - 4; 2.634 ++ size_t len = strlen(fileName) - 4; /* can't underflow */ 2.635 + char *scratch = userData; 2.636 + 2.637 +- if (strcmp(fileName + len, "/dev")) 2.638 ++ /* len check is for paranoid reasons */ 2.639 ++ if (strcmp(fileName + len, "/dev") || len >= PATH_MAX) 2.640 + return FALSE; 2.641 + 2.642 + strcpy(scratch, fileName); 2.643 +- scratch[len] = 0; 2.644 ++ scratch[len] = '\0'; 2.645 + make_device(scratch, 0); 2.646 + 2.647 + return TRUE; 2.648 +@@ -287,12 +331,6 @@ 2.649 + int cnt; 2.650 + int firmware_fd, loading_fd, data_fd; 2.651 + 2.652 +- /* check for $FIRMWARE from kernel */ 2.653 +- /* XXX: dont bother: open(NULL) works same as open("no-such-file") 2.654 +- * if (!firmware) 2.655 +- * return; 2.656 +- */ 2.657 +- 2.658 + /* check for /lib/firmware/$FIRMWARE */ 2.659 + xchdir("/lib/firmware"); 2.660 + firmware_fd = xopen(firmware, O_RDONLY); 2.661 +@@ -304,16 +342,15 @@ 2.662 + xchdir(sysfs_path); 2.663 + for (cnt = 0; cnt < 30; ++cnt) { 2.664 + loading_fd = open("loading", O_WRONLY); 2.665 +- if (loading_fd == -1) 2.666 +- sleep(1); 2.667 +- else 2.668 +- break; 2.669 ++ if (loading_fd != -1) 2.670 ++ goto loading; 2.671 ++ sleep(1); 2.672 + } 2.673 +- if (loading_fd == -1) 2.674 +- goto out; 2.675 ++ goto out; 2.676 + 2.677 ++ loading: 2.678 + /* tell kernel we're loading by `echo 1 > /sys/$DEVPATH/loading` */ 2.679 +- if (write(loading_fd, "1", 1) != 1) 2.680 ++ if (full_write(loading_fd, "1", 1) != 1) 2.681 + goto out; 2.682 + 2.683 + /* load firmware by `cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data */ 2.684 +@@ -324,9 +361,9 @@ 2.685 + 2.686 + /* tell kernel result by `echo [0|-1] > /sys/$DEVPATH/loading` */ 2.687 + if (cnt > 0) 2.688 +- write(loading_fd, "0", 1); 2.689 ++ full_write(loading_fd, "0", 1); 2.690 + else 2.691 +- write(loading_fd, "-1", 2); 2.692 ++ full_write(loading_fd, "-1", 2); 2.693 + 2.694 + out: 2.695 + if (ENABLE_FEATURE_CLEAN_UP) { 2.696 +@@ -341,16 +378,14 @@ 2.697 + { 2.698 + char *action; 2.699 + char *env_path; 2.700 +- RESERVE_CONFIG_BUFFER(temp,PATH_MAX); 2.701 ++ RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); 2.702 + 2.703 + xchdir("/dev"); 2.704 + 2.705 +- if (argc == 2 && !strcmp(argv[1],"-s")) { 2.706 +- 2.707 ++ if (argc == 2 && !strcmp(argv[1], "-s")) { 2.708 + /* Scan: 2.709 + * mdev -s 2.710 + */ 2.711 +- 2.712 + struct stat st; 2.713 + 2.714 + xstat("/", &st); 2.715 +@@ -366,26 +401,27 @@ 2.716 + fileAction, dirAction, temp, 0); 2.717 + 2.718 + } else { 2.719 +- 2.720 + /* Hotplug: 2.721 + * env ACTION=... DEVPATH=... mdev 2.722 + * ACTION can be "add" or "remove" 2.723 + * DEVPATH is like "/block/sda" or "/class/input/mice" 2.724 + */ 2.725 +- 2.726 + action = getenv("ACTION"); 2.727 + env_path = getenv("DEVPATH"); 2.728 + if (!action || !env_path) 2.729 + bb_show_usage(); 2.730 + 2.731 +- sprintf(temp, "/sys%s", env_path); 2.732 ++ snprintf(temp, PATH_MAX, "/sys%s", env_path); 2.733 + if (!strcmp(action, "remove")) 2.734 + make_device(temp, 1); 2.735 + else if (!strcmp(action, "add")) { 2.736 + make_device(temp, 0); 2.737 + 2.738 +- if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) 2.739 +- load_firmware(getenv("FIRMWARE"), temp); 2.740 ++ if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) { 2.741 ++ char *fw = getenv("FIRMWARE"); 2.742 ++ if (fw) 2.743 ++ load_firmware(fw, temp); 2.744 ++ } 2.745 + } 2.746 + } 2.747 + 2.748 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-pidof.patch 2.749 +--- busybox-1.10.1/libbb/procps.c Sat Apr 19 05:50:33 2008 2.750 ++++ busybox-1.10.1-pidof/libbb/procps.c Sat Apr 26 01:18:32 2008 2.751 +@@ -258,7 +258,7 @@ 2.752 + &sp->start_time, 2.753 + &vsz, 2.754 + &rss); 2.755 +- if (n != 10) 2.756 ++ if (n != 11) 2.757 + break; 2.758 + /* vsz is in bytes and we want kb */ 2.759 + sp->vsz = vsz >> 10; 2.760 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-ssd.patch 2.761 +--- busybox-1.10.1/debianutils/start_stop_daemon.c Sat Apr 19 05:50:30 2008 2.762 ++++ busybox-1.10.1-ssd/debianutils/start_stop_daemon.c Tue Apr 22 03:13:13 2008 2.763 +@@ -11,7 +11,6 @@ 2.764 + /* NB: we have a problem here with /proc/NN/exe usage, similar to 2.765 + * one fixed in killall/pidof */ 2.766 + 2.767 +-#include <getopt.h> 2.768 + #include <sys/resource.h> 2.769 + 2.770 + /* Override ENABLE_FEATURE_PIDFILE */ 2.771 +@@ -33,6 +32,7 @@ 2.772 + int user_id; 2.773 + smallint quiet; 2.774 + smallint signal_nr; 2.775 ++ struct stat execstat; 2.776 + }; 2.777 + #define G (*(struct globals*)&bb_common_bufsiz1) 2.778 + #define found (G.found ) 2.779 +@@ -43,6 +43,7 @@ 2.780 + #define user_id (G.user_id ) 2.781 + #define quiet (G.quiet ) 2.782 + #define signal_nr (G.signal_nr ) 2.783 ++#define execstat (G.execstat ) 2.784 + #define INIT_G() \ 2.785 + do { \ 2.786 + user_id = -1; \ 2.787 +@@ -50,25 +51,21 @@ 2.788 + } while (0) 2.789 + 2.790 + 2.791 +-static int pid_is_exec(pid_t pid, const char *name) 2.792 ++static int pid_is_exec(pid_t pid) 2.793 + { 2.794 ++ struct stat st; 2.795 + char buf[sizeof("/proc//exe") + sizeof(int)*3]; 2.796 +- char *execbuf; 2.797 +- int n; 2.798 + 2.799 + sprintf(buf, "/proc/%u/exe", pid); 2.800 +- n = strlen(name) + 1; 2.801 +- execbuf = xzalloc(n + 1); 2.802 +- readlink(buf, execbuf, n); 2.803 +- /* if readlink fails because link target is longer than strlen(name), 2.804 +- * execbuf still contains "", and strcmp will return !0. */ 2.805 +- n = strcmp(execbuf, name); 2.806 +- if (ENABLE_FEATURE_CLEAN_UP) 2.807 +- free(execbuf); 2.808 +- return !n; /* nonzero (true) if execbuf == name */ 2.809 ++ if (stat(buf, &st) < 0) 2.810 ++ return 0; 2.811 ++ if (st.st_dev == execstat.st_dev 2.812 ++ && st.st_ino == execstat.st_ino) 2.813 ++ return 1; 2.814 ++ return 0; 2.815 + } 2.816 + 2.817 +-static int pid_is_user(int pid, int uid) 2.818 ++static int pid_is_user(int pid) 2.819 + { 2.820 + struct stat sb; 2.821 + char buf[sizeof("/proc/") + sizeof(int)*3]; 2.822 +@@ -76,42 +73,39 @@ 2.823 + sprintf(buf, "/proc/%u", pid); 2.824 + if (stat(buf, &sb) != 0) 2.825 + return 0; 2.826 +- return (sb.st_uid == uid); 2.827 ++ return (sb.st_uid == user_id); 2.828 + } 2.829 + 2.830 +-static int pid_is_cmd(pid_t pid, const char *name) 2.831 ++static int pid_is_cmd(pid_t pid) 2.832 + { 2.833 +- char fname[sizeof("/proc//stat") + sizeof(int)*3]; 2.834 +- char *buf; 2.835 +- int r = 0; 2.836 ++ char buf[256]; /* is it big enough? */ 2.837 ++ char *p, *pe; 2.838 + 2.839 +- sprintf(fname, "/proc/%u/stat", pid); 2.840 +- buf = xmalloc_open_read_close(fname, NULL); 2.841 +- if (buf) { 2.842 +- char *p = strchr(buf, '('); 2.843 +- if (p) { 2.844 +- char *pe = strrchr(++p, ')'); 2.845 +- if (pe) { 2.846 +- *pe = '\0'; 2.847 +- r = !strcmp(p, name); 2.848 +- } 2.849 +- } 2.850 +- free(buf); 2.851 +- } 2.852 +- return r; 2.853 ++ sprintf(buf, "/proc/%u/stat", pid); 2.854 ++ if (open_read_close(buf, buf, sizeof(buf) - 1) < 0) 2.855 ++ return 0; 2.856 ++ buf[sizeof(buf) - 1] = '\0'; /* paranoia */ 2.857 ++ p = strchr(buf, '('); 2.858 ++ if (!p) 2.859 ++ return 0; 2.860 ++ pe = strrchr(++p, ')'); 2.861 ++ if (!pe) 2.862 ++ return 0; 2.863 ++ *pe = '\0'; 2.864 ++ return !strcmp(p, cmdname); 2.865 + } 2.866 + 2.867 + static void check(int pid) 2.868 + { 2.869 + struct pid_list *p; 2.870 + 2.871 +- if (execname && !pid_is_exec(pid, execname)) { 2.872 ++ if (execname && !pid_is_exec(pid)) { 2.873 + return; 2.874 + } 2.875 +- if (userspec && !pid_is_user(pid, user_id)) { 2.876 ++ if (userspec && !pid_is_user(pid)) { 2.877 + return; 2.878 + } 2.879 +- if (cmdname && !pid_is_cmd(pid, cmdname)) { 2.880 ++ if (cmdname && !pid_is_cmd(pid)) { 2.881 + return; 2.882 + } 2.883 + p = xmalloc(sizeof(*p)); 2.884 +@@ -148,9 +142,16 @@ 2.885 + procdir = xopendir("/proc"); 2.886 + 2.887 + pid = 0; 2.888 +- while ((entry = readdir(procdir)) != NULL) { 2.889 ++ while(1) { 2.890 ++ errno = 0; /* clear any previous error */ 2.891 ++ entry = readdir(procdir); 2.892 ++// TODO: check for exact errno(s) which mean that we got stale entry 2.893 ++ if (errno) /* Stale entry, process has died after opendir */ 2.894 ++ continue; 2.895 ++ if (!entry) /* EOF, no more entries */ 2.896 ++ break; 2.897 + pid = bb_strtou(entry->d_name, NULL, 10); 2.898 +- if (errno) 2.899 ++ if (errno) /* NaN */ 2.900 + continue; 2.901 + check(pid); 2.902 + } 2.903 +@@ -165,8 +166,6 @@ 2.904 + struct pid_list *p; 2.905 + int killed = 0; 2.906 + 2.907 +- do_procinit(); 2.908 +- 2.909 + if (cmdname) { 2.910 + if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname); 2.911 + if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname; 2.912 +@@ -251,7 +250,7 @@ 2.913 + }; 2.914 + 2.915 + int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 2.916 +-int start_stop_daemon_main(int argc, char **argv) 2.917 ++int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv) 2.918 + { 2.919 + unsigned opt; 2.920 + char *signame; 2.921 +@@ -293,7 +292,7 @@ 2.922 + // if (retry_arg) 2.923 + // retries = xatoi_u(retry_arg); 2.924 + // ) 2.925 +- argc -= optind; 2.926 ++ //argc -= optind; 2.927 + argv += optind; 2.928 + 2.929 + if (userspec) { 2.930 +@@ -301,13 +300,15 @@ 2.931 + if (errno) 2.932 + user_id = xuname2uid(userspec); 2.933 + } 2.934 ++ if (execname) 2.935 ++ xstat(execname, &execstat); 2.936 + 2.937 ++ do_procinit(); /* Both start and stop needs to know current processes */ 2.938 ++ 2.939 + if (opt & CTX_STOP) { 2.940 + int i = do_stop(); 2.941 + return (opt & OPT_OKNODO) ? 0 : (i <= 0); 2.942 + } 2.943 +- 2.944 +- do_procinit(); 2.945 + 2.946 + if (found) { 2.947 + if (!quiet) 2.948 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-taskset.patch 2.949 +--- busybox-1.10.1/miscutils/taskset.c Sat Apr 19 06:03:13 2008 2.950 ++++ busybox-1.10.1-taskset/miscutils/taskset.c Fri Apr 25 18:58:53 2008 2.951 +@@ -94,8 +94,10 @@ 2.952 + unsigned i; 2.953 + /* Do not allow zero mask: */ 2.954 + unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); 2.955 ++ enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 }; 2.956 ++ 2.957 + CPU_ZERO(&mask); 2.958 +- for (i = 0; i < CPU_SETSIZE; i++) { 2.959 ++ for (i = 0; i < CNT_BIT; i++) { 2.960 + unsigned long long bit = (1ULL << i); 2.961 + if (bit & m) 2.962 + CPU_SET(i, &mask); 2.963 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-trylink.patch 2.964 +--- busybox-1.10.1/scripts/trylink Sat Apr 19 05:50:27 2008 2.965 ++++ busybox-1.10.1-trylink/scripts/trylink Wed Apr 30 02:10:19 2008 2.966 +@@ -66,7 +66,7 @@ 2.967 + #if defined(__GLIBC__) && !defined(__UCLIBC__) 2.968 + syntax error here 2.969 + #endif 2.970 +- " >"$tempname" 2.971 ++ " >"$tempname".c 2.972 + if $CC "$tempname".c -c -o "$tempname".o >/dev/null 2>&1; then 2.973 + echo "$2"; 2.974 + else