wok 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