Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/libbb
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- Location:
- branches/3.2/mindi-busybox/libbb
- Files:
-
- 56 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/libbb/Config.src
r2725 r3232 15 15 Minimum allowable password length. 16 16 17 config MD5_S IZE_VS_SPEED17 config MD5_SMALL 18 18 int "MD5: Trade bytes for speed (0:fast, 3:slow)" 19 default 219 default 1 20 20 range 0 3 21 21 help … … 29 29 3 (smallest) 5.1 4912 30 30 31 config SHA3_SMALL 32 int "SHA3: Trade bytes for speed (0:fast, 1:slow)" 33 default 1 34 range 0 1 35 help 36 Trade binary size versus speed for the sha3sum algorithm. 37 SHA3_SMALL=0 compared to SHA3_SMALL=1 (approximate): 38 64-bit x86: +270 bytes of code, 45% faster 39 32-bit x86: +450 bytes of code, 75% faster 40 31 41 config FEATURE_FAST_TOP 32 42 bool "Faster /proc scanning code (+100 bytes)" … … 81 91 config FEATURE_EDITING_HISTORY 82 92 int "History size" 83 range 0 99999 93 # Don't allow way too big values here, code uses fixed "char *history[N]" struct member 94 range 0 9999 84 95 default 255 85 96 depends on FEATURE_EDITING 86 97 help 87 Specify command history size .98 Specify command history size (0 - disable). 88 99 89 100 config FEATURE_EDITING_SAVEHISTORY … … 93 104 help 94 105 Enable history saving in shells. 106 107 config FEATURE_EDITING_SAVE_ON_EXIT 108 bool "Save history on shell exit, not after every command" 109 default n 110 depends on FEATURE_EDITING_SAVEHISTORY 111 help 112 Save history on shell exit, not after every command. 113 114 config FEATURE_REVERSE_SEARCH 115 bool "Reverse history search" 116 default y 117 depends on FEATURE_EDITING_SAVEHISTORY 118 help 119 Enable readline-like Ctrl-R combination for reverse history search. 120 Increases code by about 0.5k. 95 121 96 122 config FEATURE_TAB_COMPLETION … … 136 162 but prevents a symlink attack. 137 163 Similarly, "cp file device" will not send file's data 138 to the device. 164 to the device. (To do that, use "cat file >device") 139 165 140 166 config FEATURE_VERBOSE_CP_MESSAGE … … 157 183 default 4 158 184 help 159 Size of buffer used by cp, mv, install etc.185 Size of buffer used by cp, mv, install, wget etc. 160 186 Buffers which are 4 kb or less will be allocated on stack. 161 187 Bigger buffers will be allocated with mmap, with fallback to 4 kb 162 188 stack buffer if mmap fails. 163 189 190 config FEATURE_SKIP_ROOTFS 191 bool "Skip rootfs in mount table" 192 default y 193 help 194 Ignore rootfs entry in mount table. 195 196 In Linux, kernel has a special filesystem, rootfs, which is initially 197 mounted on /. It contains initramfs data, if kernel is configured 198 to have one. Usually, another file system is mounted over / early 199 in boot process, and therefore most tools which manipulate 200 mount table, such as df, will skip rootfs entry. 201 202 However, some systems do not mount anything on /. 203 If you need to configure busybox for one of these systems, 204 you may find it useful to turn this option off to make df show 205 initramfs statistics. 206 207 Otherwise, choose Y. 208 164 209 config MONOTONIC_SYSCALL 165 210 bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" 166 211 default n 167 depends onPLATFORM_LINUX212 select PLATFORM_LINUX 168 213 help 169 214 Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring -
branches/3.2/mindi-busybox/libbb/Kbuild.src
r2725 r3232 14 14 lib-y += ask_confirmation.o 15 15 lib-y += bb_askpass.o 16 lib-y += bb_basename.o17 16 lib-y += bb_bswap_64.o 18 17 lib-y += bb_do_delay.o … … 60 59 lib-y += make_directory.o 61 60 lib-y += makedev.o 62 lib-y += match_fstype.o63 61 lib-y += hash_md5_sha.o 64 62 # Alternative (disabled) MD5 implementation … … 66 64 lib-y += messages.o 67 65 lib-y += mode_string.o 68 lib-y += obscure.o69 66 lib-y += parse_mode.o 70 lib-y += parse_config.o71 67 lib-y += perror_msg.o 72 68 lib-y += perror_nomsg.o … … 102 98 lib-y += trim.o 103 99 lib-y += u_signal_names.o 104 lib-y += udp_io.o105 100 lib-y += uuencode.o 106 101 lib-y += vdprintf.o … … 121 116 lib-y += xrealloc_vector.o 122 117 118 lib-$(CONFIG_PLATFORM_LINUX) += match_fstype.o 119 123 120 lib-$(CONFIG_FEATURE_UTMP) += utmp.o 124 121 … … 130 127 lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o 131 128 129 lib-$(CONFIG_NC) += udp_io.o 130 lib-$(CONFIG_DNSD) += udp_io.o 131 lib-$(CONFIG_NTPD) += udp_io.o 132 lib-$(CONFIG_TFTP) += udp_io.o 133 lib-$(CONFIG_TFTPD) += udp_io.o 134 lib-$(CONFIG_TCPSVD) += udp_io.o 135 lib-$(CONFIG_UDPSVD) += udp_io.o 136 lib-$(CONFIG_TRACEROUTE) += udp_io.o 137 132 138 lib-$(CONFIG_LOSETUP) += loop.o 133 139 lib-$(CONFIG_FEATURE_MOUNT_LOOP) += loop.o … … 138 144 lib-$(CONFIG_DELUSER) += update_passwd.o 139 145 140 lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o 146 lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o 141 147 lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o 142 148 lib-$(CONFIG_CRYPTPW) += pw_encrypt.o … … 161 167 lib-$(CONFIG_POWERTOP) += get_cpu_count.o 162 168 169 lib-$(CONFIG_PING) += inet_cksum.o 170 lib-$(CONFIG_TRACEROUTE) += inet_cksum.o 171 lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o 172 lib-$(CONFIG_UDHCPC) += inet_cksum.o 173 lib-$(CONFIG_UDHCPC6) += inet_cksum.o 174 lib-$(CONFIG_UDHCPD) += inet_cksum.o 175 163 176 # We shouldn't build xregcomp.c if we don't need it - this ensures we don't 164 177 # require regex.h to be in the include dir even if we don't need it thereby -
branches/3.2/mindi-busybox/libbb/appletlib.c
r2725 r3232 28 28 */ 29 29 #include "busybox.h" 30 #include <assert.h> 31 #include <malloc.h> 32 /* Try to pull in PAGE_SIZE */ 33 #ifdef __linux__ 34 # include <sys/user.h> 35 #endif 36 #ifdef __GNU__ /* Hurd */ 37 # include <mach/vm_param.h> 30 31 #if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ 32 || defined(__APPLE__) \ 33 ) 34 # include <malloc.h> /* for mallopt */ 38 35 #endif 39 36 … … 43 40 #include "applets.h" 44 41 #undef PROTOTYPES 45 46 42 47 43 /* Include generated applet names, pointers to <applet>_main, etc */ … … 55 51 #endif 56 52 57 58 53 #include "usage_compressed.h" 54 59 55 60 56 #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE … … 67 63 68 64 static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 69 # include " archive.h"65 # include "bb_archive.h" 70 66 static const char *unpack_usage_messages(void) 71 67 { … … 145 141 146 142 #if NUM_APPLETS > 8 147 /* NB: any char pointer will work as well, not necessarily applet_names */ 148 static int applet_name_compare(const void *name, const void *v) 149 { 150 int i = (const char *)v - applet_names; 143 static int applet_name_compare(const void *name, const void *idx) 144 { 145 int i = (int)(ptrdiff_t)idx - 1; 151 146 return strcmp(name, APPLET_NAME(i)); 152 147 } … … 157 152 /* Do a binary search to find the applet entry given the name. */ 158 153 const char *p; 159 p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare); 160 if (!p) 161 return -1; 162 return p - applet_names; 154 p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare); 155 /* 156 * if (!p) return -1; 157 * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :) 158 */ 159 return (int)(ptrdiff_t)p - 1; 163 160 #else 164 161 /* A version which does not pull in bsearch */ … … 228 225 IF_FEATURE_SUID(static uid_t ruid;) /* real uid */ 229 226 230 #if ENABLE_FEATURE_SUID_CONFIG 231 232 /* applets[] is const, so we have to define this "override" structure */ 233 static struct BB_suid_config { 227 # if ENABLE_FEATURE_SUID_CONFIG 228 229 static struct suid_config_t { 230 /* next ptr must be first: this struct needs to be llist-compatible */ 231 struct suid_config_t *m_next; 232 struct bb_uidgid_t m_ugid; 234 233 int m_applet; 235 uid_t m_uid;236 gid_t m_gid;237 234 mode_t m_mode; 238 struct BB_suid_config *m_next;239 235 } *suid_config; 240 236 … … 245 241 { 246 242 struct group *grp = getgrgid(g); 247 248 243 if (grp) { 249 244 char **mem; 250 251 245 for (mem = grp->gr_mem; *mem; mem++) { 252 246 struct passwd *pwd = getpwnam(*mem); 253 254 247 if (pwd && (pwd->pw_uid == u)) 255 248 return 1; … … 259 252 } 260 253 261 /* This should probably be a libbb routine. In that case, 262 * I'd probably rename it to something like bb_trimmed_slice. 263 */ 254 /* libbb candidate */ 264 255 static char *get_trimmed_slice(char *s, char *e) 265 256 { … … 279 270 } 280 271 281 /* Don't depend on the tools to combine strings. */282 static const char config_file[] ALIGN1 = "/etc/busybox.conf";283 284 /* We don't supply a value for the nul, so an index adjustment is285 * necessary below. Also, we use unsigned short here to save some286 * space even though these are really mode_t values. */287 static const unsigned short mode_mask[] ALIGN2 = {288 /* SST sst xxx --- */289 S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* user */290 S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* group */291 0, S_IXOTH, S_IXOTH, 0 /* other */292 };293 294 #define parse_error(x) do { errmsg = x; goto pe_label; } while (0)295 296 272 static void parse_config_file(void) 297 273 { 298 struct BB_suid_config *sct_head; 299 struct BB_suid_config *sct; 274 /* Don't depend on the tools to combine strings. */ 275 static const char config_file[] ALIGN1 = "/etc/busybox.conf"; 276 277 struct suid_config_t *sct_head; 300 278 int applet_no; 301 279 FILE *f; 302 280 const char *errmsg; 303 char *s;304 char *e;305 int i;306 281 unsigned lc; 307 282 smallint section; 308 char buffer[256];309 283 struct stat st; 310 311 assert(!suid_config); /* Should be set to NULL by bss init. */312 284 313 285 ruid = getuid(); … … 319 291 || (st.st_uid != 0) /* Not owned by root? */ 320 292 || (st.st_mode & (S_IWGRP | S_IWOTH)) /* Writable by non-root? */ 321 || !(f = fopen_for_read(config_file)) 293 || !(f = fopen_for_read(config_file)) /* Cannot open? */ 322 294 ) { 323 295 return; … … 329 301 330 302 while (1) { 331 s = buffer; 332 333 if (!fgets(s, sizeof(buffer), f)) { /* Are we done? */ 334 // why? 335 if (ferror(f)) { /* Make sure it wasn't a read error. */ 336 parse_error("reading"); 337 } 303 char buffer[256]; 304 char *s; 305 306 if (!fgets(buffer, sizeof(buffer), f)) { /* Are we done? */ 307 // Looks like bloat 308 //if (ferror(f)) { /* Make sure it wasn't a read error. */ 309 // errmsg = "reading"; 310 // goto pe_label; 311 //} 338 312 fclose(f); 339 313 suid_config = sct_head; /* Success, so set the pointer. */ … … 341 315 } 342 316 317 s = buffer; 343 318 lc++; /* Got a (partial) line. */ 344 319 … … 352 327 * too long if it did end with a newline. */ 353 328 if (!strchr(s, '\n') && !feof(f)) { 354 parse_error("line too long"); 329 errmsg = "line too long"; 330 goto pe_label; 355 331 } 356 332 … … 368 344 * whitespace for the section name. We also require that 369 345 * there are no stray characters after the closing bracket. */ 370 e = strchr(s, ']');346 char *e = strchr(s, ']'); 371 347 if (!e /* Missing right bracket? */ 372 348 || e[1] /* Trailing characters? */ 373 349 || !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */ 374 350 ) { 375 parse_error("section header"); 351 errmsg = "section header"; 352 goto pe_label; 376 353 } 377 354 /* Right now we only have one section so just check it. … … 398 375 399 376 /* First get the key (an applet name in our case). */ 400 e = strchr(s, '=');377 char *e = strchr(s, '='); 401 378 if (e) { 402 379 s = get_trimmed_slice(s, e); 403 380 } 404 381 if (!e || !*s) { /* Missing '=' or empty key. */ 405 parse_error("keyword"); 382 errmsg = "keyword"; 383 goto pe_label; 406 384 } 407 385 … … 412 390 applet_no = find_applet_by_name(s); 413 391 if (applet_no >= 0) { 392 unsigned i; 393 struct suid_config_t *sct; 394 414 395 /* Note: We currently don't check for duplicates! 415 396 * The last config line for each applet will be the 416 397 * one used since we insert at the head of the list. 417 398 * I suppose this could be considered a feature. */ 418 sct = x malloc(sizeof(struct BB_suid_config));399 sct = xzalloc(sizeof(*sct)); 419 400 sct->m_applet = applet_no; 420 sct->m_mode = 0;401 /*sct->m_mode = 0;*/ 421 402 sct->m_next = sct_head; 422 403 sct_head = sct; … … 427 408 428 409 for (i = 0; i < 3; i++) { 429 /* There are 4 chars + 1 nul for each of user/group/other. */ 430 static const char mode_chars[] ALIGN1 = "Ssx-\0" "Ssx-\0" "Ttx-"; 431 432 const char *q; 433 q = strchrnul(mode_chars + 5*i, *e++); 434 if (!*q) { 435 parse_error("mode"); 410 /* There are 4 chars for each of user/group/other. 411 * "x-xx" instead of "x-" are to make 412 * "idx > 3" check catch invalid chars. 413 */ 414 static const char mode_chars[] ALIGN1 = "Ssx-" "Ssx-" "x-xx"; 415 static const unsigned short mode_mask[] ALIGN2 = { 416 S_ISUID, S_ISUID|S_IXUSR, S_IXUSR, 0, /* Ssx- */ 417 S_ISGID, S_ISGID|S_IXGRP, S_IXGRP, 0, /* Ssx- */ 418 S_IXOTH, 0 /* x- */ 419 }; 420 const char *q = strchrnul(mode_chars + 4*i, *e); 421 unsigned idx = q - (mode_chars + 4*i); 422 if (idx > 3) { 423 errmsg = "mode"; 424 goto pe_label; 436 425 } 437 /* Adjust by -i to account for nul. */438 sct->m_mode |= mode_mask[(q - mode_chars) - i];426 sct->m_mode |= mode_mask[q - mode_chars]; 427 e++; 439 428 } 440 429 441 /* Now get the theuser/group info. */430 /* Now get the user/group info. */ 442 431 443 432 s = skip_whitespace(e); 444 445 /* Note: we require whitespace between the mode and the 446 * user/group info. */ 447 if ((s == e) || !(e = strchr(s, '.'))) { 448 parse_error("<uid>.<gid>"); 449 } 450 *e++ = '\0'; 451 452 /* We can't use get_ug_id here since it would exit() 453 * if a uid or gid was not found. Oh well... */ 454 sct->m_uid = bb_strtoul(s, NULL, 10); 455 if (errno) { 456 struct passwd *pwd = getpwnam(s); 457 if (!pwd) { 458 parse_error("user"); 433 /* Default is 0.0, else parse USER.GROUP: */ 434 if (*s) { 435 /* We require whitespace between mode and USER.GROUP */ 436 if ((s == e) || !(e = strchr(s, '.'))) { 437 errmsg = "uid.gid"; 438 goto pe_label; 459 439 } 460 sct->m_uid = pwd->pw_uid; 461 } 462 463 sct->m_gid = bb_strtoul(e, NULL, 10); 464 if (errno) { 465 struct group *grp; 466 grp = getgrnam(e); 467 if (!grp) { 468 parse_error("group"); 440 *e = ':'; /* get_uidgid needs USER:GROUP syntax */ 441 if (get_uidgid(&sct->m_ugid, s, /*allow_numeric:*/ 1) == 0) { 442 errmsg = "unknown user/group"; 443 goto pe_label; 469 444 } 470 sct->m_gid = grp->gr_gid;471 445 } 472 446 } … … 482 456 * are used in some future version of busybox. */ 483 457 if (!section) { 484 parse_error("keyword outside section"); 458 errmsg = "keyword outside section"; 459 goto pe_label; 485 460 } 486 461 … … 488 463 489 464 pe_label: 490 fprintf(stderr, "Parse error in %s, line %d: %s\n",491 config_file, lc, errmsg);492 493 465 fclose(f); 466 bb_error_msg("parse error in %s, line %u: %s", config_file, lc, errmsg); 467 494 468 /* Release any allocated memory before returning. */ 495 while (sct_head) { 496 sct = sct_head->m_next; 497 free(sct_head); 498 sct_head = sct; 499 } 500 } 501 #else 469 llist_free((llist_t*)sct_head, NULL); 470 } 471 # else 502 472 static inline void parse_config_file(void) 503 473 { 504 474 IF_FEATURE_SUID(ruid = getuid();) 505 475 } 506 # endif /* FEATURE_SUID_CONFIG */507 508 509 # if ENABLE_FEATURE_SUID476 # endif /* FEATURE_SUID_CONFIG */ 477 478 479 # if ENABLE_FEATURE_SUID 510 480 static void check_suid(int applet_no) 511 481 { … … 516 486 rgid = getgid(); 517 487 518 # if ENABLE_FEATURE_SUID_CONFIG488 # if ENABLE_FEATURE_SUID_CONFIG 519 489 if (suid_cfg_readable) { 520 490 uid_t uid; 521 struct BB_suid_config*sct;491 struct suid_config_t *sct; 522 492 mode_t m; 523 493 … … 528 498 goto check_need_suid; 529 499 found: 500 /* Is this user allowed to run this applet? */ 530 501 m = sct->m_mode; 531 if (sct->m_u id == ruid)502 if (sct->m_ugid.uid == ruid) 532 503 /* same uid */ 533 504 m >>= 6; 534 else if ((sct->m_ gid == rgid) || ingroup(ruid, sct->m_gid))505 else if ((sct->m_ugid.gid == rgid) || ingroup(ruid, sct->m_ugid.gid)) 535 506 /* same group / in group */ 536 507 m >>= 3; 537 538 if (!(m & S_IXOTH)) /* is x bit not set ? */ 539 bb_error_msg_and_die("you have no permission to run this applet!"); 540 541 /* _both_ sgid and group_exec have to be set for setegid */ 542 if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) 543 rgid = sct->m_gid; 544 /* else (no setegid) we will set egid = rgid */ 508 if (!(m & S_IXOTH)) /* is x bit not set? */ 509 bb_error_msg_and_die("you have no permission to run this applet"); 545 510 546 511 /* We set effective AND saved ids. If saved-id is not set 547 * like we do below, seteiud(0) can still later succeed! */ 512 * like we do below, seteuid(0) can still later succeed! */ 513 514 /* Are we directed to change gid 515 * (APPLET = *s* USER.GROUP or APPLET = *S* USER.GROUP)? 516 */ 517 if (sct->m_mode & S_ISGID) 518 rgid = sct->m_ugid.gid; 519 /* else: we will set egid = rgid, thus dropping sgid effect */ 548 520 if (setresgid(-1, rgid, rgid)) 549 521 bb_perror_msg_and_die("setresgid"); 550 522 551 /* do we have to set effective uid? */ 523 /* Are we directed to change uid 524 * (APPLET = s** USER.GROUP or APPLET = S** USER.GROUP)? 525 */ 552 526 uid = ruid; 553 527 if (sct->m_mode & S_ISUID) 554 uid = sct->m_uid; 555 /* else (no seteuid) we will set euid = ruid */ 556 528 uid = sct->m_ugid.uid; 529 /* else: we will set euid = ruid, thus dropping suid effect */ 557 530 if (setresuid(-1, uid, uid)) 558 531 bb_perror_msg_and_die("setresuid"); 559 return; 560 } 561 #if !ENABLE_FEATURE_SUID_CONFIG_QUIET 532 533 goto ret; 534 } 535 # if !ENABLE_FEATURE_SUID_CONFIG_QUIET 562 536 { 563 537 static bool onetime = 0; … … 565 539 if (!onetime) { 566 540 onetime = 1; 567 fprintf(stderr, "Using fallback suid method\n");568 } 569 } 570 # endif541 bb_error_msg("using fallback suid method"); 542 } 543 } 544 # endif 571 545 check_need_suid: 572 # endif573 if (APPLET_SUID(applet_no) == _BB_SUID_REQUIRE) {546 # endif 547 if (APPLET_SUID(applet_no) == BB_SUID_REQUIRE) { 574 548 /* Real uid is not 0. If euid isn't 0 too, suid bit 575 549 * is most probably not set on our executable */ 576 550 if (geteuid()) 577 551 bb_error_msg_and_die("must be suid to work properly"); 578 } else if (APPLET_SUID(applet_no) == _BB_SUID_DROP) {552 } else if (APPLET_SUID(applet_no) == BB_SUID_DROP) { 579 553 xsetgid(rgid); /* drop all privileges */ 580 554 xsetuid(ruid); 581 555 } 582 } 583 #else 584 #define check_suid(x) ((void)0) 585 #endif /* FEATURE_SUID */ 586 587 588 #if ENABLE_FEATURE_INSTALLER 556 # if ENABLE_FEATURE_SUID_CONFIG 557 ret: ; 558 llist_free((llist_t*)suid_config, NULL); 559 # endif 560 } 561 # else 562 # define check_suid(x) ((void)0) 563 # endif /* FEATURE_SUID */ 564 565 566 # if ENABLE_FEATURE_INSTALLER 589 567 static const char usr_bin [] ALIGN1 = "/usr/bin/"; 590 568 static const char usr_sbin[] ALIGN1 = "/usr/sbin/"; … … 593 571 &usr_bin [4], /* "/bin/" */ 594 572 &usr_sbin[4] /* "/sbin/" */ 595 # if !ENABLE_INSTALL_NO_USR573 # if !ENABLE_INSTALL_NO_USR 596 574 ,usr_bin 597 575 ,usr_sbin 598 # endif576 # endif 599 577 }; 600 601 578 602 579 /* create (sym)links for each applet */ … … 629 606 } 630 607 } 631 # else632 # define install_links(x,y,z) ((void)0)633 # endif608 # else 609 # define install_links(x,y,z) ((void)0) 610 # endif 634 611 635 612 /* If we were called as "busybox..." */ … … 652 629 full_write2_str(" multi-call binary.\n"); /* reuse */ 653 630 full_write2_str( 654 " Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko\n"655 " and others. Licensed under GPLv2.\n"656 " See source distribution for full notice.\n"631 "BusyBox is copyrighted by many authors between 1998-2012.\n" 632 "Licensed under GPLv2. See source distribution for detailed\n" 633 "copyright notices.\n" 657 634 "\n" 658 "Usage: busybox [function] [arguments]...\n" 659 " or: busybox --list[-full]\n" 635 "Usage: busybox [function [arguments]...]\n" 636 " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" 637 IF_FEATURE_INSTALLER( 638 " or: busybox --install [-s] [DIR]\n" 639 ) 660 640 " or: function [arguments]...\n" 661 641 "\n" … … 696 676 dup2(1, 2); 697 677 while (*a) { 698 # if ENABLE_FEATURE_INSTALLER699 if (argv[1][6]) /* --list- path? */678 # if ENABLE_FEATURE_INSTALLER 679 if (argv[1][6]) /* --list-full? */ 700 680 full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); 701 # endif681 # endif 702 682 full_write2_str(a); 703 683 full_write2_str("\n"); … … 711 691 int use_symbolic_links; 712 692 const char *busybox; 693 713 694 busybox = xmalloc_readlink(bb_busybox_exec_path); 714 if (!busybox) 715 busybox = bb_busybox_exec_path; 716 /* busybox --install [-s] [DIR]: */ 717 /* -s: make symlinks */ 718 /* DIR: directory to install links to */ 719 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && argv++); 695 if (!busybox) { 696 /* bb_busybox_exec_path is usually "/proc/self/exe". 697 * In chroot, readlink("/proc/self/exe") usually fails. 698 * In such case, better use argv[0] as symlink target 699 * if it is a full path name. 700 */ 701 if (argv[0][0] != '/') 702 bb_error_msg_and_die("'%s' is not an absolute path", argv[0]); 703 busybox = argv[0]; 704 } 705 /* busybox --install [-s] [DIR]: 706 * -s: make symlinks 707 * DIR: directory to install links to 708 */ 709 use_symbolic_links = (argv[2] && strcmp(argv[2], "-s") == 0 && ++argv); 720 710 install_links(busybox, use_symbolic_links, argv[2]); 721 711 return 0; … … 759 749 * should be no different from e.g. "test --foo". */ 760 750 //TODO: just compare applet_no with APPLET_NO_test 761 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) 751 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) { 752 /* If you want "foo --help" to return 0: */ 753 /*xfunc_error_retval = 0;*/ 762 754 bb_show_usage(); 755 } 763 756 } 764 757 if (ENABLE_FEATURE_SUID) … … 772 765 if (applet >= 0) 773 766 run_applet_no_and_exit(applet, argv); 774 if ( !strncmp(name, "busybox", 7))767 if (strncmp(name, "busybox", 7) == 0) 775 768 exit(busybox_main(argv)); 776 769 } … … 787 780 { 788 781 /* Tweak malloc for reduced memory consumption */ 789 #ifndef PAGE_SIZE790 # define PAGE_SIZE (4*1024) /* guess */791 #endif792 782 #ifdef M_TRIM_THRESHOLD 793 783 /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory … … 795 785 * Default is way too big: 256k 796 786 */ 797 mallopt(M_TRIM_THRESHOLD, 2 * PAGE_SIZE);787 mallopt(M_TRIM_THRESHOLD, 8 * 1024); 798 788 #endif 799 789 #ifdef M_MMAP_THRESHOLD … … 801 791 * Default is too big: 256k 802 792 */ 803 mallopt(M_MMAP_THRESHOLD, 8 * PAGE_SIZE - 256); 793 mallopt(M_MMAP_THRESHOLD, 32 * 1024 - 256); 794 #endif 795 796 #if !BB_MMU 797 /* NOMMU re-exec trick sets high-order bit in first byte of name */ 798 if (argv[0][0] & 0x80) { 799 re_execed = 1; 800 argv[0][0] &= 0x7f; 801 } 804 802 #endif 805 803 806 804 #if defined(SINGLE_APPLET_MAIN) 807 /* Only one applet is selected by the user! */ 805 /* Only one applet is selected in .config */ 806 if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) { 807 /* "busybox <applet> <params>" should still work as expected */ 808 argv++; 809 } 808 810 /* applet_names in this case is just "applet\0\0" */ 809 811 lbb_prepare(applet_names IF_FEATURE_INDIVIDUAL(, argv)); … … 812 814 lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); 813 815 814 #if !BB_MMU815 /* NOMMU re-exec trick sets high-order bit in first byte of name */816 if (argv[0][0] & 0x80) {817 re_execed = 1;818 argv[0][0] &= 0x7f;819 }820 #endif821 816 applet_name = argv[0]; 822 817 if (applet_name[0] == '-') -
branches/3.2/mindi-busybox/libbb/bb_askpass.c
r2725 r3232 31 31 struct termios tio, oldtio; 32 32 33 fputs(prompt, stdout); 34 fflush_all(); 35 tcflush(fd, TCIFLUSH); 36 33 37 tcgetattr(fd, &oldtio); 34 tcflush(fd, TCIFLUSH);35 38 tio = oldtio; 36 #ifndef IUCLC 37 # define IUCLC 0 39 #if 0 40 /* Switch off UPPERCASE->lowercase conversion (never used since 198x) 41 * and XON/XOFF (why we want to mess with this??) 42 */ 43 # ifndef IUCLC 44 # define IUCLC 0 45 # endif 46 tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); 38 47 #endif 39 tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);40 tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL |TOSTOP);48 /* Switch off echo */ 49 tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL); 41 50 tcsetattr(fd, TCSANOW, &tio); 42 51 … … 50 59 alarm(timeout); 51 60 } 52 53 fputs(prompt, stdout);54 fflush_all();55 61 56 62 if (!passwd) -
branches/3.2/mindi-busybox/libbb/bb_pwd.c
r2725 r3232 73 73 } 74 74 75 char* FAST_FUNC uid2uname_utoa( longuid)75 char* FAST_FUNC uid2uname_utoa(uid_t uid) 76 76 { 77 77 char *name = uid2uname(uid); … … 79 79 } 80 80 81 char* FAST_FUNC gid2group_utoa( longgid)81 char* FAST_FUNC gid2group_utoa(gid_t gid) 82 82 { 83 83 char *name = gid2group(gid); -
branches/3.2/mindi-busybox/libbb/bb_strtonum.c
r2725 r3232 37 37 } 38 38 39 static unsigned long long handle_errors(unsigned long long v, char **endp , char *endptr)39 static unsigned long long handle_errors(unsigned long long v, char **endp) 40 40 { 41 if (endp) *endp = endptr;41 char next_ch = **endp; 42 42 43 43 /* errno is already set to ERANGE by strtoXXX if value overflowed */ 44 if ( endptr[0]) {44 if (next_ch) { 45 45 /* "1234abcg" or out-of-range? */ 46 if (isalnum( endptr[0]) || errno)46 if (isalnum(next_ch) || errno) 47 47 return ret_ERANGE(); 48 48 /* good number, just suspicious terminator */ … … 58 58 char *endptr; 59 59 60 if (!endp) endp = &endptr; 61 *endp = (char*) arg; 62 60 63 /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */ 61 64 /* I don't think that this is right. Preventing this... */ … … 64 67 /* not 100% correct for lib func, but convenient for the caller */ 65 68 errno = 0; 66 v = strtoull(arg, &endptr, base);67 return handle_errors(v, endp , endptr);69 v = strtoull(arg, endp, base); 70 return handle_errors(v, endp); 68 71 } 69 72 … … 72 75 unsigned long long v; 73 76 char *endptr; 77 char first; 78 79 if (!endp) endp = &endptr; 80 *endp = (char*) arg; 74 81 75 82 /* Check for the weird "feature": 76 83 * a "-" string is apparently a valid "number" for strto[u]l[l]! 77 84 * It returns zero and errno is 0! :( */ 78 charfirst = (arg[0] != '-' ? arg[0] : arg[1]);85 first = (arg[0] != '-' ? arg[0] : arg[1]); 79 86 if (!isalnum(first)) return ret_ERANGE(); 80 87 81 88 errno = 0; 82 v = strtoll(arg, &endptr, base);83 return handle_errors(v, endp , endptr);89 v = strtoll(arg, endp, base); 90 return handle_errors(v, endp); 84 91 } 85 92 … … 90 97 char *endptr; 91 98 99 if (!endp) endp = &endptr; 100 *endp = (char*) arg; 101 92 102 if (!isalnum(arg[0])) return ret_ERANGE(); 93 103 errno = 0; 94 v = strtoul(arg, &endptr, base);95 return handle_errors(v, endp , endptr);104 v = strtoul(arg, endp, base); 105 return handle_errors(v, endp); 96 106 } 97 107 … … 100 110 long v; 101 111 char *endptr; 112 char first; 102 113 103 char first = (arg[0] != '-' ? arg[0] : arg[1]); 114 if (!endp) endp = &endptr; 115 *endp = (char*) arg; 116 117 first = (arg[0] != '-' ? arg[0] : arg[1]); 104 118 if (!isalnum(first)) return ret_ERANGE(); 105 119 106 120 errno = 0; 107 v = strtol(arg, &endptr, base);108 return handle_errors(v, endp , endptr);121 v = strtol(arg, endp, base); 122 return handle_errors(v, endp); 109 123 } 110 124 #endif … … 116 130 char *endptr; 117 131 132 if (!endp) endp = &endptr; 133 *endp = (char*) arg; 134 118 135 if (!isalnum(arg[0])) return ret_ERANGE(); 119 136 errno = 0; 120 v = strtoul(arg, &endptr, base);137 v = strtoul(arg, endp, base); 121 138 if (v > UINT_MAX) return ret_ERANGE(); 122 return handle_errors(v, endp , endptr);139 return handle_errors(v, endp); 123 140 } 124 141 … … 127 144 long v; 128 145 char *endptr; 146 char first; 129 147 130 char first = (arg[0] != '-' ? arg[0] : arg[1]); 148 if (!endp) endp = &endptr; 149 *endp = (char*) arg; 150 151 first = (arg[0] != '-' ? arg[0] : arg[1]); 131 152 if (!isalnum(first)) return ret_ERANGE(); 132 153 133 154 errno = 0; 134 v = strtol(arg, &endptr, base);155 v = strtol(arg, endp, base); 135 156 if (v > INT_MAX) return ret_ERANGE(); 136 157 if (v < INT_MIN) return ret_ERANGE(); 137 return handle_errors(v, endp , endptr);158 return handle_errors(v, endp); 138 159 } 139 160 #endif -
branches/3.2/mindi-busybox/libbb/copy_file.c
r2725 r3232 79 79 struct stat source_stat; 80 80 struct stat dest_stat; 81 s igned charretval = 0;82 s igned chardest_exists = 0;83 s igned charovr;81 smallint retval = 0; 82 smallint dest_exists = 0; 83 smallint ovr; 84 84 85 85 /* Inverse of cp -d ("cp without -d") */ … … 148 148 } 149 149 150 /* Create DEST */151 150 if (dest_exists) { 152 151 if (!S_ISDIR(dest_stat.st_mode)) { … … 157 156 * this check and actual creation of files inside dest */ 158 157 } else { 158 /* Create DEST */ 159 159 mode_t mode; 160 160 saved_umask = umask(0); -
branches/3.2/mindi-busybox/libbb/correct_password.c
r2725 r3232 42 42 const char *correct; 43 43 int r; 44 #if ENABLE_FEATURE_SHADOWPASSWDS45 /* Using _r function to avoid pulling in static buffers */46 struct spwd spw;47 char buffer[256];48 #endif49 50 44 /* fake salt. crypt() can choke otherwise. */ 51 45 correct = "aa"; … … 56 50 correct = pw->pw_passwd; 57 51 #if ENABLE_FEATURE_SHADOWPASSWDS 52 /* Using _r function to avoid pulling in static buffers */ 58 53 if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) { 54 struct spwd spw; 55 char buffer[256]; 59 56 /* getspnam_r may return 0 yet set result to NULL. 60 57 * At least glibc 2.4 does this. Be extra paranoid here. */ -
branches/3.2/mindi-busybox/libbb/crc32.c
r2725 r3232 60 60 61 61 while (buf != end) { 62 62 val = crc_table[(uint8_t)val ^ *(uint8_t*)buf] ^ (val >> 8); 63 63 buf = (uint8_t*)buf + 1; 64 64 } -
branches/3.2/mindi-busybox/libbb/die_if_bad_username.c
r2725 r3232 19 19 void FAST_FUNC die_if_bad_username(const char *name) 20 20 { 21 /* 1st char being dash or dot isn't valid: */ 21 const char *start = name; 22 23 /* 1st char being dash or dot isn't valid: 24 * for example, name like ".." can make adduser 25 * chown "/home/.." recursively - NOT GOOD. 26 * Name of just a single "$" is also rejected. 27 */ 22 28 goto skip; 23 /* For example, name like ".." can make adduser24 * chown "/home/.." recursively - NOT GOOD25 */26 29 27 30 do { 28 if (*name == '-' || *name == '.')29 continue; 30 skip: 31 if ( isalnum(*name)32 || *name == ' _'33 || *name == '@'31 unsigned char ch; 32 33 /* These chars are valid unless they are at the 1st pos: */ 34 if (*name == '-' 35 || *name == '.' 36 /* $ is allowed if it's the last char: */ 34 37 || (*name == '$' && !name[1]) 35 38 ) { 36 39 continue; 37 40 } 38 bb_error_msg_and_die("illegal character '%c'", *name); 41 skip: 42 ch = *name; 43 if (ch == '_' 44 /* || ch == '@' -- we disallow this too. Think about "user@host" */ 45 /* open-coded isalnum: */ 46 || (ch >= '0' && ch <= '9') 47 || ((ch|0x20) >= 'a' && (ch|0x20) <= 'z') 48 ) { 49 continue; 50 } 51 bb_error_msg_and_die("illegal character with code %u at position %u", 52 (unsigned)ch, (unsigned)(name - start)); 39 53 } while (*++name); 54 55 /* The minimum size of the login name is one char or two if 56 * last char is the '$'. Violations of this are caught above. 57 * The maximum size of the login name is LOGIN_NAME_MAX 58 * including the terminating null byte. 59 */ 60 if (name - start >= LOGIN_NAME_MAX) 61 bb_error_msg_and_die("name is too long"); 40 62 } -
branches/3.2/mindi-busybox/libbb/dump.c
r2725 r3232 72 72 * case it's a %s format. 73 73 */ 74 while (strchr(index_str + 1, *++fmt)); 74 while (strchr(index_str + 1, *++fmt)) 75 continue; 75 76 if (*fmt == '.' && isdigit(*++fmt)) { 76 77 prec = atoi(fmt); … … 100 101 { 101 102 enum { NOTOKAY, USEBCNT, USEPREC } sokay; 102 PR *pr, **nextpr = NULL;103 103 FU *fu; 104 PR *pr; 104 105 char *p1, *p2, *p3; 105 106 char savech, *fmtp; … … 112 113 * conversion character gets its own. 113 114 */ 114 for (nconv = 0, fmtp = fu->fmt; *fmtp; nextpr = &pr->nextpr) {115 for (nconv = 0, fmtp = fu->fmt; *fmtp; ) { 115 116 /* NOSTRICT */ 116 117 /* DBU:[dvae@cray.com] zalloc so that forward ptrs start out NULL*/ … … 118 119 if (!fu->nextpr) 119 120 fu->nextpr = pr; 120 /* ignore nextpr -- its unused inside the loop and is121 * uninitialized 1st time through.122 */123 121 124 122 /* skip preceding text and up to the next % sign */ … … 296 294 * repeat it as necessary. 297 295 * 298 * if ,rep count is greater than 1, no trailing whitespace296 * if rep count is greater than 1, no trailing whitespace 299 297 * gets output from the last iteration of the format unit. 300 298 */ 301 299 for (fu = fs->nextfu; fu; fu = fu->nextfu) { 302 if (!fu->nextfu && fs->bcnt < dumper->blocksize 303 && !(fu->flags & F_SETREP) && fu->bcnt 300 if (!fu->nextfu 301 && fs->bcnt < dumper->blocksize 302 && !(fu->flags & F_SETREP) 303 && fu->bcnt 304 304 ) { 305 305 fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; 306 306 } 307 if (fu->reps > 1 ) {307 if (fu->reps > 1 && fu->nextpr) { 308 308 for (pr = fu->nextpr;; pr = pr->nextpr) 309 309 if (!pr->nextpr) … … 725 725 for (;;) { 726 726 p = skip_whitespace(p); 727 if ( !*p) {727 if (*p == '\0') { 728 728 break; 729 729 } … … 753 753 /* skip slash and trailing white space */ 754 754 if (*p == '/') { 755 p = skip_whitespace( ++p);755 p = skip_whitespace(p + 1); 756 756 } 757 757 … … 767 767 tfu->bcnt = atoi(savep); 768 768 /* skip trailing white space */ 769 p = skip_whitespace( ++p);769 p = skip_whitespace(p + 1); 770 770 } 771 771 … … 775 775 } 776 776 for (savep = ++p; *p != '"';) { 777 if (*p++ == 0) {777 if (*p++ == '\0') { 778 778 bb_error_msg_and_die("bad format {%s}", fmt); 779 779 } … … 786 786 /* alphabetic escape sequences have to be done in place */ 787 787 for (p2 = p1;; ++p1, ++p2) { 788 if ( !*p1) {788 if (*p1 == '\0') { 789 789 *p2 = *p1; 790 790 break; -
branches/3.2/mindi-busybox/libbb/execable.c
r2725 r3232 69 69 70 70 #if ENABLE_FEATURE_PREFER_APPLETS 71 /* just like the real execvp, but try to launch an applet named 'file' first 72 */ 73 int FAST_FUNC bb_execvp(const char *file, char *const argv[]) 71 /* just like the real execvp, but try to launch an applet named 'file' first */ 72 int FAST_FUNC BB_EXECVP(const char *file, char *const argv[]) 74 73 { 75 return execvp(find_applet_by_name(file) >= 0 ? bb_busybox_exec_path : file, 76 argv); 74 if (find_applet_by_name(file) >= 0) 75 execvp(bb_busybox_exec_path, argv); 76 return execvp(file, argv); 77 77 } 78 78 #endif -
branches/3.2/mindi-busybox/libbb/find_mount_point.c
r2725 r3232 31 31 devno_of_name = s.st_dev; 32 32 block_dev = 0; 33 if (S_ISBLK(s.st_mode)) { 33 /* Why S_ISCHR? - UBI volumes use char devices, not block */ 34 if (S_ISBLK(s.st_mode) || S_ISCHR(s.st_mode)) { 34 35 devno_of_name = s.st_rdev; 35 36 block_dev = 1; … … 44 45 * and it makes sense to always ignore it. 45 46 * Otherwise people can't reference their "real" root! */ 46 if ( strcmp(mountEntry->mnt_fsname, "rootfs") == 0)47 if (ENABLE_FEATURE_SKIP_ROOTFS && strcmp(mountEntry->mnt_fsname, "rootfs") == 0) 47 48 continue; 48 49 -
branches/3.2/mindi-busybox/libbb/find_root_device.c
r2725 r3232 30 30 int len, rem; 31 31 32 len = strlen(ap->devpath); 33 rem = DEVNAME_MAX-2 - len; 34 if (rem <= 0) 35 return NULL; 36 32 37 dir = opendir(ap->devpath); 33 38 if (!dir) 34 39 return NULL; 35 40 36 len = strlen(ap->devpath);37 rem = DEVNAME_MAX-2 - len;38 if (rem <= 0)39 return NULL;40 41 ap->devpath[len++] = '/'; 41 42 -
branches/3.2/mindi-busybox/libbb/get_last_path_component.c
r2725 r3232 7 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 #include "libbb.h" 9 10 10 #include "libbb.h" 11 const char* FAST_FUNC bb_basename(const char *name) 12 { 13 const char *cp = strrchr(name, '/'); 14 if (cp) 15 return cp + 1; 16 return name; 17 } 18 11 19 /* 12 20 * "/" -> "/" -
branches/3.2/mindi-busybox/libbb/get_line_from_file.c
r2725 r3232 12 12 #include "libbb.h" 13 13 14 /* This function reads an entire line from a text file, up to a newline 15 * or NUL byte, inclusive. It returns a malloc'ed char * which 16 * must be free'ed by the caller. If end is NULL '\n' isn't considered 17 * end of line. If end isn't NULL, length of the chunk is stored in it. 18 * If lineno is not NULL, *lineno is incremented for each line, 19 * and also trailing '\' is recognized as line continuation. 20 * 21 * Returns NULL if EOF/error. */ 22 char* FAST_FUNC bb_get_chunk_with_continuation(FILE *file, int *end, int *lineno) 14 char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end) 23 15 { 24 16 int ch; 25 intidx = 0;17 unsigned idx = 0; 26 18 char *linebuf = NULL; 27 int linebufsz = 0;28 19 29 20 while ((ch = getc(file)) != EOF) { 30 21 /* grow the line buffer as necessary */ 31 if (idx >= linebufsz) { 32 linebufsz += 256; 33 linebuf = xrealloc(linebuf, linebufsz); 34 } 22 if (!(idx & 0xff)) 23 linebuf = xrealloc(linebuf, idx + 0x100); 35 24 linebuf[idx++] = (char) ch; 36 if ( !ch)25 if (ch == '\0') 37 26 break; 38 if (end && ch == '\n') { 39 if (lineno == NULL) 40 break; 41 (*lineno)++; 42 if (idx < 2 || linebuf[idx-2] != '\\') 43 break; 44 idx -= 2; 45 } 27 if (end && ch == '\n') 28 break; 46 29 } 47 30 if (end) … … 58 41 } 59 42 return linebuf; 60 }61 62 char* FAST_FUNC bb_get_chunk_from_file(FILE *file, int *end)63 {64 return bb_get_chunk_with_continuation(file, end, NULL);65 43 } 66 44 -
branches/3.2/mindi-busybox/libbb/getopt32.c
r2725 r3232 8 8 */ 9 9 10 #include <getopt.h> 10 #if ENABLE_LONG_OPTS || ENABLE_FEATURE_GETOPT_LONG 11 # include <getopt.h> 12 #endif 11 13 #include "libbb.h" 12 14 … … 81 83 82 84 static const char applet_longopts[] ALIGN1 = 83 84 85 85 //"name\0" has_arg val 86 "verbose\0" No_argument "v" 87 ; 86 88 applet_long_options = applet_longopts; 87 89 … … 227 229 opt_complementary = "b--cf:c--bf:f--bc". If two of the 228 230 mutually exclusive options are found, getopt32 will call 229 231 bb_show_usage() and die. 230 232 231 233 "x--x" Variation of the above, it means that -x option should occur … … 466 468 for (on_off = complementary; on_off->opt_char; on_off++) 467 469 if (on_off->opt_char == *s) 468 break; 470 goto found_opt; 471 /* Without this, diagnostic of such bugs is not easy */ 472 bb_error_msg_and_die("NO OPT %c!", *s); 473 found_opt: 469 474 if (c == ':' && s[2] == ':') { 470 475 on_off->param_type = PARAM_LIST; … … 473 478 if (c == '+' && (s[2] == ':' || s[2] == '\0')) { 474 479 on_off->param_type = PARAM_INT; 480 s++; 475 481 continue; 476 482 } … … 532 538 /* In case getopt32 was already called: 533 539 * reset the libc getopt() function, which keeps internal state. 534 * run_nofork_applet _prime() does this, but we might end up here540 * run_nofork_applet() does this, but we might end up here 535 541 * also via gunzip_main() -> gzip_main(). Play safe. 536 542 */ … … 542 548 #endif 543 549 /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ 544 545 pargv = NULL;546 550 547 551 /* Note: just "getopt() <= 0" will not work well for … … 575 579 if (on_off->counter) 576 580 (*(on_off->counter))++; 577 if (o n_off->param_type == PARAM_LIST) {578 if (o ptarg)581 if (optarg) { 582 if (on_off->param_type == PARAM_LIST) { 579 583 llist_add_to_end((llist_t **)(on_off->optarg), optarg); 580 } else if (on_off->param_type == PARAM_INT) { 581 if (optarg) 584 } else if (on_off->param_type == PARAM_INT) { 582 585 //TODO: xatoi_positive indirectly pulls in printf machinery 583 586 *(unsigned*)(on_off->optarg) = xatoi_positive(optarg); 584 } else if (on_off->optarg) { 585 if (optarg) 587 } else if (on_off->optarg) { 586 588 *(char **)(on_off->optarg) = optarg; 587 } 588 if (pargv != NULL) 589 break; 589 } 590 } 590 591 } 591 592 -
branches/3.2/mindi-busybox/libbb/getpty.c
r2725 r3232 20 20 grantpt(p); /* chmod+chown corresponding slave pty */ 21 21 unlockpt(p); /* (what does this do?) */ 22 #if 0 /* if ptsname_r is not available... */ 23 const char *name; 24 name = ptsname(p); /* find out the name of slave pty */ 25 if (!name) { 26 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); 22 # ifndef HAVE_PTSNAME_R 23 { 24 const char *name; 25 name = ptsname(p); /* find out the name of slave pty */ 26 if (!name) { 27 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); 28 } 29 safe_strncpy(line, name, GETPTY_BUFSIZE); 27 30 } 28 safe_strncpy(line, name, GETPTY_BUFSIZE); 29 #else 31 # else 30 32 /* find out the name of slave pty */ 31 33 if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { … … 33 35 } 34 36 line[GETPTY_BUFSIZE-1] = '\0'; 35 # endif37 # endif 36 38 return p; 37 39 } -
branches/3.2/mindi-busybox/libbb/hash_md5_sha.c
r2725 r3232 32 32 } 33 33 34 /* rotl64 only used for sha3 currently */ 35 static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n) 36 { 37 return (x << n) | (x >> (64 - n)); 38 } 34 39 35 40 /* Feed data through a temporary buffer. … … 52 57 buffer = (const char *)buffer + remaining; 53 58 bufpos += remaining; 54 /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */59 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ 55 60 bufpos -= 64; 56 61 if (bufpos != 0) … … 105 110 106 111 /* 0: fastest, 3: smallest */ 107 #if CONFIG_MD5_S IZE_VS_SPEED< 0108 # define MD5_S IZE_VS_SPEED0109 #elif CONFIG_MD5_S IZE_VS_SPEED> 3110 # define MD5_S IZE_VS_SPEED3112 #if CONFIG_MD5_SMALL < 0 113 # define MD5_SMALL 0 114 #elif CONFIG_MD5_SMALL > 3 115 # define MD5_SMALL 3 111 116 #else 112 # define MD5_S IZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED117 # define MD5_SMALL CONFIG_MD5_SMALL 113 118 #endif 114 119 … … 130 135 static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) 131 136 { 132 #if MD5_S IZE_VS_SPEED> 0137 #if MD5_SMALL > 0 133 138 /* Before we start, one word to the strange constants. 134 139 They are defined in RFC 1321 as … … 158 163 }; 159 164 static const char P_array[] ALIGN1 = { 160 # if MD5_S IZE_VS_SPEED> 1165 # if MD5_SMALL > 1 161 166 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ 162 167 # endif … … 172 177 uint32_t D = ctx->hash[3]; 173 178 174 #if MD5_S IZE_VS_SPEED>= 2 /* 2 or 3 */179 #if MD5_SMALL >= 2 /* 2 or 3 */ 175 180 176 181 static const char S_array[] ALIGN1 = { … … 186 191 uint32_t temp; 187 192 188 # if BB_BIG_ENDIAN 189 for (i = 0; i < 16; i++) 190 words[i] = SWAP_LE32(words[i]); 191 # endif 192 193 # if MD5_SIZE_VS_SPEED == 3 193 if (BB_BIG_ENDIAN) 194 for (i = 0; i < 16; i++) 195 words[i] = SWAP_LE32(words[i]); 196 197 # if MD5_SMALL == 3 194 198 pc = C_array; 195 199 pp = P_array; … … 221 225 B = temp; 222 226 } 223 # else /* MD5_S IZE_VS_SPEED== 2 */227 # else /* MD5_SMALL == 2 */ 224 228 pc = C_array; 225 229 pp = P_array; … … 272 276 ctx->hash[3] += D; 273 277 274 #else /* MD5_S IZE_VS_SPEED== 0 or 1 */278 #else /* MD5_SMALL == 0 or 1 */ 275 279 276 280 uint32_t A_save = A; … … 278 282 uint32_t C_save = C; 279 283 uint32_t D_save = D; 280 # if MD5_S IZE_VS_SPEED== 1284 # if MD5_SMALL == 1 281 285 const uint32_t *pc; 282 286 const char *pp; … … 300 304 301 305 /* Round 1 */ 302 # if MD5_S IZE_VS_SPEED== 1306 # if MD5_SMALL == 1 303 307 pc = C_array; 304 308 for (i = 0; i < 4; i++) { … … 340 344 341 345 /* Round 2 */ 342 # if MD5_S IZE_VS_SPEED== 1346 # if MD5_SMALL == 1 343 347 pp = P_array; 344 348 for (i = 0; i < 4; i++) { … … 368 372 369 373 /* Round 3 */ 370 # if MD5_S IZE_VS_SPEED== 1374 # if MD5_SMALL == 1 371 375 for (i = 0; i < 4; i++) { 372 376 OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); … … 395 399 396 400 /* Round 4 */ 397 # if MD5_S IZE_VS_SPEED== 1401 # if MD5_SMALL == 1 398 402 for (i = 0; i < 4; i++) { 399 403 OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); … … 463 467 464 468 /* The MD5 result is in little endian byte order */ 465 #if BB_BIG_ENDIAN 466 ctx->hash[0] = SWAP_LE32(ctx->hash[0]); 467 ctx->hash[1] = SWAP_LE32(ctx->hash[1]); 468 ctx->hash[2] = SWAP_LE32(ctx->hash[2]); 469 ctx->hash[3] = SWAP_LE32(ctx->hash[3]); 470 #endif 469 if (BB_BIG_ENDIAN) { 470 ctx->hash[0] = SWAP_LE32(ctx->hash[0]); 471 ctx->hash[1] = SWAP_LE32(ctx->hash[1]); 472 ctx->hash[2] = SWAP_LE32(ctx->hash[2]); 473 ctx->hash[3] = SWAP_LE32(ctx->hash[3]); 474 } 475 471 476 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); 472 477 } … … 835 840 buffer = (const char *)buffer + remaining; 836 841 bufpos += remaining; 837 /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */842 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ 838 843 bufpos -= 128; 839 844 if (bufpos != 0) … … 897 902 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 898 903 } 904 905 906 /* 907 * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, 908 * Michael Peeters and Gilles Van Assche. For more information, feedback or 909 * questions, please refer to our website: http://keccak.noekeon.org/ 910 * 911 * Implementation by Ronny Van Keer, 912 * hereby denoted as "the implementer". 913 * 914 * To the extent possible under law, the implementer has waived all copyright 915 * and related or neighboring rights to the source code in this file. 916 * http://creativecommons.org/publicdomain/zero/1.0/ 917 * 918 * Busybox modifications (C) Lauri Kasanen, under the GPLv2. 919 */ 920 921 #if CONFIG_SHA3_SMALL < 0 922 # define SHA3_SMALL 0 923 #elif CONFIG_SHA3_SMALL > 1 924 # define SHA3_SMALL 1 925 #else 926 # define SHA3_SMALL CONFIG_SHA3_SMALL 927 #endif 928 929 enum { 930 SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */ 931 }; 932 933 /* 934 * In the crypto literature this function is usually called Keccak-f(). 935 */ 936 static void sha3_process_block72(uint64_t *state) 937 { 938 enum { NROUNDS = 24 }; 939 940 /* Elements should be 64-bit, but top half is always zero or 0x80000000. 941 * We encode 63rd bits in a separate word below. 942 * Same is true for 31th bits, which lets us use 16-bit table instead of 64-bit. 943 * The speed penalty is lost in the noise. 944 */ 945 static const uint16_t IOTA_CONST[NROUNDS] = { 946 0x0001, 947 0x8082, 948 0x808a, 949 0x8000, 950 0x808b, 951 0x0001, 952 0x8081, 953 0x8009, 954 0x008a, 955 0x0088, 956 0x8009, 957 0x000a, 958 0x808b, 959 0x008b, 960 0x8089, 961 0x8003, 962 0x8002, 963 0x0080, 964 0x800a, 965 0x000a, 966 0x8081, 967 0x8080, 968 0x0001, 969 0x8008, 970 }; 971 /* bit for CONST[0] is in msb: 0011 0011 0000 0111 1101 1101 */ 972 const uint32_t IOTA_CONST_bit63 = (uint32_t)(0x3307dd00); 973 /* bit for CONST[0] is in msb: 0001 0110 0011 1000 0001 1011 */ 974 const uint32_t IOTA_CONST_bit31 = (uint32_t)(0x16381b00); 975 976 static const uint8_t ROT_CONST[24] = { 977 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 978 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44, 979 }; 980 static const uint8_t PI_LANE[24] = { 981 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 982 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1, 983 }; 984 /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/ 985 986 unsigned x, y; 987 unsigned round; 988 989 if (BB_BIG_ENDIAN) { 990 for (x = 0; x < 25; x++) { 991 state[x] = SWAP_LE64(state[x]); 992 } 993 } 994 995 for (round = 0; round < NROUNDS; ++round) { 996 /* Theta */ 997 { 998 uint64_t BC[10]; 999 for (x = 0; x < 5; ++x) { 1000 BC[x + 5] = BC[x] = state[x] 1001 ^ state[x + 5] ^ state[x + 10] 1002 ^ state[x + 15] ^ state[x + 20]; 1003 } 1004 /* Using 2x5 vector above eliminates the need to use 1005 * BC[MOD5[x+N]] trick below to fetch BC[(x+N) % 5], 1006 * and the code is a bit _smaller_. 1007 */ 1008 for (x = 0; x < 5; ++x) { 1009 uint64_t temp = BC[x + 4] ^ rotl64(BC[x + 1], 1); 1010 state[x] ^= temp; 1011 state[x + 5] ^= temp; 1012 state[x + 10] ^= temp; 1013 state[x + 15] ^= temp; 1014 state[x + 20] ^= temp; 1015 } 1016 } 1017 1018 /* Rho Pi */ 1019 if (SHA3_SMALL) { 1020 uint64_t t1 = state[1]; 1021 for (x = 0; x < 24; ++x) { 1022 uint64_t t0 = state[PI_LANE[x]]; 1023 state[PI_LANE[x]] = rotl64(t1, ROT_CONST[x]); 1024 t1 = t0; 1025 } 1026 } else { 1027 /* Especially large benefit for 32-bit arch (75% faster): 1028 * 64-bit rotations by non-constant usually are SLOW on those. 1029 * We resort to unrolling here. 1030 * This optimizes out PI_LANE[] and ROT_CONST[], 1031 * but generates 300-500 more bytes of code. 1032 */ 1033 uint64_t t0; 1034 uint64_t t1 = state[1]; 1035 #define RhoPi_twice(x) \ 1036 t0 = state[PI_LANE[x ]]; \ 1037 state[PI_LANE[x ]] = rotl64(t1, ROT_CONST[x ]); \ 1038 t1 = state[PI_LANE[x+1]]; \ 1039 state[PI_LANE[x+1]] = rotl64(t0, ROT_CONST[x+1]); 1040 RhoPi_twice(0); RhoPi_twice(2); 1041 RhoPi_twice(4); RhoPi_twice(6); 1042 RhoPi_twice(8); RhoPi_twice(10); 1043 RhoPi_twice(12); RhoPi_twice(14); 1044 RhoPi_twice(16); RhoPi_twice(18); 1045 RhoPi_twice(20); RhoPi_twice(22); 1046 #undef RhoPi_twice 1047 } 1048 1049 /* Chi */ 1050 for (y = 0; y <= 20; y += 5) { 1051 uint64_t BC0, BC1, BC2, BC3, BC4; 1052 BC0 = state[y + 0]; 1053 BC1 = state[y + 1]; 1054 BC2 = state[y + 2]; 1055 state[y + 0] = BC0 ^ ((~BC1) & BC2); 1056 BC3 = state[y + 3]; 1057 state[y + 1] = BC1 ^ ((~BC2) & BC3); 1058 BC4 = state[y + 4]; 1059 state[y + 2] = BC2 ^ ((~BC3) & BC4); 1060 state[y + 3] = BC3 ^ ((~BC4) & BC0); 1061 state[y + 4] = BC4 ^ ((~BC0) & BC1); 1062 } 1063 1064 /* Iota */ 1065 state[0] ^= IOTA_CONST[round] 1066 | (uint32_t)((IOTA_CONST_bit31 << round) & 0x80000000) 1067 | (uint64_t)((IOTA_CONST_bit63 << round) & 0x80000000) << 32; 1068 } 1069 1070 if (BB_BIG_ENDIAN) { 1071 for (x = 0; x < 25; x++) { 1072 state[x] = SWAP_LE64(state[x]); 1073 } 1074 } 1075 } 1076 1077 void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) 1078 { 1079 memset(ctx, 0, sizeof(*ctx)); 1080 } 1081 1082 void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) 1083 { 1084 #if SHA3_SMALL 1085 const uint8_t *data = buffer; 1086 unsigned bufpos = ctx->bytes_queued; 1087 1088 while (1) { 1089 unsigned remaining = SHA3_IBLK_BYTES - bufpos; 1090 if (remaining > len) 1091 remaining = len; 1092 len -= remaining; 1093 /* XOR data into buffer */ 1094 while (remaining != 0) { 1095 uint8_t *buf = (uint8_t*)ctx->state; 1096 buf[bufpos] ^= *data++; 1097 bufpos++; 1098 remaining--; 1099 } 1100 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ 1101 bufpos -= SHA3_IBLK_BYTES; 1102 if (bufpos != 0) 1103 break; 1104 /* Buffer is filled up, process it */ 1105 sha3_process_block72(ctx->state); 1106 /*bufpos = 0; - already is */ 1107 } 1108 ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES; 1109 #else 1110 /* +50 bytes code size, but a bit faster because of long-sized XORs */ 1111 const uint8_t *data = buffer; 1112 unsigned bufpos = ctx->bytes_queued; 1113 1114 /* If already data in queue, continue queuing first */ 1115 while (len != 0 && bufpos != 0) { 1116 uint8_t *buf = (uint8_t*)ctx->state; 1117 buf[bufpos] ^= *data++; 1118 len--; 1119 bufpos++; 1120 if (bufpos == SHA3_IBLK_BYTES) { 1121 bufpos = 0; 1122 goto do_block; 1123 } 1124 } 1125 1126 /* Absorb complete blocks */ 1127 while (len >= SHA3_IBLK_BYTES) { 1128 /* XOR data onto beginning of state[]. 1129 * We try to be efficient - operate one word at a time, not byte. 1130 * Careful wrt unaligned access: can't just use "*(long*)data"! 1131 */ 1132 unsigned count = SHA3_IBLK_BYTES / sizeof(long); 1133 long *buf = (long*)ctx->state; 1134 do { 1135 long v; 1136 move_from_unaligned_long(v, (long*)data); 1137 *buf++ ^= v; 1138 data += sizeof(long); 1139 } while (--count); 1140 len -= SHA3_IBLK_BYTES; 1141 do_block: 1142 sha3_process_block72(ctx->state); 1143 } 1144 1145 /* Queue remaining data bytes */ 1146 while (len != 0) { 1147 uint8_t *buf = (uint8_t*)ctx->state; 1148 buf[bufpos] ^= *data++; 1149 bufpos++; 1150 len--; 1151 } 1152 1153 ctx->bytes_queued = bufpos; 1154 #endif 1155 } 1156 1157 void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) 1158 { 1159 /* Padding */ 1160 uint8_t *buf = (uint8_t*)ctx->state; 1161 buf[ctx->bytes_queued] ^= 1; 1162 buf[SHA3_IBLK_BYTES - 1] ^= 0x80; 1163 1164 sha3_process_block72(ctx->state); 1165 1166 /* Output */ 1167 memcpy(resbuf, ctx->state, 64); 1168 } -
branches/3.2/mindi-busybox/libbb/hash_md5prime.c
r2725 r3232 60 60 * 61 61 * Reintroduced the loop unrolling in md5_transform and added the 62 * MD5_S IZE_VS_SPEEDoption for configurability. Define below as:62 * MD5_SMALL option for configurability. Define below as: 63 63 * 0 fully unrolled loops 64 64 * 1 partially unrolled (4 ops per loop) … … 76 76 77 77 /* 1: fastest, 3: smallest */ 78 #if CONFIG_MD5_S IZE_VS_SPEED< 179 # define MD5_S IZE_VS_SPEED180 #elif CONFIG_MD5_S IZE_VS_SPEED> 381 # define MD5_S IZE_VS_SPEED378 #if CONFIG_MD5_SMALL < 1 79 # define MD5_SMALL 1 80 #elif CONFIG_MD5_SMALL > 3 81 # define MD5_SMALL 3 82 82 #else 83 # define MD5_S IZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED83 # define MD5_SMALL CONFIG_MD5_SMALL 84 84 #endif 85 85 … … 153 153 { 154 154 uint32_t a, b, c, d, x[16]; 155 #if MD5_S IZE_VS_SPEED> 1155 #if MD5_SMALL > 1 156 156 uint32_t temp; 157 157 const unsigned char *ps; … … 163 163 6, 10, 15, 21 164 164 }; 165 #endif /* MD5_S IZE_VS_SPEED> 1 */166 167 #if MD5_S IZE_VS_SPEED> 0165 #endif /* MD5_SMALL > 1 */ 166 167 #if MD5_SMALL > 0 168 168 const uint32_t *pc; 169 169 const unsigned char *pp; … … 199 199 }; 200 200 201 #endif /* MD5_S IZE_VS_SPEED> 0 */201 #endif /* MD5_SMALL > 0 */ 202 202 203 203 memcpy32_le2cpu(x, block, 64); … … 208 208 d = state[3]; 209 209 210 #if MD5_S IZE_VS_SPEED> 2210 #if MD5_SMALL > 2 211 211 pc = C; 212 212 pp = P; … … 234 234 a = d; d = c; c = b; b = temp; 235 235 } 236 #elif MD5_S IZE_VS_SPEED> 1236 #elif MD5_SMALL > 1 237 237 pc = C; 238 238 pp = P; … … 261 261 temp = d; d = c; c = b; b = a; a = temp; 262 262 } 263 #elif MD5_S IZE_VS_SPEED> 0263 #elif MD5_SMALL > 0 264 264 pc = C; 265 265 pp = P; -
branches/3.2/mindi-busybox/libbb/inet_common.c
r2725 r3232 98 98 #ifdef DEBUG 99 99 bb_error_msg("rresolve: unsupported address family %d!", 100 100 s_in->sin_family); 101 101 #endif 102 102 errno = EAFNOSUPPORT; … … 165 165 int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6) 166 166 { 167 struct addrinfo req, *ai ;167 struct addrinfo req, *ai = NULL; 168 168 int s; 169 169 170 memset(&req, '\0', sizeof req);170 memset(&req, 0, sizeof(req)); 171 171 req.ai_family = AF_INET6; 172 172 s = getaddrinfo(name, NULL, &req, &ai); 173 if (s ) {173 if (s != 0) { 174 174 bb_error_msg("getaddrinfo: %s: %d", name, s); 175 175 return -1; 176 176 } 177 memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6)); 178 freeaddrinfo(ai); 177 memcpy(sin6, ai->ai_addr, sizeof(*sin6)); 178 if (ai) 179 freeaddrinfo(ai); 179 180 return 0; 180 181 } … … 195 196 #ifdef DEBUG 196 197 bb_error_msg("rresolve: unsupported address family %d!", 197 198 sin6->sin6_family); 198 199 #endif 199 200 errno = EAFNOSUPPORT; … … 210 211 } 211 212 212 s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), 213 name, sizeof(name), NULL, 0, 0); 214 if (s) { 213 s = getnameinfo((struct sockaddr *) sin6, sizeof(*sin6), 214 name, sizeof(name), 215 /*serv,servlen:*/ NULL, 0, 216 0); 217 if (s != 0) { 215 218 bb_error_msg("getnameinfo failed"); 216 219 return NULL; -
branches/3.2/mindi-busybox/libbb/isdirectory.c
r2725 r3232 16 16 * Nonexistent files return FALSE. 17 17 */ 18 int FAST_FUNC is_directory(const char *fileName, int followLinks , struct stat *statBuf)18 int FAST_FUNC is_directory(const char *fileName, int followLinks) 19 19 { 20 20 int status; 21 struct stat astatBuf; 22 23 if (statBuf == NULL) { 24 /* use auto stack buffer */ 25 statBuf = &astatBuf; 26 } 21 struct stat statBuf; 27 22 28 23 if (followLinks) 29 status = stat(fileName, statBuf);24 status = stat(fileName, &statBuf); 30 25 else 31 status = lstat(fileName, statBuf);26 status = lstat(fileName, &statBuf); 32 27 33 status = (status == 0 && S_ISDIR(statBuf ->st_mode));28 status = (status == 0 && S_ISDIR(statBuf.st_mode)); 34 29 35 30 return status; -
branches/3.2/mindi-busybox/libbb/kernel_version.c
r2725 r3232 21 21 { 22 22 struct utsname name; 23 char *s ;23 char *s, *t; 24 24 int i, r; 25 25 26 if (uname(&name) == -1) { 27 bb_perror_msg("can't get system information"); 28 return 0; 29 } 30 26 uname(&name); /* never fails */ 31 27 s = name.release; 32 28 r = 0; 33 29 for (i = 0; i < 3; i++) { 34 r = r * 256 + atoi(strtok(s, ".")); 30 t = strtok(s, "."); 31 r = r * 256 + (t ? atoi(t) : 0); 35 32 s = NULL; 36 33 } -
branches/3.2/mindi-busybox/libbb/lineedit.c
r2725 r3232 42 42 #include "libbb.h" 43 43 #include "unicode.h" 44 #ifndef _POSIX_VDISABLE 45 # define _POSIX_VDISABLE '\0' 46 #endif 47 44 48 45 49 #ifdef TEST … … 185 189 IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \ 186 190 } while (0) 191 187 192 static void deinit_S(void) 188 193 { … … 203 208 204 209 #if ENABLE_UNICODE_SUPPORT 205 static size_t load_string(const char *src, int maxsize) 206 { 207 ssize_t len = mbstowcs(command_ps, src, maxsize - 1); 208 if (len < 0) 209 len = 0; 210 command_ps[len] = BB_NUL; 211 return len; 210 static size_t load_string(const char *src) 211 { 212 if (unicode_status == UNICODE_ON) { 213 ssize_t len = mbstowcs(command_ps, src, S.maxsize - 1); 214 if (len < 0) 215 len = 0; 216 command_ps[len] = BB_NUL; 217 return len; 218 } else { 219 unsigned i = 0; 220 while (src[i] && i < S.maxsize - 1) { 221 command_ps[i] = src[i]; 222 i++; 223 } 224 command_ps[i] = BB_NUL; 225 return i; 226 } 212 227 } 213 228 static unsigned save_string(char *dst, unsigned maxsize) 214 229 { 230 if (unicode_status == UNICODE_ON) { 215 231 # if !ENABLE_UNICODE_PRESERVE_BROKEN 216 ssize_t len = wcstombs(dst, command_ps, maxsize - 1);217 if (len < 0)218 len = 0;219 dst[len] = '\0';220 return len;232 ssize_t len = wcstombs(dst, command_ps, maxsize - 1); 233 if (len < 0) 234 len = 0; 235 dst[len] = '\0'; 236 return len; 221 237 # else 222 unsigned dstpos = 0; 223 unsigned srcpos = 0; 224 225 maxsize--; 226 while (dstpos < maxsize) { 227 wchar_t wc; 228 int n = srcpos; 229 230 /* Convert up to 1st invalid byte (or up to end) */ 231 while ((wc = command_ps[srcpos]) != BB_NUL 232 && !unicode_is_raw_byte(wc) 233 ) { 238 unsigned dstpos = 0; 239 unsigned srcpos = 0; 240 241 maxsize--; 242 while (dstpos < maxsize) { 243 wchar_t wc; 244 int n = srcpos; 245 246 /* Convert up to 1st invalid byte (or up to end) */ 247 while ((wc = command_ps[srcpos]) != BB_NUL 248 && !unicode_is_raw_byte(wc) 249 ) { 250 srcpos++; 251 } 252 command_ps[srcpos] = BB_NUL; 253 n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); 254 if (n < 0) /* should not happen */ 255 break; 256 dstpos += n; 257 if (wc == BB_NUL) /* usually is */ 258 break; 259 260 /* We do have invalid byte here! */ 261 command_ps[srcpos] = wc; /* restore it */ 234 262 srcpos++; 235 } 236 command_ps[srcpos] = BB_NUL; 237 n = wcstombs(dst + dstpos, command_ps + n, maxsize - dstpos); 238 if (n < 0) /* should not happen */ 239 break; 240 dstpos += n; 241 if (wc == BB_NUL) /* usually is */ 242 break; 243 244 /* We do have invalid byte here! */ 245 command_ps[srcpos] = wc; /* restore it */ 246 srcpos++; 247 if (dstpos == maxsize) 248 break; 249 dst[dstpos++] = (char) wc; 250 } 251 dst[dstpos] = '\0'; 252 return dstpos; 263 if (dstpos == maxsize) 264 break; 265 dst[dstpos++] = (char) wc; 266 } 267 dst[dstpos] = '\0'; 268 return dstpos; 253 269 # endif 270 } else { 271 unsigned i = 0; 272 while ((dst[i] = command_ps[i]) != 0) 273 i++; 274 return i; 275 } 254 276 } 255 277 /* I thought just fputwc(c, stdout) would work. But no... */ 256 278 static void BB_PUTCHAR(wchar_t c) 257 279 { 258 char buf[MB_CUR_MAX + 1]; 259 mbstate_t mbst = { 0 }; 260 ssize_t len; 261 262 len = wcrtomb(buf, c, &mbst); 263 if (len > 0) { 264 buf[len] = '\0'; 265 fputs(buf, stdout); 280 if (unicode_status == UNICODE_ON) { 281 char buf[MB_CUR_MAX + 1]; 282 mbstate_t mbst = { 0 }; 283 ssize_t len = wcrtomb(buf, c, &mbst); 284 if (len > 0) { 285 buf[len] = '\0'; 286 fputs(buf, stdout); 287 } 288 } else { 289 /* In this case, c is always one byte */ 290 putchar(c); 266 291 } 267 292 } … … 298 323 } 299 324 #else /* !UNICODE */ 300 static size_t load_string(const char *src , int maxsize)301 { 302 safe_strncpy(command_ps, src, maxsize);325 static size_t load_string(const char *src) 326 { 327 safe_strncpy(command_ps, src, S.maxsize); 303 328 return strlen(command_ps); 304 329 } … … 1203 1228 /* where do we want to have cursor after all? */ 1204 1229 strcpy(&command[cursor_mb], chosen_match + match_pfx_len); 1205 len = load_string(command , S.maxsize);1230 len = load_string(command); 1206 1231 /* add match and tail */ 1207 1232 sprintf(&command[cursor_mb], "%s%s", chosen_match + match_pfx_len, match_buf); 1208 command_len = load_string(command , S.maxsize);1233 command_len = load_string(command); 1209 1234 /* write out the matched command */ 1210 1235 /* paranoia: load_string can return 0 on conv error, … … 1227 1252 line_input_t *n = xzalloc(sizeof(*n)); 1228 1253 n->flags = flags; 1254 n->max_history = MAX_HISTORY; 1229 1255 return n; 1230 1256 } … … 1232 1258 1233 1259 #if MAX_HISTORY > 0 1260 1261 unsigned size_from_HISTFILESIZE(const char *hp) 1262 { 1263 int size = MAX_HISTORY; 1264 if (hp) { 1265 size = atoi(hp); 1266 if (size <= 0) 1267 return 1; 1268 if (size > MAX_HISTORY) 1269 return MAX_HISTORY; 1270 } 1271 return size; 1272 } 1234 1273 1235 1274 static void save_command_ps_at_cur_history(void) … … 1313 1352 /* fill temp_h[], retaining only last MAX_HISTORY lines */ 1314 1353 memset(temp_h, 0, sizeof(temp_h)); 1315 st_parm->cnt_history_in_file = idx = 0; 1354 idx = 0; 1355 st_parm->cnt_history_in_file = 0; 1316 1356 while ((line = xmalloc_fgetline(fp)) != NULL) { 1317 1357 if (line[0] == '\0') { … … 1323 1363 st_parm->cnt_history_in_file++; 1324 1364 idx++; 1325 if (idx == MAX_HISTORY)1365 if (idx == st_parm->max_history) 1326 1366 idx = 0; 1327 1367 } … … 1332 1372 while (temp_h[idx] == NULL) { 1333 1373 idx++; 1334 if (idx == MAX_HISTORY)1374 if (idx == st_parm->max_history) 1335 1375 idx = 0; 1336 1376 } … … 1338 1378 1339 1379 /* copy temp_h[] to st_parm->history[] */ 1340 for (i = 0; i < MAX_HISTORY;) {1380 for (i = 0; i < st_parm->max_history;) { 1341 1381 line = temp_h[idx]; 1342 1382 if (!line) 1343 1383 break; 1344 1384 idx++; 1345 if (idx == MAX_HISTORY)1385 if (idx == st_parm->max_history) 1346 1386 idx = 0; 1347 1387 line_len = strlen(line); … … 1351 1391 } 1352 1392 st_parm->cnt_history = i; 1353 } 1354 } 1355 1356 /* state->flags is already checked to be nonzero */ 1393 if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) 1394 st_parm->cnt_history_in_file = i; 1395 } 1396 } 1397 1398 # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1399 void save_history(line_input_t *st) 1400 { 1401 FILE *fp; 1402 1403 if (!st->hist_file) 1404 return; 1405 if (st->cnt_history <= st->cnt_history_in_file) 1406 return; 1407 1408 fp = fopen(st->hist_file, "a"); 1409 if (fp) { 1410 int i, fd; 1411 char *new_name; 1412 line_input_t *st_temp; 1413 1414 for (i = st->cnt_history_in_file; i < st->cnt_history; i++) 1415 fprintf(fp, "%s\n", st->history[i]); 1416 fclose(fp); 1417 1418 /* we may have concurrently written entries from others. 1419 * load them */ 1420 st_temp = new_line_input_t(st->flags); 1421 st_temp->hist_file = st->hist_file; 1422 st_temp->max_history = st->max_history; 1423 load_history(st_temp); 1424 1425 /* write out temp file and replace hist_file atomically */ 1426 new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid()); 1427 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1428 if (fd >= 0) { 1429 fp = xfdopen_for_write(fd); 1430 for (i = 0; i < st_temp->cnt_history; i++) 1431 fprintf(fp, "%s\n", st_temp->history[i]); 1432 fclose(fp); 1433 if (rename(new_name, st->hist_file) == 0) 1434 st->cnt_history_in_file = st_temp->cnt_history; 1435 } 1436 free(new_name); 1437 free_line_input_t(st_temp); 1438 } 1439 } 1440 # else 1357 1441 static void save_history(char *str) 1358 1442 { 1359 1443 int fd; 1360 1444 int len, len2; 1445 1446 if (!state->hist_file) 1447 return; 1361 1448 1362 1449 fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); … … 1374 1461 /* did we write so much that history file needs trimming? */ 1375 1462 state->cnt_history_in_file++; 1376 if (state->cnt_history_in_file > MAX_HISTORY* 4) {1463 if (state->cnt_history_in_file > state->max_history * 4) { 1377 1464 char *new_name; 1378 1465 line_input_t *st_temp; … … 1382 1469 st_temp = new_line_input_t(state->flags); 1383 1470 st_temp->hist_file = state->hist_file; 1471 st_temp->max_history = state->max_history; 1384 1472 load_history(st_temp); 1385 1473 1386 1474 /* write out temp file and replace hist_file atomically */ 1387 1475 new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); 1388 fd = open( state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600);1476 fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); 1389 1477 if (fd >= 0) { 1390 1478 FILE *fp; … … 1402 1490 } 1403 1491 } 1492 # endif 1404 1493 # else 1405 1494 # define load_history(a) ((void)0) … … 1420 1509 return; 1421 1510 1422 free(state->history[ MAX_HISTORY]); /* redundant, paranoia */1423 state->history[ MAX_HISTORY] = NULL; /* redundant, paranoia */1511 free(state->history[state->max_history]); /* redundant, paranoia */ 1512 state->history[state->max_history] = NULL; /* redundant, paranoia */ 1424 1513 1425 1514 /* If history[] is full, remove the oldest command */ 1426 /* we need to keep history[ MAX_HISTORY] empty, hence >=, not > */1427 if (i >= MAX_HISTORY) {1515 /* we need to keep history[state->max_history] empty, hence >=, not > */ 1516 if (i >= state->max_history) { 1428 1517 free(state->history[0]); 1429 for (i = 0; i < MAX_HISTORY-1; i++)1518 for (i = 0; i < state->max_history-1; i++) 1430 1519 state->history[i] = state->history[i+1]; 1431 /* i == MAX_HISTORY-1 */ 1432 } 1433 /* i <= MAX_HISTORY-1 */ 1520 /* i == state->max_history-1 */ 1521 # if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1522 if (state->cnt_history_in_file) 1523 state->cnt_history_in_file--; 1524 # endif 1525 } 1526 /* i <= state->max_history-1 */ 1434 1527 state->history[i++] = xstrdup(str); 1435 /* i <= MAX_HISTORY*/1528 /* i <= state->max_history */ 1436 1529 state->cur_history = i; 1437 1530 state->cnt_history = i; 1438 # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY 1439 if ((state->flags & SAVE_HISTORY) && state->hist_file) 1440 save_history(str); 1531 # if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1532 save_history(str); 1441 1533 # endif 1442 1534 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) … … 1645 1737 * poll([{fd=0, events=POLLIN}], 1, 0) = 0 (Timeout) <-- no input exists 1646 1738 * write(1, "\33[6n", 4) = 4 <-- send the ESC sequence, quick! 1647 * poll([{fd=0, events=POLLIN}], 1, 4294967295) = 1 ([{fd=0, revents=POLLIN}])1739 * poll([{fd=0, events=POLLIN}], 1, -1) = 1 ([{fd=0, revents=POLLIN}]) 1648 1740 * read(0, "\n", 1) = 1 <-- oh crap, user's input got in first 1649 1741 */ … … 1803 1895 int sv_errno = errno; 1804 1896 unsigned width; 1897 1805 1898 get_terminal_width_height(0, &width, NULL); 1806 cmdedit_setwidth(width, nsig /* - just a yes/no flag */); 1807 if (nsig == SIGWINCH)1808 signal(SIGWINCH, win_changed); /* rearm ourself */ 1899 //FIXME: cmdedit_setwidth() -> redraw() -> printf() -> KABOOM! (we are in signal handler!) 1900 cmdedit_setwidth(width, /*redraw_flg:*/ nsig); 1901 1809 1902 errno = sv_errno; 1810 1903 } 1811 1904 1812 static int lineedit_read_key(char *read_key_buffer )1905 static int lineedit_read_key(char *read_key_buffer, int timeout) 1813 1906 { 1814 1907 int64_t ic; 1815 int timeout = -1;1816 1908 #if ENABLE_UNICODE_SUPPORT 1817 1909 char unicode_buf[MB_CUR_MAX + 1]; … … 1912 2004 #define CTRL(a) ((a) & ~0x40) 1913 2005 2006 enum { 2007 VI_CMDMODE_BIT = 0x40000000, 2008 /* 0x80000000 bit flags KEYCODE_xxx */ 2009 }; 2010 2011 #if ENABLE_FEATURE_REVERSE_SEARCH 2012 /* Mimic readline Ctrl-R reverse history search. 2013 * When invoked, it shows the following prompt: 2014 * (reverse-i-search)'': user_input [cursor pos unchanged by Ctrl-R] 2015 * and typing results in search being performed: 2016 * (reverse-i-search)'tmp': cd /tmp [cursor under t in /tmp] 2017 * Search is performed by looking at progressively older lines in history. 2018 * Ctrl-R again searches for the next match in history. 2019 * Backspace deletes last matched char. 2020 * Control keys exit search and return to normal editing (at current history line). 2021 */ 2022 static int32_t reverse_i_search(void) 2023 { 2024 char match_buf[128]; /* for user input */ 2025 char read_key_buffer[KEYCODE_BUFFER_SIZE]; 2026 const char *matched_history_line; 2027 const char *saved_prompt; 2028 int32_t ic; 2029 2030 matched_history_line = NULL; 2031 read_key_buffer[0] = 0; 2032 match_buf[0] = '\0'; 2033 2034 /* Save and replace the prompt */ 2035 saved_prompt = cmdedit_prompt; 2036 goto set_prompt; 2037 2038 while (1) { 2039 int h; 2040 unsigned match_buf_len = strlen(match_buf); 2041 2042 fflush_all(); 2043 //FIXME: correct timeout? 2044 ic = lineedit_read_key(read_key_buffer, -1); 2045 2046 switch (ic) { 2047 case CTRL('R'): /* searching for the next match */ 2048 break; 2049 2050 case '\b': 2051 case '\x7f': 2052 /* Backspace */ 2053 if (unicode_status == UNICODE_ON) { 2054 while (match_buf_len != 0) { 2055 uint8_t c = match_buf[--match_buf_len]; 2056 if ((c & 0xc0) != 0x80) /* start of UTF-8 char? */ 2057 break; /* yes */ 2058 } 2059 } else { 2060 if (match_buf_len != 0) 2061 match_buf_len--; 2062 } 2063 match_buf[match_buf_len] = '\0'; 2064 break; 2065 2066 default: 2067 if (ic < ' ' 2068 || (!ENABLE_UNICODE_SUPPORT && ic >= 256) 2069 || (ENABLE_UNICODE_SUPPORT && ic >= VI_CMDMODE_BIT) 2070 ) { 2071 goto ret; 2072 } 2073 2074 /* Append this char */ 2075 #if ENABLE_UNICODE_SUPPORT 2076 if (unicode_status == UNICODE_ON) { 2077 mbstate_t mbstate = { 0 }; 2078 char buf[MB_CUR_MAX + 1]; 2079 int len = wcrtomb(buf, ic, &mbstate); 2080 if (len > 0) { 2081 buf[len] = '\0'; 2082 if (match_buf_len + len < sizeof(match_buf)) 2083 strcpy(match_buf + match_buf_len, buf); 2084 } 2085 } else 2086 #endif 2087 if (match_buf_len < sizeof(match_buf) - 1) { 2088 match_buf[match_buf_len] = ic; 2089 match_buf[match_buf_len + 1] = '\0'; 2090 } 2091 break; 2092 } /* switch (ic) */ 2093 2094 /* Search in history for match_buf */ 2095 h = state->cur_history; 2096 if (ic == CTRL('R')) 2097 h--; 2098 while (h >= 0) { 2099 if (state->history[h]) { 2100 char *match = strstr(state->history[h], match_buf); 2101 if (match) { 2102 state->cur_history = h; 2103 matched_history_line = state->history[h]; 2104 command_len = load_string(matched_history_line); 2105 cursor = match - matched_history_line; 2106 //FIXME: cursor position for Unicode case 2107 2108 free((char*)cmdedit_prompt); 2109 set_prompt: 2110 cmdedit_prompt = xasprintf("(reverse-i-search)'%s': ", match_buf); 2111 cmdedit_prmt_len = strlen(cmdedit_prompt); 2112 goto do_redraw; 2113 } 2114 } 2115 h--; 2116 } 2117 2118 /* Not found */ 2119 match_buf[match_buf_len] = '\0'; 2120 beep(); 2121 continue; 2122 2123 do_redraw: 2124 redraw(cmdedit_y, command_len - cursor); 2125 } /* while (1) */ 2126 2127 ret: 2128 if (matched_history_line) 2129 command_len = load_string(matched_history_line); 2130 2131 free((char*)cmdedit_prompt); 2132 cmdedit_prompt = saved_prompt; 2133 cmdedit_prmt_len = strlen(cmdedit_prompt); 2134 redraw(cmdedit_y, command_len - cursor); 2135 2136 return ic; 2137 } 2138 #endif 2139 1914 2140 /* maxsize must be >= 2. 1915 2141 * Returns: … … 1918 2144 * >0 length of input string, including terminating '\n' 1919 2145 */ 1920 int FAST_FUNC read_line_input( const char *prompt, char *command, int maxsize, line_input_t *st)2146 int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) 1921 2147 { 1922 2148 int len; … … 1955 2181 S.maxsize = maxsize; 1956 2182 1957 /* With nullflags, no other fields are ever used */2183 /* With zero flags, no other fields are ever used */ 1958 2184 state = st ? st : (line_input_t*) &const_int_0; 1959 2185 #if MAX_HISTORY > 0 1960 2186 # if ENABLE_FEATURE_EDITING_SAVEHISTORY 1961 if ( (state->flags & SAVE_HISTORY) &&state->hist_file)2187 if (state->hist_file) 1962 2188 if (state->cnt_history == 0) 1963 2189 load_history(state); … … 1979 2205 1980 2206 new_settings = initial_settings; 1981 new_settings.c_lflag &= ~ICANON; /* unbuffered input */ 1982 /* Turn off echoing and CTRL-C, so we can trap it */ 1983 new_settings.c_lflag &= ~(ECHO | ECHONL | ISIG); 1984 /* Hmm, in linux c_cc[] is not parsed if ICANON is off */ 2207 /* ~ICANON: unbuffered input (most c_cc[] are disabled, VMIN/VTIME are enabled) */ 2208 /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ 2209 /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ 2210 new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); 2211 /* reads would block only if < 1 char is available */ 1985 2212 new_settings.c_cc[VMIN] = 1; 2213 /* no timeout (reads block forever) */ 1986 2214 new_settings.c_cc[VTIME] = 0; 1987 /* Turn off CTRL-C, so we can trap it */ 1988 #ifndef _POSIX_VDISABLE 1989 # define _POSIX_VDISABLE '\0' 1990 #endif 1991 new_settings.c_cc[VINTR] = _POSIX_VDISABLE; 2215 /* Should be not needed if ISIG is off: */ 2216 /* Turn off CTRL-C */ 2217 /* new_settings.c_cc[VINTR] = _POSIX_VDISABLE; */ 1992 2218 tcsetattr_stdin_TCSANOW(&new_settings); 1993 2219 1994 /* Now initialize things */1995 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);1996 win_changed(0); /* do initial resizing */1997 2220 #if ENABLE_USERNAME_OR_HOMEDIR 1998 2221 { … … 2008 2231 2009 2232 #if 0 2010 for (i = 0; i <= MAX_HISTORY; i++)2233 for (i = 0; i <= state->max_history; i++) 2011 2234 bb_error_msg("history[%d]:'%s'", i, state->history[i]); 2012 2235 bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history); … … 2016 2239 parse_and_put_prompt(prompt); 2017 2240 ask_terminal(); 2241 2242 /* Install window resize handler (NB: after *all* init is complete) */ 2243 //FIXME: save entire sigaction! 2244 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); 2245 win_changed(0); /* get initial window size */ 2018 2246 2019 2247 read_key_buffer[0] = 0; … … 2027 2255 * in one place. 2028 2256 */ 2029 enum {2030 VI_CMDMODE_BIT = 0x40000000,2031 /* 0x80000000 bit flags KEYCODE_xxx */2032 };2033 2257 int32_t ic, ic_raw; 2034 2258 2035 2259 fflush_all(); 2036 ic = ic_raw = lineedit_read_key(read_key_buffer); 2037 2260 ic = ic_raw = lineedit_read_key(read_key_buffer, timeout); 2261 2262 #if ENABLE_FEATURE_REVERSE_SEARCH 2263 again: 2264 #endif 2038 2265 #if ENABLE_FEATURE_EDITING_VI 2039 2266 newdelflag = 1; … … 2139 2366 input_backspace(); 2140 2367 break; 2368 #if ENABLE_FEATURE_REVERSE_SEARCH 2369 case CTRL('R'): 2370 ic = ic_raw = reverse_i_search(); 2371 goto again; 2372 #endif 2141 2373 2142 2374 #if ENABLE_FEATURE_EDITING_VI … … 2195 2427 int nc, sc; 2196 2428 2197 ic = lineedit_read_key(read_key_buffer );2429 ic = lineedit_read_key(read_key_buffer, timeout); 2198 2430 if (errno) /* error */ 2199 2431 goto return_error_indicator; … … 2259 2491 case 'r'|VI_CMDMODE_BIT: 2260 2492 //FIXME: unicode case? 2261 ic = lineedit_read_key(read_key_buffer );2493 ic = lineedit_read_key(read_key_buffer, timeout); 2262 2494 if (errno) /* error */ 2263 2495 goto return_error_indicator; … … 2276 2508 input_backward(1); 2277 2509 } 2510 /* Handle a few ESC-<key> combinations the same way 2511 * standard readline bindings (IOW: bash) do. 2512 * Often, Alt-<key> generates ESC-<key>. 2513 */ 2514 ic = lineedit_read_key(read_key_buffer, timeout); 2515 switch (ic) { 2516 //case KEYCODE_LEFT: - bash doesn't do this 2517 case 'b': 2518 ctrl_left(); 2519 break; 2520 //case KEYCODE_RIGHT: - bash doesn't do this 2521 case 'f': 2522 ctrl_right(); 2523 break; 2524 //case KEYCODE_DELETE: - bash doesn't do this 2525 case 'd': /* Alt-D */ 2526 { 2527 /* Delete word forward */ 2528 int nc, sc = cursor; 2529 ctrl_right(); 2530 nc = cursor - sc; 2531 input_backward(nc); 2532 while (--nc >= 0) 2533 input_delete(1); 2534 break; 2535 } 2536 case '\b': /* Alt-Backspace(?) */ 2537 case '\x7f': /* Alt-Backspace(?) */ 2538 //case 'w': - bash doesn't do this 2539 { 2540 /* Delete word backward */ 2541 int sc = cursor; 2542 ctrl_left(); 2543 while (sc-- > cursor) 2544 input_delete(1); 2545 break; 2546 } 2547 } 2278 2548 break; 2279 2549 #endif /* FEATURE_COMMAND_EDITING_VI */ … … 2292 2562 /* change command */ 2293 2563 command_len = load_string(state->history[state->cur_history] ? 2294 state->history[state->cur_history] : "" , maxsize);2564 state->history[state->cur_history] : ""); 2295 2565 /* redraw and go to eol (bol, in vi) */ 2296 2566 redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); … … 2304 2574 break; 2305 2575 case KEYCODE_CTRL_LEFT: 2576 case KEYCODE_ALT_LEFT: /* bash doesn't do it */ 2306 2577 ctrl_left(); 2307 2578 break; 2308 2579 case KEYCODE_CTRL_RIGHT: 2580 case KEYCODE_ALT_RIGHT: /* bash doesn't do it */ 2309 2581 ctrl_right(); 2310 2582 break; … … 2458 2730 fputs(prompt, stdout); 2459 2731 fflush_all(); 2460 fgets(command, maxsize, stdin); 2732 if (!fgets(command, maxsize, stdin)) 2733 return -1; 2461 2734 return strlen(command); 2462 2735 } -
branches/3.2/mindi-busybox/libbb/llist.c
r2725 r3232 63 63 /* Recursively free all elements in the linked list. If freeit != NULL 64 64 * call it on each datum in the list */ 65 void FAST_FUNC llist_free(llist_t *elm, void (*freeit) 65 void FAST_FUNC llist_free(llist_t *elm, void (*freeit)(void *data)) 66 66 { 67 67 while (elm) { -
branches/3.2/mindi-busybox/libbb/loop.c
r2725 r3232 85 85 file/offset if it finds one. 86 86 */ 87 int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset )87 int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) 88 88 { 89 89 char dev[LOOP_NAMESIZE]; … … 94 94 95 95 /* Open the file. Barf if this doesn't work. */ 96 mode = O_RDWR;96 mode = ro ? O_RDONLY : O_RDWR; 97 97 ffd = open(file, mode); 98 98 if (ffd < 0) { 99 mode = O_RDONLY; 100 ffd = open(file, mode); 99 if (mode != O_RDONLY) { 100 mode = O_RDONLY; 101 ffd = open(file, mode); 102 } 101 103 if (ffd < 0) 102 104 return -errno; … … 149 151 150 152 /* If this block device already set up right, re-use it. 151 152 153 153 * (Yes this is racy, but associating two loop devices with the same 154 * file isn't pretty either. In general, mounting the same file twice 155 * without using losetup manually is problematic.) 154 156 */ 155 157 } else -
branches/3.2/mindi-busybox/libbb/make_directory.c
r2725 r3232 108 108 if ((mode != -1) && (chmod(path, mode) < 0)) { 109 109 fail_msg = "set permissions of"; 110 if (flags & FILEUTILS_IGNORE_CHMOD_ERR) { 111 flags = 0; 112 goto print_err; 113 } 110 114 break; 111 115 } … … 117 121 } /* while (1) */ 118 122 123 flags = -1; 124 print_err: 119 125 bb_perror_msg("can't %s directory '%s'", fail_msg, path); 120 flags = -1;121 126 goto ret; 122 127 ret0: -
branches/3.2/mindi-busybox/libbb/makedev.c
r2725 r3232 9 9 /* We do not include libbb.h - #define makedev() is there! */ 10 10 #include "platform.h" 11 #include <features.h> 12 #include <sys/sysmacros.h> 11 12 /* Different Unixes want different headers for makedev */ 13 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ 14 || defined(__APPLE__) 15 # include <sys/types.h> 16 #else 17 # include <features.h> 18 # include <sys/sysmacros.h> 19 #endif 13 20 14 21 #ifdef __GLIBC__ 15 /* At least glibc has horrendously large inline for this, so wrap it */22 /* At least glibc has horrendously large inline for this, so wrap it. */ 16 23 /* uclibc people please check - do we need "&& !__UCLIBC__" above? */ 17 24 18 /* suppress gcc "no previous prototype" warning */19 unsigned long long FAST_FUNC bb_makedev(unsigned int major, unsigned intminor);20 unsigned long long FAST_FUNC bb_makedev(unsigned int major, unsigned intminor)25 /* Suppress gcc "no previous prototype" warning */ 26 unsigned long long FAST_FUNC bb_makedev(unsigned major, unsigned minor); 27 unsigned long long FAST_FUNC bb_makedev(unsigned major, unsigned minor) 21 28 { 22 29 return makedev(major, minor); -
branches/3.2/mindi-busybox/libbb/match_fstype.c
r2725 r3232 12 12 13 13 #include "libbb.h" 14 15 #ifdef HAVE_MNTENT_H 14 16 15 17 int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) … … 41 43 return !match; 42 44 } 45 46 #endif /* HAVE_MNTENT_H */ -
branches/3.2/mindi-busybox/libbb/messages.c
r2725 r3232 23 23 24 24 25 const char bb_msg_memory_exhausted[] ALIGN1 = " memory exhausted";25 const char bb_msg_memory_exhausted[] ALIGN1 = "out of memory"; 26 26 const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'"; 27 27 const char bb_msg_unknown[] ALIGN1 = "(unknown)"; … … 49 49 const int const_int_0 = 0; 50 50 51 #i nclude <utmp.h>51 #if ENABLE_FEATURE_WTMP 52 52 /* This is usually something like "/var/adm/wtmp" or "/var/log/wtmp" */ 53 53 const char bb_path_wtmp_file[] ALIGN1 = 54 # if defined _PATH_WTMP54 # if defined _PATH_WTMP 55 55 _PATH_WTMP; 56 # elif defined WTMP_FILE56 # elif defined WTMP_FILE 57 57 WTMP_FILE; 58 #else 59 #error unknown path to wtmp file 58 # else 59 # error unknown path to wtmp file 60 # endif 60 61 #endif 61 62 -
branches/3.2/mindi-busybox/libbb/obscure.c
r2725 r3232 110 110 return "similar to username"; 111 111 } 112 #ifndef __BIONIC__ 112 113 /* no gecos as-is, as sub-string, reversed, capitalized, doubled */ 113 114 if (pw->pw_gecos[0] && string_checker(new_p, pw->pw_gecos)) { 114 115 return "similar to gecos"; 115 116 } 117 #endif 116 118 /* hostname as-is, as sub-string, reversed, capitalized, doubled */ 117 119 hostname = safe_gethostname(); -
branches/3.2/mindi-busybox/libbb/parse_config.c
r2725 r3232 9 9 */ 10 10 11 /* Uncomment to enable test applet */ 12 ////config:config PARSE 13 ////config: bool "Uniform config file parser debugging applet: parse" 14 ////config: default n 15 ////config: help 16 ////config: Typical usage of parse API: 17 ////config: char *t[3]; 18 ////config: parser_t *p = config_open(filename); 19 ////config: while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens 20 ////config: bb_error_msg("TOKENS: '%s''%s''%s'", t[0], t[1], t[2]); 21 ////config: } 22 ////config: config_close(p); 23 24 ////applet:IF_PARSE(APPLET(parse, BB_DIR_USR_BIN, BB_SUID_DROP)) 25 26 //kbuild:lib-y += parse_config.o 27 28 //usage:#define parse_trivial_usage 29 //usage: "[-x] [-n MAXTOKENS] [-m MINTOKENS] [-d DELIMS] [-f FLAGS] FILE..." 30 //usage:#define parse_full_usage "\n\n" 31 //usage: " -x Suppress output (for benchmarking)" 32 11 33 #include "libbb.h" 12 34 … … 16 38 { 17 39 const char *delims = "# \t"; 40 char **t; 18 41 unsigned flags = PARSE_NORMAL; 19 42 int mintokens = 0, ntokens = 128; 43 unsigned noout; 20 44 21 45 opt_complementary = "-1:n+:m+:f+"; 22 getopt32(argv, "n:m:d:f:", &ntokens, &mintokens, &delims, &flags);46 noout = 1 & getopt32(argv, "xn:m:d:f:", &ntokens, &mintokens, &delims, &flags); 23 47 //argc -= optind; 24 48 argv += optind; 49 50 t = xmalloc(sizeof(t[0]) * ntokens); 25 51 while (*argv) { 52 int n; 26 53 parser_t *p = config_open(*argv); 27 if (p) { 28 int n; 29 char **t = xmalloc(sizeof(char *) * ntokens); 30 while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) { 54 while ((n = config_read(p, t, ntokens, mintokens, delims, flags)) != 0) { 55 if (!noout) { 31 56 for (int i = 0; i < n; ++i) 32 57 printf("[%s]", t[i]); 33 58 puts(""); 34 59 } 35 config_close(p);36 }60 } 61 config_close(p); 37 62 argv++; 38 63 } … … 40 65 } 41 66 #endif 42 43 /*44 45 Typical usage:46 47 ----- CUT -----48 char *t[3]; // tokens placeholder49 parser_t *p = config_open(filename);50 if (p) {51 // parse line-by-line52 while (config_read(p, t, 3, 0, delimiters, flags)) { // 1..3 tokens53 // use tokens54 bb_error_msg("TOKENS: [%s][%s][%s]", t[0], t[1], t[2]);55 }56 ...57 // free parser58 config_close(p);59 }60 ----- CUT -----61 62 */63 67 64 68 parser_t* FAST_FUNC config_open2(const char *filename, FILE* FAST_FUNC (*fopen_func)(const char *path)) … … 80 84 } 81 85 82 static void config_free_data(parser_t *parser)83 {84 free(parser->line);85 parser->line = NULL;86 if (PARSE_KEEP_COPY) { /* compile-time constant */87 free(parser->data);88 parser->data = NULL;89 }90 }91 92 86 void FAST_FUNC config_close(parser_t *parser) 93 87 { 94 88 if (parser) { 95 config_free_data(parser); 89 if (PARSE_KEEP_COPY) /* compile-time constant */ 90 free(parser->data); 96 91 fclose(parser->fp); 92 free(parser->line); 93 free(parser->nline); 97 94 free(parser); 98 95 } 99 96 } 97 98 /* This function reads an entire line from a text file, 99 * up to a newline, exclusive. 100 * Trailing '\' is recognized as line continuation. 101 * Returns -1 if EOF/error. 102 */ 103 static int get_line_with_continuation(parser_t *parser) 104 { 105 ssize_t len, nlen; 106 char *line; 107 108 len = getline(&parser->line, &parser->line_alloc, parser->fp); 109 if (len <= 0) 110 return len; 111 112 line = parser->line; 113 for (;;) { 114 parser->lineno++; 115 if (line[len - 1] == '\n') 116 len--; 117 if (len == 0 || line[len - 1] != '\\') 118 break; 119 len--; 120 121 nlen = getline(&parser->nline, &parser->nline_alloc, parser->fp); 122 if (nlen <= 0) 123 break; 124 125 if (parser->line_alloc < len + nlen + 1) { 126 parser->line_alloc = len + nlen + 1; 127 line = parser->line = xrealloc(line, parser->line_alloc); 128 } 129 memcpy(&line[len], parser->nline, nlen); 130 len += nlen; 131 } 132 133 line[len] = '\0'; 134 return len; 135 } 136 100 137 101 138 /* … … 127 164 char *line; 128 165 int ntokens, mintokens; 129 int t, len; 166 int t; 167 168 if (!parser) 169 return 0; 130 170 131 171 ntokens = (uint8_t)flags; 132 172 mintokens = (uint8_t)(flags >> 8); 133 173 134 if (parser == NULL) 174 again: 175 memset(tokens, 0, sizeof(tokens[0]) * ntokens); 176 177 /* Read one line (handling continuations with backslash) */ 178 if (get_line_with_continuation(parser) < 0) 135 179 return 0; 136 180 137 again: 138 memset(tokens, 0, sizeof(tokens[0]) * ntokens); 139 config_free_data(parser); 140 141 /* Read one line (handling continuations with backslash) */ 142 line = bb_get_chunk_with_continuation(parser->fp, &len, &parser->lineno); 143 if (line == NULL) 144 return 0; 145 parser->line = line; 146 147 /* Strip trailing line-feed if any */ 148 if (len && line[len-1] == '\n') 149 line[len-1] = '\0'; 181 line = parser->line; 150 182 151 183 /* Skip token in the start of line? */ … … 156 188 goto again; 157 189 158 if (flags & PARSE_KEEP_COPY) 190 if (flags & PARSE_KEEP_COPY) { 191 free(parser->data); 159 192 parser->data = xstrdup(line); 193 } 160 194 161 195 /* Tokenize the line */ … … 171 205 } else { 172 206 /* Combining, find comment char if any */ 173 line = strchrnul(line, delims[0]);207 line = strchrnul(line, PARSE_EOL_COMMENTS ? delims[0] : '\0'); 174 208 175 209 /* Trim any extra delimiters from the end */ … … 203 237 if (flags & PARSE_MIN_DIE) 204 238 xfunc_die(); 205 if (flags & PARSE_KEEP_COPY)206 free(parser->data);207 239 goto again; 208 240 } -
branches/3.2/mindi-busybox/libbb/platform.c
r2725 r3232 43 43 #endif 44 44 45 #ifndef HAVE_ FDPRINTF46 /* dprintf is now actuallypart of POSIX.1, but was only added in 2008 */47 int fdprintf(int fd, const char *format, ...)45 #ifndef HAVE_DPRINTF 46 /* dprintf is now part of POSIX.1, but was only added in 2008 */ 47 int dprintf(int fd, const char *format, ...) 48 48 { 49 49 va_list p; … … 135 135 } 136 136 #endif 137 138 #ifndef HAVE_STPCPY 139 char* FAST_FUNC stpcpy(char *p, const char *to_add) 140 { 141 while ((*p = *to_add) != '\0') { 142 p++; 143 to_add++; 144 } 145 return p; 146 } 147 #endif 148 149 #ifndef HAVE_GETLINE 150 ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream) 151 { 152 int ch; 153 char *line = *lineptr; 154 size_t alloced = *n; 155 size_t len = 0; 156 157 do { 158 ch = fgetc(stream); 159 if (ch == EOF) 160 break; 161 if (len + 1 >= alloced) { 162 alloced += alloced/4 + 64; 163 line = xrealloc(line, alloced); 164 } 165 line[len++] = ch; 166 } while (ch != '\n'); 167 168 if (len == 0) 169 return -1; 170 171 line[len] = '\0'; 172 *lineptr = line; 173 *n = alloced; 174 return len; 175 } 176 #endif -
branches/3.2/mindi-busybox/libbb/procps.c
r2725 r3232 13 13 14 14 15 typedef struct unsigned_to_name_map_t {16 longid;15 typedef struct id_to_name_map_t { 16 uid_t id; 17 17 char name[USERNAME_MAX_SIZE]; 18 } unsigned_to_name_map_t;18 } id_to_name_map_t; 19 19 20 20 typedef struct cache_t { 21 unsigned_to_name_map_t *cache;21 id_to_name_map_t *cache; 22 22 int size; 23 23 } cache_t; … … 40 40 /* Returns -N-1 if not found. */ 41 41 /* cp->cache[N] is allocated and must be filled in this case */ 42 static int get_cached(cache_t *cp, u nsignedid)42 static int get_cached(cache_t *cp, uid_t id) 43 43 { 44 44 int i; … … 53 53 #endif 54 54 55 static char* get_cached(cache_t *cp, longid,56 char* FAST_FUNC x2x_utoa( longid))55 static char* get_cached(cache_t *cp, uid_t id, 56 char* FAST_FUNC x2x_utoa(uid_t id)) 57 57 { 58 58 int i; … … 128 128 unsigned long n = 0; 129 129 130 while ((c = *str++) != ' ') { 130 /* Need to stop on both ' ' and '\n' */ 131 while ((c = *str++) > ' ') { 131 132 c = ((c|0x20) - '0'); 132 133 if (c > 9) 133 / / c = c + '0' - 'a' + 10:134 /* c = c + '0' - 'a' + 10: */ 134 135 c = c - ('a' - '0' - 10); 135 136 n = n*16 + c; … … 144 145 static unsigned long fast_strtoul_10(char **endptr) 145 146 { 146 char c;147 unsigned char c; 147 148 char *str = *endptr; 148 149 unsigned long n = *str - '0'; 149 150 150 while ((c = *++str) != ' ') 151 /* Need to stop on both ' ' and '\n' */ 152 while ((c = *++str) > ' ') 151 153 n = n*10 + (c - '0'); 152 154 … … 179 181 #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP 180 182 int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, 181 183 void (*cb)(struct smaprec *, void *), void *data) 182 184 { 183 185 FILE *file; … … 199 201 while (fgets(buf, PROCPS_BUFSIZE, file)) { 200 202 // Each mapping datum has this form: 201 // f7d29000-f7d39000 rw-s ADR M:m OFS FILE203 // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME 202 204 // Size: nnn kB 203 205 // Rss: nnn kB … … 224 226 if (tp) { 225 227 // We reached next mapping - the line of this form: 226 // f7d29000-f7d39000 rw-s ADR M:m OFS FILE228 // f7d29000-f7d39000 rw-s FILEOFS M:m INODE FILENAME 227 229 228 230 if (cb) { … … 243 245 strncpy(currec.smap_mode, tp, sizeof(currec.smap_mode)-1); 244 246 245 // skipping "rw-s ADR M:m OFS"247 // skipping "rw-s FILEOFS M:m INODE " 246 248 tp = skip_whitespace(skip_fields(tp, 4)); 247 249 // filter out /dev/something (something != zero) … … 285 287 procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) 286 288 { 287 struct dirent *entry;288 char buf[PROCPS_BUFSIZE];289 char filename[sizeof("/proc//cmdline") + sizeof(int)*3];290 char *filename_tail;291 long tasknice;292 unsigned pid;293 int n;294 struct stat sb;295 296 289 if (!sp) 297 290 sp = alloc_procps_scan(); 298 291 299 292 for (;;) { 293 struct dirent *entry; 294 char buf[PROCPS_BUFSIZE]; 295 long tasknice; 296 unsigned pid; 297 int n; 298 char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2]; 299 char *filename_tail; 300 300 301 #if ENABLE_FEATURE_SHOW_THREADS 301 if ( (flags & PSSCAN_TASKS) &&sp->task_dir) {302 if (sp->task_dir) { 302 303 entry = readdir(sp->task_dir); 303 304 if (entry) … … 321 322 * there will be /proc/PID/task/PID (same PID!), 322 323 * so just go ahead and dive into /proc/PID/task. */ 323 char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3]; 324 sprintf(task_dir, "/proc/%u/task", pid); 325 sp->task_dir = xopendir(task_dir); 324 sprintf(filename, "/proc/%u/task", pid); 325 /* Note: if opendir fails, we just go to next /proc/XXX */ 326 sp->task_dir = opendir(filename); 327 sp->main_thread_pid = pid; 326 328 continue; 327 329 } … … 346 348 #endif 347 349 348 filename_tail = filename + sprintf(filename, "/proc/%u/", pid); 350 #if ENABLE_FEATURE_SHOW_THREADS 351 if (sp->task_dir) 352 filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid); 353 else 354 #endif 355 filename_tail = filename + sprintf(filename, "/proc/%u/", pid); 349 356 350 357 if (flags & PSSCAN_UIDGID) { 358 struct stat sb; 351 359 if (stat(filename, &sb)) 352 360 continue; /* process probably exited */ … … 356 364 } 357 365 358 if (flags & PSSCAN_STAT) { 366 /* These are all retrieved from proc/NN/stat in one go: */ 367 if (flags & (PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID 368 | PSSCAN_COMM | PSSCAN_STATE 369 | PSSCAN_VSZ | PSSCAN_RSS 370 | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_START_TIME 371 | PSSCAN_TTY | PSSCAN_NICE 372 | PSSCAN_CPU) 373 ) { 359 374 char *cp, *comm1; 360 375 int tty; … … 411 426 continue; /* bogus data, get next /proc/XXX */ 412 427 # if ENABLE_FEATURE_TOP_SMP_PROCESS 413 if (n < 11+15)428 if (n == 11) 414 429 sp->last_seen_on_cpu = 0; 415 430 # endif … … 558 573 { 559 574 int sz; 560 char filename[sizeof("/proc/ /cmdline") + sizeof(int)*3];575 char filename[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; 561 576 562 577 sprintf(filename, "/proc/%u/cmdline", pid); 563 578 sz = open_read_close(filename, buf, col - 1); 564 579 if (sz > 0) { 580 const char *base; 581 int comm_len; 582 565 583 buf[sz] = '\0'; 566 584 while (--sz >= 0 && buf[sz] == '\0') 567 585 continue; 568 do { 586 /* Prevent basename("process foo/bar") = "bar" */ 587 strchrnul(buf, ' ')[0] = '\0'; 588 base = bb_basename(buf); /* before we replace argv0's NUL with space */ 589 while (sz >= 0) { 569 590 if ((unsigned char)(buf[sz]) < ' ') 570 591 buf[sz] = ' '; 571 } while (--sz >= 0); 592 sz--; 593 } 594 595 /* If comm differs from argv0, prepend "{comm} ". 596 * It allows to see thread names set by prctl(PR_SET_NAME). 597 */ 598 if (base[0] == '-') /* "-sh" (login shell)? */ 599 base++; 600 comm_len = strlen(comm); 601 /* Why compare up to comm_len, not COMM_LEN-1? 602 * Well, some processes rewrite argv, and use _spaces_ there 603 * while rewriting. (KDE is observed to do it). 604 * I prefer to still treat argv0 "process foo bar" 605 * as 'equal' to comm "process". 606 */ 607 if (strncmp(base, comm, comm_len) != 0) { 608 comm_len += 3; 609 if (col > comm_len) 610 memmove(buf + comm_len, buf, col - comm_len); 611 snprintf(buf, col, "{%s}", comm); 612 if (col <= comm_len) 613 return; 614 buf[comm_len - 1] = ' '; 615 buf[col - 1] = '\0'; 616 } 617 572 618 } else { 573 619 snprintf(buf, col, "[%s]", comm); -
branches/3.2/mindi-busybox/libbb/progress.c
r2725 r3232 53 53 } 54 54 55 void FAST_FUNC bb_progress_init(bb_progress_t *p )55 void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile) 56 56 { 57 #if ENABLE_UNICODE_SUPPORT 58 init_unicode(); 59 p->curfile = unicode_conv_to_printable_fixedwidth(/*NULL,*/ curfile, 20); 60 #else 61 p->curfile = curfile; 62 #endif 57 63 p->start_sec = monotonic_sec(); 58 p->last update_sec = p->start_sec;59 p->last size = 0;60 p-> inited = 1;64 p->last_update_sec = p->start_sec; 65 p->last_change_sec = p->start_sec; 66 p->last_size = 0; 61 67 } 62 68 69 /* File already had beg_size bytes. 70 * Then we started downloading. 71 * We downloaded "transferred" bytes so far. 72 * Download is expected to stop when total size (beg_size + transferred) 73 * will be "totalsize" bytes. 74 * If totalsize == 0, then it is unknown. 75 */ 63 76 void FAST_FUNC bb_progress_update(bb_progress_t *p, 64 const char *curfile, 65 off_t beg_range, 66 off_t transferred, 67 off_t totalsize) 77 uoff_t beg_size, 78 uoff_t transferred, 79 uoff_t totalsize) 68 80 { 69 81 uoff_t beg_and_transferred; 70 82 unsigned since_last_update, elapsed; 71 unsigned ratio; 72 int barlength, i; 73 74 /* totalsize == 0 if it is unknown */ 83 int barlength; 84 int kiloscale; 85 86 //transferred = 1234; /* use for stall detection testing */ 87 //totalsize = 0; /* use for unknown size download testing */ 75 88 76 89 elapsed = monotonic_sec(); 77 since_last_update = elapsed - p->lastupdate_sec; 78 /* Do not update on every call 79 * (we can be called on every network read!) */ 80 if (since_last_update == 0 && !totalsize) 81 return; 82 83 beg_and_transferred = beg_range + transferred; 84 ratio = 100; 85 if (beg_and_transferred < totalsize) { 86 /* Do not update on every call 87 * (we can be called on every network read!) */ 88 if (since_last_update == 0) 89 return; 90 /* long long helps to have it working even if !LFS */ 91 ratio = 100ULL * beg_and_transferred / (uoff_t)totalsize; 92 } 93 94 #if ENABLE_UNICODE_SUPPORT 95 init_unicode(); 96 /* libbb candidate? */ 97 { 98 wchar_t wbuf21[21]; 99 char *buf = xstrdup(curfile); 100 unsigned len; 101 102 /* trim to 20 wide chars max (sets wbuf21[20] to 0) 103 * also, in case mbstowcs fails, we at least 104 * dont get garbage */ 105 memset(wbuf21, 0, sizeof(wbuf21)); 106 /* convert to wide chars, no more than 20 */ 107 len = mbstowcs(wbuf21, curfile, 20); /* NB: may return -1 */ 108 /* back to multibyte; cant overflow */ 109 wcstombs(buf, wbuf21, INT_MAX); 110 len = (len > 20) ? 0 : 20 - len; 111 fprintf(stderr, "\r%s%*s%4u%% ", buf, len, "", ratio); 112 free(buf); 113 } 114 #else 115 fprintf(stderr, "\r%-20.20s%4u%% ", curfile, ratio); 116 #endif 117 118 barlength = get_tty2_width() - 49; 119 if (barlength > 0) { 120 /* god bless gcc for variable arrays :) */ 121 char buf[barlength + 1]; 122 unsigned stars = (unsigned)barlength * ratio / (unsigned)100; 123 memset(buf, ' ', barlength); 124 buf[barlength] = '\0'; 125 memset(buf, '*', stars); 126 fprintf(stderr, "|%s|", buf); 127 } 128 129 i = 0; 90 since_last_update = elapsed - p->last_update_sec; 91 p->last_update_sec = elapsed; 92 93 if (totalsize != 0 && transferred >= totalsize - beg_size) { 94 /* Last call. Do not skip this update */ 95 transferred = totalsize - beg_size; /* sanitize just in case */ 96 } 97 else if (since_last_update == 0) { 98 /* 99 * Do not update on every call 100 * (we can be called on every network read!) 101 */ 102 return; 103 } 104 105 kiloscale = 0; 106 /* 107 * Scale sizes down if they are close to overflowing. 108 * This allows calculations like (100 * transferred / totalsize) 109 * without risking overflow: we guarantee 10 highest bits to be 0. 110 * Introduced error is less than 1 / 2^12 ~= 0.025% 111 */ 112 if (ULONG_MAX > 0xffffffff || sizeof(off_t) == 4 || sizeof(off_t) != 8) { 113 /* 114 * 64-bit CPU || small off_t: in either case, 115 * >> is cheap, single-word operation. 116 * ... || strange off_t: also use this code 117 * (it is safe, just suboptimal wrt code size), 118 * because 32/64 optimized one works only for 64-bit off_t. 119 */ 120 if (totalsize >= (1 << 22)) { 121 totalsize >>= 10; 122 beg_size >>= 10; 123 transferred >>= 10; 124 kiloscale = 1; 125 } 126 } else { 127 /* 32-bit CPU and 64-bit off_t. 128 * Use a 40-bit shift, it is easier to do on 32-bit CPU. 129 */ 130 /* ONE suppresses "warning: shift count >= width of type" */ 131 #define ONE (sizeof(off_t) > 4) 132 if (totalsize >= (uoff_t)(1ULL << 54*ONE)) { 133 totalsize = (uint32_t)(totalsize >> 32*ONE) >> 8; 134 beg_size = (uint32_t)(beg_size >> 32*ONE) >> 8; 135 transferred = (uint32_t)(transferred >> 32*ONE) >> 8; 136 kiloscale = 4; 137 } 138 } 139 140 if (ENABLE_UNICODE_SUPPORT) 141 fprintf(stderr, "\r%s", p->curfile); 142 else 143 fprintf(stderr, "\r%-20.20s", p->curfile); 144 145 beg_and_transferred = beg_size + transferred; 146 147 if (totalsize != 0) { 148 unsigned ratio = 100 * beg_and_transferred / totalsize; 149 fprintf(stderr, "%4u%%", ratio); 150 151 barlength = get_tty2_width() - 49; 152 if (barlength > 0) { 153 /* god bless gcc for variable arrays :) */ 154 char buf[barlength + 1]; 155 unsigned stars = (unsigned)barlength * beg_and_transferred / totalsize; 156 memset(buf, ' ', barlength); 157 buf[barlength] = '\0'; 158 memset(buf, '*', stars); 159 fprintf(stderr, " |%s|", buf); 160 } 161 } 162 130 163 while (beg_and_transferred >= 100000) { 131 i++;132 164 beg_and_transferred >>= 10; 165 kiloscale++; 133 166 } 134 167 /* see http://en.wikipedia.org/wiki/Tera */ 135 fprintf(stderr, "%6u%c ", (unsigned)beg_and_transferred, " kMGTPEZY"[i]); 136 #define beg_and_transferred dont_use_beg_and_transferred_below 137 138 if (transferred > p->lastsize) { 139 p->lastupdate_sec = elapsed; 140 p->lastsize = transferred; 168 fprintf(stderr, "%6u%c", (unsigned)beg_and_transferred, " kMGTPEZY"[kiloscale]); 169 #define beg_and_transferred dont_use_beg_and_transferred_below() 170 171 since_last_update = elapsed - p->last_change_sec; 172 if ((unsigned)transferred != p->last_size) { 173 p->last_change_sec = elapsed; 174 p->last_size = (unsigned)transferred; 141 175 if (since_last_update >= STALLTIME) { 142 /* We "cut o ff" these seconds from elapsed time176 /* We "cut out" these seconds from elapsed time 143 177 * by adjusting start time */ 144 178 p->start_sec += since_last_update; … … 146 180 since_last_update = 0; /* we are un-stalled now */ 147 181 } 182 148 183 elapsed -= p->start_sec; /* now it's "elapsed since start" */ 149 184 150 185 if (since_last_update >= STALLTIME) { 151 fprintf(stderr, " - stalled -"); 186 fprintf(stderr, " - stalled -"); 187 } else if (!totalsize || !transferred || (int)elapsed < 0) { 188 fprintf(stderr, " --:--:-- ETA"); 152 189 } else { 153 off_t to_download = totalsize - beg_range; 154 if (!totalsize || transferred <= 0 || (int)elapsed <= 0 || transferred > to_download) { 155 fprintf(stderr, "--:--:-- ETA"); 156 } else { 157 /* to_download / (transferred/elapsed) - elapsed: */ 158 /* (long long helps to have working ETA even if !LFS) */ 159 unsigned eta = (unsigned long long)to_download*elapsed/(uoff_t)transferred - elapsed; 160 unsigned secs = eta % 3600; 161 fprintf(stderr, "%02u:%02u:%02u ETA", eta / 3600, secs / 60, secs % 60); 162 } 190 unsigned eta, secs, hours; 191 192 totalsize -= beg_size; /* now it's "total to upload" */ 193 194 /* Estimated remaining time = 195 * estimated_sec_to_dl_totalsize_bytes - elapsed_sec = 196 * totalsize / average_bytes_sec_so_far - elapsed = 197 * totalsize / (transferred/elapsed) - elapsed = 198 * totalsize * elapsed / transferred - elapsed 199 */ 200 eta = totalsize * elapsed / transferred - elapsed; 201 if (eta >= 1000*60*60) 202 eta = 1000*60*60 - 1; 203 secs = eta % 3600; 204 hours = eta / 3600; 205 fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60); 163 206 } 164 207 } -
branches/3.2/mindi-busybox/libbb/pw_encrypt.c
r2725 r3232 28 28 } 29 29 30 int FAST_FUNC crypt_make_salt(char *p, int cnt , int x)30 int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) 31 31 { 32 x += getpid() + time(NULL); 32 /* was: x += ... */ 33 int x = getpid() + monotonic_us(); 33 34 do { 34 35 /* x = (x*1664525 + 1013904223) % 2^32 generator is lame … … 46 47 *p = '\0'; 47 48 return x; 49 } 50 51 char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) 52 { 53 int len = 2/2; 54 char *salt_ptr = salt; 55 if (algo[0] != 'd') { /* not des */ 56 len = 8/2; /* so far assuming md5 */ 57 *salt_ptr++ = '$'; 58 *salt_ptr++ = '1'; 59 *salt_ptr++ = '$'; 60 #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA 61 if (algo[0] == 's') { /* sha */ 62 salt[1] = '5' + (strcmp(algo, "sha512") == 0); 63 len = 16/2; 64 } 65 #endif 66 } 67 crypt_make_salt(salt_ptr, len); 68 return salt_ptr; 48 69 } 49 70 -
branches/3.2/mindi-busybox/libbb/read_key.c
r2725 r3232 16 16 int n; 17 17 18 /* Known escape sequences for cursor and function keys */ 18 /* Known escape sequences for cursor and function keys. 19 * See "Xterm Control Sequences" 20 * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html 21 */ 19 22 static const char esccmds[] ALIGN1 = { 20 23 'O','A' |0x80,KEYCODE_UP , … … 41 44 '[','D' |0x80,KEYCODE_LEFT , 42 45 /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift-<arrow> */ 43 /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> */46 /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt-<arrow> - implemented below */ 44 47 /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift-<arrow> */ 45 48 /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl-<arrow> - implemented below */ 46 49 /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift-<arrow> */ 50 /* ESC [ 1 ; 7 x, where x = A/B/C/D: Ctrl-Alt-<arrow> */ 51 /* ESC [ 1 ; 8 x, where x = A/B/C/D: Ctrl-Alt-Shift-<arrow> */ 47 52 '[','H' |0x80,KEYCODE_HOME , /* xterm */ 48 /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */49 53 '[','F' |0x80,KEYCODE_END , /* xterm */ 54 /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home (End similarly?) */ 55 /* '[','Z' |0x80,KEYCODE_SHIFT_TAB, */ 50 56 '[','1','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ 51 57 '[','2','~' |0x80,KEYCODE_INSERT , … … 64 70 '[','8','~' |0x80,KEYCODE_END , /* vt100? linux vt? or what? */ 65 71 #if 0 66 '[','1','1','~'|0x80,KEYCODE_FUN1 , 67 '[','1','2','~'|0x80,KEYCODE_FUN2 , 68 '[','1','3','~'|0x80,KEYCODE_FUN3 , 69 '[','1','4','~'|0x80,KEYCODE_FUN4 , 72 '[','1','1','~'|0x80,KEYCODE_FUN1 , /* old xterm, deprecated by ESC O P */ 73 '[','1','2','~'|0x80,KEYCODE_FUN2 , /* old xterm... */ 74 '[','1','3','~'|0x80,KEYCODE_FUN3 , /* old xterm... */ 75 '[','1','4','~'|0x80,KEYCODE_FUN4 , /* old xterm... */ 70 76 '[','1','5','~'|0x80,KEYCODE_FUN5 , 71 77 /* [ESC] ESC [ 1 5 [;2] ~ - [Alt-][Shift-]F5 */ … … 87 93 '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT, 88 94 '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT , 95 /* '[','1',';','3','A' |0x80,KEYCODE_ALT_UP , - unused */ 96 /* '[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN , - unused */ 97 '[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT, 98 '[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT , 99 /* '[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE, - unused */ 89 100 0 90 /* ESC [ Z - Shift-Tab */91 101 }; 92 102 … … 215 225 n++; 216 226 /* Try to decipher "ESC [ NNN ; NNN R" sequence */ 217 if ((ENABLE_FEATURE_EDITING_ASK_TERMINAL || ENABLE_FEATURE_VI_ASK_TERMINAL) 227 if ((ENABLE_FEATURE_EDITING_ASK_TERMINAL 228 || ENABLE_FEATURE_VI_ASK_TERMINAL 229 || ENABLE_FEATURE_LESS_ASK_TERMINAL 230 ) 218 231 && n >= 5 219 232 && buffer[0] == '[' -
branches/3.2/mindi-busybox/libbb/read_printf.c
r2725 r3232 8 8 */ 9 9 #include "libbb.h" 10 11 #define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \12 || ENABLE_FEATURE_SEAMLESS_BZ2 \13 || ENABLE_FEATURE_SEAMLESS_GZ \14 /* || ENABLE_FEATURE_SEAMLESS_Z */ \15 )16 17 #if ZIPPED18 # include "archive.h"19 #endif20 10 21 11 … … 56 46 * Thankfully, poll() doesn't care about O_NONBLOCK flag. 57 47 */ 58 ssize_t FAST_FUNC nonblock_ safe_read(int fd, void *buf, size_t count)48 ssize_t FAST_FUNC nonblock_immune_read(int fd, void *buf, size_t count, int loop_on_EINTR) 59 49 { 60 50 struct pollfd pfd[1]; … … 62 52 63 53 while (1) { 64 n = safe_read(fd, buf, count);54 n = loop_on_EINTR ? safe_read(fd, buf, count) : read(fd, buf, count); 65 55 if (n >= 0 || errno != EAGAIN) 66 56 return n; … … 68 58 pfd[0].fd = fd; 69 59 pfd[0].events = POLLIN; 70 safe_poll(pfd, 1, -1); /* note: this pulls in printf */ 60 /* note: safe_poll pulls in printf */ 61 loop_on_EINTR ? safe_poll(pfd, 1, -1) : poll(pfd, 1, -1); 71 62 } 72 63 } … … 75 66 // Reads byte-by-byte. Useful when it is important to not read ahead. 76 67 // Bytes are appended to pfx (which must be malloced, or NULL). 77 char* FAST_FUNC xmalloc_reads(int fd, char *buf,size_t *maxsz_p)68 char* FAST_FUNC xmalloc_reads(int fd, size_t *maxsz_p) 78 69 { 79 70 char *p; 80 size_t sz = buf ? strlen(buf) : 0; 71 char *buf = NULL; 72 size_t sz = 0; 81 73 size_t maxsz = maxsz_p ? *maxsz_p : (INT_MAX - 4095); 82 74 83 75 goto jump_in; 76 84 77 while (sz < maxsz) { 85 78 if ((size_t)(p - buf) == sz) { … … 89 82 sz += 128; 90 83 } 91 /* nonblock_safe_read() because we are used by e.g. shells */92 if (nonblock_safe_read(fd, p, 1) != 1) {/* EOF/error */84 if (nonblock_immune_read(fd, p, 1, /*loop_on_EINTR:*/ 1) != 1) { 85 /* EOF/error */ 93 86 if (p == buf) { /* we read nothing */ 94 87 free(buf); … … 242 235 return buf; 243 236 } 244 245 /* Used by e.g. rpm which gives us a fd without filename,246 * thus we can't guess the format from filename's extension.247 */248 #if ZIPPED249 void FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)250 {251 const int fail_if_not_detected = 1;252 union {253 uint8_t b[4];254 uint16_t b16[2];255 uint32_t b32[1];256 } magic;257 int offset = -2;258 # if BB_MMU259 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);260 enum { xformer_prog = 0 };261 # else262 enum { xformer = 0 };263 const char *xformer_prog;264 # endif265 266 /* .gz and .bz2 both have 2-byte signature, and their267 * unpack_XXX_stream wants this header skipped. */268 xread(fd, magic.b16, sizeof(magic.b16[0]));269 if (ENABLE_FEATURE_SEAMLESS_GZ270 && magic.b16[0] == GZIP_MAGIC271 ) {272 # if BB_MMU273 xformer = unpack_gz_stream;274 # else275 xformer_prog = "gunzip";276 # endif277 goto found_magic;278 }279 if (ENABLE_FEATURE_SEAMLESS_BZ2280 && magic.b16[0] == BZIP2_MAGIC281 ) {282 # if BB_MMU283 xformer = unpack_bz2_stream;284 # else285 xformer_prog = "bunzip2";286 # endif287 goto found_magic;288 }289 if (ENABLE_FEATURE_SEAMLESS_XZ290 && magic.b16[0] == XZ_MAGIC1291 ) {292 offset = -6;293 xread(fd, magic.b32, sizeof(magic.b32[0]));294 if (magic.b32[0] == XZ_MAGIC2) {295 # if BB_MMU296 xformer = unpack_xz_stream;297 /* unpack_xz_stream wants fd at position 6, no need to seek */298 //xlseek(fd, offset, SEEK_CUR);299 # else300 xformer_prog = "unxz";301 # endif302 goto found_magic;303 }304 }305 306 /* No known magic seen */307 if (fail_if_not_detected)308 bb_error_msg_and_die("no gzip"309 IF_FEATURE_SEAMLESS_BZ2("/bzip2")310 IF_FEATURE_SEAMLESS_XZ("/xz")311 " magic");312 xlseek(fd, offset, SEEK_CUR);313 return;314 315 found_magic:316 # if !BB_MMU317 /* NOMMU version of open_transformer execs318 * an external unzipper that wants319 * file position at the start of the file */320 xlseek(fd, offset, SEEK_CUR);321 # endif322 open_transformer(fd, xformer, xformer_prog);323 }324 #endif /* ZIPPED */325 326 int FAST_FUNC open_zipped(const char *fname)327 {328 #if !ZIPPED329 return open(fname, O_RDONLY);330 #else331 char *sfx;332 int fd;333 334 fd = open(fname, O_RDONLY);335 if (fd < 0)336 return fd;337 338 sfx = strrchr(fname, '.');339 if (sfx) {340 sfx++;341 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, "lzma") == 0)342 /* .lzma has no header/signature, just trust it */343 open_transformer(fd, unpack_lzma_stream, "unlzma");344 else345 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, "gz") == 0)346 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, "bz2") == 0)347 || (ENABLE_FEATURE_SEAMLESS_XZ && strcmp(sfx, "xz") == 0)348 ) {349 setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/);350 }351 }352 353 return fd;354 #endif355 }356 357 void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)358 {359 int fd;360 char *image;361 362 fd = open_zipped(fname);363 if (fd < 0)364 return NULL;365 366 image = xmalloc_read(fd, maxsz_p);367 if (!image)368 bb_perror_msg("read error from '%s'", fname);369 close(fd);370 371 return image;372 } -
branches/3.2/mindi-busybox/libbb/remove_file.c
r2725 r3232 34 34 35 35 if (!(flags & FILEUTILS_RECUR)) { 36 bb_error_msg(" %s:is a directory", path);36 bb_error_msg("'%s' is a directory", path); 37 37 return -1; 38 38 } -
branches/3.2/mindi-busybox/libbb/safe_gethostname.c
r2725 r3232 51 51 return xstrndup(!uts.nodename[0] ? "?" : uts.nodename, sizeof(uts.nodename)); 52 52 } 53 54 /*55 * On success return the current malloced and NUL terminated domainname.56 * On error return malloced and NUL terminated string "?".57 * This is an illegal first character for a domainname.58 * The returned malloced string must be freed by the caller.59 */60 char* FAST_FUNC safe_getdomainname(void)61 {62 #if defined(__linux__)63 /* The field domainname of struct utsname is Linux specific. */64 struct utsname uts;65 uname(&uts);66 return xstrndup(!uts.domainname[0] ? "?" : uts.domainname, sizeof(uts.domainname));67 #else68 /* We really don't care about people with domain names wider than most screens */69 char buf[256];70 int r = getdomainname(buf, sizeof(buf));71 buf[sizeof(buf)-1] = '\0';72 return xstrdup(r < 0 ? "?" : buf);73 #endif74 } -
branches/3.2/mindi-busybox/libbb/selinux_common.c
r2725 r3232 11 11 12 12 context_t FAST_FUNC set_security_context_component(security_context_t cur_context, 13 13 char *user, char *role, char *type, char *range) 14 14 { 15 15 context_t con = context_new(cur_context); -
branches/3.2/mindi-busybox/libbb/setup_environment.c
r2725 r3232 33 33 void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw) 34 34 { 35 if (!shell || !shell[0]) 36 shell = DEFAULT_SHELL; 37 35 38 /* Change the current working directory to be the home directory 36 39 * of the user */ 37 if (chdir(pw->pw_dir)) { 38 xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/"); 39 bb_error_msg("can't chdir to home directory '%s'", pw->pw_dir); 40 if (!(flags & SETUP_ENV_NO_CHDIR)) { 41 if (chdir(pw->pw_dir) != 0) { 42 bb_error_msg("can't change directory to '%s'", pw->pw_dir); 43 xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/"); 44 } 40 45 } 41 46 -
branches/3.2/mindi-busybox/libbb/signals.c
r2725 r3232 40 40 while (sigs) { 41 41 if (sigs & bit) { 42 sigs &= ~bit;42 sigs -= bit; 43 43 signal(sig_no, f); 44 44 } … … 61 61 while (sigs) { 62 62 if (sigs & bit) { 63 sigs &= ~bit;63 sigs -= bit; 64 64 sigaction_set(sig_no, &sa); 65 65 } … … 98 98 sig_unblock(sig); 99 99 raise(sig); 100 _exit( EXIT_FAILURE); /* Should not reach it */100 _exit(sig | 128); /* Should not reach it */ 101 101 } 102 102 -
branches/3.2/mindi-busybox/libbb/single_argv.c
r2725 r3232 11 11 char* FAST_FUNC single_argv(char **argv) 12 12 { 13 if (argv[1] && strcmp(argv[1], "--") == 0) 14 argv++; 13 15 if (!argv[1] || argv[2]) 14 16 bb_show_usage(); -
branches/3.2/mindi-busybox/libbb/time.c
r2725 r3232 92 92 * Everything but the minutes is optional 93 93 * 94 * This coincides with the format of "touch -t TIME" 94 * "touch -t DATETIME" format: [[[[[YY]YY]MM]DD]hh]mm[.ss] 95 * Some, but not all, Unix "date DATETIME" commands 96 * move [[YY]YY] past minutes mm field (!). 97 * Coreutils date does it, and SUS mandates it. 98 * (date -s DATETIME does not support this format. lovely!) 99 * In bbox, this format is special-cased in date applet 100 * (IOW: this function assumes "touch -t" format). 95 101 */ 102 unsigned cur_year = ptm->tm_year; 96 103 int len = strchrnul(date_str, '.') - date_str; 97 104 … … 134 141 /* Adjust month from 1-12 to 0-11 */ 135 142 ptm->tm_mon -= 1; 143 if ((int)cur_year >= 50) { /* >= 1950 */ 144 /* Adjust year: */ 145 /* 1. Put it in the current century */ 146 ptm->tm_year += (cur_year / 100) * 100; 147 /* 2. If too far in the past, +100 years */ 148 if (ptm->tm_year < cur_year - 50) 149 ptm->tm_year += 100; 150 /* 3. If too far in the future, -100 years */ 151 if (ptm->tm_year > cur_year + 50) 152 ptm->tm_year -= 100; 153 } 136 154 } else 137 155 /* ccyymmddHHMM[.SS] */ -
branches/3.2/mindi-busybox/libbb/u_signal_names.c
r2725 r3232 7 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 10 //config:config FEATURE_RTMINMAX 11 //config: bool "Support RTMIN[+n] and RTMAX[-n] signal names" 12 //config: default y 13 //config: help 14 //config: Support RTMIN[+n] and RTMAX[-n] signal names 15 //config: in kill, killall etc. This costs ~250 bytes. 9 16 10 17 #include "libbb.h" … … 118 125 [SIGSYS ] = "SYS", 119 126 #endif 127 #if ENABLE_FEATURE_RTMINMAX 128 # ifdef __SIGRTMIN 129 [__SIGRTMIN] = "RTMIN", 130 # endif 131 // This makes array about x2 bigger. 132 // More compact approach is to special-case SIGRTMAX in print_signames() 133 //# ifdef __SIGRTMAX 134 // [__SIGRTMAX] = "RTMAX", 135 //# endif 136 #endif 120 137 }; 121 138 … … 135 152 return i; 136 153 137 #if ENABLE_DESKTOP && (defined(SIGIOT) || defined(SIGIO)) 154 #if ENABLE_DESKTOP 155 # if defined(SIGIOT) || defined(SIGIO) 138 156 /* SIGIO[T] are aliased to other names, 139 157 * thus cannot be stored in the signals[] array. 140 158 * Need special code to recognize them */ 141 159 if ((name[0] | 0x20) == 'i' && (name[1] | 0x20) == 'o') { 142 # ifdef SIGIO160 # ifdef SIGIO 143 161 if (!name[2]) 144 162 return SIGIO; 145 # endif146 # ifdef SIGIOT163 # endif 164 # ifdef SIGIOT 147 165 if ((name[2] | 0x20) == 't' && !name[3]) 148 166 return SIGIOT; 149 #endif 150 } 167 # endif 168 } 169 # endif 170 #endif 171 172 #if ENABLE_FEATURE_RTMINMAX 173 # if defined(SIGRTMIN) && defined(SIGRTMAX) 174 /* libc may use some rt sigs for pthreads and therefore "remap" SIGRTMIN/MAX, 175 * but we want to use "raw" SIGRTMIN/MAX. Underscored names, if exist, provide 176 * them. If they don't exist, fall back to non-underscored ones: */ 177 # if !defined(__SIGRTMIN) 178 # define __SIGRTMIN SIGRTMIN 179 # endif 180 # if !defined(__SIGRTMAX) 181 # define __SIGRTMAX SIGRTMAX 182 # endif 183 if (strncasecmp(name, "RTMIN", 5) == 0) { 184 if (!name[5]) 185 return __SIGRTMIN; 186 if (name[5] == '+') { 187 i = bb_strtou(name + 6, NULL, 10); 188 if (!errno && i <= __SIGRTMAX - __SIGRTMIN) 189 return __SIGRTMIN + i; 190 } 191 } 192 else if (strncasecmp(name, "RTMAX", 5) == 0) { 193 if (!name[5]) 194 return __SIGRTMAX; 195 if (name[5] == '-') { 196 i = bb_strtou(name + 6, NULL, 10); 197 if (!errno && i <= __SIGRTMAX - __SIGRTMIN) 198 return __SIGRTMAX - i; 199 } 200 } 201 # endif 151 202 #endif 152 203 … … 176 227 const char *name = signals[signo]; 177 228 if (name[0]) 178 puts(name); 179 } 229 printf("%2u) %s\n", signo, name); 230 } 231 #if ENABLE_FEATURE_RTMINMAX 232 # ifdef __SIGRTMAX 233 printf("%2u) %s\n", __SIGRTMAX, "RTMAX"); 234 # endif 235 #endif 180 236 } -
branches/3.2/mindi-busybox/libbb/udp_io.c
r2725 r3232 14 14 */ 15 15 void FAST_FUNC 16 socket_want_pktinfo(int fd )16 socket_want_pktinfo(int fd UNUSED_PARAM) 17 17 { 18 18 #ifdef IP_PKTINFO -
branches/3.2/mindi-busybox/libbb/unicode.c
r2725 r3232 24 24 /* Unicode support using libc locale support. */ 25 25 26 void FAST_FUNC init_unicode(void)26 void FAST_FUNC reinit_unicode(const char *LANG) 27 27 { 28 28 static const char unicode_0x394[] = { 0xce, 0x94, 0 }; 29 29 size_t width; 30 30 31 if (unicode_status != UNICODE_UNKNOWN) 32 return; 31 //TODO: avoid repeated calls by caching last string? 32 setlocale(LC_ALL, (LANG && LANG[0]) ? LANG : "C"); 33 33 34 /* In unicode, this is a one character string */ 34 35 // can use unicode_strlen(string) too, but otherwise unicode_strlen() is unused … … 37 38 } 38 39 40 void FAST_FUNC init_unicode(void) 41 { 42 if (unicode_status == UNICODE_UNKNOWN) 43 reinit_unicode(getenv("LANG")); 44 } 45 39 46 #else 40 47 … … 42 49 43 50 # if ENABLE_FEATURE_CHECK_UNICODE_IN_ENV 44 void FAST_FUNC init_unicode(void) 45 { 46 char *lang; 47 48 if (unicode_status != UNICODE_UNKNOWN) 49 return; 50 51 void FAST_FUNC reinit_unicode(const char *LANG) 52 { 51 53 unicode_status = UNICODE_OFF; 52 lang = getenv("LANG"); 53 if (!lang || !(strstr(lang, ".utf") || strstr(lang, ".UTF"))) 54 if (!LANG || !(strstr(LANG, ".utf") || strstr(LANG, ".UTF"))) 54 55 return; 55 56 unicode_status = UNICODE_ON; 57 } 58 59 void FAST_FUNC init_unicode(void) 60 { 61 if (unicode_status == UNICODE_UNKNOWN) 62 reinit_unicode(getenv("LANG")); 56 63 } 57 64 # endif … … 1108 1115 return unicode_conv_to_printable2(stats, src, INT_MAX, 0); 1109 1116 } 1117 char* FAST_FUNC unicode_conv_to_printable_fixedwidth(/*uni_stat_t *stats,*/ const char *src, unsigned width) 1118 { 1119 return unicode_conv_to_printable2(/*stats:*/ NULL, src, width, UNI_FLAG_PAD); 1120 } 1121 1122 #ifdef UNUSED 1110 1123 char* FAST_FUNC unicode_conv_to_printable_maxwidth(uni_stat_t *stats, const char *src, unsigned maxwidth) 1111 1124 { 1112 1125 return unicode_conv_to_printable2(stats, src, maxwidth, 0); 1113 1126 } 1114 char* FAST_FUNC unicode_conv_to_printable_fixedwidth(uni_stat_t *stats, const char *src, unsigned width) 1115 { 1116 return unicode_conv_to_printable2(stats, src, width, UNI_FLAG_PAD); 1117 } 1118 1119 #ifdef UNUSED 1127 1120 1128 unsigned FAST_FUNC unicode_padding_to_width(unsigned width, const char *src) 1121 1129 { -
branches/3.2/mindi-busybox/libbb/utmp.c
r2725 r3232 8 8 */ 9 9 #include "libbb.h" 10 #include <utmp.h>11 10 12 11 static void touch(const char *filename) -
branches/3.2/mindi-busybox/libbb/uuencode.c
r2725 r3232 11 11 12 12 /* Conversion table. for base 64 */ 13 const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = {13 const char bb_uuenc_tbl_base64[65 + 1] ALIGN1 = { 14 14 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 15 15 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', … … 21 21 '4', '5', '6', '7', '8', '9', '+', '/', 22 22 '=' /* termination character */, 23 '\ n', '\0' /* needed for uudecode.c*/23 '\0' /* needed for uudecode.c only */ 24 24 }; 25 25 … … 74 74 75 75 /* 76 * Decode base64 encoded string. Stops on '\0'. 77 * 78 * Returns: pointer to the undecoded part of source. 79 * If points to '\0', then the source was fully decoded. 80 * (*pp_dst): advanced past the last written byte. 81 */ 82 const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) 83 { 84 char *dst = *pp_dst; 85 const char *src_tail; 86 87 while (1) { 88 unsigned char six_bit[4]; 89 int count = 0; 90 91 /* Fetch up to four 6-bit values */ 92 src_tail = src; 93 while (count < 4) { 94 char *table_ptr; 95 int ch; 96 97 /* Get next _valid_ character. 98 * bb_uuenc_tbl_base64[] contains this string: 99 * 0 1 2 3 4 5 6 100 * 01234567890123456789012345678901234567890123456789012345678901234 101 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" 102 */ 103 do { 104 ch = *src; 105 if (ch == '\0') { 106 if (count == 0) { 107 /* Example: 108 * If we decode "QUJD <NUL>", we want 109 * to return ptr to NUL, not to ' ', 110 * because we did fully decode 111 * the string (to "ABC"). 112 */ 113 src_tail = src; 114 } 115 goto ret; 116 } 117 src++; 118 table_ptr = strchr(bb_uuenc_tbl_base64, ch); 119 //TODO: add BASE64_FLAG_foo to die on bad char? 120 } while (!table_ptr); 121 122 /* Convert encoded character to decimal */ 123 ch = table_ptr - bb_uuenc_tbl_base64; 124 125 /* ch is 64 if char was '=', otherwise 0..63 */ 126 if (ch == 64) 127 break; 128 six_bit[count] = ch; 129 count++; 130 } 131 132 /* Transform 6-bit values to 8-bit ones. 133 * count can be < 4 when we decode the tail: 134 * "eQ==" -> "y", not "y NUL NUL". 135 * Note that (count > 1) is always true, 136 * "x===" encoding is not valid: 137 * even a single zero byte encodes as "AA==". 138 * However, with current logic we come here with count == 1 139 * when we decode "==" tail. 140 */ 141 if (count > 1) 142 *dst++ = six_bit[0] << 2 | six_bit[1] >> 4; 143 if (count > 2) 144 *dst++ = six_bit[1] << 4 | six_bit[2] >> 2; 145 if (count > 3) 146 *dst++ = six_bit[2] << 6 | six_bit[3]; 147 /* Note that if we decode "AA==" and ate first '=', 148 * we just decoded one char (count == 2) and now we'll 149 * do the loop once more to decode second '='. 150 */ 151 } /* while (1) */ 152 ret: 153 *pp_dst = dst; 154 return src_tail; 155 } 156 157 /* 76 158 * Decode base64 encoded stream. 77 159 * Can stop on EOF, specified char, or on uuencode-style "====" line: … … 84 166 #define uu_style_end (flags & BASE64_FLAG_UU_STOP) 85 167 86 int term_count = 0; 168 /* uuencoded files have 61 byte lines. Use 64 byte buffer 169 * to process line at a time. 170 */ 171 enum { BUFFER_SIZE = 64 }; 172 173 char in_buf[BUFFER_SIZE + 2]; 174 char out_buf[BUFFER_SIZE / 4 * 3 + 2]; 175 char *out_tail; 176 const char *in_tail; 177 int term_seen = 0; 178 int in_count = 0; 87 179 88 180 while (1) { 89 unsigned char translated[4]; 90 int count = 0; 91 92 /* Process one group of 4 chars */ 93 while (count < 4) { 94 char *table_ptr; 95 int ch; 96 97 /* Get next _valid_ character. 98 * bb_uuenc_tbl_base64[] contains this string: 99 * 0 1 2 3 4 5 6 100 * 012345678901234567890123456789012345678901234567890123456789012345 101 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" 181 while (in_count < BUFFER_SIZE) { 182 int ch = fgetc(src_stream); 183 if (ch == exit_char) { 184 if (in_count == 0) 185 return; 186 term_seen = 1; 187 break; 188 } 189 if (ch == EOF) { 190 term_seen = 1; 191 break; 192 } 193 /* Prevent "====" line to be split: stop if we see '\n'. 194 * We can also skip other whitespace and skirt the problem 195 * of files with NULs by stopping on any control char or space: 102 196 */ 103 do { 104 ch = fgetc(src_stream); 105 if (ch == exit_char && count == 0) 106 return; 107 if (ch == EOF) 108 bb_error_msg_and_die("truncated base64 input"); 109 table_ptr = strchr(bb_uuenc_tbl_base64, ch); 110 //TODO: add BASE64_FLAG_foo to die on bad char? 111 //Note that then we may need to still allow '\r' (for mail processing) 112 } while (!table_ptr); 113 114 /* Convert encoded character to decimal */ 115 ch = table_ptr - bb_uuenc_tbl_base64; 116 117 if (ch == 65 /* '\n' */) { 118 /* Terminating "====" line? */ 119 if (uu_style_end && term_count == 4) 120 return; /* yes */ 121 term_count = 0; 122 continue; 123 } 124 /* ch is 64 if char was '=', otherwise 0..63 */ 125 translated[count] = ch & 63; /* 64 -> 0 */ 126 if (ch == 64) { 127 term_count++; 128 break; 129 } 130 count++; 131 term_count = 0; 132 } 133 134 /* Merge 6 bit chars to 8 bit. 135 * count can be < 4 when we decode the tail: 136 * "eQ==" -> "y", not "y NUL NUL" 137 */ 138 if (count > 1) 139 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream); 140 if (count > 2) 141 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream); 142 if (count > 3) 143 fputc(translated[2] << 6 | translated[3], dst_stream); 144 } /* while (1) */ 197 if (ch <= ' ') 198 break; 199 in_buf[in_count++] = ch; 200 } 201 in_buf[in_count] = '\0'; 202 203 /* Did we encounter "====" line? */ 204 if (uu_style_end && strcmp(in_buf, "====") == 0) 205 return; 206 207 out_tail = out_buf; 208 in_tail = decode_base64(&out_tail, in_buf); 209 210 fwrite(out_buf, (out_tail - out_buf), 1, dst_stream); 211 212 if (term_seen) { 213 /* Did we consume ALL characters? */ 214 if (*in_tail == '\0') 215 return; 216 /* No */ 217 bb_error_msg_and_die("truncated base64 input"); 218 } 219 220 /* It was partial decode */ 221 in_count = strlen(in_tail); 222 memmove(in_buf, in_tail, in_count); 223 } 145 224 } -
branches/3.2/mindi-busybox/libbb/vdprintf.c
r2725 r3232 13 13 int FAST_FUNC vdprintf(int d, const char *format, va_list ap) 14 14 { 15 char buf[ BUF_SIZE];15 char buf[8 * 1024]; 16 16 int len; 17 17 18 len = vsnprintf(buf, BUF_SIZE, format, ap);18 len = vsnprintf(buf, sizeof(buf), format, ap); 19 19 return write(d, buf, len); 20 20 } -
branches/3.2/mindi-busybox/libbb/vfork_daemon_rexec.c
r2725 r3232 70 70 71 71 #if ENABLE_FEATURE_PREFER_APPLETS 72 void FAST_FUNC save_nofork_data(struct nofork_save_area *save) 72 struct nofork_save_area { 73 jmp_buf die_jmp; 74 const char *applet_name; 75 uint32_t option_mask32; 76 int die_sleep; 77 uint8_t xfunc_error_retval; 78 }; 79 static void save_nofork_data(struct nofork_save_area *save) 73 80 { 74 81 memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); … … 77 84 save->option_mask32 = option_mask32; 78 85 save->die_sleep = die_sleep; 79 save->saved = 1; 80 } 81 82 void FAST_FUNC restore_nofork_data(struct nofork_save_area *save) 86 } 87 static void restore_nofork_data(struct nofork_save_area *save) 83 88 { 84 89 memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); … … 89 94 } 90 95 91 int FAST_FUNC run_nofork_applet _prime(struct nofork_save_area *old,int applet_no, char **argv)96 int FAST_FUNC run_nofork_applet(int applet_no, char **argv) 92 97 { 93 98 int rc, argc; 99 struct nofork_save_area old; 100 101 save_nofork_data(&old); 94 102 95 103 applet_name = APPLET_NAME(applet_no); 96 104 97 105 xfunc_error_retval = EXIT_FAILURE; 98 99 /* Special flag for xfunc_die(). If xfunc will "die"100 * in NOFORK applet, xfunc_die() sees negative101 * die_sleep and longjmp here instead. */102 die_sleep = -1;103 106 104 107 /* In case getopt() or getopt32() was already called: … … 131 134 argc++; 132 135 136 /* Special flag for xfunc_die(). If xfunc will "die" 137 * in NOFORK applet, xfunc_die() sees negative 138 * die_sleep and longjmp here instead. */ 139 die_sleep = -1; 140 133 141 rc = setjmp(die_jmp); 134 142 if (!rc) { … … 139 147 /* Finally we can call NOFORK applet's main() */ 140 148 rc = applet_main[applet_no](argc, tmp_argv); 141 142 /* The whole reason behind nofork_save_area is that <applet>_main143 * may exit non-locally! For example, in hush Ctrl-Z tries144 * (modulo bugs) to dynamically create a child (backgrounded task)145 * if it detects that Ctrl-Z was pressed when a NOFORK was running.146 * Testcase: interactive "rm -i".147 * Don't fool yourself into thinking "and <applet>_main() returns148 * quickly here" and removing "useless" nofork_save_area code. */149 150 149 } else { /* xfunc died in NOFORK applet */ 151 150 /* in case they meant to return 0... */ … … 155 154 156 155 /* Restoring some globals */ 157 restore_nofork_data( old);156 restore_nofork_data(&old); 158 157 159 158 /* Other globals can be simply reset to defaults */ … … 166 165 return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ 167 166 } 168 169 int FAST_FUNC run_nofork_applet(int applet_no, char **argv)170 {171 struct nofork_save_area old;172 173 /* Saving globals */174 save_nofork_data(&old);175 return run_nofork_applet_prime(&old, applet_no, argv);176 }177 167 #endif /* FEATURE_PREFER_APPLETS */ 178 168 … … 184 174 185 175 if (a >= 0 && (APPLET_IS_NOFORK(a) 186 # if BB_MMU176 # if BB_MMU 187 177 || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */ 188 # endif178 # endif 189 179 )) { 190 # if BB_MMU180 # if BB_MMU 191 181 if (APPLET_IS_NOFORK(a)) 192 # endif182 # endif 193 183 { 194 184 return run_nofork_applet(a, argv); 195 185 } 196 # if BB_MMU186 # if BB_MMU 197 187 /* MMU only */ 198 188 /* a->noexec is true */ … … 203 193 xfunc_error_retval = EXIT_FAILURE; 204 194 run_applet_no_and_exit(a, argv); 205 # endif195 # endif 206 196 } 207 197 #endif /* FEATURE_PREFER_APPLETS */ … … 264 254 if (fork_or_rexec(argv)) 265 255 exit(EXIT_SUCCESS); /* parent */ 266 /* if daemonizing, make sure wedetach from stdio & ctty */256 /* if daemonizing, detach from stdio & ctty */ 267 257 setsid(); 268 258 dup2(fd, 0); 269 259 dup2(fd, 1); 270 260 dup2(fd, 2); 261 if (flags & DAEMON_DOUBLE_FORK) { 262 /* On Linux, session leader can acquire ctty 263 * unknowingly, by opening a tty. 264 * Prevent this: stop being a session leader. 265 */ 266 if (fork_or_rexec(argv)) 267 exit(EXIT_SUCCESS); /* parent */ 268 } 271 269 } 272 270 while (fd > 2) { -
branches/3.2/mindi-busybox/libbb/xatonum_template.c
r2725 r3232 60 60 61 61 /* Note: trailing space is an error. 62 62 * It would be easy enough to allow though if desired. */ 63 63 if (*e) 64 64 goto inval; -
branches/3.2/mindi-busybox/libbb/xconnect.c
r2725 r3232 135 135 } 136 136 137 void FAST_FUNC set_nport(len_and_sockaddr *lsa, unsigned port) 138 { 139 #if ENABLE_FEATURE_IPV6 140 if (lsa->u.sa.sa_family == AF_INET6) { 141 lsa->u.sin6.sin6_port = port; 137 void FAST_FUNC set_nport(struct sockaddr *sa, unsigned port) 138 { 139 #if ENABLE_FEATURE_IPV6 140 if (sa->sa_family == AF_INET6) { 141 struct sockaddr_in6 *sin6 = (void*) sa; 142 sin6->sin6_port = port; 142 143 return; 143 144 } 144 145 #endif 145 if (lsa->u.sa.sa_family == AF_INET) { 146 lsa->u.sin.sin_port = port; 146 if (sa->sa_family == AF_INET) { 147 struct sockaddr_in *sin = (void*) sa; 148 sin->sin_port = port; 147 149 return; 148 150 } … … 256 258 memset(&hint, 0 , sizeof(hint)); 257 259 hint.ai_family = af; 258 /* Need ed. Or else we willget each address thrice (or more)260 /* Need SOCK_STREAM, or else we get each address thrice (or more) 259 261 * for each possible socket type (tcp,udp,raw...): */ 260 262 hint.ai_socktype = SOCK_STREAM; … … 284 286 285 287 set_port: 286 set_nport( r, htons(port));288 set_nport(&r->u.sa, htons(port)); 287 289 ret: 288 freeaddrinfo(result); 290 if (result) 291 freeaddrinfo(result); 289 292 return r; 290 293 } … … 320 323 } 321 324 322 #undef xsocket_type 323 int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, IF_FEATURE_IPV6(int family,) int sock_type) 324 { 325 IF_NOT_FEATURE_IPV6(enum { family = AF_INET };) 325 int FAST_FUNC xsocket_type(len_and_sockaddr **lsap, int family, int sock_type) 326 { 326 327 len_and_sockaddr *lsa; 327 328 int fd; 328 329 int len; 329 330 330 #if ENABLE_FEATURE_IPV6331 331 if (family == AF_UNSPEC) { 332 #if ENABLE_FEATURE_IPV6 332 333 fd = socket(AF_INET6, sock_type, 0); 333 334 if (fd >= 0) { … … 335 336 goto done; 336 337 } 338 #endif 337 339 family = AF_INET; 338 340 } 339 #endif 341 340 342 fd = xsocket(family, sock_type, 0); 343 341 344 len = sizeof(struct sockaddr_in); 345 if (family == AF_UNIX) 346 len = sizeof(struct sockaddr_un); 342 347 #if ENABLE_FEATURE_IPV6 343 348 if (family == AF_INET6) { … … 355 360 int FAST_FUNC xsocket_stream(len_and_sockaddr **lsap) 356 361 { 357 return xsocket_type(lsap, IF_FEATURE_IPV6(AF_UNSPEC,)SOCK_STREAM);362 return xsocket_type(lsap, AF_UNSPEC, SOCK_STREAM); 358 363 } 359 364 … … 368 373 fd = xsocket(lsa->u.sa.sa_family, sock_type, 0); 369 374 } else { 370 fd = xsocket_type(&lsa, IF_FEATURE_IPV6(AF_UNSPEC,)sock_type);371 set_nport( lsa, htons(port));375 fd = xsocket_type(&lsa, AF_UNSPEC, sock_type); 376 set_nport(&lsa->u.sa, htons(port)); 372 377 } 373 378 setsockopt_reuseaddr(fd); -
branches/3.2/mindi-busybox/libbb/xfuncs.c
r2725 r3232 26 26 27 27 /* Turn on nonblocking I/O on a fd */ 28 int FAST_FUNC ndelay_on(int fd) 29 { 30 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 31 } 32 33 int FAST_FUNC ndelay_off(int fd) 34 { 35 return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK); 36 } 37 38 int FAST_FUNC close_on_exec_on(int fd) 39 { 40 return fcntl(fd, F_SETFD, FD_CLOEXEC); 28 void FAST_FUNC ndelay_on(int fd) 29 { 30 int flags = fcntl(fd, F_GETFL); 31 if (flags & O_NONBLOCK) 32 return; 33 fcntl(fd, F_SETFL, flags | O_NONBLOCK); 34 } 35 36 void FAST_FUNC ndelay_off(int fd) 37 { 38 int flags = fcntl(fd, F_GETFL); 39 if (!(flags & O_NONBLOCK)) 40 return; 41 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 42 } 43 44 void FAST_FUNC close_on_exec_on(int fd) 45 { 46 fcntl(fd, F_SETFD, FD_CLOEXEC); 41 47 } 42 48 … … 235 241 if (s) { 236 242 value = atoi(s); 237 /* If LINES/COLUMNS are set, preten tthat there is243 /* If LINES/COLUMNS are set, pretend that there is 238 244 * no error getting w/h, this prevents some ugly 239 245 * cursor tricks by our callers */ -
branches/3.2/mindi-busybox/libbb/xfuncs_printf.c
r2725 r3232 356 356 { 357 357 if (chdir(path)) 358 bb_perror_msg_and_die("c hdir(%s)", path);358 bb_perror_msg_and_die("can't change directory to '%s'", path); 359 359 } 360 360 … … 362 362 { 363 363 if (chroot(path)) 364 bb_perror_msg_and_die("can't change root directory to %s", path); 364 bb_perror_msg_and_die("can't change root directory to '%s'", path); 365 xchdir("/"); 365 366 } 366 367
Note:
See TracChangeset
for help on using the changeset viewer.