wok-4.x diff busybox/stuff/busybox-1.10.1-fixes-1.10.1.u @ rev 3000

slim: Fix pre_install func to backup config file (Thanks firmit)
author Christophe Lincoln <pankso@slitaz.org>
date Mon May 11 21:44:31 2009 +0200 (2009-05-11)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/busybox/stuff/busybox-1.10.1-fixes-1.10.1.u	Mon May 11 21:44:31 2009 +0200
     1.3 @@ -0,0 +1,971 @@
     1.4 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-completion.patch
     1.5 +--- busybox-1.10.1/libbb/lineedit.c	Sat Apr 19 05:50:33 2008
     1.6 ++++ busybox-1.10.1-completion/libbb/lineedit.c	Thu Apr 24 06:45:39 2008
     1.7 +@@ -518,8 +518,8 @@
     1.8 + 
     1.9 + 	for (i = 0; i < npaths; i++) {
    1.10 + 		dir = opendir(paths[i]);
    1.11 +-		if (!dir)                       /* Don't print an error */
    1.12 +-			continue;
    1.13 ++		if (!dir)
    1.14 ++			continue; /* don't print an error */
    1.15 + 
    1.16 + 		while ((next = readdir(dir)) != NULL) {
    1.17 + 			int len1;
    1.18 +@@ -529,18 +529,21 @@
    1.19 + 			if (strncmp(str_found, pfind, strlen(pfind)))
    1.20 + 				continue;
    1.21 + 			/* not see .name without .match */
    1.22 +-			if (*str_found == '.' && *pfind == 0) {
    1.23 ++			if (*str_found == '.' && *pfind == '\0') {
    1.24 + 				if (NOT_LONE_CHAR(paths[i], '/') || str_found[1])
    1.25 + 					continue;
    1.26 + 				str_found = ""; /* only "/" */
    1.27 + 			}
    1.28 + 			found = concat_path_file(paths[i], str_found);
    1.29 +-			/* hmm, remover in progress? */
    1.30 +-			if (lstat(found, &st) < 0)
    1.31 ++			/* hmm, remove in progress? */
    1.32 ++			/* NB: stat() first so that we see is it a directory;
    1.33 ++			 * but if that fails, use lstat() so that
    1.34 ++			 * we still match dangling links */
    1.35 ++			if (stat(found, &st) && lstat(found, &st))
    1.36 + 				goto cont;
    1.37 + 			/* find with dirs? */
    1.38 + 			if (paths[i] != dirbuf)
    1.39 +-				strcpy(found, next->d_name);    /* only name */
    1.40 ++				strcpy(found, next->d_name); /* only name */
    1.41 + 
    1.42 + 			len1 = strlen(found);
    1.43 + 			found = xrealloc(found, len1 + 2);
    1.44 +@@ -548,7 +551,7 @@
    1.45 + 			found[len1+1] = '\0';
    1.46 + 
    1.47 + 			if (S_ISDIR(st.st_mode)) {
    1.48 +-				/* name is directory      */
    1.49 ++				/* name is a directory */
    1.50 + 				if (found[len1-1] != '/') {
    1.51 + 					found[len1] = '/';
    1.52 + 				}
    1.53 +@@ -566,7 +569,7 @@
    1.54 + 		closedir(dir);
    1.55 + 	}
    1.56 + 	if (paths != path1) {
    1.57 +-		free(paths[0]);                 /* allocated memory only in first member */
    1.58 ++		free(paths[0]); /* allocated memory is only in first member */
    1.59 + 		free(paths);
    1.60 + 	}
    1.61 + #undef dirbuf
    1.62 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-echo.patch
    1.63 +--- busybox-1.10.1/coreutils/echo.c	Sat Apr 19 05:50:32 2008
    1.64 ++++ busybox-1.10.1-echo/coreutils/echo.c	Wed Apr 30 02:37:08 2008
    1.65 +@@ -27,10 +27,8 @@
    1.66 + 
    1.67 + /* This is a NOFORK applet. Be very careful! */
    1.68 + 
    1.69 +-/* argc is unused, but removing it precludes compiler from
    1.70 +- * using call -> jump optimization */
    1.71 ++/* NB: can be used by shell even if not enabled as applet */
    1.72 + 
    1.73 +-int echo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    1.74 + int echo_main(int argc ATTRIBUTE_UNUSED, char **argv)
    1.75 + {
    1.76 + 	const char *arg;
    1.77 +@@ -110,15 +108,19 @@
    1.78 + 				}
    1.79 + #if !ENABLE_FEATURE_FANCY_ECHO
    1.80 + 				/* SUSv3 specifies that octal escapes must begin with '0'. */
    1.81 +-				if ( (((unsigned char)*arg) - '1') >= 7)
    1.82 ++				if ( ((int)(unsigned char)(*arg) - '0') >= 8) /* '8' or bigger */
    1.83 + #endif
    1.84 + 				{
    1.85 + 					/* Since SUSv3 mandates a first digit of 0, 4-digit octals
    1.86 + 					* of the form \0### are accepted. */
    1.87 +-					if (*arg == '0' && ((unsigned char)(arg[1]) - '0') < 8) {
    1.88 +-						arg++;
    1.89 ++					if (*arg == '0') {
    1.90 ++						/* NB: don't turn "...\0" into "...\" */
    1.91 ++						if (arg[1] && ((unsigned char)(arg[1]) - '0') < 8) {
    1.92 ++							arg++;
    1.93 ++						}
    1.94 + 					}
    1.95 +-					/* bb_process_escape_sequence can handle nul correctly */
    1.96 ++					/* bb_process_escape_sequence handles NUL correctly
    1.97 ++					 * ("...\" case). */
    1.98 + 					c = bb_process_escape_sequence(&arg);
    1.99 + 				}
   1.100 + 			}
   1.101 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-fixes-1.10.1.u
   1.102 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-hppa.patch
   1.103 +--- busybox-1.10.1/include/libbb.h	Sat Apr 19 05:50:36 2008
   1.104 ++++ busybox-1.10.1-hppa/include/libbb.h	Mon Apr 28 10:34:36 2008
   1.105 +@@ -288,20 +288,20 @@
   1.106 + 	 * SIGSYS   Bad argument to routine
   1.107 + 	 * SIGTRAP  Trace/breakpoint trap
   1.108 + 	 */
   1.109 +-	BB_FATAL_SIGS = 0
   1.110 +-		+ (1 << SIGHUP)
   1.111 +-		+ (1 << SIGINT)
   1.112 +-		+ (1 << SIGTERM)
   1.113 +-		+ (1 << SIGPIPE)   // Write to pipe with no readers
   1.114 +-		+ (1 << SIGQUIT)   // Quit from keyboard
   1.115 +-		+ (1 << SIGABRT)   // Abort signal from abort(3)
   1.116 +-		+ (1 << SIGALRM)   // Timer signal from alarm(2)
   1.117 +-		+ (1 << SIGVTALRM) // Virtual alarm clock
   1.118 +-		+ (1 << SIGXCPU)   // CPU time limit exceeded
   1.119 +-		+ (1 << SIGXFSZ)   // File size limit exceeded
   1.120 +-		+ (1 << SIGUSR1)   // Yes kids, these are also fatal!
   1.121 +-		+ (1 << SIGUSR2)
   1.122 +-		+ 0,
   1.123 ++	BB_FATAL_SIGS = (int)(0
   1.124 ++		+ (1LL << SIGHUP)
   1.125 ++		+ (1LL << SIGINT)
   1.126 ++		+ (1LL << SIGTERM)
   1.127 ++		+ (1LL << SIGPIPE)   // Write to pipe with no readers
   1.128 ++		+ (1LL << SIGQUIT)   // Quit from keyboard
   1.129 ++		+ (1LL << SIGABRT)   // Abort signal from abort(3)
   1.130 ++		+ (1LL << SIGALRM)   // Timer signal from alarm(2)
   1.131 ++		+ (1LL << SIGVTALRM) // Virtual alarm clock
   1.132 ++		+ (1LL << SIGXCPU)   // CPU time limit exceeded
   1.133 ++		+ (1LL << SIGXFSZ)   // File size limit exceeded
   1.134 ++		+ (1LL << SIGUSR1)   // Yes kids, these are also fatal!
   1.135 ++		+ (1LL << SIGUSR2)
   1.136 ++		+ 0),
   1.137 + };
   1.138 + void bb_signals(int sigs, void (*f)(int));
   1.139 + /* Unlike signal() and bb_signals, sets handler with sigaction()
   1.140 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-httpd.patch
   1.141 +--- busybox-1.10.1/networking/httpd.c	Sat Apr 19 05:50:27 2008
   1.142 ++++ busybox-1.10.1-httpd/networking/httpd.c	Wed May  7 11:19:11 2008
   1.143 +@@ -1457,6 +1457,11 @@
   1.144 + 				}
   1.145 + 			}
   1.146 + #endif
   1.147 ++			/* restore default signal dispositions for CGI process */
   1.148 ++			signal(SIGCHLD, SIG_DFL);
   1.149 ++			signal(SIGPIPE, SIG_DFL);
   1.150 ++			signal(SIGHUP, SIG_DFL);
   1.151 ++
   1.152 + 			execv(fullpath, argv);
   1.153 + 			if (verbose)
   1.154 + 				bb_perror_msg("exec %s", fullpath);
   1.155 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-ioctl.patch
   1.156 +--- busybox-1.10.1/include/libbb.h	Sat Apr 19 05:50:36 2008
   1.157 ++++ busybox-1.10.1-ioctl/include/libbb.h	Thu Apr 24 06:45:03 2008
   1.158 +@@ -995,16 +995,16 @@
   1.159 + /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */
   1.160 + int get_terminal_width_height(int fd, int *width, int *height);
   1.161 + 
   1.162 +-int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
   1.163 +-void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
   1.164 ++int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
   1.165 ++void ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5)));
   1.166 + #if ENABLE_IOCTL_HEX2STR_ERROR
   1.167 +-int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name);
   1.168 +-void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name);
   1.169 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name);
   1.170 ++void bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name);
   1.171 + #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request)
   1.172 + #define xioctl(fd,request,argp)        bb_xioctl(fd,request,argp,#request)
   1.173 + #else
   1.174 +-int bb_ioctl_or_warn(int fd, int request, void *argp);
   1.175 +-void bb_xioctl(int fd, int request, void *argp);
   1.176 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp);
   1.177 ++void bb_xioctl(int fd, unsigned request, void *argp);
   1.178 + #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp)
   1.179 + #define xioctl(fd,request,argp)        bb_xioctl(fd,request,argp)
   1.180 + #endif
   1.181 +--- busybox-1.10.1/libbb/xfuncs.c	Sat Apr 19 05:50:33 2008
   1.182 ++++ busybox-1.10.1-ioctl/libbb/xfuncs.c	Thu Apr 24 06:45:14 2008
   1.183 +@@ -704,7 +704,7 @@
   1.184 + 	return ret;
   1.185 + }
   1.186 + 
   1.187 +-void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...)
   1.188 ++void ioctl_or_perror_and_die(int fd, unsigned request, void *argp, const char *fmt,...)
   1.189 + {
   1.190 + 	va_list p;
   1.191 + 
   1.192 +@@ -717,7 +717,7 @@
   1.193 + 	}
   1.194 + }
   1.195 + 
   1.196 +-int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...)
   1.197 ++int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...)
   1.198 + {
   1.199 + 	va_list p;
   1.200 + 	int ret = ioctl(fd, request, argp);
   1.201 +@@ -731,7 +731,7 @@
   1.202 + }
   1.203 + 
   1.204 + #if ENABLE_IOCTL_HEX2STR_ERROR
   1.205 +-int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name)
   1.206 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp, const char *ioctl_name)
   1.207 + {
   1.208 + 	int ret;
   1.209 + 
   1.210 +@@ -740,13 +740,13 @@
   1.211 + 		bb_simple_perror_msg(ioctl_name);
   1.212 + 	return ret;
   1.213 + }
   1.214 +-void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name)
   1.215 ++void bb_xioctl(int fd, unsigned request, void *argp, const char *ioctl_name)
   1.216 + {
   1.217 + 	if (ioctl(fd, request, argp) < 0)
   1.218 + 		bb_simple_perror_msg_and_die(ioctl_name);
   1.219 + }
   1.220 + #else
   1.221 +-int bb_ioctl_or_warn(int fd, int request, void *argp)
   1.222 ++int bb_ioctl_or_warn(int fd, unsigned request, void *argp)
   1.223 + {
   1.224 + 	int ret;
   1.225 + 
   1.226 +@@ -755,7 +755,7 @@
   1.227 + 		bb_perror_msg("ioctl %#x failed", request);
   1.228 + 	return ret;
   1.229 + }
   1.230 +-void bb_xioctl(int fd, int request, void *argp)
   1.231 ++void bb_xioctl(int fd, unsigned request, void *argp)
   1.232 + {
   1.233 + 	if (ioctl(fd, request, argp) < 0)
   1.234 + 		bb_perror_msg_and_die("ioctl %#x failed", request);
   1.235 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-mdev.patch
   1.236 +--- busybox-1.10.1/util-linux/mdev.c	Sat Apr 19 05:50:39 2008
   1.237 ++++ busybox-1.10.1-mdev/util-linux/mdev.c	Fri May  2 14:48:06 2008
   1.238 +@@ -12,6 +12,8 @@
   1.239 + #include "libbb.h"
   1.240 + #include "xregex.h"
   1.241 + 
   1.242 ++#define ENABLE_FEATURE_MDEV_RENAME_REGEXP 1
   1.243 ++
   1.244 + struct globals {
   1.245 + 	int root_major, root_minor;
   1.246 + };
   1.247 +@@ -21,7 +23,21 @@
   1.248 + 
   1.249 + #define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */
   1.250 + 
   1.251 ++/* We use additional 64+ bytes in make_device() */
   1.252 ++#define SCRATCH_SIZE 80
   1.253 ++
   1.254 ++static char *next_field(char *s)
   1.255 ++{
   1.256 ++	char *end = skip_non_whitespace(s);
   1.257 ++	s = skip_whitespace(end);
   1.258 ++	*end = '\0';
   1.259 ++	if (*s == '\0')
   1.260 ++		s = NULL;
   1.261 ++	return s;
   1.262 ++}
   1.263 ++
   1.264 + /* mknod in /dev based on a path like "/sys/block/hda/hda1" */
   1.265 ++/* NB: "mdev -s" may call us many times, do not leak memory/fds! */
   1.266 + static void make_device(char *path, int delete)
   1.267 + {
   1.268 + 	const char *device_name;
   1.269 +@@ -29,7 +45,7 @@
   1.270 + 	int mode = 0660;
   1.271 + 	uid_t uid = 0;
   1.272 + 	gid_t gid = 0;
   1.273 +-	char *temp = path + strlen(path);
   1.274 ++	char *dev_maj_min = path + strlen(path);
   1.275 + 	char *command = NULL;
   1.276 + 	char *alias = NULL;
   1.277 + 
   1.278 +@@ -42,156 +58,178 @@
   1.279 + 	 * also depend on path having writeable space after it.
   1.280 + 	 */
   1.281 + 	if (!delete) {
   1.282 +-		strcat(path, "/dev");
   1.283 +-		len = open_read_close(path, temp + 1, 64);
   1.284 +-		*temp++ = 0;
   1.285 ++		strcpy(dev_maj_min, "/dev");
   1.286 ++		len = open_read_close(path, dev_maj_min + 1, 64);
   1.287 ++		*dev_maj_min++ = '\0';
   1.288 + 		if (len < 1) {
   1.289 +-			if (ENABLE_FEATURE_MDEV_EXEC)
   1.290 +-				/* no "dev" file, so just try to run script */
   1.291 +-				*temp = 0;
   1.292 +-			else
   1.293 ++			if (!ENABLE_FEATURE_MDEV_EXEC)
   1.294 + 				return;
   1.295 ++			/* no "dev" file, so just try to run script */
   1.296 ++			*dev_maj_min = '\0';
   1.297 + 		}
   1.298 + 	}
   1.299 + 
   1.300 + 	/* Determine device name, type, major and minor */
   1.301 + 	device_name = bb_basename(path);
   1.302 +-	type = (path[5] == 'c' ? S_IFCHR : S_IFBLK);
   1.303 ++	/* http://kernel.org/doc/pending/hotplug.txt says that only
   1.304 ++	 * "/sys/block/..." is for block devices. "sys/bus" etc is not! */
   1.305 ++	type = (strncmp(&path[5], "block/", 6) == 0 ? S_IFBLK : S_IFCHR);
   1.306 + 
   1.307 + 	if (ENABLE_FEATURE_MDEV_CONF) {
   1.308 + 		FILE *fp;
   1.309 +-		char *line, *vline;
   1.310 ++		char *line, *val, *next;
   1.311 + 		unsigned lineno = 0;
   1.312 + 
   1.313 +-		/* If we have a config file, look up the user settings */
   1.314 ++		/* If we have config file, look up user settings */
   1.315 + 		fp = fopen_or_warn("/etc/mdev.conf", "r");
   1.316 + 		if (!fp)
   1.317 + 			goto end_parse;
   1.318 + 
   1.319 +-		while ((vline = line = xmalloc_getline(fp)) != NULL) {
   1.320 +-			int field;
   1.321 ++		while ((line = xmalloc_getline(fp)) != NULL) {
   1.322 ++			regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
   1.323 + 
   1.324 +-			/* A pristine copy for command execution. */
   1.325 +-			char *orig_line;
   1.326 +-			if (ENABLE_FEATURE_MDEV_EXEC)
   1.327 +-				orig_line = xstrdup(line);
   1.328 +-
   1.329 + 			++lineno;
   1.330 ++			trim(line);
   1.331 ++			if (!line[0])
   1.332 ++				goto next_line;
   1.333 + 
   1.334 +-			/* Three fields: regex, uid:gid, mode */
   1.335 +-			for (field = 0; field < (3 + ENABLE_FEATURE_MDEV_RENAME + ENABLE_FEATURE_MDEV_EXEC); ++field) {
   1.336 ++			/* Fields: regex uid:gid mode [alias] [cmd] */
   1.337 + 
   1.338 +-				/* Find a non-empty field */
   1.339 +-				char *val;
   1.340 +-				do {
   1.341 +-					val = strtok(vline, " \t");
   1.342 +-					vline = NULL;
   1.343 +-				} while (val && !*val);
   1.344 +-				if (!val) {
   1.345 +-					if (field)
   1.346 +-						break;
   1.347 +-					else
   1.348 +-						goto next_line;
   1.349 +-				}
   1.350 ++			/* 1st field: regex to match this device */
   1.351 ++			next = next_field(line);
   1.352 ++			{
   1.353 ++				regex_t match;
   1.354 ++				int result;
   1.355 + 
   1.356 +-				if (field == 0) {
   1.357 ++				/* Is this it? */
   1.358 ++				xregcomp(&match, line, REG_EXTENDED);
   1.359 ++				result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0);
   1.360 ++				regfree(&match);
   1.361 + 
   1.362 +-					/* Regex to match this device */
   1.363 +-					regex_t match;
   1.364 +-					regmatch_t off;
   1.365 +-					int result;
   1.366 ++				//bb_error_msg("matches:");
   1.367 ++				//for (int i = 0; i < ARRAY_SIZE(off); i++) {
   1.368 ++				//	if (off[i].rm_so < 0) continue;
   1.369 ++				//	bb_error_msg("match %d: '%.*s'\n", i,
   1.370 ++				//		(int)(off[i].rm_eo - off[i].rm_so),
   1.371 ++				//		device_name + off[i].rm_so);
   1.372 ++				//}
   1.373 + 
   1.374 +-					/* Is this it? */
   1.375 +-					xregcomp(&match, val, REG_EXTENDED);
   1.376 +-					result = regexec(&match, device_name, 1, &off, 0);
   1.377 +-					regfree(&match);
   1.378 ++				/* If not this device, skip rest of line */
   1.379 ++				/* (regexec returns whole pattern as "range" 0) */
   1.380 ++				if (result || off[0].rm_so || off[0].rm_eo != strlen(device_name))
   1.381 ++					goto next_line;
   1.382 ++			}
   1.383 + 
   1.384 +-					/* If not this device, skip rest of line */
   1.385 +-					if (result || off.rm_so || off.rm_eo != strlen(device_name))
   1.386 +-						goto next_line;
   1.387 ++			/* This line matches: stop parsing the file
   1.388 ++			 * after parsing the rest of fields */
   1.389 + 
   1.390 +-				} else if (field == 1) {
   1.391 ++			/* 2nd field: uid:gid - device ownership */
   1.392 ++			if (!next) /* field must exist */
   1.393 ++				bb_error_msg_and_die("bad line %u", lineno);
   1.394 ++			val = next;
   1.395 ++			next = next_field(val);
   1.396 ++			{
   1.397 ++				struct passwd *pass;
   1.398 ++				struct group *grp;
   1.399 ++				char *str_uid = val;
   1.400 ++				char *str_gid = strchrnul(val, ':');
   1.401 + 
   1.402 +-					/* uid:gid device ownership */
   1.403 +-					struct passwd *pass;
   1.404 +-					struct group *grp;
   1.405 ++				if (*str_gid)
   1.406 ++					*str_gid++ = '\0';
   1.407 ++				/* Parse UID */
   1.408 ++				pass = getpwnam(str_uid);
   1.409 ++				if (pass)
   1.410 ++					uid = pass->pw_uid;
   1.411 ++				else
   1.412 ++					uid = strtoul(str_uid, NULL, 10);
   1.413 ++				/* Parse GID */
   1.414 ++				grp = getgrnam(str_gid);
   1.415 ++				if (grp)
   1.416 ++					gid = grp->gr_gid;
   1.417 ++				else
   1.418 ++					gid = strtoul(str_gid, NULL, 10);
   1.419 ++			}
   1.420 + 
   1.421 +-					char *str_uid = val;
   1.422 +-					char *str_gid = strchr(val, ':');
   1.423 +-					if (str_gid)
   1.424 +-						*str_gid = '\0', ++str_gid;
   1.425 ++			/* 3rd field: mode - device permissions */
   1.426 ++			if (!next) /* field must exist */
   1.427 ++				bb_error_msg_and_die("bad line %u", lineno);
   1.428 ++			val = next;
   1.429 ++			next = next_field(val);
   1.430 ++			mode = strtoul(val, NULL, 8);
   1.431 + 
   1.432 +-					/* Parse UID */
   1.433 +-					pass = getpwnam(str_uid);
   1.434 +-					if (pass)
   1.435 +-						uid = pass->pw_uid;
   1.436 +-					else
   1.437 +-						uid = strtoul(str_uid, NULL, 10);
   1.438 ++			/* 4th field (opt): >alias */
   1.439 ++			if (ENABLE_FEATURE_MDEV_RENAME) {
   1.440 ++				if (!next)
   1.441 ++					break;
   1.442 ++				if (*next == '>') {
   1.443 ++#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
   1.444 ++					char *s, *p;
   1.445 ++					unsigned i, n;
   1.446 ++#endif
   1.447 ++					val = next;
   1.448 ++					next = next_field(val);
   1.449 ++#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
   1.450 ++					/* substitute %1..9 with off[1..9], if any */
   1.451 ++					n = 0;
   1.452 ++					s = val;
   1.453 ++					while (*s && *s++ == '%')
   1.454 ++						n++;
   1.455 + 
   1.456 +-					/* parse GID */
   1.457 +-					grp = getgrnam(str_gid);
   1.458 +-					if (grp)
   1.459 +-						gid = grp->gr_gid;
   1.460 +-					else
   1.461 +-						gid = strtoul(str_gid, NULL, 10);
   1.462 +-
   1.463 +-				} else if (field == 2) {
   1.464 +-
   1.465 +-					/* Mode device permissions */
   1.466 +-					mode = strtoul(val, NULL, 8);
   1.467 +-
   1.468 +-				} else if (ENABLE_FEATURE_MDEV_RENAME && field == 3) {
   1.469 +-
   1.470 +-					if (*val != '>')
   1.471 +-						++field;
   1.472 +-					else
   1.473 +-						alias = xstrdup(val + 1);
   1.474 +-
   1.475 ++					p = alias = xzalloc(strlen(val) + n * strlen(device_name));
   1.476 ++					s = val + 1;
   1.477 ++					while (*s) {
   1.478 ++						*p = *s;
   1.479 ++						if ('%' == *s) {
   1.480 ++							i = (s[1] - '0');
   1.481 ++							if (i <= 9 && off[i].rm_so >= 0) {
   1.482 ++								n = off[i].rm_eo - off[i].rm_so;
   1.483 ++								strncpy(p, device_name + off[i].rm_so, n);
   1.484 ++								p += n - 1;
   1.485 ++								s++;
   1.486 ++							}
   1.487 ++						}
   1.488 ++						p++;
   1.489 ++						s++;
   1.490 ++					}
   1.491 ++#else
   1.492 ++					alias = xstrdup(val + 1);
   1.493 ++#endif
   1.494 + 				}
   1.495 ++			}
   1.496 + 
   1.497 +-				if (ENABLE_FEATURE_MDEV_EXEC && field == 3 + ENABLE_FEATURE_MDEV_RENAME) {
   1.498 ++			/* The rest (opt): command to run */
   1.499 ++			if (!next)
   1.500 ++				break;
   1.501 ++			val = next;
   1.502 ++			if (ENABLE_FEATURE_MDEV_EXEC) {
   1.503 ++				const char *s = "@$*";
   1.504 ++				const char *s2 = strchr(s, *val);
   1.505 + 
   1.506 +-					/* Optional command to run */
   1.507 +-					const char *s = "@$*";
   1.508 +-					const char *s2 = strchr(s, *val);
   1.509 ++				if (!s2)
   1.510 ++					bb_error_msg_and_die("bad line %u", lineno);
   1.511 + 
   1.512 +-					if (!s2) {
   1.513 +-						/* Force error */
   1.514 +-						field = 1;
   1.515 +-						break;
   1.516 +-					}
   1.517 +-
   1.518 +-					/* Correlate the position in the "@$*" with the delete
   1.519 +-					 * step so that we get the proper behavior.
   1.520 +-					 */
   1.521 +-					if ((s2 - s + 1) & (1 << delete))
   1.522 +-						command = xstrdup(orig_line + (val + 1 - line));
   1.523 ++				/* Correlate the position in the "@$*" with the delete
   1.524 ++				 * step so that we get the proper behavior:
   1.525 ++				 * @cmd: run on create
   1.526 ++				 * $cmd: run on delete
   1.527 ++				 * *cmd: run on both
   1.528 ++				 */
   1.529 ++				if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) {
   1.530 ++					command = xstrdup(val + 1);
   1.531 + 				}
   1.532 + 			}
   1.533 +-
   1.534 +-			/* Did everything parse happily? */
   1.535 +-			if (field <= 2)
   1.536 +-				bb_error_msg_and_die("bad line %u", lineno);
   1.537 +-
   1.538 ++			/* end of field parsing */
   1.539 ++			break; /* we found matching line, stop */
   1.540 +  next_line:
   1.541 + 			free(line);
   1.542 +-			if (ENABLE_FEATURE_MDEV_EXEC)
   1.543 +-				free(orig_line);
   1.544 +-		}
   1.545 ++		} /* end of "while line is read from /etc/mdev.conf" */
   1.546 + 
   1.547 +-		if (ENABLE_FEATURE_CLEAN_UP)
   1.548 +-			fclose(fp);
   1.549 +-
   1.550 +- end_parse:	/* nothing */ ;
   1.551 ++		free(line); /* in case we used "break" to get here */
   1.552 ++		fclose(fp);
   1.553 + 	}
   1.554 ++ end_parse:
   1.555 + 
   1.556 +-	if (!delete) {
   1.557 +-		if (sscanf(temp, "%d:%d", &major, &minor) != 2) {
   1.558 +-			if (ENABLE_FEATURE_MDEV_EXEC)
   1.559 +-				goto skip_creation;
   1.560 +-			else
   1.561 +-				return;
   1.562 +-		}
   1.563 ++	if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) {
   1.564 + 
   1.565 + 		if (ENABLE_FEATURE_MDEV_RENAME)
   1.566 + 			unlink(device_name);
   1.567 +@@ -208,39 +246,44 @@
   1.568 + 			if (ENABLE_FEATURE_MDEV_RENAME && alias) {
   1.569 + 				char *dest;
   1.570 + 
   1.571 +-				temp = strrchr(alias, '/');
   1.572 +-				if (temp) {
   1.573 +-					if (temp[1] != '\0')
   1.574 +-						/* given a file name, so rename it */
   1.575 +-						*temp = '\0';
   1.576 ++				/* ">bar/": rename to bar/device_name */
   1.577 ++				/* ">bar[/]baz": rename to bar[/]baz */
   1.578 ++				dest = strrchr(alias, '/');
   1.579 ++				if (dest) { /* ">bar/[baz]" ? */
   1.580 ++					*dest = '\0'; /* mkdir bar */
   1.581 + 					bb_make_directory(alias, 0755, FILEUTILS_RECUR);
   1.582 +-					dest = concat_path_file(alias, device_name);
   1.583 +-				} else
   1.584 +-					dest = alias;
   1.585 ++					*dest = '/';
   1.586 ++					if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */
   1.587 ++						dest = alias;
   1.588 ++						alias = concat_path_file(alias, device_name);
   1.589 ++						free(dest);
   1.590 ++					}
   1.591 ++				}
   1.592 + 
   1.593 +-				rename(device_name, dest); // TODO: xrename?
   1.594 +-				symlink(dest, device_name);
   1.595 ++				/* recreate device_name as a symlink to moved device node */
   1.596 ++				if (rename(device_name, alias) == 0) {
   1.597 ++					symlink(alias, device_name);
   1.598 ++				}
   1.599 + 
   1.600 +-				if (alias != dest)
   1.601 +-					free(alias);
   1.602 +-				free(dest);
   1.603 ++				free(alias);
   1.604 + 			}
   1.605 + 		}
   1.606 +- skip_creation: /* nothing */ ;
   1.607 + 	}
   1.608 ++
   1.609 + 	if (ENABLE_FEATURE_MDEV_EXEC && command) {
   1.610 +-		/* setenv will leak memory, so use putenv */
   1.611 ++		/* setenv will leak memory, use putenv/unsetenv/free */
   1.612 + 		char *s = xasprintf("MDEV=%s", device_name);
   1.613 + 		putenv(s);
   1.614 + 		if (system(command) == -1)
   1.615 +-			bb_perror_msg_and_die("cannot run %s", command);
   1.616 ++			bb_perror_msg_and_die("can't run '%s'", command);
   1.617 + 		s[4] = '\0';
   1.618 + 		unsetenv(s);
   1.619 + 		free(s);
   1.620 + 		free(command);
   1.621 + 	}
   1.622 ++
   1.623 + 	if (delete)
   1.624 +-		remove_file(device_name, FILEUTILS_FORCE);
   1.625 ++		unlink(device_name);
   1.626 + }
   1.627 + 
   1.628 + /* File callback for /sys/ traversal */
   1.629 +@@ -249,14 +292,15 @@
   1.630 +                       void *userData,
   1.631 +                       int depth ATTRIBUTE_UNUSED)
   1.632 + {
   1.633 +-	size_t len = strlen(fileName) - 4;
   1.634 ++	size_t len = strlen(fileName) - 4; /* can't underflow */
   1.635 + 	char *scratch = userData;
   1.636 + 
   1.637 +-	if (strcmp(fileName + len, "/dev"))
   1.638 ++	/* len check is for paranoid reasons */
   1.639 ++	if (strcmp(fileName + len, "/dev") || len >= PATH_MAX)
   1.640 + 		return FALSE;
   1.641 + 
   1.642 + 	strcpy(scratch, fileName);
   1.643 +-	scratch[len] = 0;
   1.644 ++	scratch[len] = '\0';
   1.645 + 	make_device(scratch, 0);
   1.646 + 
   1.647 + 	return TRUE;
   1.648 +@@ -287,12 +331,6 @@
   1.649 + 	int cnt;
   1.650 + 	int firmware_fd, loading_fd, data_fd;
   1.651 + 
   1.652 +-	/* check for $FIRMWARE from kernel */
   1.653 +-	/* XXX: dont bother: open(NULL) works same as open("no-such-file")
   1.654 +-	 * if (!firmware)
   1.655 +-	 *	return;
   1.656 +-	 */
   1.657 +-
   1.658 + 	/* check for /lib/firmware/$FIRMWARE */
   1.659 + 	xchdir("/lib/firmware");
   1.660 + 	firmware_fd = xopen(firmware, O_RDONLY);
   1.661 +@@ -304,16 +342,15 @@
   1.662 + 	xchdir(sysfs_path);
   1.663 + 	for (cnt = 0; cnt < 30; ++cnt) {
   1.664 + 		loading_fd = open("loading", O_WRONLY);
   1.665 +-		if (loading_fd == -1)
   1.666 +-			sleep(1);
   1.667 +-		else
   1.668 +-			break;
   1.669 ++		if (loading_fd != -1)
   1.670 ++			goto loading;
   1.671 ++		sleep(1);
   1.672 + 	}
   1.673 +-	if (loading_fd == -1)
   1.674 +-		goto out;
   1.675 ++	goto out;
   1.676 + 
   1.677 ++ loading:
   1.678 + 	/* tell kernel we're loading by `echo 1 > /sys/$DEVPATH/loading` */
   1.679 +-	if (write(loading_fd, "1", 1) != 1)
   1.680 ++	if (full_write(loading_fd, "1", 1) != 1)
   1.681 + 		goto out;
   1.682 + 
   1.683 + 	/* load firmware by `cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data */
   1.684 +@@ -324,9 +361,9 @@
   1.685 + 
   1.686 + 	/* tell kernel result by `echo [0|-1] > /sys/$DEVPATH/loading` */
   1.687 + 	if (cnt > 0)
   1.688 +-		write(loading_fd, "0", 1);
   1.689 ++		full_write(loading_fd, "0", 1);
   1.690 + 	else
   1.691 +-		write(loading_fd, "-1", 2);
   1.692 ++		full_write(loading_fd, "-1", 2);
   1.693 + 
   1.694 +  out:
   1.695 + 	if (ENABLE_FEATURE_CLEAN_UP) {
   1.696 +@@ -341,16 +378,14 @@
   1.697 + {
   1.698 + 	char *action;
   1.699 + 	char *env_path;
   1.700 +-	RESERVE_CONFIG_BUFFER(temp,PATH_MAX);
   1.701 ++	RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE);
   1.702 + 
   1.703 + 	xchdir("/dev");
   1.704 + 
   1.705 +-	if (argc == 2 && !strcmp(argv[1],"-s")) {
   1.706 +-
   1.707 ++	if (argc == 2 && !strcmp(argv[1], "-s")) {
   1.708 + 		/* Scan:
   1.709 + 		 * mdev -s
   1.710 + 		 */
   1.711 +-
   1.712 + 		struct stat st;
   1.713 + 
   1.714 + 		xstat("/", &st);
   1.715 +@@ -366,26 +401,27 @@
   1.716 + 			fileAction, dirAction, temp, 0);
   1.717 + 
   1.718 + 	} else {
   1.719 +-
   1.720 + 		/* Hotplug:
   1.721 + 		 * env ACTION=... DEVPATH=... mdev
   1.722 + 		 * ACTION can be "add" or "remove"
   1.723 + 		 * DEVPATH is like "/block/sda" or "/class/input/mice"
   1.724 + 		 */
   1.725 +-
   1.726 + 		action = getenv("ACTION");
   1.727 + 		env_path = getenv("DEVPATH");
   1.728 + 		if (!action || !env_path)
   1.729 + 			bb_show_usage();
   1.730 + 
   1.731 +-		sprintf(temp, "/sys%s", env_path);
   1.732 ++		snprintf(temp, PATH_MAX, "/sys%s", env_path);
   1.733 + 		if (!strcmp(action, "remove"))
   1.734 + 			make_device(temp, 1);
   1.735 + 		else if (!strcmp(action, "add")) {
   1.736 + 			make_device(temp, 0);
   1.737 + 
   1.738 +-			if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE)
   1.739 +-				load_firmware(getenv("FIRMWARE"), temp);
   1.740 ++			if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) {
   1.741 ++				char *fw = getenv("FIRMWARE");
   1.742 ++				if (fw)
   1.743 ++					load_firmware(fw, temp);
   1.744 ++			}
   1.745 + 		}
   1.746 + 	}
   1.747 + 
   1.748 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-pidof.patch
   1.749 +--- busybox-1.10.1/libbb/procps.c	Sat Apr 19 05:50:33 2008
   1.750 ++++ busybox-1.10.1-pidof/libbb/procps.c	Sat Apr 26 01:18:32 2008
   1.751 +@@ -258,7 +258,7 @@
   1.752 + 				&sp->start_time,
   1.753 + 				&vsz,
   1.754 + 				&rss);
   1.755 +-			if (n != 10)
   1.756 ++			if (n != 11)
   1.757 + 				break;
   1.758 + 			/* vsz is in bytes and we want kb */
   1.759 + 			sp->vsz = vsz >> 10;
   1.760 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-ssd.patch
   1.761 +--- busybox-1.10.1/debianutils/start_stop_daemon.c	Sat Apr 19 05:50:30 2008
   1.762 ++++ busybox-1.10.1-ssd/debianutils/start_stop_daemon.c	Tue Apr 22 03:13:13 2008
   1.763 +@@ -11,7 +11,6 @@
   1.764 + /* NB: we have a problem here with /proc/NN/exe usage, similar to
   1.765 +  * one fixed in killall/pidof */
   1.766 + 
   1.767 +-#include <getopt.h>
   1.768 + #include <sys/resource.h>
   1.769 + 
   1.770 + /* Override ENABLE_FEATURE_PIDFILE */
   1.771 +@@ -33,6 +32,7 @@
   1.772 + 	int user_id;
   1.773 + 	smallint quiet;
   1.774 + 	smallint signal_nr;
   1.775 ++	struct stat execstat;
   1.776 + };
   1.777 + #define G (*(struct globals*)&bb_common_bufsiz1)
   1.778 + #define found             (G.found               )
   1.779 +@@ -43,6 +43,7 @@
   1.780 + #define user_id           (G.user_id             )
   1.781 + #define quiet             (G.quiet               )
   1.782 + #define signal_nr         (G.signal_nr           )
   1.783 ++#define execstat          (G.execstat            )
   1.784 + #define INIT_G() \
   1.785 +         do { \
   1.786 + 		user_id = -1; \
   1.787 +@@ -50,25 +51,21 @@
   1.788 +         } while (0)
   1.789 + 
   1.790 + 
   1.791 +-static int pid_is_exec(pid_t pid, const char *name)
   1.792 ++static int pid_is_exec(pid_t pid)
   1.793 + {
   1.794 ++	struct stat st;
   1.795 + 	char buf[sizeof("/proc//exe") + sizeof(int)*3];
   1.796 +-	char *execbuf;
   1.797 +-	int n;
   1.798 + 
   1.799 + 	sprintf(buf, "/proc/%u/exe", pid);
   1.800 +-	n = strlen(name) + 1;
   1.801 +-	execbuf = xzalloc(n + 1);
   1.802 +-	readlink(buf, execbuf, n);
   1.803 +-	/* if readlink fails because link target is longer than strlen(name),
   1.804 +-	 * execbuf still contains "", and strcmp will return !0. */
   1.805 +-	n = strcmp(execbuf, name);
   1.806 +-	if (ENABLE_FEATURE_CLEAN_UP)
   1.807 +-		free(execbuf);
   1.808 +-	return !n; /* nonzero (true) if execbuf == name */
   1.809 ++	if (stat(buf, &st) < 0)
   1.810 ++		return 0;
   1.811 ++	if (st.st_dev == execstat.st_dev
   1.812 ++	 && st.st_ino == execstat.st_ino)
   1.813 ++		return 1;
   1.814 ++	return 0;
   1.815 + }
   1.816 + 
   1.817 +-static int pid_is_user(int pid, int uid)
   1.818 ++static int pid_is_user(int pid)
   1.819 + {
   1.820 + 	struct stat sb;
   1.821 + 	char buf[sizeof("/proc/") + sizeof(int)*3];
   1.822 +@@ -76,42 +73,39 @@
   1.823 + 	sprintf(buf, "/proc/%u", pid);
   1.824 + 	if (stat(buf, &sb) != 0)
   1.825 + 		return 0;
   1.826 +-	return (sb.st_uid == uid);
   1.827 ++	return (sb.st_uid == user_id);
   1.828 + }
   1.829 + 
   1.830 +-static int pid_is_cmd(pid_t pid, const char *name)
   1.831 ++static int pid_is_cmd(pid_t pid)
   1.832 + {
   1.833 +-	char fname[sizeof("/proc//stat") + sizeof(int)*3];
   1.834 +-	char *buf;
   1.835 +-	int r = 0;
   1.836 ++	char buf[256]; /* is it big enough? */
   1.837 ++	char *p, *pe;
   1.838 + 
   1.839 +-	sprintf(fname, "/proc/%u/stat", pid);
   1.840 +-	buf = xmalloc_open_read_close(fname, NULL);
   1.841 +-	if (buf) {
   1.842 +-		char *p = strchr(buf, '(');
   1.843 +-		if (p) {
   1.844 +-			char *pe = strrchr(++p, ')');
   1.845 +-			if (pe) {
   1.846 +-				*pe = '\0';
   1.847 +-				r = !strcmp(p, name);
   1.848 +-			}
   1.849 +-		}
   1.850 +-		free(buf);
   1.851 +-	}
   1.852 +-	return r;
   1.853 ++	sprintf(buf, "/proc/%u/stat", pid);
   1.854 ++	if (open_read_close(buf, buf, sizeof(buf) - 1) < 0)
   1.855 ++		return 0;
   1.856 ++	buf[sizeof(buf) - 1] = '\0'; /* paranoia */
   1.857 ++	p = strchr(buf, '(');
   1.858 ++	if (!p)
   1.859 ++		return 0;
   1.860 ++	pe = strrchr(++p, ')');
   1.861 ++	if (!pe)
   1.862 ++		return 0;
   1.863 ++	*pe = '\0';
   1.864 ++	return !strcmp(p, cmdname);
   1.865 + }
   1.866 + 
   1.867 + static void check(int pid)
   1.868 + {
   1.869 + 	struct pid_list *p;
   1.870 + 
   1.871 +-	if (execname && !pid_is_exec(pid, execname)) {
   1.872 ++	if (execname && !pid_is_exec(pid)) {
   1.873 + 		return;
   1.874 + 	}
   1.875 +-	if (userspec && !pid_is_user(pid, user_id)) {
   1.876 ++	if (userspec && !pid_is_user(pid)) {
   1.877 + 		return;
   1.878 + 	}
   1.879 +-	if (cmdname && !pid_is_cmd(pid, cmdname)) {
   1.880 ++	if (cmdname && !pid_is_cmd(pid)) {
   1.881 + 		return;
   1.882 + 	}
   1.883 + 	p = xmalloc(sizeof(*p));
   1.884 +@@ -148,9 +142,16 @@
   1.885 + 	procdir = xopendir("/proc");
   1.886 + 
   1.887 + 	pid = 0;
   1.888 +-	while ((entry = readdir(procdir)) != NULL) {
   1.889 ++	while(1) {
   1.890 ++		errno = 0; /* clear any previous error */
   1.891 ++		entry = readdir(procdir);
   1.892 ++// TODO: check for exact errno(s) which mean that we got stale entry
   1.893 ++		if (errno) /* Stale entry, process has died after opendir */
   1.894 ++			continue;
   1.895 ++		if (!entry) /* EOF, no more entries */
   1.896 ++			break;
   1.897 + 		pid = bb_strtou(entry->d_name, NULL, 10);
   1.898 +-		if (errno)
   1.899 ++		if (errno) /* NaN */
   1.900 + 			continue;
   1.901 + 		check(pid);
   1.902 + 	}
   1.903 +@@ -165,8 +166,6 @@
   1.904 + 	struct pid_list *p;
   1.905 + 	int killed = 0;
   1.906 + 
   1.907 +-	do_procinit();
   1.908 +-
   1.909 + 	if (cmdname) {
   1.910 + 		if (ENABLE_FEATURE_CLEAN_UP) what = xstrdup(cmdname);
   1.911 + 		if (!ENABLE_FEATURE_CLEAN_UP) what = cmdname;
   1.912 +@@ -251,7 +250,7 @@
   1.913 + };
   1.914 + 
   1.915 + int start_stop_daemon_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
   1.916 +-int start_stop_daemon_main(int argc, char **argv)
   1.917 ++int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv)
   1.918 + {
   1.919 + 	unsigned opt;
   1.920 + 	char *signame;
   1.921 +@@ -293,7 +292,7 @@
   1.922 + //		if (retry_arg)
   1.923 + //			retries = xatoi_u(retry_arg);
   1.924 + //	)
   1.925 +-	argc -= optind;
   1.926 ++	//argc -= optind;
   1.927 + 	argv += optind;
   1.928 + 
   1.929 + 	if (userspec) {
   1.930 +@@ -301,13 +300,15 @@
   1.931 + 		if (errno)
   1.932 + 			user_id = xuname2uid(userspec);
   1.933 + 	}
   1.934 ++	if (execname)
   1.935 ++		xstat(execname, &execstat);
   1.936 + 
   1.937 ++	do_procinit(); /* Both start and stop needs to know current processes */
   1.938 ++
   1.939 + 	if (opt & CTX_STOP) {
   1.940 + 		int i = do_stop();
   1.941 + 		return (opt & OPT_OKNODO) ? 0 : (i <= 0);
   1.942 + 	}
   1.943 +-
   1.944 +-	do_procinit();
   1.945 + 
   1.946 + 	if (found) {
   1.947 + 		if (!quiet)
   1.948 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-taskset.patch
   1.949 +--- busybox-1.10.1/miscutils/taskset.c	Sat Apr 19 06:03:13 2008
   1.950 ++++ busybox-1.10.1-taskset/miscutils/taskset.c	Fri Apr 25 18:58:53 2008
   1.951 +@@ -94,8 +94,10 @@
   1.952 + 		unsigned i;
   1.953 + 		/* Do not allow zero mask: */
   1.954 + 		unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
   1.955 ++		enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 };
   1.956 ++
   1.957 + 		CPU_ZERO(&mask);
   1.958 +-		for (i = 0; i < CPU_SETSIZE; i++) {
   1.959 ++		for (i = 0; i < CNT_BIT; i++) {
   1.960 + 			unsigned long long bit = (1ULL << i);
   1.961 + 			if (bit & m)
   1.962 + 				CPU_SET(i, &mask);
   1.963 +http://busybox.net/downloads/fixes-1.10.1/busybox-1.10.1-trylink.patch
   1.964 +--- busybox-1.10.1/scripts/trylink	Sat Apr 19 05:50:27 2008
   1.965 ++++ busybox-1.10.1-trylink/scripts/trylink	Wed Apr 30 02:10:19 2008
   1.966 +@@ -66,7 +66,7 @@
   1.967 + 	#if defined(__GLIBC__) && !defined(__UCLIBC__)
   1.968 + 	syntax error here
   1.969 + 	#endif
   1.970 +-	" >"$tempname"
   1.971 ++	" >"$tempname".c
   1.972 +     if $CC "$tempname".c -c -o "$tempname".o >/dev/null 2>&1; then
   1.973 + 	echo "$2";
   1.974 +     else