Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/miscutils
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (9 years ago)
- Location:
- branches/3.3
- Files:
-
- 4 added
- 1 deleted
- 29 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/miscutils/Config.src
r3232 r3621 133 133 manipulate real-time attributes of a process. 134 134 This requires sched_{g,s}etparam support in your libc. 135 136 config CROND137 bool "crond"138 default y139 select FEATURE_SYSLOG140 help141 Crond is a background daemon that parses individual crontab142 files and executes commands on behalf of the users in question.143 This is a port of dcron from slackware. It uses files of the144 format /var/spool/cron/crontabs/<username> files, for example:145 $ cat /var/spool/cron/crontabs/root146 # Run daily cron jobs at 4:40 every day:147 40 4 * * * /etc/cron/daily > /dev/null 2>&1148 149 config FEATURE_CROND_D150 bool "Support option -d to redirect output to stderr"151 depends on CROND152 default y153 help154 -d sets loglevel to 0 (most verbose) and directs all output to stderr.155 156 config FEATURE_CROND_CALL_SENDMAIL157 bool "Report command output via email (using sendmail)"158 default y159 depends on CROND160 help161 Command output will be sent to corresponding user via email.162 163 config FEATURE_CROND_DIR164 string "crond spool directory"165 default "/var/spool/cron"166 depends on CROND || CRONTAB167 help168 Location of crond spool.169 135 170 136 config CRONTAB … … 343 309 'last' displays a list of the last users that logged into the system. 344 310 345 choice 346 prompt "Choose last implementation" 311 config FEATURE_LAST_FANCY 312 bool "Turn on output of extra information" 313 default y 347 314 depends on LAST 348 default FEATURE_LAST_FANCY349 350 config FEATURE_LAST_SMALL351 bool "small"352 help353 This is a small version of last with just the basic set of354 features.355 356 config FEATURE_LAST_FANCY357 bool "huge"358 315 help 359 316 'last' displays detailed information about the last users that 360 317 logged into the system (mimics sysvinit last). +900 bytes. 361 endchoice362 318 363 319 config HDPARM … … 504 460 run this applet as a background job. 505 461 506 config RFKILL507 bool "rfkill"508 default n # doesn't build on Ubuntu 9.04509 select PLATFORM_LINUX510 help511 Enable/disable wireless devices.512 513 rfkill list : list all wireless devices514 rfkill list bluetooth : list all bluetooth devices515 rfkill list 1 : list device corresponding to the given index516 rfkill block|unblock wlan : block/unblock all wlan(wifi) devices517 518 462 config RUNLEVEL 519 463 bool "runlevel" … … 545 489 strings prints the printable character sequences for each file 546 490 specified. 547 548 config TASKSET549 bool "taskset"550 default n # doesn't build on some non-x86 targets (m68k)551 help552 Retrieve or set a processes's CPU affinity.553 This requires sched_{g,s}etaffinity support in your libc.554 555 config FEATURE_TASKSET_FANCY556 bool "Fancy output"557 default y558 depends on TASKSET559 help560 Add code for fancy output. This merely silences a compiler-warning561 and adds about 135 Bytes. May be needed for machines with alot562 of CPUs.563 491 564 492 config TIME … … 591 519 help 592 520 Prints a CD-ROM volume name. 593 594 config WALL595 bool "wall"596 default y597 depends on FEATURE_UTMP598 help599 Write a message to all users that are logged in.600 521 601 522 config WATCHDOG -
branches/3.3/mindi-busybox/miscutils/Kbuild.src
r2725 r3621 13 13 lib-$(CONFIG_CHAT) += chat.o 14 14 lib-$(CONFIG_CHRT) += chrt.o 15 lib-$(CONFIG_CROND) += crond.o16 15 lib-$(CONFIG_CRONTAB) += crontab.o 17 16 lib-$(CONFIG_DC) += dc.o … … 27 26 lib-$(CONFIG_HDPARM) += hdparm.o 28 27 lib-$(CONFIG_INOTIFYD) += inotifyd.o 29 lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o 30 lib-$(CONFIG_FEATURE_LAST_FANCY)+= last_fancy.o 28 29 ifeq ($(CONFIG_FEATURE_LAST_FANCY),y) 30 lib-$(CONFIG_FEATURE_LAST_FANCY) += last_fancy.o 31 else 32 lib-$(CONFIG_LAST) += last.o 33 endif 34 31 35 lib-$(CONFIG_LESS) += less.o 32 36 lib-$(CONFIG_MAKEDEVS) += makedevs.o … … 37 41 lib-$(CONFIG_RAIDAUTORUN) += raidautorun.o 38 42 lib-$(CONFIG_READAHEAD) += readahead.o 39 lib-$(CONFIG_RFKILL) += rfkill.o40 43 lib-$(CONFIG_RUNLEVEL) += runlevel.o 41 44 lib-$(CONFIG_RX) += rx.o 42 45 lib-$(CONFIG_SETSID) += setsid.o 43 46 lib-$(CONFIG_STRINGS) += strings.o 44 lib-$(CONFIG_TASKSET) += taskset.o45 47 lib-$(CONFIG_TIME) += time.o 46 48 lib-$(CONFIG_TIMEOUT) += timeout.o 47 49 lib-$(CONFIG_TTYSIZE) += ttysize.o 48 50 lib-$(CONFIG_VOLNAME) += volname.o 49 lib-$(CONFIG_WALL) += wall.o50 51 lib-$(CONFIG_WATCHDOG) += watchdog.o -
branches/3.3/mindi-busybox/miscutils/adjtimex.c
r3232 r3621 15 15 //usage: "[-q] [-o OFF] [-f FREQ] [-p TCONST] [-t TICK]" 16 16 //usage:#define adjtimex_full_usage "\n\n" 17 //usage: "Read and optionally set system timebase parameters. See adjtimex(2)\n"17 //usage: "Read or set kernel time variables. See adjtimex(2)\n" 18 18 //usage: "\n -q Quiet" 19 19 //usage: "\n -o OFF Time offset, microseconds" 20 20 //usage: "\n -f FREQ Frequency adjust, integer kernel units (65536 is 1ppm)" 21 //usage: "\n (positive values make clock run faster)"22 21 //usage: "\n -t TICK Microseconds per tick, usually 10000" 22 //usage: "\n (positive -t or -f values make clock run faster)" 23 23 //usage: "\n -p TCONST" 24 24 … … 30 30 #endif 31 31 32 static const uint16_t statlist_bit[] = {32 static const uint16_t statlist_bit[] ALIGN2 = { 33 33 STA_PLL, 34 34 STA_PPSFREQ, … … 46 46 0 47 47 }; 48 static const char statlist_name[] =48 static const char statlist_name[] ALIGN1 = 49 49 "PLL" "\0" 50 50 "PPSFREQ" "\0" … … 62 62 ; 63 63 64 static const char ret_code_descript[] =64 static const char ret_code_descript[] ALIGN1 = 65 65 "clock synchronized" "\0" 66 66 "insert leap second" "\0" … … 112 112 113 113 if (!(opt & OPT_quiet)) { 114 intsep;114 const char *sep; 115 115 const char *name; 116 116 117 117 printf( 118 118 " mode: %d\n" 119 "-o offset: %ld \n"120 "-f freq uency: %ld\n"119 "-o offset: %ld us\n" 120 "-f freq.adjust: %ld (65536 = 1ppm)\n" 121 121 " maxerror: %ld\n" 122 122 " esterror: %ld\n" … … 126 126 127 127 /* representative output of next code fragment: 128 "PLL | PPSTIME" */ 128 * "PLL | PPSTIME" 129 */ 129 130 name = statlist_name; 130 sep = 0;131 sep = ""; 131 132 for (i = 0; statlist_bit[i]; i++) { 132 133 if (txc.status & statlist_bit[i]) { 133 if (sep) 134 fputs(" | ", stdout); 135 fputs(name, stdout); 136 sep = 1; 134 printf("%s%s", sep, name); 135 sep = " | "; 137 136 } 138 137 name += strlen(name) + 1; … … 144 143 printf(")\n" 145 144 "-p timeconstant: %ld\n" 146 " precision: %ld \n"145 " precision: %ld us\n" 147 146 " tolerance: %ld\n" 148 "-t tick: %ld \n"147 "-t tick: %ld us\n" 149 148 " time.tv_sec: %ld\n" 150 149 " time.tv_usec: %ld\n" -
branches/3.3/mindi-busybox/miscutils/beep.c
r3232 r3621 89 89 } 90 90 while (rep) { 91 //bb_ info_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay);91 //bb_error_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay); 92 92 xioctl(speaker, KIOCSOUND, (void*)(uintptr_t)tickrate_div_freq); 93 93 usleep(1000 * length); -
branches/3.3/mindi-busybox/miscutils/chat.c
r3232 r3621 18 18 19 19 #include "libbb.h" 20 #include "common_bufsiz.h" 20 21 21 22 // default timeout: 45 sec … … 286 287 && (pfd.revents & POLLIN) 287 288 ) { 288 #define buf bb_common_bufsiz1289 289 llist_t *l; 290 290 ssize_t delta; 291 #define buf bb_common_bufsiz1 292 setup_common_bufsiz(); 291 293 292 294 // read next char from device … … 297 299 } 298 300 // dump device input if ECHO ON 299 if (echo > 0) {301 if (echo) { 300 302 // if (buf[buf_len] < ' ') { 301 303 // full_write(STDERR_FILENO, "^", 1); -
branches/3.3/mindi-busybox/miscutils/chrt.c
r3232 r3621 24 24 #include <sched.h> 25 25 #include "libbb.h" 26 #ifndef _POSIX_PRIORITY_SCHEDULING27 #warning your system may be foobared28 #endif29 26 30 27 static const struct { -
branches/3.3/mindi-busybox/miscutils/conspy.c
r3232 r3621 43 43 44 44 #include "libbb.h" 45 #include "common_bufsiz.h" 45 46 #include <sys/kd.h> 46 47 … … 364 365 { 365 366 char tty_name[sizeof(DEV_TTY "NN")]; 366 #define keybuf bb_common_bufsiz1367 367 struct termios termbuf; 368 368 unsigned opts; … … 383 383 applet_long_options = getopt_longopts; 384 384 #endif 385 #define keybuf bb_common_bufsiz1 386 setup_common_bufsiz(); 387 385 388 INIT_G(); 386 389 strcpy(G.vcsa_name, DEV_VCSA); … … 514 517 // Read the keys pressed 515 518 k = keybuf + G.key_count; 516 bytes_read = read(G.kbd_fd, k, sizeof(keybuf)- G.key_count);519 bytes_read = read(G.kbd_fd, k, COMMON_BUFSIZE - G.key_count); 517 520 if (bytes_read < 0) 518 521 goto abort; -
branches/3.3/mindi-busybox/miscutils/crond.c
r3232 r3621 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * crond -d[#] -c <crondir> -f -b4 *5 3 * run as root, but NOT setuid root 6 4 * … … 11 9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 12 10 */ 11 //config:config CROND 12 //config: bool "crond" 13 //config: default y 14 //config: select FEATURE_SYSLOG 15 //config: help 16 //config: Crond is a background daemon that parses individual crontab 17 //config: files and executes commands on behalf of the users in question. 18 //config: This is a port of dcron from slackware. It uses files of the 19 //config: format /var/spool/cron/crontabs/<username> files, for example: 20 //config: $ cat /var/spool/cron/crontabs/root 21 //config: # Run daily cron jobs at 4:40 every day: 22 //config: 40 4 * * * /etc/cron/daily > /dev/null 2>&1 23 //config: 24 //config:config FEATURE_CROND_D 25 //config: bool "Support option -d to redirect output to stderr" 26 //config: depends on CROND 27 //config: default y 28 //config: help 29 //config: -d N sets loglevel (0:most verbose) and directs all output to stderr. 30 //config: 31 //config:config FEATURE_CROND_CALL_SENDMAIL 32 //config: bool "Report command output via email (using sendmail)" 33 //config: default y 34 //config: depends on CROND 35 //config: help 36 //config: Command output will be sent to corresponding user via email. 37 //config: 38 //config:config FEATURE_CROND_DIR 39 //config: string "crond spool directory" 40 //config: default "/var/spool/cron" 41 //config: depends on CROND || CRONTAB 42 //config: help 43 //config: Location of crond spool. 44 45 //applet:IF_CROND(APPLET(crond, BB_DIR_USR_SBIN, BB_SUID_DROP)) 46 47 //kbuild:lib-$(CONFIG_CROND) += crond.o 13 48 14 49 //usage:#define crond_trivial_usage … … 18 53 //usage: "\n -b Background (default)" 19 54 //usage: "\n -S Log to syslog (default)" 20 //usage: "\n -l Set log level. 0 is the most verbose, default8"55 //usage: "\n -l N Set log level. Most verbose:0, default:8" 21 56 //usage: IF_FEATURE_CROND_D( 22 //usage: "\n -d Set log level, log to stderr"57 //usage: "\n -d N Set log level, log to stderr" 23 58 //usage: ) 24 //usage: "\n -L Log to file"25 //usage: "\n -c Working dir"59 //usage: "\n -L FILE Log to FILE" 60 //usage: "\n -c DIR Cron dir. Default:"CONFIG_FEATURE_CROND_DIR"/crontabs" 26 61 27 62 #include "libbb.h" 63 #include "common_bufsiz.h" 28 64 #include <syslog.h> 29 65 … … 37 73 38 74 39 #define TMPDIRCONFIG_FEATURE_CROND_DIR75 #define CRON_DIR CONFIG_FEATURE_CROND_DIR 40 76 #define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs" 41 77 #ifndef SENDMAIL … … 70 106 char *cl_mailto; /* whom to mail results, may be NULL */ 71 107 #endif 108 char *cl_shell; 72 109 /* ordered by size, not in natural order. makes code smaller: */ 73 110 char cl_Dow[7]; /* 0-6, beginning sunday */ … … 91 128 OPT_d = (1 << 6) * ENABLE_FEATURE_CROND_D, 92 129 }; 93 #if ENABLE_FEATURE_CROND_D94 # define DebugOpt (option_mask32 & OPT_d)95 #else96 # define DebugOpt 097 #endif98 99 130 100 131 struct globals { … … 107 138 char *env_var_user; 108 139 char *env_var_home; 140 char *env_var_shell; 141 char *env_var_logname; 109 142 #endif 110 143 } FIX_ALIASING; 111 #define G (*(struct globals*) &bb_common_bufsiz1)144 #define G (*(struct globals*)bb_common_bufsiz1) 112 145 #define INIT_G() do { \ 146 setup_common_bufsiz(); \ 113 147 G.log_level = 8; \ 114 148 G.crontab_dir_name = CRONTABS; \ 115 149 } while (0) 116 150 117 118 /* 0 is the most verbose, default 8 */ 119 #define LVL5 "\x05" 120 #define LVL7 "\x07" 121 #define LVL8 "\x08" 122 #define WARN9 "\x49" 123 #define DIE9 "\xc9" 124 /* level >= 20 is "error" */ 125 #define ERR20 "\x14" 126 127 static void crondlog(const char *ctl, ...) __attribute__ ((format (printf, 1, 2))); 128 static void crondlog(const char *ctl, ...) 151 /* Log levels: 152 * 0 is the most verbose, default 8. 153 * For some reason, in fact only 5, 7 and 8 are used. 154 */ 155 static void crondlog(unsigned level, const char *msg, va_list va) 156 { 157 if (level >= G.log_level) { 158 /* 159 * We are called only for info meesages. 160 * Warnings/errors use plain bb_[p]error_msg's, which 161 * need not touch syslog_level 162 * (they are ok with LOG_ERR default). 163 */ 164 syslog_level = LOG_INFO; 165 bb_verror_msg(msg, va, /* strerr: */ NULL); 166 syslog_level = LOG_ERR; 167 } 168 } 169 170 static void log5(const char *msg, ...) 129 171 { 130 172 va_list va; 131 int level = (ctl[0] & 0x1f); 132 133 va_start(va, ctl); 134 if (level >= (int)G.log_level) { 135 /* Debug mode: all to (non-redirected) stderr, */ 136 /* Syslog mode: all to syslog (logmode = LOGMODE_SYSLOG), */ 137 if (!DebugOpt && G.log_filename) { 138 /* Otherwise (log to file): we reopen log file at every write: */ 139 int logfd = open_or_warn(G.log_filename, O_WRONLY | O_CREAT | O_APPEND); 140 if (logfd >= 0) 141 xmove_fd(logfd, STDERR_FILENO); 142 } 143 /* When we log to syslog, level > 8 is logged at LOG_ERR 144 * syslog level, level <= 8 is logged at LOG_INFO. */ 145 if (level > 8) { 146 bb_verror_msg(ctl + 1, va, /* strerr: */ NULL); 147 } else { 148 char *msg = NULL; 149 vasprintf(&msg, ctl + 1, va); 150 bb_info_msg("%s: %s", applet_name, msg); 151 free(msg); 152 } 153 } 173 va_start(va, msg); 174 crondlog(4, msg, va); 154 175 va_end(va); 155 if (ctl[0] & 0x80) 156 exit(20); 157 } 176 } 177 178 static void log7(const char *msg, ...) 179 { 180 va_list va; 181 va_start(va, msg); 182 crondlog(7, msg, va); 183 va_end(va); 184 } 185 186 static void log8(const char *msg, ...) 187 { 188 va_list va; 189 va_start(va, msg); 190 crondlog(8, msg, va); 191 va_end(va); 192 } 193 158 194 159 195 static const char DowAry[] ALIGN1 = 160 196 "sun""mon""tue""wed""thu""fri""sat" 161 /* "Sun""Mon""Tue""Wed""Thu""Fri""Sat" */162 197 ; 163 198 164 199 static const char MonAry[] ALIGN1 = 165 200 "jan""feb""mar""apr""may""jun""jul""aug""sep""oct""nov""dec" 166 /* "Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec" */167 201 ; 168 202 … … 268 302 if (*ptr) { 269 303 err: 270 crondlog(WARN9"user %s: parse error at %s", user, base);304 bb_error_msg("user %s: parse error at %s", user, base); 271 305 return; 272 306 } 273 307 274 if (DebugOpt && (G.log_level <= 5)) { /* like LVL5*/275 /* can't use crondlog, it inserts '\n' */308 /* can't use log5 (it inserts newlines), open-coding it */ 309 if (G.log_level <= 5 && logmode != LOGMODE_SYSLOG) { 276 310 int i; 277 311 for (i = 0; i < modvalue; ++i) … … 369 403 char *mailTo = NULL; 370 404 #endif 405 char *shell = NULL; 371 406 372 407 delete_cronfile(fileName); 373 408 374 409 if (!getpwnam(fileName)) { 375 crondlog(LVL7"ignoring file '%s' (no such user)", fileName);410 log7("ignoring file '%s' (no such user)", fileName); 376 411 return; 377 412 } … … 394 429 CronLine *line; 395 430 396 if (!--maxLines) 431 if (!--maxLines) { 432 bb_error_msg("user %s: too many lines", fileName); 397 433 break; 434 } 435 398 436 n = config_read(parser, tokens, 6, 1, "# \t", PARSE_NORMAL | PARSE_KEEP_COPY); 399 437 if (!n) 400 438 break; 401 439 402 if (DebugOpt) 403 crondlog(LVL5 "user:%s entry:%s", fileName, parser->data); 440 log5("user:%s entry:%s", fileName, parser->data); 404 441 405 442 /* check if line is setting MAILTO= */ 406 if ( 0 == strncmp(tokens[0], "MAILTO=", 7)) {443 if (is_prefixed_with(tokens[0], "MAILTO=")) { 407 444 #if ENABLE_FEATURE_CROND_CALL_SENDMAIL 408 445 free(mailTo); … … 411 448 continue; 412 449 } 450 if (is_prefixed_with(tokens[0], "SHELL=")) { 451 free(shell); 452 shell = xstrdup(&tokens[0][6]); 453 continue; 454 } 455 //TODO: handle HOME= too? "man crontab" says: 456 //name = value 457 // 458 //where the spaces around the equal-sign (=) are optional, and any subsequent 459 //non-leading spaces in value will be part of the value assigned to name. 460 //The value string may be placed in quotes (single or double, but matching) 461 //to preserve leading or trailing blanks. 462 // 463 //Several environment variables are set up automatically by the cron(8) daemon. 464 //SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd 465 //line of the crontab's owner. HOME and SHELL may be overridden by settings 466 //in the crontab; LOGNAME may not. 467 413 468 /* check if a minimum of tokens is specified */ 414 469 if (n < 6) … … 430 485 line->cl_mailto = xstrdup(mailTo); 431 486 #endif 487 line->cl_shell = xstrdup(shell); 432 488 /* copy command */ 433 489 line->cl_cmd = xstrdup(tokens[5]); 434 if (DebugOpt) {435 crondlog(LVL5 " command:%s", tokens[5]);436 }437 490 pline = &line->cl_next; 438 491 //bb_error_msg("M[%s]F[%s][%s][%s][%s][%s][%s]", mailTo, tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]); … … 442 495 file->cf_next = G.cron_files; 443 496 G.cron_files = file; 444 445 if (maxLines == 0) {446 crondlog(WARN9 "user %s: too many lines", fileName);447 }448 497 } 449 498 config_close(parser); 499 #if ENABLE_FEATURE_CROND_CALL_SENDMAIL 500 free(mailTo); 501 #endif 502 free(shell); 450 503 } 451 504 … … 483 536 unlink(CRONUPDATE); 484 537 /* Re-chdir, in case directory was renamed & deleted */ 485 if (chdir(G.crontab_dir_name) < 0) { 486 crondlog(DIE9 "chdir(%s)", G.crontab_dir_name); 487 } 538 xchdir(G.crontab_dir_name); 488 539 489 540 /* Scan directory and add associated users */ … … 492 543 struct dirent *den; 493 544 545 /* xopendir exists, but "can't open '.'" is not informative */ 494 546 if (!dir) 495 crondlog(DIE9 "chdir(%s)", "."); /* exits */547 bb_error_msg_and_die("can't open '%s'", G.crontab_dir_name); 496 548 while ((den = readdir(dir)) != NULL) { 497 549 if (strchr(den->d_name, '.') != NULL) { … … 520 572 #endif 521 573 522 static void set_env_vars(struct passwd *pas) 523 { 574 static void set_env_vars(struct passwd *pas, const char *shell) 575 { 576 /* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL. 577 * We assume crond inherited suitable PATH. 578 */ 524 579 #if SETENV_LEAKS 580 safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name); 525 581 safe_setenv(&G.env_var_user, "USER", pas->pw_name); 526 582 safe_setenv(&G.env_var_home, "HOME", pas->pw_dir); 527 /* if we want to set user's shell instead: */ 528 /*safe_setenv(G.env_var_shell, "SHELL", pas->pw_shell);*/ 583 safe_setenv(&G.env_var_shell, "SHELL", shell); 529 584 #else 585 xsetenv("LOGNAME", pas->pw_name); 530 586 xsetenv("USER", pas->pw_name); 531 587 xsetenv("HOME", pas->pw_dir); 532 #endif 533 /* currently, we use constant one: */ 534 /*setenv("SHELL", DEFAULT_SHELL, 1); - done earlier */ 588 xsetenv("SHELL", shell); 589 #endif 535 590 } 536 591 … … 540 595 change_identity(pas); /* - initgroups, setgid, setuid */ 541 596 if (chdir(pas->pw_dir) < 0) { 542 crondlog(WARN9 "chdir(%s)", pas->pw_dir); 543 if (chdir(TMPDIR) < 0) { 544 crondlog(DIE9 "chdir(%s)", TMPDIR); /* exits */ 545 } 597 bb_error_msg("can't change directory to '%s'", pas->pw_dir); 598 xchdir(CRON_DIR); 546 599 } 547 600 } … … 551 604 552 605 static pid_t 553 fork_job(const char *user, int mailFd, 554 const char *prog, 555 const char *shell_cmd /* if NULL, we run sendmail */ 556 ) { 606 fork_job(const char *user, int mailFd, CronLine *line, bool run_sendmail) 607 { 557 608 struct passwd *pas; 609 const char *shell, *prog; 610 smallint sv_logmode; 558 611 pid_t pid; 559 612 … … 561 614 pas = getpwnam(user); 562 615 if (!pas) { 563 crondlog(WARN9"can't get uid for %s", user);616 bb_error_msg("can't get uid for %s", user); 564 617 goto err; 565 618 } 566 set_env_vars(pas); 567 619 620 shell = line->cl_shell ? line->cl_shell : DEFAULT_SHELL; 621 prog = run_sendmail ? SENDMAIL : shell; 622 623 set_env_vars(pas, shell); 624 625 sv_logmode = logmode; 568 626 pid = vfork(); 569 627 if (pid == 0) { 570 628 /* CHILD */ 571 /* initgroups, setgid, setuid, and chdir to home or TMPDIR */629 /* initgroups, setgid, setuid, and chdir to home or CRON_DIR */ 572 630 change_user(pas); 573 if (DebugOpt) { 574 crondlog(LVL5 "child running %s", prog); 575 } 631 log5("child running %s", prog); 576 632 if (mailFd >= 0) { 577 xmove_fd(mailFd, shell_cmd ? 1 : 0);633 xmove_fd(mailFd, run_sendmail ? 0 : 1); 578 634 dup2(1, 2); 579 635 } 580 636 /* crond 3.0pl1-100 puts tasks in separate process groups */ 581 637 bb_setpgrp(); 582 execlp(prog, prog, (shell_cmd ? "-c" : SENDMAIL_ARGS), shell_cmd, (char *) NULL); 583 crondlog(ERR20 "can't execute '%s' for user %s", prog, user); 584 if (shell_cmd) { 585 fdprintf(1, "Exec failed: %s -c %s\n", prog, shell_cmd); 586 } 587 _exit(EXIT_SUCCESS); 588 } 638 if (!run_sendmail) 639 execlp(prog, prog, "-c", line->cl_cmd, (char *) NULL); 640 else 641 execlp(prog, prog, SENDMAIL_ARGS, (char *) NULL); 642 /* 643 * I want this error message on stderr too, 644 * even if other messages go only to syslog: 645 */ 646 logmode |= LOGMODE_STDIO; 647 bb_error_msg_and_die("can't execute '%s' for user %s", prog, user); 648 } 649 logmode = sv_logmode; 589 650 590 651 if (pid < 0) { 591 /* FORK FAILED */ 592 crondlog(ERR20 "can't vfork"); 652 bb_perror_msg("vfork"); 593 653 err: 594 654 pid = 0; … … 615 675 if (line->cl_mailto) { 616 676 /* Open mail file (owner is root so nobody can screw with it) */ 617 snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, getpid());677 snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", CRON_DIR, user, getpid()); 618 678 mailFd = open(mailFile, O_CREAT | O_TRUNC | O_WRONLY | O_EXCL | O_APPEND, 0600); 619 679 … … 623 683 line->cl_empty_mail_size = lseek(mailFd, 0, SEEK_CUR); 624 684 } else { 625 crondlog(ERR20"can't create mail file %s for user %s, "685 bb_error_msg("can't create mail file %s for user %s, " 626 686 "discarding output", mailFile, user); 627 687 } 628 688 } 629 689 630 line->cl_pid = fork_job(user, mailFd, DEFAULT_SHELL, line->cl_cmd);690 line->cl_pid = fork_job(user, mailFd, line, /*sendmail?*/ 0); 631 691 if (mailFd >= 0) { 632 692 if (line->cl_pid <= 0) { … … 634 694 } else { 635 695 /* rename mail-file based on pid of process */ 636 char *mailFile2 = xasprintf("%s/cron.%s.%d", TMPDIR, user, (int)line->cl_pid);696 char *mailFile2 = xasprintf("%s/cron.%s.%d", CRON_DIR, user, (int)line->cl_pid); 637 697 rename(mailFile, mailFile2); // TODO: xrename? 638 698 free(mailFile2); … … 666 726 * If size has changed and the file is still valid, we send it. 667 727 */ 668 snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", TMPDIR, user, (int)pid);728 snprintf(mailFile, sizeof(mailFile), "%s/cron.%s.%d", CRON_DIR, user, (int)pid); 669 729 mailFd = open(mailFile, O_RDONLY); 670 730 unlink(mailFile); … … 684 744 line->cl_empty_mail_size = 0; 685 745 /* if (line->cl_mailto) - always true if cl_empty_mail_size was nonzero */ 686 line->cl_pid = fork_job(user, mailFd, SENDMAIL, NULL);746 line->cl_pid = fork_job(user, mailFd, line, /*sendmail?*/ 1); 687 747 } 688 748 … … 691 751 static void start_one_job(const char *user, CronLine *line) 692 752 { 753 const char *shell; 693 754 struct passwd *pas; 694 755 pid_t pid; … … 696 757 pas = getpwnam(user); 697 758 if (!pas) { 698 crondlog(WARN9"can't get uid for %s", user);759 bb_error_msg("can't get uid for %s", user); 699 760 goto err; 700 761 } 701 762 702 763 /* Prepare things before vfork */ 703 set_env_vars(pas); 764 shell = line->cl_shell ? line->cl_shell : DEFAULT_SHELL; 765 set_env_vars(pas, shell); 704 766 705 767 /* Fork as the user in question and run program */ … … 707 769 if (pid == 0) { 708 770 /* CHILD */ 709 /* initgroups, setgid, setuid, and chdir to home or TMPDIR */771 /* initgroups, setgid, setuid, and chdir to home or CRON_DIR */ 710 772 change_user(pas); 711 if (DebugOpt) { 712 crondlog(LVL5 "child running %s", DEFAULT_SHELL); 713 } 773 log5("child running %s", shell); 714 774 /* crond 3.0pl1-100 puts tasks in separate process groups */ 715 775 bb_setpgrp(); 716 execl(DEFAULT_SHELL, DEFAULT_SHELL, "-c", line->cl_cmd, (char *) NULL); 717 crondlog(ERR20 "can't execute '%s' for user %s", DEFAULT_SHELL, user); 718 _exit(EXIT_SUCCESS); 776 execl(shell, shell, "-c", line->cl_cmd, (char *) NULL); 777 bb_error_msg_and_die("can't execute '%s' for user %s", shell, user); 719 778 } 720 779 if (pid < 0) { 721 /* FORK FAILED */ 722 crondlog(ERR20 "can't vfork"); 780 bb_perror_msg("vfork"); 723 781 err: 724 782 pid = 0; … … 752 810 ptm = localtime(&t); 753 811 for (file = G.cron_files; file; file = file->cf_next) { 754 if (DebugOpt) 755 crondlog(LVL5 "file %s:", file->cf_username); 812 log5("file %s:", file->cf_username); 756 813 if (file->cf_deleted) 757 814 continue; 758 815 for (line = file->cf_lines; line; line = line->cl_next) { 759 if (DebugOpt) 760 crondlog(LVL5 " line %s", line->cl_cmd); 816 log5(" line %s", line->cl_cmd); 761 817 if (line->cl_Mins[ptm->tm_min] 762 818 && line->cl_Hrs[ptm->tm_hour] … … 764 820 && line->cl_Mons[ptm->tm_mon] 765 821 ) { 766 if (DebugOpt) { 767 crondlog(LVL5 " job: %d %s", 822 log5(" job: %d %s", 768 823 (int)line->cl_pid, line->cl_cmd); 769 }770 824 if (line->cl_pid > 0) { 771 crondlog(LVL8"user %s: process already running: %s",825 log8("user %s: process already running: %s", 772 826 file->cf_username, line->cl_cmd); 773 827 } else if (line->cl_pid == 0) { … … 798 852 start_one_job(file->cf_username, line); 799 853 pid = line->cl_pid; 800 crondlog(LVL8"USER %s pid %3d cmd %s",854 log8("USER %s pid %3d cmd %s", 801 855 file->cf_username, (int)pid, line->cl_cmd); 802 856 if (pid < 0) { … … 850 904 } 851 905 906 static void reopen_logfile_to_stderr(void) 907 { 908 if (G.log_filename) { 909 int logfd = open_or_warn(G.log_filename, O_WRONLY | O_CREAT | O_APPEND); 910 if (logfd >= 0) 911 xmove_fd(logfd, STDERR_FILENO); 912 } 913 } 914 852 915 int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 853 916 int crond_main(int argc UNUSED_PARAM, char **argv) 854 917 { 855 918 time_t t2; 856 intrescan;857 intsleep_time;919 unsigned rescan; 920 unsigned sleep_time; 858 921 unsigned opts; 859 922 … … 881 944 } 882 945 946 //signal(SIGHUP, SIG_IGN); /* ? original crond dies on HUP... */ 947 948 reopen_logfile_to_stderr(); 883 949 xchdir(G.crontab_dir_name); 884 //signal(SIGHUP, SIG_IGN); /* ? original crond dies on HUP... */ 885 xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */ 886 crondlog(LVL8 "crond (busybox "BB_VER") started, log level %d", G.log_level); 950 log8("crond (busybox "BB_VER") started, log level %d", G.log_level); 887 951 rescan_crontab_dir(); 888 952 write_pidfile(CONFIG_PID_FILE_PATH "/crond.pid"); … … 897 961 long dt; 898 962 963 /* Synchronize to 1 minute, minimum 1 second */ 899 964 t1 = t2; 900 901 /* Synchronize to 1 minute, minimum 1 second */ 902 sleep(sleep_time - (time(NULL) % sleep_time) + 1); 903 965 sleep(sleep_time - (time(NULL) % sleep_time)); 904 966 t2 = time(NULL); 905 967 dt = (long)t2 - (long)t1; 968 969 reopen_logfile_to_stderr(); 906 970 907 971 /* … … 932 996 } 933 997 process_cron_update_file(); 934 if (DebugOpt) 935 crondlog(LVL5 "wakeup dt=%ld", dt); 998 log5("wakeup dt=%ld", dt); 936 999 if (dt < -60 * 60 || dt > 60 * 60) { 937 crondlog(WARN9"time disparity of %ld minutes detected", dt / 60);1000 bb_error_msg("time disparity of %ld minutes detected", dt / 60); 938 1001 /* and we do not run any jobs in this case */ 939 1002 } else if (dt > 0) { … … 941 1004 flag_starting_jobs(t1, t2); 942 1005 start_jobs(); 1006 sleep_time = 60; 943 1007 if (check_completions() > 0) { 944 1008 /* some jobs are still running */ 945 1009 sleep_time = 10; 946 } else {947 sleep_time = 60;948 1010 } 949 1011 } -
branches/3.3/mindi-busybox/miscutils/crontab.c
r3232 r3621 54 54 BB_EXECLP(ptr, ptr, file, NULL); 55 55 bb_perror_msg_and_die("can't execute '%s'", ptr); 56 }57 58 static int open_as_user(const struct passwd *pas, const char *file)59 {60 pid_t pid;61 char c;62 63 pid = xvfork();64 if (pid) { /* PARENT */65 if (wait4pid(pid) == 0) {66 /* exitcode 0: child says it can read */67 return open(file, O_RDONLY);68 }69 return -1;70 }71 72 /* CHILD */73 /* initgroups, setgid, setuid */74 change_identity(pas);75 /* We just try to read one byte. If it works, file is readable76 * under this user. We signal that by exiting with 0. */77 _exit(safe_read(xopen(file, O_RDONLY), &c, 1) < 0);78 56 } 79 57 … … 138 116 bb_show_usage(); 139 117 if (NOT_LONE_DASH(argv[0])) { 140 src_fd = open_as_user(pas, argv[0]); 141 if (src_fd < 0) 142 bb_error_msg_and_die("user %s cannot read %s", 143 pas->pw_name, argv[0]); 118 src_fd = xopen_as_uid_gid(argv[0], O_RDONLY, pas->pw_uid, pas->pw_gid); 144 119 } 145 120 } … … 196 171 /*free(tmp_fname);*/ 197 172 /*free(new_fname);*/ 198 199 173 } /* switch */ 200 174 -
branches/3.3/mindi-busybox/miscutils/dc.c
r3232 r3621 5 5 6 6 #include "libbb.h" 7 #include "common_bufsiz.h" 7 8 #include <math.h> 8 9 … … 48 49 } FIX_ALIASING; 49 50 enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(double) }; 50 #define G (*(struct globals*) &bb_common_bufsiz1)51 #define G (*(struct globals*)bb_common_bufsiz1) 51 52 #define pointer (G.pointer ) 52 53 #define base (G.base ) 53 54 #define stack (G.stack ) 54 55 #define INIT_G() do { \ 56 setup_common_bufsiz(); \ 55 57 base = 10; \ 56 58 } while (0) 57 59 60 61 static void check_under(void) 62 { 63 if (pointer == 0) 64 bb_error_msg_and_die("stack underflow"); 65 } 58 66 59 67 static void push(double a) … … 66 74 static double pop(void) 67 75 { 68 if (pointer == 0) 69 bb_error_msg_and_die("stack underflow"); 76 check_under(); 70 77 return stack[--pointer]; 71 78 } … … 188 195 static void print_no_pop(void) 189 196 { 197 check_under(); 190 198 print_base(stack[pointer-1]); 191 199 } … … 197 205 198 206 static const struct op operators[] = { 199 {"+", add},200 {"add", add},201 {"-", sub},202 {"sub", sub},203 {"*", mul},204 {"mul", mul},205 {"/", divide},206 {"div", divide},207 207 #if ENABLE_FEATURE_DC_LIBM 208 208 {"**", power}, … … 217 217 {"eor", eor}, 218 218 {"xor", eor}, 219 {"+", add}, 220 {"add", add}, 221 {"-", sub}, 222 {"sub", sub}, 223 {"*", mul}, 224 {"mul", mul}, 225 {"/", divide}, 226 {"div", divide}, 219 227 {"p", print_no_pop}, 220 228 {"f", print_stack_no_pop}, … … 222 230 }; 223 231 232 /* Feed the stack machine */ 224 233 static void stack_machine(const char *argument) 225 234 { 226 235 char *end; 227 double d;236 double number; 228 237 const struct op *o; 229 238 230 d = strtod(argument, &end); 231 if (end != argument && *end == '\0') { 232 push(d); 239 next: 240 number = strtod(argument, &end); 241 if (end != argument) { 242 argument = end; 243 push(number); 244 goto next; 245 } 246 247 /* We might have matched a digit, eventually advance the argument */ 248 argument = skip_whitespace(argument); 249 250 if (*argument == '\0') 233 251 return; 234 }235 252 236 253 o = operators; 237 254 do { 238 if (strcmp(o->name, argument) == 0) { 255 char *after_name = is_prefixed_with(argument, o->name); 256 if (after_name) { 257 argument = after_name; 239 258 o->function(); 240 return;259 goto next; 241 260 } 242 261 o++; … … 255 274 /* take stuff from stdin if no args are given */ 256 275 char *line; 257 char *cursor;258 char *token;259 276 while ((line = xmalloc_fgetline(stdin)) != NULL) { 260 cursor = line; 261 while (1) { 262 token = skip_whitespace(cursor); 263 if (*token == '\0') 264 break; 265 cursor = skip_non_whitespace(token); 266 if (*cursor != '\0') 267 *cursor++ = '\0'; 268 stack_machine(token); 269 } 277 stack_machine(line); 270 278 free(line); 271 279 } 272 280 } else { 273 // why? it breaks "dc -2 2 + p"274 //if (argv[0][0] == '-')275 // bb_show_usage();276 281 do { 277 282 stack_machine(*argv); -
branches/3.3/mindi-busybox/miscutils/devfsd.c
r3232 r3621 285 285 /* Busybox stuff */ 286 286 #if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG 287 #define info_logger(p, fmt, args...) bb_ info_msg(fmt, ## args)287 #define info_logger(p, fmt, args...) bb_error_msg(fmt, ## args) 288 288 #define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args) 289 289 #define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args) … … 1084 1084 struct passwd *pw_ent; 1085 1085 struct group *grp_ent; 1086 static const char *msg; 1086 const char *msg; 1087 1088 if (isdigit(string[0]) || ((string[0] == '-') && isdigit(string[1]))) 1089 return atoi(string); 1090 1091 if (flag == UID && (pw_ent = getpwnam(string)) != NULL) 1092 return pw_ent->pw_uid; 1087 1093 1088 1094 if (ENABLE_DEVFSD_VERBOSE) 1089 1095 msg = "user"; 1090 1096 1091 if (isdigit(string[0]) ||((string[0] == '-') && isdigit(string[1]))) 1092 return atoi(string); 1093 1094 if (flag == UID && (pw_ent = getpwnam(string)) != NULL) 1095 return pw_ent->pw_uid; 1096 1097 if (flag == GID && (grp_ent = getgrnam(string)) != NULL) 1098 return grp_ent->gr_gid; 1099 else if (ENABLE_DEVFSD_VERBOSE) 1100 msg = "group"; 1097 if (flag == GID) { 1098 if ((grp_ent = getgrnam(string)) != NULL) 1099 return grp_ent->gr_gid; 1100 if (ENABLE_DEVFSD_VERBOSE) 1101 msg = "group"; 1102 } 1101 1103 1102 1104 if (ENABLE_DEVFSD_VERBOSE) … … 1141 1143 static const char *get_variable(const char *variable, void *info) 1142 1144 { 1143 static char sbuf[sizeof(int)*3 + 2]; /* sign and NUL */1144 1145 static char *hostname; 1145 1146 1146 1147 struct get_variable_info *gv_info = info; 1147 1148 const char *field_names[] = { 1148 "hostname", "mntpt", "devpath", "devname", 1149 "uid", "gid", "mode", hostname, mount_point, 1150 gv_info->devpath, gv_info->devname, NULL 1149 "hostname", "mntpt", "devpath", "devname", "uid", "gid", "mode", 1150 NULL, mount_point, gv_info->devpath, gv_info->devname, NULL 1151 1151 }; 1152 1152 int i; … … 1154 1154 if (!hostname) 1155 1155 hostname = safe_gethostname(); 1156 field_names[7] = hostname; 1157 1156 1158 /* index_in_str_array returns i>=0 */ 1157 1159 i = index_in_str_array(field_names, variable); … … 1163 1165 1164 1166 if (i == 4) 1165 sprintf(sbuf, "%u", gv_info->info->uid); 1166 else if (i == 5) 1167 sprintf(sbuf, "%u", gv_info->info->gid); 1168 else if (i == 6) 1169 sprintf(sbuf, "%o", gv_info->info->mode); 1170 return sbuf; 1167 return auto_string(xasprintf("%u", gv_info->info->uid)); 1168 if (i == 5) 1169 return auto_string(xasprintf("%u", gv_info->info->gid)); 1170 /* i == 6 */ 1171 return auto_string(xasprintf("%o", gv_info->info->mode)); 1171 1172 } /* End Function get_variable */ 1172 1173 … … 1404 1405 const char *pty1; 1405 1406 const char *pty2; 1406 size_t len;1407 1407 /* 1 to 5 "scsi/" , 6 to 9 "ide/host", 10 sbp/, 11 vcc/, 12 pty/ */ 1408 1408 static const char *const fmt[] = { … … 1424 1424 1425 1425 for (trans = translate_table; trans->match != NULL; ++trans) { 1426 len = strlen(trans->match); 1427 1428 if (strncmp(devname, trans->match, len) == 0) { 1426 char *after_match = is_prefixed_with(devname, trans->match); 1427 if (after_match) { 1429 1428 if (trans->format == NULL) 1430 return devname + len;1431 sprintf(buffer, trans->format, devname + len);1429 return after_match; 1430 sprintf(buffer, trans->format, after_match); 1432 1431 return buffer; 1433 1432 } -
branches/3.3/mindi-busybox/miscutils/eject.c
r3232 r3621 26 26 #include <sys/mount.h> 27 27 #include "libbb.h" 28 #if ENABLE_FEATURE_EJECT_SCSI 28 29 /* Must be after libbb.h: they need size_t */ 29 #include "fix_u32.h" 30 #include <scsi/sg.h> 31 #include <scsi/scsi.h> 32 33 /* various defines swiped from linux/cdrom.h */ 34 #define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ 35 #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ 36 #define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ 37 /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ 38 #define CDS_TRAY_OPEN 2 30 # include "fix_u32.h" 31 # include <scsi/sg.h> 32 # include <scsi/scsi.h> 33 #endif 39 34 40 35 #define dev_fd 3 … … 43 38 * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ 44 39 40 #if ENABLE_FEATURE_EJECT_SCSI 45 41 static void eject_scsi(const char *dev) 46 42 { 47 static const char sg_commands[3][6] = {43 static const char sg_commands[3][6] ALIGN1 = { 48 44 { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, 49 45 { START_STOP, 0, 0, 0, 1, 0 }, … … 77 73 ioctl(dev_fd, BLKRRPART); 78 74 } 75 #else 76 # define eject_scsi(dev) ((void)0) 77 #endif 78 79 /* various defines swiped from linux/cdrom.h */ 80 #define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ 81 #define CDROMEJECT 0x5309 /* Ejects the cdrom media */ 82 #define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ 83 /* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ 84 #define CDS_TRAY_OPEN 2 79 85 80 86 #define FLAG_CLOSE 1 -
branches/3.3/mindi-busybox/miscutils/fbsplash.c
r3232 r3621 35 35 36 36 #include "libbb.h" 37 #include "common_bufsiz.h" 37 38 #include <linux/fb.h> 38 39 … … 151 152 // map the device in memory 152 153 G.addr = mmap(NULL, 153 G.scr_var.yres* G.scr_fix.line_length,154 (G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length, 154 155 PROT_WRITE, MAP_SHARED, fbfd, 0); 155 156 if (G.addr == MAP_FAILED) … … 354 355 theme_file = stdin; 355 356 } else { 356 int fd = open_zipped(G.image_filename );357 int fd = open_zipped(G.image_filename, /*fail_if_not_compressed:*/ 0); 357 358 if (fd < 0) 358 359 bb_simple_perror_msg_and_die(G.image_filename); … … 374 375 */ 375 376 #define concat_buf bb_common_bufsiz1 377 setup_common_bufsiz(); 378 376 379 read_ptr = concat_buf; 377 380 while (1) { 378 381 int w, h, max_color_val; 379 int rem = concat_buf + sizeof(concat_buf)- read_ptr;382 int rem = concat_buf + COMMON_BUFSIZE - read_ptr; 380 383 if (rem < 2 381 384 || fgets(read_ptr, rem, theme_file) == NULL … … 517 520 // already in the pipe 518 521 while ((num_buf = xmalloc_fgetline(fp)) != NULL) { 519 if ( strncmp(num_buf, "exit", 4) == 0) {522 if (is_prefixed_with(num_buf, "exit")) { 520 523 DEBUG_MESSAGE("exit"); 521 524 break; -
branches/3.3/mindi-busybox/miscutils/flash_eraseall.c
r3232 r3621 12 12 13 13 //usage:#define flash_eraseall_trivial_usage 14 //usage: "[-j q] MTD_DEVICE"14 //usage: "[-jNq] MTD_DEVICE" 15 15 //usage:#define flash_eraseall_full_usage "\n\n" 16 16 //usage: "Erase an MTD device\n" 17 17 //usage: "\n -j Format the device for jffs2" 18 //usage: "\n -N Don't skip bad blocks" 18 19 //usage: "\n -q Don't display progress messages" 19 20 … … 23 24 24 25 #define OPTION_J (1 << 0) 25 #define OPTION_ Q(1 << 1)26 #define IS_NAND(1 << 2)27 #define BBTEST(1 << 3)26 #define OPTION_N (1 << 1) 27 #define OPTION_Q (1 << 2) 28 #define IS_NAND (1 << 3) 28 29 29 30 /* mtd/jffs2-user.h used to have this atrocity: … … 72 73 73 74 opt_complementary = "=1"; 74 flags = BBTEST | getopt32(argv, "jq");75 flags = getopt32(argv, "jNq"); 75 76 76 77 mtd_name = argv[optind]; … … 140 141 for (erase.start = 0; erase.start < meminfo.size; 141 142 erase.start += meminfo.erasesize) { 142 if ( flags & BBTEST) {143 if (!(flags & OPTION_N)) { 143 144 int ret; 144 145 loff_t offset = erase.start; … … 147 148 if (ret > 0) { 148 149 if (!(flags & OPTION_Q)) 149 bb_info_msg("\nSkipping bad block at 0x%08x", erase.start);150 printf("\nSkipping bad block at 0x%08x\n", erase.start); 150 151 continue; 151 152 } … … 155 156 */ 156 157 if (errno == EOPNOTSUPP) { 157 flags &= ~BBTEST;158 flags |= OPTION_N; 158 159 if (flags & IS_NAND) 159 160 bb_error_msg_and_die("bad block check not available"); -
branches/3.3/mindi-busybox/miscutils/flashcp.c
r3232 r3621 17 17 #include <mtd/mtd-user.h> 18 18 19 /* If 1, simulates "flashing" by writing to existing regular file */ 19 20 #define MTD_DEBUG 0 20 21 21 22 #define OPT_v (1 << 0) 22 23 23 #define BUFSIZE ( 8* 1024)24 #define BUFSIZE (4 * 1024) 24 25 25 26 static void progress(int mode, uoff_t count, uoff_t total) … … 33 34 percent = (unsigned) (percent / total); 34 35 printf("\r%s: %"OFF_FMT"u/%"OFF_FMT"u (%u%%) ", 35 (mode == 0) ? "Erasing block" : ((mode == 1) ? "Writing kb" : "Verifying kb"),36 (mode < 0) ? "Erasing block" : ((mode == 0) ? "Writing kb" : "Verifying kb"), 36 37 count, total, (unsigned)percent); 37 38 fflush_all(); … … 98 99 e.start = 0; 99 100 for (i = 1; i <= erase_count; i++) { 100 progress(0, i, erase_count); 101 errno = 0; 101 progress(-1, i, erase_count); 102 102 #if !MTD_DEBUG 103 103 if (ioctl(fd_d, MEMERASE, &e) < 0) { … … 114 114 /* doing this outer loop gives significantly smaller code 115 115 * than doing two separate loops for writing and verifying */ 116 for (i = 1; i <= 2; i++) {116 for (i = 0; i <= 1; i++) { 117 117 uoff_t done; 118 118 unsigned count; … … 123 123 count = BUFSIZE; 124 124 while (1) { 125 uoff_t rem = statb.st_size - done; 125 uoff_t rem; 126 127 progress(i, done / 1024, (uoff_t)statb.st_size / 1024); 128 rem = statb.st_size - done; 126 129 if (rem == 0) 127 130 break; 128 131 if (rem < BUFSIZE) 129 132 count = rem; 130 progress(i, done / 1024, (uoff_t)statb.st_size / 1024);131 133 xread(fd_f, buf, count); 132 if (i == 1) {134 if (i == 0) { 133 135 int ret; 136 if (count < BUFSIZE) 137 memset((char*)buf + count, 0, BUFSIZE - count); 134 138 errno = 0; 135 ret = full_write(fd_d, buf, count);136 if (ret != count) {139 ret = full_write(fd_d, buf, BUFSIZE); 140 if (ret != BUFSIZE) { 137 141 bb_perror_msg_and_die("write error at 0x%"OFF_FMT"x on %s, " 138 142 "write returned %d", 139 143 done, devicename, ret); 140 144 } 141 } else { /* i == 2*/145 } else { /* i == 1 */ 142 146 xread(fd_d, buf2, count); 143 if (memcmp(buf, buf2, count) ) {147 if (memcmp(buf, buf2, count) != 0) { 144 148 bb_error_msg_and_die("verification mismatch at 0x%"OFF_FMT"x", done); 145 149 } -
branches/3.3/mindi-busybox/miscutils/hdparm.c
r3232 r3621 64 64 65 65 #include "libbb.h" 66 #include "common_bufsiz.h" 66 67 /* must be _after_ libbb.h: */ 67 68 #include <linux/hdreg.h> … … 368 369 #endif 369 370 } FIX_ALIASING; 370 #define G (*(struct globals*)&bb_common_bufsiz1) 371 struct BUG_G_too_big { 372 char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; 373 }; 371 #define G (*(struct globals*)bb_common_bufsiz1) 374 372 #define get_identity (G.get_identity ) 375 373 #define get_geom (G.get_geom ) … … 434 432 #define hwif_ctrl (G.hwif_ctrl ) 435 433 #define hwif_irq (G.hwif_irq ) 436 #define INIT_G() do { } while (0) 434 #define INIT_G() do { \ 435 setup_common_bufsiz(); \ 436 BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ 437 } while (0) 437 438 438 439 … … 466 467 { 467 468 if (get_arg) { 468 printf(" setting %s to %l d", s, arg);469 printf(" setting %s to %lu", s, arg); 469 470 on_off(arg); 470 471 } … … 473 474 static void print_value_on_off(const char *str, unsigned long argp) 474 475 { 475 printf(" %s\t= %2l d", str, argp);476 printf(" %s\t= %2lu", str, argp); 476 477 on_off(argp != 0); 477 478 } … … 764 765 like_std = 5; 765 766 if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) 766 p rintf("powers-up in standby; SET FEATURES subcmd spins-up.\n");767 puts("powers-up in standby; SET FEATURES subcmd spins-up."); 767 768 if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) 768 p rintf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n");769 puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); 769 770 } 770 771 … … 876 877 min_std = like_std > 4 ? like_std - 3 : 1; 877 878 878 p rintf("Configuration:\n");879 puts("Configuration:"); 879 880 /* more info from the general configuration word */ 880 881 if ((eqpt != CDROM) && (like_std == 1)) { … … 910 911 bbbig = 0; 911 912 if ((ll > 0x00FBFC10) && (!val[LCYLS])) 912 p rintf("\tCHS addressing not supported\n");913 puts("\tCHS addressing not supported"); 913 914 else { 914 915 jj = val[WHATS_VALID] & OK_W54_58; … … 981 982 (val[CAPAB_0] & IORDY_OFF) ? "" :"not"); 982 983 } else 983 p rintf("no IORDY\n");984 puts("no IORDY"); 984 985 985 986 if ((like_std == 1) && val[BUF_TYPE]) { … … 1013 1014 printf("\tR/W multiple sector transfer: "); 1014 1015 if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) 1015 p rintf("not supported\n");1016 puts("not supported"); 1016 1017 else { 1017 1018 printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER); … … 1019 1020 printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER); 1020 1021 else 1021 p rintf("?\n");1022 puts("?"); 1022 1023 } 1023 1024 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { … … 1041 1042 /* ATAPI */ 1042 1043 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) 1043 p rintf("\tATA sw reset required\n");1044 puts("\tATA sw reset required"); 1044 1045 1045 1046 if (val[PKT_REL] || val[SVC_NBSY]) { … … 1057 1058 printf("\tDMA: "); 1058 1059 if (!(val[CAPAB_0] & DMA_SUP)) 1059 p rintf("not supported\n");1060 puts("not supported"); 1060 1061 else { 1061 1062 if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]) … … 1080 1081 1081 1082 if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) 1082 p rintf("\t\tInterleaved DMA support\n");1083 puts("\t\tInterleaved DMA support"); 1083 1084 1084 1085 if ((val[WHATS_VALID] & OK_W64_70) … … 1122 1123 1123 1124 if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) { 1124 p rintf("Commands/features:\n"1125 "\tEnabled\tSupported: \n");1125 puts("Commands/features:\n" 1126 "\tEnabled\tSupported:"); 1126 1127 jj = val[CMDS_SUPP_0]; 1127 1128 kk = val[CMDS_EN_0]; … … 1151 1152 && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]) 1152 1153 ) { 1153 p rintf("Security:\n");1154 puts("Security:"); 1154 1155 if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)) 1155 1156 printf("\tMaster password revision code = %u\n", val[PSWD_CODE]); … … 1367 1368 } 1368 1369 #endif /* __NEW_HD_DRIVE_ID */ 1369 p rintf("\n\n * current active mode\n\n");1370 puts("\n\n * current active mode\n"); 1370 1371 } 1371 1372 #endif … … 1508 1509 on_off(0); 1509 1510 else if (value == BUSSTATE_TRISTATE) 1510 p rintf(" (tristate)\n");1511 puts(" (tristate)"); 1511 1512 else 1512 printf(" (unknown: % d)\n", value);1513 printf(" (unknown: %u)\n", value); 1513 1514 } 1514 1515 #endif … … 1532 1533 if (standby == 254) 1533 1534 printf("reserved"); 1534 p rintf(")\n");1535 puts(")"); 1535 1536 } 1536 1537 … … 1583 1584 else 1584 1585 printf("unknown"); 1585 p rintf(")\n");1586 puts(")"); 1586 1587 } 1587 1588 #endif /* HDIO_DRIVE_CMD */ … … 1590 1591 { 1591 1592 if (flag) 1592 printf(" setting %s to %l d\n", s, value);1593 printf(" setting %s to %lu\n", s, value); 1593 1594 } 1594 1595 … … 1634 1635 printf(" attempting to "); 1635 1636 if (piomode == 255) 1636 p rintf("auto-tune PIO mode\n");1637 puts("auto-tune PIO mode"); 1637 1638 else if (piomode < 100) 1638 1639 printf("set PIO mode to %d\n", piomode); … … 1763 1764 #define WIN_STANDBYNOW2 0x94 1764 1765 #endif 1765 p rintf(" issuing standby command\n");1766 puts(" issuing standby command"); 1766 1767 args[0] = WIN_STANDBYNOW1; 1767 1768 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2); … … 1774 1775 #define WIN_SLEEPNOW2 0x99 1775 1776 #endif 1776 p rintf(" issuing sleep command\n");1777 puts(" issuing sleep command"); 1777 1778 args[0] = WIN_SLEEPNOW1; 1778 1779 ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2); … … 1780 1781 if (set_seagate) { 1781 1782 args[0] = 0xfb; 1782 p rintf(" disabling Seagate auto powersaving mode\n");1783 puts(" disabling Seagate auto powersaving mode"); 1783 1784 ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); 1784 1785 } … … 1816 1817 printf(" IO_support\t=%3ld (", parm); 1817 1818 if (parm == 0) 1818 p rintf("default 16-bit)\n");1819 puts("default 16-bit)"); 1819 1820 else if (parm == 2) 1820 p rintf("16-bit)\n");1821 puts("16-bit)"); 1821 1822 else if (parm == 1) 1822 p rintf("32-bit)\n");1823 puts("32-bit)"); 1823 1824 else if (parm == 3) 1824 p rintf("32-bit w/sync)\n");1825 puts("32-bit w/sync)"); 1825 1826 else if (parm == 8) 1826 p rintf("Request-Queue-Bypass)\n");1827 puts("Request-Queue-Bypass)"); 1827 1828 else 1828 p rintf("\?\?\?)\n");1829 puts("\?\?\?)"); 1829 1830 } 1830 1831 } … … 1838 1839 printf(fmt, "using_dma", parm); 1839 1840 if (parm == 8) 1840 p rintf(" (DMA-Assisted-PIO)\n");1841 puts(" (DMA-Assisted-PIO)"); 1841 1842 else 1842 1843 on_off(parm != 0); … … 1922 1923 dump_identity(&id); 1923 1924 } else if (errno == -ENOMSG) 1924 p rintf(" no identification info available\n");1925 puts(" no identification info available"); 1925 1926 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ 1926 1927 bb_perror_msg("HDIO_GET_IDENTITY"); -
branches/3.3/mindi-busybox/miscutils/inotifyd.c
r3232 r3621 48 48 //usage: "\n x File can't be watched anymore" 49 49 //usage: "\nIf watching a directory:" 50 //usage: "\n mSubfile is moved into dir"51 //usage: "\n ySubfile is moved out of dir"50 //usage: "\n y Subfile is moved into dir" 51 //usage: "\n m Subfile is moved out of dir" 52 52 //usage: "\n n Subfile is created" 53 53 //usage: "\n d Subfile is deleted" … … 57 57 58 58 #include "libbb.h" 59 #include "common_bufsiz.h" 59 60 #include <sys/inotify.h> 60 61 … … 162 163 // read out all pending events 163 164 // (NB: len must be int, not ssize_t or long!) 165 #define eventbuf bb_common_bufsiz1 166 setup_common_bufsiz(); 164 167 xioctl(pfd.fd, FIONREAD, &len); 165 #define eventbuf bb_common_bufsiz1 166 ie = buf = (len <= sizeof(eventbuf)) ? eventbuf : xmalloc(len); 168 ie = buf = (len <= COMMON_BUFSIZE) ? eventbuf : xmalloc(len); 167 169 len = full_read(pfd.fd, buf, len); 168 170 // process events. N.B. events may vary in length -
branches/3.3/mindi-busybox/miscutils/ionice.c
r3232 r3621 42 42 }; 43 43 44 static const char to_prio[] = "none\0realtime\0best-effort\0idle";44 static const char to_prio[] ALIGN1 = "none\0realtime\0best-effort\0idle"; 45 45 46 46 #define IOPRIO_CLASS_SHIFT 13 -
branches/3.3/mindi-busybox/miscutils/last.c
r3232 r3621 33 33 #if defined UT_LINESIZE \ 34 34 && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)) 35 #error struct utmp member char[] size(s) have changed!35 #error struct utmpx member char[] size(s) have changed! 36 36 #elif defined __UT_LINESIZE \ 37 && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 64) || (__UT_HOSTSIZE != 256)) 38 #error struct utmp member char[] size(s) have changed! 37 && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 32) || (__UT_HOSTSIZE != 256)) 38 /* __UT_NAMESIZE was checked with 64 above, but glibc-2.11 definitely uses 32! */ 39 #error struct utmpx member char[] size(s) have changed! 39 40 #endif 40 41 41 42 #if EMPTY != 0 || RUN_LVL != 1 || BOOT_TIME != 2 || NEW_TIME != 3 || \ 42 43 OLD_TIME != 4 43 #error Values for the ut_type field of struct utmp changed44 #error Values for the ut_type field of struct utmpx changed 44 45 #endif 45 46 … … 47 48 int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 48 49 { 49 struct utmp ut;50 struct utmpx ut; 50 51 int n, file = STDIN_FILENO; 51 52 time_t t_tmp; … … 88 89 ut.ut_type = n != 3 ? n : SHUTDOWN_TIME; 89 90 #else 90 if ( strncmp(ut.ut_user, "shutdown", 8) == 0)91 if (is_prefixed_with(ut.ut_user, "shutdown")) 91 92 ut.ut_type = SHUTDOWN_TIME; 92 else if ( strncmp(ut.ut_user, "reboot", 6) == 0)93 else if (is_prefixed_with(ut.ut_user, "reboot")) 93 94 ut.ut_type = BOOT_TIME; 94 else if ( strncmp(ut.ut_user, "runlevel", 8) == 0)95 else if (is_prefixed_with(ut.ut_user, "runlevel")) 95 96 ut.ut_type = RUN_LVL; 96 97 #endif -
branches/3.3/mindi-busybox/miscutils/last_fancy.c
r3232 r3621 23 23 INET6_ADDRSTRLEN, INET6_ADDRSTRLEN, "HOST", "LOGIN", " TIME", "" 24 24 25 #if !defined __UT_LINESIZE && defined UT_LINESIZE 26 # define __UT_LINESIZE UT_LINESIZE 27 #endif 28 25 29 enum { 26 30 NORMAL, … … 40 44 #define show_wide (option_mask32 & LAST_OPT_W) 41 45 42 static void show_entry(struct utmp *ut, int state, time_t dur_secs)46 static void show_entry(struct utmpx *ut, int state, time_t dur_secs) 43 47 { 44 48 unsigned days, hours, mins; 45 char duration[ 32];49 char duration[sizeof("(%u+02:02)") + sizeof(int)*3]; 46 50 char login_time[17]; 47 51 char logout_time[8]; … … 54 58 tmp = ut->ut_tv.tv_sec; 55 59 safe_strncpy(login_time, ctime(&tmp), 17); 56 snprintf(logout_time, 8, "- %s", ctime(&dur_secs) + 11); 60 tmp = dur_secs; 61 snprintf(logout_time, 8, "- %s", ctime(&tmp) + 11); 57 62 58 63 dur_secs = MAX(dur_secs - (time_t)ut->ut_tv.tv_sec, (time_t)0); … … 104 109 } 105 110 106 static int get_ut_type(struct utmp *ut)111 static int get_ut_type(struct utmpx *ut) 107 112 { 108 113 if (ut->ut_line[0] == '~') { … … 142 147 } 143 148 144 static int is_runlevel_shutdown(struct utmp *ut)149 static int is_runlevel_shutdown(struct utmpx *ut) 145 150 { 146 151 if (((ut->ut_pid & 255) == '0') || ((ut->ut_pid & 255) == '6')) { … … 154 159 int last_main(int argc UNUSED_PARAM, char **argv) 155 160 { 156 struct utmp ut;161 struct utmpx ut; 157 162 const char *filename = _PATH_WTMP; 158 163 llist_t *zlist; … … 229 234 } 230 235 /* add_entry */ 231 llist_add_to(&zlist, memcpy(xmalloc(sizeof(ut)),&ut, sizeof(ut)));236 llist_add_to(&zlist, xmemdup(&ut, sizeof(ut))); 232 237 break; 233 238 case USER_PROCESS: { … … 242 247 llist_t *el, *next; 243 248 for (el = zlist; el; el = next) { 244 struct utmp *up = (struct utmp*)el->data;249 struct utmpx *up = (struct utmpx *)el->data; 245 250 next = el->link; 246 if (strncmp(up->ut_line, ut.ut_line, UT_LINESIZE) == 0) {251 if (strncmp(up->ut_line, ut.ut_line, __UT_LINESIZE) == 0) { 247 252 if (show) { 248 253 show_entry(&ut, NORMAL, up->ut_tv.tv_sec); … … 271 276 } 272 277 /* add_entry */ 273 llist_add_to(&zlist, memcpy(xmalloc(sizeof(ut)),&ut, sizeof(ut)));278 llist_add_to(&zlist, xmemdup(&ut, sizeof(ut))); 274 279 break; 275 280 } -
branches/3.3/mindi-busybox/miscutils/less.c
r3232 r3621 48 48 //config: help 49 49 //config: The -M/-m flag enables a more sophisticated status line. 50 //config: 51 //config:config FEATURE_LESS_TRUNCATE 52 //config: bool "Enable -S" 53 //config: default y 54 //config: depends on LESS 55 //config: help 56 //config: The -S flag causes long lines to be truncated rather than 57 //config: wrapped. 50 58 //config: 51 59 //config:config FEATURE_LESS_MARKS … … 99 107 100 108 //usage:#define less_trivial_usage 101 //usage: "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~I?] [FILE]..." 109 //usage: "[-E" IF_FEATURE_LESS_REGEXP("I")IF_FEATURE_LESS_FLAGS("Mm") 110 //usage: "N" IF_FEATURE_LESS_TRUNCATE("S") "h~] [FILE]..." 102 111 //usage:#define less_full_usage "\n\n" 103 112 //usage: "View FILE (or stdin) one screenful at a time\n" 104 113 //usage: "\n -E Quit once the end of a file is reached" 114 //usage: IF_FEATURE_LESS_REGEXP( 115 //usage: "\n -I Ignore case in all searches" 116 //usage: ) 105 117 //usage: IF_FEATURE_LESS_FLAGS( 106 118 //usage: "\n -M,-m Display status line with line numbers" … … 108 120 //usage: ) 109 121 //usage: "\n -N Prefix line number to each line" 110 //usage: "\n -I Ignore case in all searches" 122 //usage: IF_FEATURE_LESS_TRUNCATE( 123 //usage: "\n -S Truncate long lines" 124 //usage: ) 111 125 //usage: "\n -~ Suppress ~s displayed past EOF" 112 126 … … 114 128 115 129 #include "libbb.h" 130 #include "common_bufsiz.h" 116 131 #if ENABLE_FEATURE_LESS_REGEXP 117 132 #include "xregex.h" … … 143 158 FLAG_TILDE = 1 << 4, 144 159 FLAG_I = 1 << 5, 145 FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_ DASHCMD,160 FLAG_S = (1 << 6) * ENABLE_FEATURE_LESS_TRUNCATE, 146 161 /* hijack command line options variable for internal state vars */ 147 162 LESS_STATE_MATCH_BACKWARDS = 1 << 15, … … 175 190 char *filename; 176 191 char **files; 192 #if ENABLE_FEATURE_LESS_FLAGS 193 int num_lines; /* a flag if < 0, line count if >= 0 */ 194 # define REOPEN_AND_COUNT (-1) 195 # define REOPEN_STDIN (-2) 196 # define NOT_REGULAR_FILE (-3) 197 #endif 177 198 #if ENABLE_FEATURE_LESS_MARKS 178 199 unsigned num_marks; … … 216 237 #define filename (G.filename ) 217 238 #define files (G.files ) 239 #define num_lines (G.num_lines ) 218 240 #define num_marks (G.num_marks ) 219 241 #define mark_lines (G.mark_lines ) … … 318 340 if (*d != '\0') { 319 341 new_line_pos++; 320 if (*d == '\t') /* tab */342 if (*d == '\t') { /* tab */ 321 343 new_line_pos += 7; 344 new_line_pos &= (~7); 345 } 322 346 s++; 323 347 d++; … … 381 405 #endif 382 406 407 static int at_end(void) 408 { 409 return (option_mask32 & FLAG_S) 410 ? !(cur_fline <= max_fline && 411 max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) 412 : !(max_fline > cur_fline + max_displayed_line); 413 } 414 383 415 /* Devilishly complex routine. 384 416 * … … 403 435 * (takes into account tabs and backspaces) 404 436 * eof_error - < 0 error, == 0 EOF, > 0 not EOF/error 437 * 438 * "git log -p | less -m" on the kernel git tree is a good test for EAGAINs, 439 * "/search on very long input" and "reaching max line count" corner cases. 405 440 */ 406 441 static void read_lines(void) 407 442 { 408 #define readbuf bb_common_bufsiz1409 443 char *current_line, *p; 410 444 int w = width; 411 445 char last_terminated = terminated; 446 time_t last_time = 0; 447 int retry_EAGAIN = 2; 412 448 #if ENABLE_FEATURE_LESS_REGEXP 413 449 unsigned old_max_fline = max_fline; 414 time_t last_time = 0; 415 unsigned seconds_p1 = 3; /* seconds_to_loop + 1 */ 416 #endif 450 #endif 451 452 #define readbuf bb_common_bufsiz1 453 setup_common_bufsiz(); 454 455 /* (careful: max_fline can be -1) */ 456 if (max_fline + 1 > MAXLINES) 457 return; 417 458 418 459 if (option_mask32 & FLAG_N) 419 460 w -= 8; 420 461 421 IF_FEATURE_LESS_REGEXP(again0:) 422 423 p = current_line = ((char*)xmalloc(w + 4)) + 4; 424 max_fline += last_terminated; 462 p = current_line = ((char*)xmalloc(w + 5)) + 4; 425 463 if (!last_terminated) { 426 464 const char *cp = flines[max_fline]; 427 strcpy(p, cp); 428 p += strlen(current_line); 429 free(MEMPTR(flines[max_fline])); 465 p = stpcpy(p, cp); 466 free(MEMPTR(cp)); 430 467 /* last_line_pos is still valid from previous read_lines() */ 431 468 } else { 469 max_fline++; 432 470 last_line_pos = 0; 433 471 } … … 440 478 /* if no unprocessed chars left, eat more */ 441 479 if (readpos >= readeof) { 442 ndelay_on(0); 443 eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); 444 ndelay_off(0); 480 int flags = ndelay_on(0); 481 482 while (1) { 483 time_t t; 484 485 errno = 0; 486 eof_error = safe_read(STDIN_FILENO, readbuf, COMMON_BUFSIZE); 487 if (errno != EAGAIN) 488 break; 489 t = time(NULL); 490 if (t != last_time) { 491 last_time = t; 492 if (--retry_EAGAIN < 0) 493 break; 494 } 495 sched_yield(); 496 } 497 fcntl(0, F_SETFL, flags); /* ndelay_off(0) */ 445 498 readpos = 0; 446 499 readeof = eof_error; 447 500 if (eof_error <= 0) 448 501 goto reached_eof; 502 retry_EAGAIN = 1; 449 503 } 450 504 c = readbuf[readpos]; … … 465 519 new_last_line_pos &= (~7); 466 520 } 467 if ((int)new_last_line_pos > =w)521 if ((int)new_last_line_pos > w) 468 522 break; 469 523 last_line_pos = new_last_line_pos; … … 481 535 *p = '\0'; 482 536 } /* end of "read chars until we have a line" loop */ 537 #if 0 538 //BUG: also triggers on this: 539 // { printf "\nfoo\n"; sleep 1; printf "\nbar\n"; } | less 540 // (resulting in lost empty line between "foo" and "bar" lines) 541 // the "terminated" logic needs fixing (or explaining) 483 542 /* Corner case: linewrap with only "" wrapping to next line */ 484 543 /* Looks ugly on screen, so we do not store this empty line */ … … 488 547 continue; 489 548 } 549 #endif 490 550 reached_eof: 491 551 last_terminated = terminated; … … 501 561 break; 502 562 } 503 if (!(option_mask32 & FLAG_S) 504 ? (max_fline > cur_fline + max_displayed_line) 505 : (max_fline >= cur_fline 506 && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) 507 ) { 563 if (!at_end()) { 508 564 #if !ENABLE_FEATURE_LESS_REGEXP 509 565 break; … … 518 574 } 519 575 if (eof_error <= 0) { 520 if (eof_error < 0) {521 if (errno == EAGAIN) {522 /* not yet eof or error, reset flag (or else523 * we will hog CPU - select() will return524 * immediately */525 eof_error = 1;526 } else {527 print_statusline(bb_msg_read_error);528 }529 }530 #if !ENABLE_FEATURE_LESS_REGEXP531 576 break; 532 #else533 if (wanted_match < num_matches) {534 break;535 } else { /* goto_match called us */536 time_t t = time(NULL);537 if (t != last_time) {538 last_time = t;539 if (--seconds_p1 == 0)540 break;541 }542 sched_yield();543 goto again0; /* go loop again (max 2 seconds) */544 }545 #endif546 577 } 547 578 max_fline++; 548 current_line = ((char*)xmalloc(w + 4)) + 4;579 current_line = ((char*)xmalloc(w + 5)) + 4; 549 580 p = current_line; 550 581 last_line_pos = 0; 551 582 } /* end of "read lines until we reach cur_fline" loop */ 583 584 if (eof_error < 0) { 585 if (errno == EAGAIN) { 586 eof_error = 1; 587 } else { 588 print_statusline(bb_msg_read_error); 589 } 590 } 591 #if ENABLE_FEATURE_LESS_FLAGS 592 else if (eof_error == 0) 593 num_lines = max_lineno; 594 #endif 595 552 596 fill_match_lines(old_max_fline); 553 597 #if ENABLE_FEATURE_LESS_REGEXP … … 559 603 560 604 #if ENABLE_FEATURE_LESS_FLAGS 561 /* Interestingly, writing calc_percent as a function saves around 32 bytes 562 * on my build. */ 563 static int calc_percent(void) 564 { 565 unsigned p = (100 * (cur_fline+max_displayed_line+1) + max_fline/2) / (max_fline+1); 566 return p <= 100 ? p : 100; 605 static int safe_lineno(int fline) 606 { 607 if (fline >= max_fline) 608 fline = max_fline - 1; 609 610 /* also catches empty file (max_fline == 0) */ 611 if (fline < 0) 612 return 0; 613 614 return LINENO(flines[fline]) + 1; 615 } 616 617 /* count number of lines in file */ 618 static void update_num_lines(void) 619 { 620 int count, fd; 621 struct stat stbuf; 622 ssize_t len, i; 623 char buf[4096]; 624 625 /* only do this for regular files */ 626 if (num_lines == REOPEN_AND_COUNT || num_lines == REOPEN_STDIN) { 627 count = 0; 628 fd = open("/proc/self/fd/0", O_RDONLY); 629 if (fd < 0 && num_lines == REOPEN_AND_COUNT) { 630 /* "filename" is valid only if REOPEN_AND_COUNT */ 631 fd = open(filename, O_RDONLY); 632 } 633 if (fd < 0) { 634 /* somebody stole my file! */ 635 num_lines = NOT_REGULAR_FILE; 636 return; 637 } 638 if (fstat(fd, &stbuf) != 0 || !S_ISREG(stbuf.st_mode)) { 639 num_lines = NOT_REGULAR_FILE; 640 goto do_close; 641 } 642 while ((len = safe_read(fd, buf, sizeof(buf))) > 0) { 643 for (i = 0; i < len; ++i) { 644 if (buf[i] == '\n' && ++count == MAXLINES) 645 goto done; 646 } 647 } 648 done: 649 num_lines = count; 650 do_close: 651 close(fd); 652 } 567 653 } 568 654 … … 570 656 static void m_status_print(void) 571 657 { 572 int percentage; 658 int first, last; 659 unsigned percent; 573 660 574 661 if (less_gets_pos >= 0) /* don't touch statusline while input is done! */ … … 579 666 if (num_files > 1) 580 667 printf(" (file %i of %i)", current_file, num_files); 581 printf(" lines %i-%i/%i ", 582 cur_fline + 1, cur_fline + max_displayed_line + 1, 583 max_fline + 1); 584 if (cur_fline >= (int)(max_fline - max_displayed_line)) { 585 printf("(END)"NORMAL); 668 669 first = safe_lineno(cur_fline); 670 last = (option_mask32 & FLAG_S) 671 ? MIN(first + max_displayed_line, max_lineno) 672 : safe_lineno(cur_fline + max_displayed_line); 673 printf(" lines %i-%i", first, last); 674 675 update_num_lines(); 676 if (num_lines >= 0) 677 printf("/%i", num_lines); 678 679 if (at_end()) { 680 printf(" (END)"); 586 681 if (num_files > 1 && current_file != num_files) 587 printf(HIGHLIGHT" - next: %s"NORMAL, files[current_file]); 588 return; 589 } 590 percentage = calc_percent(); 591 printf("%i%%"NORMAL, percentage); 682 printf(" - next: %s", files[current_file]); 683 } else if (num_lines > 0) { 684 percent = (100 * last + num_lines/2) / num_lines; 685 printf(" %i%%", percent <= 100 ? percent : 100); 686 } 687 printf(NORMAL); 592 688 } 593 689 #endif … … 611 707 612 708 clear_line(); 613 if (cur_fline && cur_fline < (int)(max_fline - max_displayed_line)) {709 if (cur_fline && !at_end()) { 614 710 bb_putchar(':'); 615 711 return; … … 624 720 } 625 721 print_hilite(p); 626 }627 628 static void cap_cur_fline(int nlines)629 {630 int diff;631 if (cur_fline < 0)632 cur_fline = 0;633 if (cur_fline + max_displayed_line > max_fline + TILDES) {634 cur_fline -= nlines;635 if (cur_fline < 0)636 cur_fline = 0;637 diff = max_fline - (cur_fline + max_displayed_line) + TILDES;638 /* As the number of lines requested was too large, we just move639 * to the end of the file */640 if (diff > 0)641 cur_fline += diff;642 }643 722 } 644 723 … … 654 733 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"; 655 734 656 static void lineno_str(char *nbuf9, const char *line) 657 { 658 nbuf9[0] = '\0'; 659 if (option_mask32 & FLAG_N) { 660 const char *fmt; 661 unsigned n; 662 663 if (line == empty_line_marker) { 664 memset(nbuf9, ' ', 8); 665 nbuf9[8] = '\0'; 666 return; 667 } 735 static void print_lineno(const char *line) 736 { 737 const char *fmt = " "; 738 unsigned n = n; /* for compiler */ 739 740 if (line != empty_line_marker) { 668 741 /* Width of 7 preserves tab spacing in the text */ 669 742 fmt = "%7u "; 670 743 n = LINENO(line) + 1; 671 if (n > 9999999 ) {744 if (n > 9999999 && MAXLINES > 9999999) { 672 745 n %= 10000000; 673 746 fmt = "%07u "; 674 747 } 675 sprintf(nbuf9, fmt, n);676 }748 } 749 printf(fmt, n); 677 750 } 678 751 … … 686 759 regmatch_t match_structs; 687 760 688 char buf[width]; 689 char nbuf9[9]; 761 char buf[width+1]; 690 762 const char *str = line; 691 763 char *p = buf; … … 737 809 } 738 810 739 lineno_str(nbuf9, line); 740 if (!growline) { 741 printf(CLEAR_2_EOL"%s%s\n", nbuf9, str); 742 return; 743 } 744 printf(CLEAR_2_EOL"%s%s%s\n", nbuf9, growline, str); 811 printf("%s%s\n", growline ? growline : "", str); 745 812 free(growline); 746 813 } … … 751 818 static void print_ascii(const char *str) 752 819 { 753 char buf[width]; 754 char nbuf9[9]; 820 char buf[width+1]; 755 821 char *p; 756 822 size_t n; 757 758 lineno_str(nbuf9, str);759 printf(CLEAR_2_EOL"%s", nbuf9);760 823 761 824 while (*str) { … … 791 854 792 855 move_cursor(0, 0); 793 for (i = 0; i <= max_displayed_line; i++) 856 for (i = 0; i <= max_displayed_line; i++) { 857 printf(CLEAR_2_EOL); 858 if (option_mask32 & FLAG_N) 859 print_lineno(buffer[i]); 794 860 if (pattern_valid) 795 861 print_found(buffer[i]); 796 862 else 797 863 print_ascii(buffer[i]); 864 } 865 if ((option_mask32 & FLAG_E) 866 && eof_error <= 0 867 && (max_fline - cur_fline) <= max_displayed_line 868 ) { 869 less_exit(EXIT_SUCCESS); 870 } 798 871 status_print(); 799 872 } … … 802 875 { 803 876 unsigned i; 804 #if ENABLE_FEATURE_LESS_ DASHCMD877 #if ENABLE_FEATURE_LESS_TRUNCATE 805 878 int fpos = cur_fline; 806 879 … … 834 907 } 835 908 909 /* move cur_fline to a given line number, reading lines if necessary */ 910 static void goto_lineno(int target) 911 { 912 if (target <= 0 ) { 913 cur_fline = 0; 914 } 915 else if (target > LINENO(flines[cur_fline])) { 916 retry: 917 while (LINENO(flines[cur_fline]) != target && cur_fline < max_fline) 918 ++cur_fline; 919 /* target not reached but more input is available */ 920 if (LINENO(flines[cur_fline]) != target && eof_error > 0) { 921 read_lines(); 922 goto retry; 923 } 924 } 925 else { 926 /* search backwards through already-read lines */ 927 while (LINENO(flines[cur_fline]) != target && cur_fline > 0) 928 --cur_fline; 929 } 930 } 931 932 static void cap_cur_fline(void) 933 { 934 if ((option_mask32 & FLAG_S)) { 935 if (cur_fline > max_fline) 936 cur_fline = max_fline; 937 if (LINENO(flines[cur_fline]) + max_displayed_line > max_lineno + TILDES) { 938 goto_lineno(max_lineno - max_displayed_line + TILDES); 939 read_lines(); 940 } 941 } 942 else { 943 if (cur_fline + max_displayed_line > max_fline + TILDES) 944 cur_fline = max_fline - max_displayed_line + TILDES; 945 if (cur_fline < 0) 946 cur_fline = 0; 947 } 948 } 949 836 950 /* Move the buffer up and down in the file in order to scroll */ 837 951 static void buffer_down(int nlines) 838 952 { 839 cur_fline += nlines; 953 if ((option_mask32 & FLAG_S)) 954 goto_lineno(LINENO(flines[cur_fline]) + nlines); 955 else 956 cur_fline += nlines; 840 957 read_lines(); 841 cap_cur_fline( nlines);958 cap_cur_fline(); 842 959 buffer_fill_and_print(); 843 960 } … … 845 962 static void buffer_up(int nlines) 846 963 { 847 cur_fline -= nlines; 848 if (cur_fline < 0) cur_fline = 0; 964 if ((option_mask32 & FLAG_S)) { 965 goto_lineno(LINENO(flines[cur_fline]) - nlines); 966 } 967 else { 968 cur_fline -= nlines; 969 if (cur_fline < 0) 970 cur_fline = 0; 971 } 849 972 read_lines(); 850 973 buffer_fill_and_print(); 851 974 } 852 975 976 /* display a given line where the argument can be either an index into 977 * the flines array or a line number */ 978 static void buffer_to_line(int linenum, int is_lineno) 979 { 980 if (linenum <= 0) 981 cur_fline = 0; 982 else if (is_lineno) 983 goto_lineno(linenum); 984 else 985 cur_fline = linenum; 986 read_lines(); 987 cap_cur_fline(); 988 buffer_fill_and_print(); 989 } 990 853 991 static void buffer_line(int linenum) 854 992 { 855 if (linenum < 0) 856 linenum = 0; 857 cur_fline = linenum; 858 read_lines(); 859 if (linenum + max_displayed_line > max_fline) 860 linenum = max_fline - max_displayed_line + TILDES; 861 if (linenum < 0) 862 linenum = 0; 863 cur_fline = linenum; 864 buffer_fill_and_print(); 993 buffer_to_line(linenum, FALSE); 994 } 995 996 static void buffer_lineno(int lineno) 997 { 998 buffer_to_line(lineno, TRUE); 865 999 } 866 1000 … … 869 1003 if (filename) { 870 1004 xmove_fd(xopen(filename, O_RDONLY), STDIN_FILENO); 1005 #if ENABLE_FEATURE_LESS_FLAGS 1006 num_lines = REOPEN_AND_COUNT; 1007 #endif 871 1008 } else { 872 1009 /* "less" with no arguments in argv[] */ 873 1010 /* For status line only */ 874 1011 filename = xstrdup(bb_msg_standard_input); 1012 #if ENABLE_FEATURE_LESS_FLAGS 1013 num_lines = REOPEN_STDIN; 1014 #endif 875 1015 } 876 1016 readpos = 0; … … 924 1064 rd = 1; 925 1065 /* Are we interested in stdin? */ 926 //TODO: reuse code for determining this 927 if (!(option_mask32 & FLAG_S) 928 ? !(max_fline > cur_fline + max_displayed_line) 929 : !(max_fline >= cur_fline 930 && max_lineno > LINENO(flines[cur_fline]) + max_displayed_line) 931 ) { 1066 if (at_end()) { 932 1067 if (eof_error > 0) /* did NOT reach eof yet */ 933 1068 rd = 0; /* yes, we are interested in stdin */ … … 1240 1375 while (i < sizeof(num_input)-1) { 1241 1376 keypress = less_getch(i + 1); 1242 if ((unsigned)keypress > 255 || !isdigit( num_input[i]))1377 if ((unsigned)keypress > 255 || !isdigit(keypress)) 1243 1378 break; 1244 1379 num_input[i] = keypress; … … 1264 1399 break; 1265 1400 case 'g': case '<': case 'G': case '>': 1266 cur_fline = num + max_displayed_line; 1267 read_lines(); 1268 buffer_line(num - 1); 1401 buffer_lineno(num - 1); 1269 1402 break; 1270 1403 case 'p': case '%': 1271 num = num * (max_fline / 100); /* + max_fline / 2; */ 1272 cur_fline = num + max_displayed_line; 1273 read_lines(); 1274 buffer_line(num); 1404 #if ENABLE_FEATURE_LESS_FLAGS 1405 update_num_lines(); 1406 num = num * (num_lines > 0 ? num_lines : max_lineno) / 100; 1407 #else 1408 num = num * max_lineno / 100; 1409 #endif 1410 buffer_lineno(num); 1275 1411 break; 1276 1412 #if ENABLE_FEATURE_LESS_REGEXP … … 1312 1448 option_mask32 ^= FLAG_TILDE; 1313 1449 break; 1450 #if ENABLE_FEATURE_LESS_TRUNCATE 1314 1451 case 'S': 1315 1452 option_mask32 ^= FLAG_S; 1316 1453 buffer_fill_and_print(); 1317 1454 break; 1455 #endif 1318 1456 #if ENABLE_FEATURE_LESS_LINENUMS 1319 1457 case 'N': … … 1609 1747 int less_main(int argc, char **argv) 1610 1748 { 1749 char *tty_name; 1750 int tty_fd; 1751 1611 1752 INIT_G(); 1612 1753 1613 /* TODO: -x: do not interpret backspace, -xx: tab also */ 1614 /* -xxx: newline also */ 1615 /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ 1616 getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S")); 1754 /* TODO: -x: do not interpret backspace, -xx: tab also 1755 * -xxx: newline also 1756 * -w N: assume width N (-xxx -w 32: hex viewer of sorts) 1757 * -s: condense many empty lines to one 1758 * (used by some setups for manpage display) 1759 */ 1760 getopt32(argv, "EMmN~I" IF_FEATURE_LESS_TRUNCATE("S") /*ignored:*/"s"); 1617 1761 argc -= optind; 1618 1762 argv += optind; … … 1638 1782 empty_line_marker = ""; 1639 1783 1640 kbd_fd = open(CURRENT_TTY, O_RDONLY); 1641 if (kbd_fd < 0) 1642 return bb_cat(argv); 1643 ndelay_on(kbd_fd); 1784 /* Some versions of less can survive w/o controlling tty, 1785 * try to do the same. This also allows to specify an alternative 1786 * tty via "less 1<>TTY". 1787 * We don't try to use STDOUT_FILENO directly, 1788 * since we want to set this fd to non-blocking mode, 1789 * and not bother with restoring it on exit. 1790 */ 1791 tty_name = xmalloc_ttyname(STDOUT_FILENO); 1792 if (tty_name) { 1793 tty_fd = open(tty_name, O_RDONLY); 1794 free(tty_name); 1795 if (tty_fd < 0) 1796 goto try_ctty; 1797 } else { 1798 /* Try controlling tty */ 1799 try_ctty: 1800 tty_fd = open(CURRENT_TTY, O_RDONLY); 1801 if (tty_fd < 0) 1802 return bb_cat(argv); 1803 } 1804 ndelay_on(tty_fd); 1805 kbd_fd = tty_fd; /* save in a global */ 1644 1806 1645 1807 tcgetattr(kbd_fd, &term_orig); … … 1806 1968 or from within less by using the - or -- command. 1807 1969 Options may be given in one of two forms: either a single 1808 character preceded by a -, or a name prece eded by --.1970 character preceded by a -, or a name preceded by --. 1809 1971 -? ........ --help 1810 1972 Display help (from command line). -
branches/3.3/mindi-busybox/miscutils/man.c
r3232 r3621 67 67 68 68 line = xmalloc_open_zipped_read_close(man_filename, NULL); 69 if (!line || strncmp(line, ".so ", 4) != 0) {69 if (!line || !is_prefixed_with(line, ".so ")) { 70 70 free(line); 71 71 goto ordinary_manpage; … … 103 103 ordinary_manpage: 104 104 close(STDIN_FILENO); 105 open_zipped(man_filename ); /* guaranteed to use fd 0 (STDIN_FILENO) */105 open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */ 106 106 /* "2>&1" is added so that nroff errors are shown in pager too. 107 107 * Otherwise it may show just empty screen */ 108 108 cmd = xasprintf( 109 man ? "gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s" 109 /* replaced -Tlatin1 with -Tascii for non-UTF8 displays */ 110 man ? "gtbl | nroff -Tascii -mandoc 2>&1 | %s" 110 111 : "%s", 111 112 pager); … … 147 148 } 148 149 150 static char **add_MANPATH(char **man_path_list, int *count_mp, char *path) 151 { 152 if (path) while (*path) { 153 char *next_path; 154 char **path_element; 155 156 next_path = strchr(path, ':'); 157 if (next_path) { 158 if (next_path == path) /* "::"? */ 159 goto next; 160 *next_path = '\0'; 161 } 162 /* Do we already have path? */ 163 path_element = man_path_list; 164 if (path_element) while (*path_element) { 165 if (strcmp(*path_element, path) == 0) 166 goto skip; 167 path_element++; 168 } 169 man_path_list = xrealloc_vector(man_path_list, 4, *count_mp); 170 man_path_list[*count_mp] = xstrdup(path); 171 (*count_mp)++; 172 /* man_path_list is NULL terminated */ 173 /* man_path_list[*count_mp] = NULL; - xrealloc_vector did it */ 174 skip: 175 if (!next_path) 176 break; 177 /* "path" may be a result of getenv(), be nice and don't mangle it */ 178 *next_path = ':'; 179 next: 180 path = next_path + 1; 181 } 182 return man_path_list; 183 } 184 149 185 int man_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 150 186 int man_main(int argc UNUSED_PARAM, char **argv) 151 187 { 152 188 parser_t *parser; 153 const char *pager; 154 char **man_path_list; 189 const char *pager = ENABLE_LESS ? "less" : "more"; 155 190 char *sec_list; 156 191 char *cur_path, *cur_sect; 157 int count_mp, cur_mp; 192 char **man_path_list; 193 int count_mp; 194 int cur_mp; 158 195 int opt, not_found; 159 196 char *token[2]; … … 163 200 argv += optind; 164 201 165 sec_list = xstrdup(" 1:2:3:4:5:6:7:8:9");166 /* Last valid man_path_list[] is [0x10] */ 202 sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9"); 203 167 204 count_mp = 0; 168 man_path_list = xzalloc(0x11 * sizeof(man_path_list[0])); 169 man_path_list[0] = getenv("MANPATH"); 170 if (!man_path_list[0]) /* default, may be overridden by /etc/man.conf */ 205 man_path_list = add_MANPATH(NULL, &count_mp, 206 getenv("MANDATORY_MANPATH"+10) /* "MANPATH" */ 207 ); 208 if (!man_path_list) { 209 /* default, may be overridden by /etc/man.conf */ 210 man_path_list = xzalloc(2 * sizeof(man_path_list[0])); 171 211 man_path_list[0] = (char*)"/usr/man"; 172 else 173 count_mp++; 174 pager = getenv("MANPAGER"); 175 if (!pager) { 176 pager = getenv("PAGER"); 177 if (!pager) 178 pager = "more"; 212 /* count_mp stays 0. 213 * Thus, man.conf will overwrite man_path_list[0] 214 * if a path is defined there. 215 */ 179 216 } 180 217 … … 191 228 if (!token[1]) 192 229 continue; 230 if (strcmp("DEFINE", token[0]) == 0) { 231 if (is_prefixed_with("pager", token[1])) { 232 pager = xstrdup(skip_whitespace(token[1]) + 5); 233 } 234 } else 193 235 if (strcmp("MANDATORY_MANPATH"+10, token[0]) == 0 /* "MANPATH"? */ 194 236 || strcmp("MANDATORY_MANPATH", token[0]) == 0 195 237 ) { 196 char *path = token[1]; 197 while (*path) { 198 char *next_path; 199 char **path_element; 200 201 next_path = strchr(path, ':'); 202 if (next_path) { 203 *next_path = '\0'; 204 if (next_path++ == path) /* "::"? */ 205 goto next; 206 } 207 /* Do we already have path? */ 208 path_element = man_path_list; 209 while (*path_element) { 210 if (strcmp(*path_element, path) == 0) 211 goto skip; 212 path_element++; 213 } 214 man_path_list = xrealloc_vector(man_path_list, 4, count_mp); 215 man_path_list[count_mp] = xstrdup(path); 216 count_mp++; 217 /* man_path_list is NULL terminated */ 218 /*man_path_list[count_mp] = NULL; - xrealloc_vector did it */ 219 skip: 220 if (!next_path) 221 break; 222 next: 223 path = next_path; 224 } 238 man_path_list = add_MANPATH(man_path_list, &count_mp, token[1]); 225 239 } 226 240 if (strcmp("MANSECT", token[0]) == 0) { … … 230 244 } 231 245 config_close(parser); 246 247 { 248 /* environment overrides setting from man.config */ 249 char *env_pager = getenv("MANPAGER"); 250 if (!env_pager) 251 env_pager = getenv("PAGER"); 252 if (env_pager) 253 pager = env_pager; 254 } 232 255 233 256 not_found = 0; -
branches/3.3/mindi-busybox/miscutils/microcom.c
r3232 r3621 20 20 21 21 #include "libbb.h" 22 #include "common_bufsiz.h" 22 23 23 24 // set raw tty mode … … 156 157 } 157 158 if (pfd[0].revents) { 159 ssize_t len; 158 160 #define iobuf bb_common_bufsiz1 159 s size_t len;161 setup_common_bufsiz(); 160 162 // read from device -> write to stdout 161 len = safe_read(sfd, iobuf, sizeof(iobuf));163 len = safe_read(sfd, iobuf, COMMON_BUFSIZE); 162 164 if (len > 0) 163 165 full_write(STDOUT_FILENO, iobuf, len); -
branches/3.3/mindi-busybox/miscutils/nandwrite.c
r3232 r3621 24 24 25 25 //applet:IF_NANDWRITE(APPLET(nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP)) 26 //applet:IF_NAND WRITE(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump))26 //applet:IF_NANDDUMP(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump)) 27 27 28 28 //kbuild:lib-$(CONFIG_NANDWRITE) += nandwrite.o … … 30 30 31 31 //usage:#define nandwrite_trivial_usage 32 //usage: "[- p] [-s ADDR] MTD_DEVICE [FILE]"32 //usage: "[-np] [-s ADDR] MTD_DEVICE [FILE]" 33 33 //usage:#define nandwrite_full_usage "\n\n" 34 //usage: "Write to the specified MTD device\n" 34 //usage: "Write to MTD_DEVICE\n" 35 //usage: "\n -n Write without ecc" 35 36 //usage: "\n -p Pad to page size" 36 37 //usage: "\n -s ADDR Start address" 37 38 38 39 //usage:#define nanddump_trivial_usage 39 //usage: "[- o] [-b] [-s ADDR] [-f FILE] MTD_DEVICE"40 //usage: "[-no]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" 40 41 //usage:#define nanddump_full_usage "\n\n" 41 //usage: "Dump the specified MTD device\n" 42 //usage: "Dump MTD_DEVICE\n" 43 //usage: "\n -n Read without ecc" 42 44 //usage: "\n -o Dump oob data" 43 //usage: "\n -b Omit bad block from the dump"44 45 //usage: "\n -s ADDR Start address" 45 46 //usage: "\n -l LEN Length" 46 47 //usage: "\n -f FILE Dump to file ('-' for stdout)" 48 //usage: IF_LONG_OPTS( 49 //usage: "\n --bb=METHOD:" 50 //usage: "\n skipbad: skip bad blocks" 51 //usage: "\n padbad: substitute bad blocks by 0xff (default)" 52 //usage: ) 47 53 48 54 #include "libbb.h" … … 54 60 #define OPT_p (1 << 0) /* nandwrite only */ 55 61 #define OPT_o (1 << 0) /* nanddump only */ 56 #define OPT_ s(1 << 1)57 #define OPT_ b(1 << 2)62 #define OPT_n (1 << 1) 63 #define OPT_s (1 << 2) 58 64 #define OPT_f (1 << 3) 59 65 #define OPT_l (1 << 4) 66 #define OPT_bb (1 << 5) /* must be the last one in the list */ 67 68 #define BB_PADBAD (1 << 0) 69 #define BB_SKIPBAD (1 << 1) 60 70 61 71 /* helper for writing out 0xff for bad blocks pad */ … … 65 75 unsigned count; 66 76 67 /* round len to the next page */68 len = ( len | ~(meminfo->writesize - 1)) + 1;77 /* round len to the next page only if len is not already on a page */ 78 len = ((len - 1) | (meminfo->writesize - 1)) + 1; 69 79 70 80 memset(buf, 0xff, sizeof(buf)); … … 103 113 unsigned char *oobbuf; 104 114 unsigned opts; 115 unsigned bb_method = BB_SKIPBAD; 105 116 int fd; 106 117 ssize_t cnt; … … 110 121 struct mtd_oob_buf oob; 111 122 unsigned char *filebuf; 112 const char *opt_s = "0", *opt_f = "-", *opt_l ;123 const char *opt_s = "0", *opt_f = "-", *opt_l, *opt_bb; 113 124 114 125 if (IS_NANDDUMP) { 115 126 opt_complementary = "=1"; 116 opts = getopt32(argv, "os:bf:l:", &opt_s, &opt_f, &opt_l); 127 #if ENABLE_LONG_OPTS 128 applet_long_options = 129 "bb\0" Required_argument "\xff"; /* no short equivalent */ 130 #endif 131 opts = getopt32(argv, "ons:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb); 117 132 } else { /* nandwrite */ 118 133 opt_complementary = "-1:?2"; 119 opts = getopt32(argv, "p s:", &opt_s);134 opts = getopt32(argv, "pns:", &opt_s); 120 135 } 121 136 argv += optind; … … 133 148 xioctl(fd, MEMGETINFO, &meminfo); 134 149 150 if (opts & OPT_n) 151 xioctl(fd, MTDFILEMODE, (void *)MTD_FILE_MODE_RAW); 152 135 153 mtdoffset = xstrtou(opt_s, 0); 136 154 if (IS_NANDDUMP && (opts & OPT_l)) { … … 138 156 if (length < meminfo.size - mtdoffset) 139 157 end_addr = mtdoffset + length; 158 } 159 if (IS_NANDDUMP && (opts & OPT_bb)) { 160 if (strcmp("skipbad", opt_bb) == 0) 161 bb_method = BB_SKIPBAD; 162 else if (strcmp("padbad", opt_bb) == 0) 163 bb_method = BB_PADBAD; 164 else 165 bb_show_usage(); 140 166 } 141 167 … … 163 189 if (tmp != blockstart) { 164 190 /* bad block(s), advance mtdoffset */ 165 if (IS_NANDDUMP && !(opts & OPT_b)) { 166 int bad_len = MIN(tmp, end_addr) - mtdoffset; 167 dump_bad(&meminfo, bad_len, opts & OPT_o); 191 if (IS_NANDDUMP) { 192 if (bb_method == BB_PADBAD) { 193 int bad_len = MIN(tmp, end_addr) - mtdoffset; 194 dump_bad(&meminfo, bad_len, opts & OPT_o); 195 } 196 /* with option skipbad, increase the total length */ 197 if (bb_method == BB_SKIPBAD) { 198 end_addr += (tmp - blockstart); 199 } 168 200 } 169 201 mtdoffset = tmp; … … 183 215 if (IS_NANDWRITE) 184 216 printf("Writing at 0x%08x\n", mtdoffset); 185 else if (mtdoffset > blockstart && !(opts & OPT_b)) { 186 int bad_len = MIN(mtdoffset, limit) - blockstart; 187 dump_bad(&meminfo, bad_len, opts & OPT_o); 217 else if (mtdoffset > blockstart) { 218 if (bb_method == BB_PADBAD) { 219 /* dump FF padded bad block */ 220 int bad_len = MIN(mtdoffset, limit) - blockstart; 221 dump_bad(&meminfo, bad_len, opts & OPT_o); 222 } else if (bb_method == BB_SKIPBAD) { 223 /* for skipbad, increase the length */ 224 if ((end_addr + mtdoffset - blockstart) > end_addr) 225 end_addr += (mtdoffset - blockstart); 226 else 227 end_addr = ~0; 228 limit = MIN(meminfo.size, end_addr); 229 } 188 230 } 189 231 if (mtdoffset >= limit) -
branches/3.3/mindi-busybox/miscutils/rfkill.c
r3232 r3621 7 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 10 //config:config RFKILL 11 //config: bool "rfkill" 12 //config: default n # doesn't build on Ubuntu 9.04 13 //config: select PLATFORM_LINUX 14 //config: help 15 //config: Enable/disable wireless devices. 16 //config: 17 //config: rfkill list : list all wireless devices 18 //config: rfkill list bluetooth : list all bluetooth devices 19 //config: rfkill list 1 : list device corresponding to the given index 20 //config: rfkill block|unblock wlan : block/unblock all wlan(wifi) devices 21 //config: 22 23 //applet:IF_RFKILL(APPLET(rfkill, BB_DIR_USR_SBIN, BB_SUID_DROP)) 24 25 //kbuild:lib-$(CONFIG_RFKILL) += rfkill.o 9 26 10 27 //usage:#define rfkill_trivial_usage -
branches/3.3/mindi-busybox/miscutils/runlevel.c
r3232 r3621 30 30 int runlevel_main(int argc UNUSED_PARAM, char **argv) 31 31 { 32 struct utmp *ut;32 struct utmpx *ut; 33 33 char prev; 34 34 35 if (argv[1]) utmp name(argv[1]);35 if (argv[1]) utmpxname(argv[1]); 36 36 37 setut ent();38 while ((ut = getut ent()) != NULL) {37 setutxent(); 38 while ((ut = getutxent()) != NULL) { 39 39 if (ut->ut_type == RUN_LVL) { 40 40 prev = ut->ut_pid / 256; … … 42 42 printf("%c %c\n", prev, ut->ut_pid % 256); 43 43 if (ENABLE_FEATURE_CLEAN_UP) 44 endut ent();44 endutxent(); 45 45 return 0; 46 46 } … … 50 50 51 51 if (ENABLE_FEATURE_CLEAN_UP) 52 endut ent();52 endutxent(); 53 53 return 1; 54 54 } -
branches/3.3/mindi-busybox/miscutils/setsid.c
r3232 r3621 16 16 17 17 //usage:#define setsid_trivial_usage 18 //usage: " PROG ARGS"18 //usage: "[-c] PROG ARGS" 19 19 //usage:#define setsid_full_usage "\n\n" 20 20 //usage: "Run PROG in a new session. PROG will have no controlling terminal\n" 21 //usage: "and will not be affected by keyboard signals ( Ctrl-C etc).\n"22 //usage: "See setsid(2) for details."21 //usage: "and will not be affected by keyboard signals (^C etc).\n" 22 //usage: "\n -c Set controlling terminal to stdin" 23 23 24 24 #include "libbb.h" … … 27 27 int setsid_main(int argc UNUSED_PARAM, char **argv) 28 28 { 29 if (!argv[1]) 30 bb_show_usage(); 29 unsigned opt; 30 31 opt_complementary = "-1"; /* at least one arg */ 32 opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ 33 argv += optind; 31 34 32 35 /* setsid() is allowed only when we are not a process group leader. 33 36 * Otherwise our PID serves as PGID of some existing process group 34 * and cannot be used as PGID of a new process group. */ 37 * and cannot be used as PGID of a new process group. 38 * 39 * Example: setsid() below fails when run alone in interactive shell: 40 * $ setsid PROG 41 * because shell's child (setsid) is put in a new process group. 42 * But doesn't fail if shell is not interactive 43 * (and therefore doesn't create process groups for pipes), 44 * or if setsid is not the first process in the process group: 45 * $ true | setsid PROG 46 * or if setsid is executed in backquotes (`setsid PROG`)... 47 */ 35 48 if (setsid() < 0) { 36 49 pid_t pid = fork_or_rexec(argv); … … 44 57 * does not do such trick. 45 58 */ 46 exit(EXIT_SUCCESS);59 return EXIT_SUCCESS; 47 60 } 48 61 … … 52 65 } 53 66 54 argv++; 67 if (opt) { 68 /* -c: set (with stealing) controlling tty */ 69 ioctl(0, TIOCSCTTY, 1); 70 } 71 55 72 BB_EXECVP_or_die(argv); 56 73 } -
branches/3.3/mindi-busybox/miscutils/taskset.c
r3232 r3621 6 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 7 */ 8 9 //config:config TASKSET 10 //config: bool "taskset" 11 //config: default n # doesn't build on some non-x86 targets (m68k) 12 //config: help 13 //config: Retrieve or set a processes's CPU affinity. 14 //config: This requires sched_{g,s}etaffinity support in your libc. 15 //config: 16 //config:config FEATURE_TASKSET_FANCY 17 //config: bool "Fancy output" 18 //config: default y 19 //config: depends on TASKSET 20 //config: help 21 //config: Add code for fancy output. This merely silences a compiler-warning 22 //config: and adds about 135 Bytes. May be needed for machines with alot 23 //config: of CPUs. 24 25 //applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) 26 //kbuild:lib-$(CONFIG_TASKSET) += taskset.o 8 27 9 28 //usage:#define taskset_trivial_usage … … 23 42 //usage: "$ taskset -p 1\n" 24 43 //usage: "pid 1's current affinity mask: 3\n" 44 /* 45 Not yet implemented: 46 * -a/--all-tasks (affect all threads) 47 * -c/--cpu-list (specify CPUs via "1,3,5-7") 48 */ 25 49 26 50 #include <sched.h> … … 52 76 static unsigned long long from_cpuset(cpu_set_t *mask) 53 77 { 54 struct BUG_CPU_SETSIZE_is_too_small { 55 char BUG_CPU_SETSIZE_is_too_small[ 56 CPU_SETSIZE < sizeof(int) ? -1 : 1]; 57 }; 58 char *p = (void*)mask; 59 60 /* Take the least significant bits. Careful! 61 * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases 78 BUILD_BUG_ON(CPU_SETSIZE < 8*sizeof(int)); 79 80 /* Take the least significant bits. Assume cpu_set_t is 81 * implemented as an array of unsigned long or unsigned 82 * int. 62 83 */ 63 #if BB_BIG_ENDIAN 64 /* For big endian, it means LAST bits */65 if (CPU_SETSIZE < sizeof(long))66 p += CPU_SETSIZE - sizeof(int);67 else if (CPU_SETSIZE < sizeof(long long)) 68 p += CPU_SETSIZE - sizeof(long);69 else70 p += CPU_SETSIZE - sizeof(long long);71 #endif 72 if (CPU_SETSIZE < sizeof(long))73 return *(unsigned*)p;74 if (CPU_SETSIZE < sizeof(long long))75 return *(unsigned long*)p; 76 return *(unsigned long long*) p;84 if (CPU_SETSIZE < 8*sizeof(long)) 85 return *(unsigned*)mask; 86 if (CPU_SETSIZE < 8*sizeof(long long)) 87 return *(unsigned long*)mask; 88 # if BB_BIG_ENDIAN 89 if (sizeof(long long) > sizeof(long)) { 90 /* We can put two long in the long long, but they have to 91 * be swapped: the least significant word comes first in the 92 * array */ 93 unsigned long *p = (void*)mask; 94 return p[0] + ((unsigned long long)p[1] << (8*sizeof(long))); 95 } 96 # endif 97 return *(unsigned long long*)mask; 77 98 } 78 99 #endif … … 129 150 } 130 151 131 { /* Affinity was specified, translate it into cpu_set_t */ 152 /* Affinity was specified, translate it into cpu_set_t */ 153 CPU_ZERO(&mask); 154 if (!ENABLE_FEATURE_TASKSET_FANCY) { 132 155 unsigned i; 156 unsigned long long m; 157 133 158 /* Do not allow zero mask: */ 134 unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); 135 enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 }; 136 137 CPU_ZERO(&mask); 138 for (i = 0; i < CNT_BIT; i++) { 139 unsigned long long bit = (1ULL << i); 140 if (bit & m) 159 m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); 160 i = 0; 161 do { 162 if (m & 1) 141 163 CPU_SET(i, &mask); 164 i++; 165 m >>= 1; 166 } while (m != 0); 167 } else { 168 unsigned i; 169 char *last_byte; 170 char *bin; 171 uint8_t bit_in_byte; 172 173 /* Cheap way to get "long enough" buffer */ 174 bin = xstrdup(aff); 175 176 if (aff[0] != '0' || (aff[1]|0x20) != 'x') { 177 /* TODO: decimal/octal masks are still limited to 2^64 */ 178 unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); 179 bin += strlen(bin); 180 last_byte = bin - 1; 181 while (m) { 182 *--bin = m & 0xff; 183 m >>= 8; 184 } 185 } else { 186 /* aff is "0x.....", we accept very long masks in this form */ 187 last_byte = hex2bin(bin, aff + 2, INT_MAX); 188 if (!last_byte) { 189 bad_aff: 190 bb_error_msg_and_die("bad affinity '%s'", aff); 191 } 192 last_byte--; /* now points to the last byte */ 193 } 194 195 i = 0; 196 bit_in_byte = 1; 197 while (last_byte >= bin) { 198 if (bit_in_byte & *last_byte) { 199 if (i >= CPU_SETSIZE) 200 goto bad_aff; 201 CPU_SET(i, &mask); 202 //bb_error_msg("bit %d set", i); 203 } 204 i++; 205 /* bit_in_byte is uint8_t! & 0xff is implied */ 206 bit_in_byte = (bit_in_byte << 1); 207 if (!bit_in_byte) { 208 bit_in_byte = 1; 209 last_byte--; 210 } 142 211 } 143 212 } -
branches/3.3/mindi-busybox/miscutils/wall.c
r3232 r3621 6 6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 7 */ 8 9 //config:config WALL 10 //config: bool "wall" 11 //config: default y 12 //config: depends on FEATURE_UTMP 13 //config: help 14 //config: Write a message to all users that are logged in. 15 16 /* Needs to be run by root or be suid root - needs to write to /dev/TTY: */ 17 //applet:IF_WALL(APPLET(wall, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) 18 19 //kbuild:lib-$(CONFIG_WALL) += wall.o 8 20 9 21 //usage:#define wall_trivial_usage … … 21 33 int wall_main(int argc UNUSED_PARAM, char **argv) 22 34 { 23 struct utmp *ut;35 struct utmpx *ut; 24 36 char *msg; 25 int fd = argv[1] ? xopen(argv[1], O_RDONLY) : STDIN_FILENO;37 int fd; 26 38 39 fd = STDIN_FILENO; 40 if (argv[1]) { 41 /* The applet is setuid. 42 * Access to the file must be under user's uid/gid. 43 */ 44 fd = xopen_as_uid_gid(argv[1], O_RDONLY, getuid(), getgid()); 45 } 27 46 msg = xmalloc_read(fd, NULL); 28 47 if (ENABLE_FEATURE_CLEAN_UP && argv[1]) 29 48 close(fd); 30 setut ent();31 while ((ut = getut ent()) != NULL) {49 setutxent(); 50 while ((ut = getutxent()) != NULL) { 32 51 char *line; 33 52 if (ut->ut_type != USER_PROCESS) … … 38 57 } 39 58 if (ENABLE_FEATURE_CLEAN_UP) { 40 endut ent();59 endutxent(); 41 60 free(msg); 42 61 }
Note:
See TracChangeset
for help on using the changeset viewer.