Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/coreutils
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (16 years ago)
- Location:
- branches/2.2.5/mindi-busybox/coreutils
- Files:
-
- 6 added
- 7 deleted
- 72 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/coreutils/Config.in
r821 r1765 6 6 menu "Coreutils" 7 7 8 config CONFIG_BASENAME8 config BASENAME 9 9 bool "basename" 10 10 default n … … 14 14 to enable the 'basename' utility. 15 15 16 config C ONFIG_CAL16 config CAL 17 17 bool "cal" 18 18 default n … … 20 20 cal is used to display a monthly calender. 21 21 22 config C ONFIG_CAT22 config CAT 23 23 bool "cat" 24 24 default n … … 27 27 output. Enable this option if you wish to enable the 'cat' utility. 28 28 29 config C ONFIG_CATV29 config CATV 30 30 bool "catv" 31 31 default n … … 34 34 implementations' cat -v option). 35 35 36 config C ONFIG_CHGRP36 config CHGRP 37 37 bool "chgrp" 38 38 default n … … 40 40 chgrp is used to change the group ownership of files. 41 41 42 config C ONFIG_CHMOD42 config CHMOD 43 43 bool "chmod" 44 44 default n … … 46 46 chmod is used to change the access permission of files. 47 47 48 config C ONFIG_CHOWN48 config CHOWN 49 49 bool "chown" 50 50 default n … … 53 53 of files. 54 54 55 config C ONFIG_CHROOT55 config CHROOT 56 56 bool "chroot" 57 57 default n … … 60 60 The default command is `/bin/sh'. 61 61 62 config C ONFIG_CKSUM62 config CKSUM 63 63 bool "cksum" 64 64 default n … … 66 66 cksum is used to calculate the CRC32 checksum of a file. 67 67 68 config CONFIG_CMP 69 bool "cmp" 70 default n 71 help 72 cmp is used to compare two files and returns the result 73 to standard output. 74 75 config CONFIG_COMM 68 config COMM 76 69 bool "comm" 77 70 default n … … 80 73 a three-column output. 81 74 82 config C ONFIG_CP75 config CP 83 76 bool "cp" 84 77 default n … … 86 79 cp is used to copy files and directories. 87 80 88 config C ONFIG_CUT81 config CUT 89 82 bool "cut" 90 83 default n … … 93 86 each file to stdout. 94 87 95 config CONFIG_DATE88 config DATE 96 89 bool "date" 97 90 default n … … 100 93 current time in the given format. 101 94 102 config CONFIG_FEATURE_DATE_ISOFMT95 config FEATURE_DATE_ISOFMT 103 96 bool "Enable ISO date format output (-I)" 104 97 default y 105 depends on CONFIG_DATE98 depends on DATE 106 99 help 107 100 Enable option (-I) to output an ISO-8601 compliant 108 101 date/time string. 109 102 110 config CONFIG_DD103 config DD 111 104 bool "dd" 112 105 default n … … 116 109 while optionally performing conversions on it. 117 110 118 config CONFIG_FEATURE_DD_SIGNAL_HANDLING111 config FEATURE_DD_SIGNAL_HANDLING 119 112 bool "Enable DD signal handling for status reporting" 120 113 default y 121 depends on CONFIG_DD122 help 123 sending a SIGUSR1 signal to a running `dd' process makes it 124 print to standard error the number of records read and written 114 depends on DD 115 help 116 sending a SIGUSR1 signal to a running `dd' process makes it 117 print to standard error the number of records read and written 125 118 so far, then to resume copying. 126 119 127 $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid 120 $ dd if=/dev/zero of=/dev/null& pid=$! $ kill -USR1 $pid; sleep 1; kill $pid 128 121 10899206+0 records in 10899206+0 records out 129 122 130 config CONFIG_FEATURE_DD_IBS_OBS123 config FEATURE_DD_IBS_OBS 131 124 bool "Enable ibs, obs and conv options" 132 125 default n 133 depends on CONFIG_DD126 depends on DD 134 127 help 135 128 Enables support for writing a certain number of bytes in and out, 136 129 at a time, and performing conversions on the data stream. 137 130 138 config CONFIG_DF131 config DF 139 132 bool "df" 140 133 default n … … 143 136 on filesystems. 144 137 145 config CONFIG_DIFF 146 bool "diff" 147 default n 148 help 149 diff compares two files or directories and outputs the 150 differences between them in a form that can be given to 151 the patch command. 152 153 config CONFIG_FEATURE_DIFF_BINARY 154 bool "Enable checks for binary files" 155 default y 156 depends on CONFIG_DIFF 157 help 158 This option enables support for checking for binary files 159 before a comparison is carried out. 160 161 config CONFIG_FEATURE_DIFF_DIR 162 bool "Enable directory support" 163 default y 164 depends on CONFIG_DIFF 165 help 166 This option enables support for directory and subdirectory 167 comparison. 168 169 config CONFIG_FEATURE_DIFF_MINIMAL 170 bool "Enable -d option to find smaller sets of changes" 171 default n 172 depends on CONFIG_DIFF 173 help 174 Enabling this option allows the use of -d to make diff 175 try hard to find the smallest possible set of changes. 176 177 config CONFIG_DIRNAME 138 config DIRNAME 178 139 bool "dirname" 179 140 default n … … 182 143 a file name. 183 144 184 config CONFIG_DOS2UNIX145 config DOS2UNIX 185 146 bool "dos2unix/unix2dos" 186 147 default n … … 189 150 UNIX format, and vice versa. 190 151 191 config CONFIG_UNIX2DOS152 config UNIX2DOS 192 153 bool 193 154 default y 194 depends on CONFIG_DOS2UNIX155 depends on DOS2UNIX 195 156 help 196 157 unix2dos is used to convert a text file from UNIX format to 197 158 DOS format, and vice versa. 198 159 199 config CONFIG_DU160 config DU 200 161 bool "du (default blocksize of 512 bytes)" 201 162 default n … … 204 165 for specified files. 205 166 206 config CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K167 config FEATURE_DU_DEFAULT_BLOCKSIZE_1K 207 168 bool "Use a default blocksize of 1024 bytes (1K)" 208 169 default y 209 depends on CONFIG_DU170 depends on DU 210 171 help 211 172 Use a blocksize of (1K) instead of the default 512b. 212 173 213 config CONFIG_ECHO174 config ECHO 214 175 bool "echo (basic SuSv3 version taking no options)" 215 176 default n … … 218 179 219 180 # this entry also appears in shell/Config.in, next to the echo builtin 220 config CONFIG_FEATURE_FANCY_ECHO181 config FEATURE_FANCY_ECHO 221 182 bool "Enable echo options (-n and -e)" 222 183 default y 223 depends on CONFIG_ECHO184 depends on ECHO 224 185 help 225 186 This adds options (-n and -e) to echo. 226 187 227 config CONFIG_ENV188 config ENV 228 189 bool "env" 229 190 default n … … 233 194 environment. 234 195 235 config CONFIG_FEATURE_ENV_LONG_OPTIONS196 config FEATURE_ENV_LONG_OPTIONS 236 197 bool "Enable long options" 237 198 default n 238 depends on CONFIG_ENV && CONFIG_GETOPT_LONG199 depends on ENV && GETOPT_LONG 239 200 help 240 201 Support long options for the env applet. 241 202 242 config CONFIG_EXPR 203 config EXPAND 204 bool "expand" 205 default n 206 help 207 By default, convert all tabs to spaces. 208 209 config FEATURE_EXPAND_LONG_OPTIONS 210 bool "Enable long options" 211 default n 212 depends on EXPAND && GETOPT_LONG 213 help 214 Support long options for the expand applet. 215 216 config EXPR 243 217 bool "expr" 244 218 default n … … 247 221 to standard output. 248 222 249 config CONFIG_EXPR_MATH_SUPPORT_64223 config EXPR_MATH_SUPPORT_64 250 224 bool "Extend Posix numbers support to 64 bit" 251 225 default n 252 depends on CONFIG_EXPR226 depends on EXPR 253 227 help 254 228 Enable 64-bit math support in the expr applet. This will make … … 256 230 large numbers. 257 231 258 config CONFIG_FALSE232 config FALSE 259 233 bool "false" 260 234 default n … … 262 236 false returns an exit code of FALSE (1). 263 237 264 config CONFIG_FOLD238 config FOLD 265 239 bool "fold" 266 240 default n … … 268 242 Wrap text to fit a specific width. 269 243 270 config CONFIG_HEAD244 config HEAD 271 245 bool "head" 272 246 default n … … 275 249 from files. 276 250 277 config CONFIG_FEATURE_FANCY_HEAD251 config FEATURE_FANCY_HEAD 278 252 bool "Enable head options (-c, -q, and -v)" 279 253 default n 280 depends on CONFIG_HEAD254 depends on HEAD 281 255 help 282 256 This enables the head options (-c, -q, and -v). 283 257 284 config CONFIG_HOSTID258 config HOSTID 285 259 bool "hostid" 286 260 default n … … 289 263 the current host. 290 264 291 config CONFIG_ID265 config ID 292 266 bool "id" 293 267 default n … … 295 269 id displays the current user and group ID names. 296 270 297 config CONFIG_INSTALL271 config INSTALL 298 272 bool "install" 299 273 default n … … 301 275 Copy files and set attributes. 302 276 303 config CONFIG_FEATURE_INSTALL_LONG_OPTIONS277 config FEATURE_INSTALL_LONG_OPTIONS 304 278 bool "Enable long options" 305 279 default n 306 depends on CONFIG_INSTALL && CONFIG_GETOPT_LONG280 depends on INSTALL && GETOPT_LONG 307 281 help 308 282 Support long options for the install applet. 309 283 310 config CONFIG_LENGTH284 config LENGTH 311 285 bool "length" 312 286 default n … … 314 288 length is used to print out the length of a specified string. 315 289 316 config CONFIG_LN290 config LN 317 291 bool "ln" 318 292 default n … … 320 294 ln is used to create hard or soft links between files. 321 295 322 config CONFIG_LOGNAME296 config LOGNAME 323 297 bool "logname" 324 298 default n … … 326 300 logname is used to print the current user's login name. 327 301 328 config CONFIG_LS302 config LS 329 303 bool "ls" 330 304 default n … … 332 306 ls is used to list the contents of directories. 333 307 334 config CONFIG_FEATURE_LS_FILETYPES308 config FEATURE_LS_FILETYPES 335 309 bool "Enable filetyping options (-p and -F)" 336 310 default y 337 depends on CONFIG_LS311 depends on LS 338 312 help 339 313 Enable the ls options (-p and -F). 340 314 341 config CONFIG_FEATURE_LS_FOLLOWLINKS315 config FEATURE_LS_FOLLOWLINKS 342 316 bool "Enable symlinks dereferencing (-L)" 343 317 default y 344 depends on CONFIG_LS318 depends on LS 345 319 help 346 320 Enable the ls option (-L). 347 321 348 config CONFIG_FEATURE_LS_RECURSIVE322 config FEATURE_LS_RECURSIVE 349 323 bool "Enable recursion (-R)" 350 324 default y 351 depends on CONFIG_LS325 depends on LS 352 326 help 353 327 Enable the ls option (-R). 354 328 355 config CONFIG_FEATURE_LS_SORTFILES329 config FEATURE_LS_SORTFILES 356 330 bool "Sort the file names" 357 331 default y 358 depends on CONFIG_LS332 depends on LS 359 333 help 360 334 Allow ls to sort file names alphabetically. 361 335 362 config CONFIG_FEATURE_LS_TIMESTAMPS336 config FEATURE_LS_TIMESTAMPS 363 337 bool "Show file timestamps" 364 338 default y 365 depends on CONFIG_LS339 depends on LS 366 340 help 367 341 Allow ls to display timestamps for files. 368 342 369 config CONFIG_FEATURE_LS_USERNAME343 config FEATURE_LS_USERNAME 370 344 bool "Show username/groupnames" 371 345 default y 372 depends on CONFIG_LS346 depends on LS 373 347 help 374 348 Allow ls to display username/groupname for files. 375 349 376 config CONFIG_FEATURE_LS_COLOR350 config FEATURE_LS_COLOR 377 351 bool "Allow use of color to identify file types" 378 352 default y 379 depends on CONFIG_LS && CONFIG_GETOPT_LONG353 depends on LS && GETOPT_LONG 380 354 help 381 355 This enables the --color option to ls. 382 356 383 config CONFIG_FEATURE_LS_COLOR_IS_DEFAULT357 config FEATURE_LS_COLOR_IS_DEFAULT 384 358 bool "Produce colored ls output by default" 385 359 default n 386 depends on CONFIG_FEATURE_LS_COLOR360 depends on FEATURE_LS_COLOR 387 361 help 388 362 Saying yes here will turn coloring on by default, … … 392 366 many output screens. 393 367 394 config CONFIG_MD5SUM368 config MD5SUM 395 369 bool "md5sum" 396 370 default n … … 398 372 md5sum is used to print or check MD5 checksums. 399 373 400 config CONFIG_MKDIR374 config MKDIR 401 375 bool "mkdir" 402 376 default n … … 404 378 mkdir is used to create directories with the specified names. 405 379 406 config CONFIG_FEATURE_MKDIR_LONG_OPTIONS380 config FEATURE_MKDIR_LONG_OPTIONS 407 381 bool "Enable long options" 408 382 default n 409 depends on CONFIG_MKDIR && CONFIG_GETOPT_LONG383 depends on MKDIR && GETOPT_LONG 410 384 help 411 385 Support long options for the mkdir applet. 412 386 413 config CONFIG_MKFIFO387 config MKFIFO 414 388 bool "mkfifo" 415 389 default n … … 418 392 The `mknod' program can also create FIFOs. 419 393 420 config CONFIG_MKNOD394 config MKNOD 421 395 bool "mknod" 422 396 default n … … 425 399 files with the specified names. 426 400 427 config CONFIG_MV401 config MV 428 402 bool "mv" 429 403 default n … … 431 405 mv is used to move or rename files or directories. 432 406 433 config CONFIG_FEATURE_MV_LONG_OPTIONS407 config FEATURE_MV_LONG_OPTIONS 434 408 bool "Enable long options" 435 409 default n 436 depends on CONFIG_MV && CONFIG_GETOPT_LONG410 depends on MV && GETOPT_LONG 437 411 help 438 412 Support long options for the mv applet. 439 413 440 config CONFIG_NICE414 config NICE 441 415 bool "nice" 442 416 default n … … 444 418 nice runs a program with modified scheduling priority. 445 419 446 config CONFIG_NOHUP420 config NOHUP 447 421 bool "nohup" 448 422 default n … … 450 424 run a command immune to hangups, with output to a non-tty. 451 425 452 config CONFIG_OD426 config OD 453 427 bool "od" 454 428 default n … … 456 430 od is used to dump binary files in octal and other formats. 457 431 458 config CONFIG_PRINTENV432 config PRINTENV 459 433 bool "printenv" 460 434 default n … … 462 436 printenv is used to print all or part of environment. 463 437 464 config CONFIG_PRINTF438 config PRINTF 465 439 bool "printf" 466 440 default n … … 469 443 It's similar to `echo' except it has more options. 470 444 471 config CONFIG_PWD445 config PWD 472 446 bool "pwd" 473 447 default n … … 475 449 pwd is used to print the current directory. 476 450 477 config CONFIG_REALPATH 451 config READLINK 452 bool "readlink" 453 default n 454 help 455 This program reads a symbolic link and returns the name 456 of the file it points to 457 458 config FEATURE_READLINK_FOLLOW 459 bool "Enable canonicalization by following all symlinks (-f)" 460 default n 461 depends on READLINK 462 help 463 Enable the readlink option (-f). 464 465 config REALPATH 478 466 bool "realpath" 479 467 default n … … 482 470 This isn't provided by GNU shellutils, but where else does it belong. 483 471 484 config CONFIG_RM472 config RM 485 473 bool "rm" 486 474 default n … … 488 476 rm is used to remove files or directories. 489 477 490 config CONFIG_RMDIR478 config RMDIR 491 479 bool "rmdir" 492 480 default n … … 494 482 rmdir is used to remove empty directories. 495 483 496 config CONFIG_SEQ484 config SEQ 497 485 bool "seq" 498 486 default n … … 500 488 print a sequence of numbers 501 489 502 config CONFIG_SHA1SUM490 config SHA1SUM 503 491 bool "sha1sum" 504 492 default n … … 506 494 Compute and check SHA1 message digest 507 495 508 config CONFIG_SLEEP496 config SLEEP 509 497 bool "sleep (single integer arg with no suffix)" 510 498 default n … … 512 500 sleep is used to pause for a specified number of seconds, 513 501 514 config CONFIG_FEATURE_FANCY_SLEEP502 config FEATURE_FANCY_SLEEP 515 503 bool "Enable multiple integer args and optional time suffixes" 516 504 default n 517 depends on CONFIG_SLEEP505 depends on SLEEP 518 506 help 519 507 Allow sleep to pause for specified minutes, hours, and days. 520 508 521 config CONFIG_SORT509 config SORT 522 510 bool "sort" 523 511 default n … … 525 513 sort is used to sort lines of text in specified files. 526 514 527 config CONFIG_FEATURE_SORT_BIG515 config FEATURE_SORT_BIG 528 516 bool "full SuSv3 compliant sort (Support -ktcsbdfiozgM)" 529 517 default y 530 depends on CONFIG_SORT518 depends on SORT 531 519 help 532 520 Without this, sort only supports -r, -u, and an integer version … … 537 525 http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html 538 526 539 config CONFIG_STAT 527 config SPLIT 528 bool "split" 529 default n 530 help 531 split a file into pieces. 532 533 config FEATURE_SPLIT_FANCY 534 bool "fancy extensions" 535 default n 536 depends on SPLIT 537 help 538 Add support for features not required by SUSv3. 539 Supports additional suffixes 'b' for 512 bytes, 540 'g' for 1GiB for the -b option. 541 542 config STAT 540 543 bool "stat" 541 544 default n … … 543 546 display file or filesystem status. 544 547 545 config CONFIG_FEATURE_STAT_FORMAT548 config FEATURE_STAT_FORMAT 546 549 bool "Enable custom formats (-c)" 547 550 default n 548 depends on CONFIG_STAT551 depends on STAT 549 552 help 550 553 Without this, stat will not support the '-c format' option where … … 552 555 7k to a nonstatic build on amd64. 553 556 554 config CONFIG_STTY557 config STTY 555 558 bool "stty" 556 559 default n … … 558 561 stty is used to change and print terminal line settings. 559 562 560 config CONFIG_SUM563 config SUM 561 564 bool "sum" 562 565 default n … … 564 567 checksum and count the blocks in a file 565 568 566 config CONFIG_SYNC569 config SYNC 567 570 bool "sync" 568 571 default n … … 570 573 sync is used to flush filesystem buffers. 571 574 572 config CONFIG_TAIL575 config TAIL 573 576 bool "tail" 574 577 default n … … 577 580 from files. 578 581 579 config CONFIG_FEATURE_FANCY_TAIL582 config FEATURE_FANCY_TAIL 580 583 bool "Enable extra tail options (-q, -s, and -v)" 581 584 default y 582 depends on CONFIG_TAIL585 depends on TAIL 583 586 help 584 587 The options (-q, -s, and -v) are provided by GNU tail, but 585 588 are not specific in the SUSv3 standard. 586 589 587 config CONFIG_TEE590 config TEE 588 591 bool "tee" 589 592 default n … … 592 595 to standard output and files. 593 596 594 config CONFIG_FEATURE_TEE_USE_BLOCK_IO597 config FEATURE_TEE_USE_BLOCK_IO 595 598 bool "Enable block i/o (larger/faster) instead of byte i/o." 596 599 default n 597 depends on CONFIG_TEE600 depends on TEE 598 601 help 599 602 Enable this option for a faster tee, at expense of size. 600 603 601 config CONFIG_TEST604 config TEST 602 605 bool "test" 603 606 default n … … 607 610 has test built in, ash can build it in optionally. 608 611 609 config CONFIG_FEATURE_TEST_64612 config FEATURE_TEST_64 610 613 bool "Extend test to 64 bit" 611 614 default n 612 depends on CONFIG_TEST615 depends on TEST 613 616 help 614 617 Enable 64-bit support in test. 615 618 616 config CONFIG_TOUCH619 config TOUCH 617 620 bool "touch" 618 621 default n … … 621 624 modification timestamp of specified files. 622 625 623 config CONFIG_TR626 config TR 624 627 bool "tr" 625 628 default n … … 628 631 input, writing to standard output. 629 632 630 config CONFIG_FEATURE_TR_CLASSES633 config FEATURE_TR_CLASSES 631 634 bool "Enable character classes (such as [:upper:])" 632 635 default n 633 depends on CONFIG_TR636 depends on TR 634 637 help 635 638 Enable character classes, enabling commands such as: 636 639 tr [:upper:] [:lower:] to convert input into lowercase. 637 640 638 config CONFIG_FEATURE_TR_EQUIV641 config FEATURE_TR_EQUIV 639 642 bool "Enable equivalence classes" 640 643 default n 641 depends on CONFIG_TR644 depends on TR 642 645 help 643 646 Enable equivalence classes, which essentially add the enclosed … … 647 650 is possible. 648 651 649 config CONFIG_TRUE652 config TRUE 650 653 bool "true" 651 654 default n … … 653 656 true returns an exit code of TRUE (0). 654 657 655 config CONFIG_TTY658 config TTY 656 659 bool "tty" 657 660 default n … … 660 663 standard output. 661 664 662 config CONFIG_UNAME665 config UNAME 663 666 bool "uname" 664 667 default n … … 666 669 uname is used to print system information. 667 670 668 config CONFIG_UNIQ 671 config UNEXPAND 672 bool "unexpand" 673 default n 674 help 675 By default, convert only leading sequences of blanks to tabs. 676 677 config FEATURE_UNEXPAND_LONG_OPTIONS 678 bool "Enable long options" 679 default n 680 depends on UNEXPAND && GETOPT_LONG 681 help 682 Support long options for the unexpand applet. 683 684 config UNIQ 669 685 bool "uniq" 670 686 default n … … 672 688 uniq is used to remove duplicate lines from a sorted file. 673 689 674 config CONFIG_USLEEP690 config USLEEP 675 691 bool "usleep" 676 692 default n … … 678 694 usleep is used to pause for a specified number of microseconds. 679 695 680 config CONFIG_UUDECODE696 config UUDECODE 681 697 bool "uudecode" 682 698 default n … … 684 700 uudecode is used to decode a uuencoded file. 685 701 686 config CONFIG_UUENCODE702 config UUENCODE 687 703 bool "uuencode" 688 704 default n … … 690 706 uuencode is used to uuencode a file. 691 707 692 config CONFIG_WATCH 693 bool "watch" 694 default n 695 select CONFIG_DATE 696 help 697 watch is used to execute a program periodically, showing 698 output to the screen. 699 700 config CONFIG_WC 708 config WC 701 709 bool "wc" 702 710 default n … … 705 713 in specified files. 706 714 707 config CONFIG_WHO 715 config FEATURE_WC_LARGE 716 bool "Support very large files in wc" 717 default n 718 depends on WC 719 help 720 Use "unsigned long long" in wc for count variables 721 722 config WHO 708 723 bool "who" 709 724 default n 710 select CONFIG_FEATURE_UTMP725 select FEATURE_UTMP 711 726 help 712 727 who is used to show who is logged on. 713 728 714 config CONFIG_WHOAMI729 config WHOAMI 715 730 bool "whoami" 716 731 default n … … 719 734 user id (same as id -un). 720 735 721 config CONFIG_YES736 config YES 722 737 bool "yes" 723 738 default n … … 727 742 728 743 comment "Common options for cp and mv" 729 depends on C ONFIG_CP || CONFIG_MV730 731 config CONFIG_FEATURE_PRESERVE_HARDLINKS744 depends on CP || MV 745 746 config FEATURE_PRESERVE_HARDLINKS 732 747 bool "Preserve hard links" 733 748 default n 734 depends on C ONFIG_CP || CONFIG_MV749 depends on CP || MV 735 750 help 736 751 Allow cp and mv to preserve hard links. 737 752 738 753 comment "Common options for ls, more and telnet" 739 depends on CONFIG_LS || CONFIG_MORE || CONFIG_TELNET740 741 config CONFIG_FEATURE_AUTOWIDTH754 depends on LS || MORE || TELNET 755 756 config FEATURE_AUTOWIDTH 742 757 bool "Calculate terminal & column widths" 743 758 default y 744 depends on CONFIG_LS || CONFIG_MORE || CONFIG_TELNET759 depends on LS || MORE || TELNET 745 760 help 746 761 This option allows utilities such as 'ls', 'more' and 'telnet' 747 to determine the width of the screen, which can allow them to 762 to determine the width of the screen, which can allow them to 748 763 display additional text or avoid wrapping text onto the next line. 749 If you leave this disabled, your utilities will be especially 764 If you leave this disabled, your utilities will be especially 750 765 primitive and will be unable to determine the current screen width. 751 766 752 767 comment "Common options for df, du, ls" 753 depends on CONFIG_DF || CONFIG_DU || CONFIG_LS754 755 config CONFIG_FEATURE_HUMAN_READABLE768 depends on DF || DU || LS 769 770 config FEATURE_HUMAN_READABLE 756 771 bool "Support for human readable output (example 13k, 23M, 235G)" 757 772 default n 758 depends on CONFIG_DF || CONFIG_DU || CONFIG_LS773 depends on DF || DU || LS 759 774 help 760 775 Allow df, du, and ls to have human readable output. 761 776 762 777 comment "Common options for md5sum, sha1sum" 763 depends on CONFIG_MD5SUM || CONFIG_SHA1SUM764 765 config CONFIG_FEATURE_MD5_SHA1_SUM_CHECK778 depends on MD5SUM || SHA1SUM 779 780 config FEATURE_MD5_SHA1_SUM_CHECK 766 781 bool "Enable -c, -s and -w options" 767 782 default n 768 depends on CONFIG_MD5SUM || CONFIG_SHA1SUM783 depends on MD5SUM || SHA1SUM 769 784 help 770 785 Enabling the -c options allows files to be checked -
branches/2.2.5/mindi-busybox/coreutils/basename.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 20 8 * 21 9 */ … … 33 21 */ 34 22 35 #include <stdlib.h> 36 #include <stdio.h> 37 #include <string.h> 38 #include "busybox.h" 23 #include "libbb.h" 39 24 25 /* This is a NOFORK applet. Be very careful! */ 26 27 int basename_main(int argc, char **argv); 40 28 int basename_main(int argc, char **argv) 41 29 { … … 59 47 puts(s); 60 48 61 bb_fflush_stdout_and_exit(EXIT_SUCCESS);49 return fflush(stdout); 62 50 } -
branches/2.2.5/mindi-busybox/coreutils/cal.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Calendar implementation for busybox … … 4 5 * See original copyright at the end of this file 5 6 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 */ 21 9 22 10 /* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */ … … 30 18 */ 31 19 32 #include <sys/types.h> 33 #include <ctype.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <time.h> 38 #include <unistd.h> 39 40 #include "busybox.h" 41 42 #ifdef CONFIG_LOCALE_SUPPORT 43 #include <locale.h> 44 #endif 20 #include "libbb.h" 21 22 /* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ 45 23 46 24 #define THURSDAY 4 /* for reformation */ … … 53 31 #define SPACE -1 /* used in day array */ 54 32 55 static const char days_in_month[]= {33 static const unsigned char days_in_month[] ALIGN1 = { 56 34 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 57 35 }; 58 36 59 static const char sep1752[]= {60 37 static const unsigned char sep1752[] ALIGN1 = { 38 1, 2, 14, 15, 16, 61 39 17, 18, 19, 20, 21, 22, 23, 62 40 24, 25, 26, 27, 28, 29, 30 63 41 }; 64 42 65 static intjulian;43 static unsigned julian; 66 44 67 45 /* leap year -- account for Gregorian reformation in 1752 */ 68 #define leap_year(yr) \ 69 ((yr) <= 1752 ? !((yr) % 4) : \ 70 (!((yr) % 4) && ((yr) % 100)) || !((yr) % 400)) 71 72 static int is_leap_year(int year) 73 { 74 return leap_year(year); 75 } 76 #undef leap_year 77 #define leap_year(yr) is_leap_year(yr) 46 static int leap_year(unsigned yr) 47 { 48 if (yr <= 1752) 49 return !(yr % 4); 50 return (!(yr % 4) && (yr % 100)) || !(yr % 400); 51 } 78 52 79 53 /* number of centuries since 1700, not inclusive */ … … 89 63 ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr)) 90 64 91 static void center (char *, int, int);92 static void day_array (int, int, int*);93 static void trim_trailing_spaces_and_print 65 static void center(char *, unsigned, unsigned); 66 static void day_array(unsigned, unsigned, unsigned *); 67 static void trim_trailing_spaces_and_print(char *); 94 68 95 69 static void blank_string(char *buf, size_t buflen); 96 static char *build_row(char *p, int*dp);70 static char *build_row(char *p, unsigned *dp); 97 71 98 72 #define DAY_LEN 3 /* 3 spaces per day */ … … 102 76 #define HEAD_SEP 2 /* spaces between day headings */ 103 77 78 int cal_main(int argc, char **argv); 104 79 int cal_main(int argc, char **argv) 105 80 { … … 107 82 struct tm zero_tm; 108 83 time_t now; 109 intmonth, year, flags, i;84 unsigned month, year, flags, i; 110 85 char *month_names[12]; 111 86 char day_headings[28]; /* 28 for julian, 21 for nonjulian */ 112 87 char buf[40]; 113 88 114 #ifdef CONFIG_LOCALE_SUPPORT 115 setlocale(LC_TIME, ""); 116 #endif 117 118 flags = bb_getopt_ulflags(argc, argv, "jy"); 119 89 flags = getopt32(argv, "jy"); 120 90 julian = flags & 1; 121 91 month = 0; 122 92 argv += optind; 123 124 month = 0; 125 126 if ((argc -= optind) > 2) { 93 argc -= optind; 94 95 if (argc > 2) { 127 96 bb_show_usage(); 128 97 } … … 137 106 } else { 138 107 if (argc == 2) { 139 month = bb_xgetularg10_bnd(*argv++, 1, 12);140 } 141 year = bb_xgetularg10_bnd(*argv, 1, 9999);142 } 143 144 blank_string(day_headings, sizeof(day_headings) - 7 + 108 month = xatou_range(*argv++, 1, 12); 109 } 110 year = xatou_range(*argv, 1, 9999); 111 } 112 113 blank_string(day_headings, sizeof(day_headings) - 7 + 7*julian); 145 114 146 115 i = 0; … … 148 117 zero_tm.tm_mon = i; 149 118 strftime(buf, sizeof(buf), "%B", &zero_tm); 150 month_names[i] = bb_xstrdup(buf);119 month_names[i] = xstrdup(buf); 151 120 152 121 if (i < 7) { … … 158 127 159 128 if (month) { 160 introw, len, days[MAXDAYS];161 int*dp = days;129 unsigned row, len, days[MAXDAYS]; 130 unsigned *dp = days; 162 131 char lineout[30]; 163 132 164 133 day_array(month, year, dp); 165 134 len = sprintf(lineout, "%s %d", month_names[month - 1], year); 166 bb_printf("%*s%s\n%s\n",135 printf("%*s%s\n%s\n", 167 136 ((7*julian + WEEK_LEN) - len) / 2, "", 168 137 lineout, day_headings); … … 173 142 } 174 143 } else { 175 introw, which_cal, week_len, days[12][MAXDAYS];176 int*dp;144 unsigned row, which_cal, week_len, days[12][MAXDAYS]; 145 unsigned *dp; 177 146 char lineout[80]; 178 147 … … 195 164 } 196 165 center(month_names[month + 2 - julian], week_len, 0); 197 bb_printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings);166 printf("\n%s%*s%s", day_headings, HEAD_SEP, "", day_headings); 198 167 if (!julian) { 199 bb_printf("%*s%s", HEAD_SEP, "", day_headings);168 printf("%*s%s", HEAD_SEP, "", day_headings); 200 169 } 201 170 putchar('\n'); … … 211 180 } 212 181 213 bb_fflush_stdout_and_exit(0);182 fflush_stdout_and_exit(0); 214 183 } 215 184 … … 221 190 * builds that array for any month from Jan. 1 through Dec. 9999. 222 191 */ 223 static void day_array(int month, int year, int *days) 224 { 225 long temp; 226 int i; 227 int j_offset; 228 int day, dw, dm; 192 static void day_array(unsigned month, unsigned year, unsigned *days) 193 { 194 unsigned long temp; 195 unsigned i; 196 unsigned day, dw, dm; 229 197 230 198 memset(days, SPACE, MAXDAYS * sizeof(int)); 231 199 232 200 if ((month == 9) && (year == 1752)) { 201 /* Assumes the Gregorian reformation eliminates 202 * 3 Sep. 1752 through 13 Sep. 1752. 203 */ 204 unsigned j_offset = julian * 244; 233 205 size_t oday = 0; 234 235 j_offset = julian * 244; 206 236 207 do { 237 208 days[oday+2] = sep1752[oday] + j_offset; … … 242 213 243 214 /* day_in_year 244 * 215 * return the 1 based day number within the year 245 216 */ 246 217 day = 1; … … 255 226 256 227 /* day_in_week 257 * 258 * 259 * 260 * 228 * return the 0 based day number for any date from 1 Jan. 1 to 229 * 31 Dec. 9999. Assumes the Gregorian reformation eliminates 230 * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all 231 * missing days. 261 232 */ 262 dw = THURSDAY; 263 temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) 264 + day; 233 temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) + day; 265 234 if (temp < FIRST_MISSING_DAY) { 266 235 dw = ((temp - 1 + SATURDAY) % 7); 267 } else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)){236 } else { 268 237 dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); 269 238 } … … 278 247 } 279 248 280 while (dm){249 do { 281 250 days[dw++] = day++; 282 --dm; 283 } 251 } while (--dm); 284 252 } 285 253 … … 291 259 ++p; 292 260 } 293 while (p >s) {261 while (p != s) { 294 262 --p; 295 263 if (!(isspace)(*p)) { /* We want the function... not the inline. */ … … 302 270 } 303 271 304 static void center(char *str, int len, intseparate)305 { 306 intn = strlen(str);272 static void center(char *str, unsigned len, unsigned separate) 273 { 274 unsigned n = strlen(str); 307 275 len -= n; 308 bb_printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, "");276 printf("%*s%*s", (len/2) + n, str, (len/2) + (len % 2) + separate, ""); 309 277 } 310 278 … … 315 283 } 316 284 317 static char *build_row(char *p, int*dp)318 { 319 intcol, val, day;285 static char *build_row(char *p, unsigned *dp) 286 { 287 unsigned col, val, day; 320 288 321 289 memset(p, ' ', (julian + DAY_LEN) * 7); … … 323 291 col = 0; 324 292 do { 325 if ((day = *dp++) != SPACE) { 293 day = *dp++; 294 if (day != SPACE) { 326 295 if (julian) { 327 296 ++p; … … 332 301 } 333 302 } 334 if ((val = day / 10) > 0) { 303 val = day / 10; 304 if (val > 0) { 335 305 *p = val + '0'; 336 306 } … … 376 346 * SUCH DAMAGE. 377 347 */ 378 379 -
branches/2.2.5/mindi-busybox/coreutils/cat.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * Licensed under GPLv2 or later, see file License in this tarball for details.7 * Licensed under GPLv2, see file License in this tarball for details. 8 8 */ 9 9 … … 11 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ 12 12 13 #include "busybox.h" 14 #include <unistd.h> 13 #include "libbb.h" 15 14 16 int cat_main(int argc, char **argv) 15 /* This is a NOFORK applet. Be very careful! */ 16 17 18 int bb_cat(char **argv) 17 19 { 18 FILE *f; 20 static const char *const argv_dash[] = { "-", NULL }; 21 22 int fd; 19 23 int retval = EXIT_SUCCESS; 20 24 21 bb_getopt_ulflags(argc, argv, "u"); 22 23 argv += optind; 24 if (!*argv) { 25 *--argv = "-"; 26 } 25 if (!*argv) 26 argv = (char**) &argv_dash; 27 27 28 28 do { 29 if ((f = bb_wfopen_input(*argv)) != NULL) { 30 int r = bb_copyfd_eof(fileno(f), STDOUT_FILENO); 31 bb_fclose_nonstdin(f); 32 if (r >= 0) { 29 fd = STDIN_FILENO; 30 if (!LONE_DASH(*argv)) 31 fd = open_or_warn(*argv, O_RDONLY); 32 if (fd >= 0) { 33 /* This is not an xfunc - never exits */ 34 off_t r = bb_copyfd_eof(fd, STDOUT_FILENO); 35 if (fd != STDIN_FILENO) 36 close(fd); 37 if (r >= 0) 33 38 continue; 34 }35 39 } 36 40 retval = EXIT_FAILURE; … … 39 43 return retval; 40 44 } 45 46 int cat_main(int argc, char **argv); 47 int cat_main(int argc, char **argv) 48 { 49 getopt32(argv, "u"); 50 argv += optind; 51 return bb_cat(argv); 52 } -
branches/2.2.5/mindi-busybox/coreutils/catv.c
r821 r1765 11 11 * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz */ 12 12 13 #include "busybox.h" 14 #include <unistd.h> 15 #include <fcntl.h> 13 #include "libbb.h" 16 14 15 int catv_main(int argc, char **argv); 17 16 int catv_main(int argc, char **argv) 18 17 { 19 int retval = EXIT_SUCCESS, fd, flags; 18 int retval = EXIT_SUCCESS; 19 int fd; 20 unsigned flags; 20 21 21 flags = bb_getopt_ulflags(argc, argv, "etv"); 22 flags ^= 4; 22 flags = getopt32(argv, "etv"); 23 #define CATV_OPT_e (1<<0) 24 #define CATV_OPT_t (1<<1) 25 #define CATV_OPT_v (1<<2) 26 flags ^= CATV_OPT_v; 27 argv += optind; 23 28 24 // Loop through files. 25 26 argv += optind; 29 /* Read from stdin if there's nothing else to do. */ 30 fd = 0; 31 if (!argv[0]) { 32 argv--; 33 goto jump_in; 34 } 27 35 do { 28 // Read from stdin if there's nothing else to do. 29 30 fd = 0; 31 if (*argv && 0>(fd = bb_xopen(*argv, O_RDONLY))) retval = EXIT_FAILURE; 32 else for(;;) { 36 fd = open_or_warn(*argv, O_RDONLY); 37 if (fd < 0) { 38 retval = EXIT_FAILURE; 39 continue; 40 } 41 jump_in: 42 for (;;) { 33 43 int i, res; 34 44 35 res = read(fd, bb_common_bufsiz1, sizeof(bb_common_bufsiz1)); 36 if (res < 0) retval = EXIT_FAILURE; 37 if (res <1) break; 38 for (i=0; i<res; i++) { 39 char c=bb_common_bufsiz1[i]; 45 #define read_buf bb_common_bufsiz1 46 res = read(fd, read_buf, COMMON_BUFSIZE); 47 if (res < 0) 48 retval = EXIT_FAILURE; 49 if (res < 1) 50 break; 51 for (i = 0; i < res; i++) { 52 unsigned char c = read_buf[i]; 40 53 41 if (c > 126 && (flags & 4)) {54 if (c > 126 && (flags & CATV_OPT_v)) { 42 55 if (c == 127) { 43 56 printf("^?"); 44 57 continue; 45 } else {46 printf("M-");47 c -= 128;48 58 } 59 printf("M-"); 60 c -= 128; 49 61 } 50 62 if (c < 32) { 51 63 if (c == 10) { 52 if (flags & 1) putchar('$'); 53 } else if (flags & (c==9 ? 2 : 4)) { 64 if (flags & CATV_OPT_e) 65 putchar('$'); 66 } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { 54 67 printf("^%c", c+'@'); 55 68 continue; … … 59 72 } 60 73 } 61 if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd); 74 if (ENABLE_FEATURE_CLEAN_UP && fd) 75 close(fd); 62 76 } while (*++argv); 63 77 64 return retval;78 fflush_stdout_and_exit(retval); 65 79 } -
branches/2.2.5/mindi-busybox/coreutils/chgrp.c
r821 r1765 8 8 */ 9 9 10 /* BB_AUDIT SUSv3 defects - unsupported options -h, -H, -L, and -P. */ 11 /* BB_AUDIT GNU defects - unsupported options -h, -c, -f, -v, and long options. */ 12 /* BB_AUDIT Note: gnu chgrp does not support -H, -L, or -P. */ 10 /* BB_AUDIT SUSv3 defects - none? */ 11 /* BB_AUDIT GNU defects - unsupported long options. */ 13 12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/chgrp.html */ 14 13 15 #include <stdlib.h> 16 #include <unistd.h> 17 #include "busybox.h" 14 #include "libbb.h" 18 15 19 /* Don't use lchown glibc older then 2.1.x */ 20 #if (__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1) 21 #define lchown chown 22 #endif 16 /* This is a NOEXEC applet. Be very careful! */ 23 17 24 static int fileAction(const char *fileName, struct stat *statbuf, void* junk)25 {26 if (lchown(fileName, statbuf->st_uid, *((long *) junk)) == 0) {27 return (TRUE);28 }29 bb_perror_msg("%s", fileName); /* Avoid multibyte problems. */30 return (FALSE);31 }32 18 19 int chgrp_main(int argc, char **argv); 33 20 int chgrp_main(int argc, char **argv) 34 21 { 35 long gid; 36 int recursiveFlag; 37 int retval = EXIT_SUCCESS; 38 39 recursiveFlag = bb_getopt_ulflags(argc, argv, "R"); 40 41 if (argc - optind < 2) { 42 bb_show_usage(); 22 /* "chgrp [opts] abc file(s)" == "chown [opts] :abc file(s)" */ 23 char **p = argv; 24 while (*++p) { 25 if (p[0][0] != '-') { 26 p[0] = xasprintf(":%s", p[0]); 27 break; 28 } 43 29 } 44 45 argv += optind; 46 47 /* Find the selected group */ 48 gid = get_ug_id(*argv, bb_xgetgrnam); 49 ++argv; 50 51 /* Ok, ready to do the deed now */ 52 do { 53 if (! recursive_action (*argv, recursiveFlag, FALSE, FALSE, 54 fileAction, fileAction, &gid)) { 55 retval = EXIT_FAILURE; 56 } 57 } while (*++argv); 58 59 return retval; 30 return chown_main(argc, argv); 60 31 } -
branches/2.2.5/mindi-busybox/coreutils/chmod.c
r821 r1765 12 12 13 13 /* BB_AUDIT SUSv3 compliant */ 14 /* BB_AUDIT GNU defects - unsupported options -c, -f, -v, andlong options. */14 /* BB_AUDIT GNU defects - unsupported long options. */ 15 15 /* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */ 16 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <unistd.h> 21 #include <sys/stat.h> 22 #include "busybox.h" 17 #include "libbb.h" 23 18 24 static int fileAction(const char *fileName, struct stat *statbuf, void* junk) 19 /* This is a NOEXEC applet. Be very careful! */ 20 21 22 #define OPT_RECURSE (option_mask32 & 1) 23 #define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 2) SKIP_DESKTOP(0)) 24 #define OPT_CHANGED (USE_DESKTOP(option_mask32 & 4) SKIP_DESKTOP(0)) 25 #define OPT_QUIET (USE_DESKTOP(option_mask32 & 8) SKIP_DESKTOP(0)) 26 #define OPT_STR "R" USE_DESKTOP("vcf") 27 28 /* coreutils: 29 * chmod never changes the permissions of symbolic links; the chmod 30 * system call cannot change their permissions. This is not a problem 31 * since the permissions of symbolic links are never used. 32 * However, for each symbolic link listed on the command line, chmod changes 33 * the permissions of the pointed-to file. In contrast, chmod ignores 34 * symbolic links encountered during recursive directory traversals. 35 */ 36 37 static int fileAction(const char *fileName, struct stat *statbuf, void* param, int depth) 25 38 { 26 if (!bb_parse_mode((char *)junk, &(statbuf->st_mode))) 27 bb_error_msg_and_die( "invalid mode: %s", (char *)junk); 28 if (chmod(fileName, statbuf->st_mode) == 0) 29 return (TRUE); 30 bb_perror_msg("%s", fileName); /* Avoid multibyte problems. */ 31 return (FALSE); 39 mode_t newmode; 40 41 /* match coreutils behavior */ 42 if (depth == 0) { 43 /* statbuf holds lstat result, but we need stat (follow link) */ 44 if (stat(fileName, statbuf)) 45 goto err; 46 } else { /* depth > 0: skip links */ 47 if (S_ISLNK(statbuf->st_mode)) 48 return TRUE; 49 } 50 newmode = statbuf->st_mode; 51 52 if (!bb_parse_mode((char *)param, &newmode)) 53 bb_error_msg_and_die("invalid mode: %s", (char *)param); 54 55 if (chmod(fileName, newmode) == 0) { 56 if (OPT_VERBOSE 57 || (OPT_CHANGED && statbuf->st_mode != newmode) 58 ) { 59 printf("mode of '%s' changed to %04o (%s)\n", fileName, 60 newmode & 07777, bb_mode_string(newmode)+1); 61 } 62 return TRUE; 63 } 64 err: 65 if (!OPT_QUIET) 66 bb_perror_msg("%s", fileName); 67 return FALSE; 32 68 } 33 69 34 int chmod_main(int ATTRIBUTE_UNUSED argc, char **argv) 70 int chmod_main(int argc, char **argv); 71 int chmod_main(int argc, char **argv) 35 72 { 36 73 int retval = EXIT_SUCCESS; 37 int recursiveFlag = FALSE; 38 int count; 74 char *arg, **argp; 39 75 char *smode; 40 char **p;41 char *p0;42 char opt = '-';43 76 44 ++argv; 45 count = 0; 46 47 for (p = argv ; *p ; p++) { 48 p0 = p[0]; 49 if (p0[0] == opt) { 50 if ((p0[1] == '-') && !p0[2]) { 51 opt = 0; /* Disable further option processing. */ 52 continue; 53 } 54 if (p0[1] == 'R') { 55 char *s = p0 + 2; 56 while (*s == 'R') { 57 ++s; 58 } 59 if (*s) { 60 bb_show_usage(); 61 } 62 recursiveFlag = TRUE; 63 continue; 64 } 65 if (count) { 66 bb_show_usage(); 67 } 77 /* Convert first encountered -r into ar, -w into aw etc 78 * so that getopt would not eat it */ 79 argp = argv; 80 while ((arg = *++argp)) { 81 /* Mode spec must be the first arg (sans -R etc) */ 82 /* (protect against mishandling e.g. "chmod 644 -r") */ 83 if (arg[0] != '-') { 84 arg = NULL; 85 break; 68 86 } 69 argv[count] = p0; 70 ++count; 87 /* An option. Not a -- or valid option? */ 88 if (arg[1] && !strchr("-"OPT_STR, arg[1])) { 89 arg[0] = 'a'; 90 break; 91 } 71 92 } 72 93 73 argv[count] = NULL; 94 /* Parse options */ 95 opt_complementary = "-2"; 96 getopt32(argv, ("-"OPT_STR) + 1); /* Reuse string */ 97 argv += optind; 74 98 75 if (count < 2) { 76 bb_show_usage(); 77 } 78 79 smode = *argv; 80 ++argv; 99 /* Restore option-like mode if needed */ 100 if (arg) arg[0] = '-'; 81 101 82 102 /* Ok, ready to do the deed now */ 103 smode = *argv++; 83 104 do { 84 if (! recursive_action (*argv, recursiveFlag, TRUE, FALSE, 85 fileAction, fileAction, smode)) { 105 if (!recursive_action(*argv, 106 OPT_RECURSE, // recurse 107 fileAction, // file action 108 fileAction, // dir action 109 smode, // user data 110 0) // depth 111 ) { 86 112 retval = EXIT_FAILURE; 87 113 } … … 90 116 return retval; 91 117 } 118 119 /* 120 Security: chmod is too important and too subtle. 121 This is a test script (busybox chmod versus coreutils). 122 Run it in empty directory. 123 124 #!/bin/sh 125 t1="/tmp/busybox chmod" 126 t2="/usr/bin/chmod" 127 create() { 128 rm -rf $1; mkdir $1 129 ( 130 cd $1 || exit 1 131 mkdir dir 132 >up 133 >file 134 >dir/file 135 ln -s dir linkdir 136 ln -s file linkfile 137 ln -s ../up dir/up 138 ) 139 } 140 tst() { 141 (cd test1; $t1 $1) 142 (cd test2; $t2 $1) 143 (cd test1; ls -lR) >out1 144 (cd test2; ls -lR) >out2 145 echo "chmod $1" >out.diff 146 if ! diff -u out1 out2 >>out.diff; then exit 1; fi 147 rm out.diff 148 } 149 echo "If script produced 'out.diff' file, then at least one testcase failed" 150 create test1; create test2 151 tst "a+w file" 152 tst "a-w dir" 153 tst "a+w linkfile" 154 tst "a-w linkdir" 155 tst "-R a+w file" 156 tst "-R a-w dir" 157 tst "-R a+w linkfile" 158 tst "-R a-w linkdir" 159 tst "a-r,a+x linkfile" 160 */ -
branches/2.2.5/mindi-busybox/coreutils/chown.c
r821 r1765 8 8 */ 9 9 10 /* BB_AUDIT SUSv3 defects - unsupported options -h, -H, -L, and -P. */ 11 /* BB_AUDIT GNU defects - unsupported options -h, -c, -f, -v, and long options. */ 12 /* BB_AUDIT Note: gnu chown does not support -H, -L, or -P. */ 10 /* BB_AUDIT SUSv3 defects - none? */ 11 /* BB_AUDIT GNU defects - unsupported long options. */ 13 12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ 14 13 15 #include <stdlib.h> 16 #include <unistd.h> 17 #include <string.h> 18 #include "busybox.h" 14 #include "libbb.h" 19 15 20 static uid_t uid = -1; 21 static gid_t gid = -1; 16 /* This is a NOEXEC applet. Be very careful! */ 22 17 23 static int (*chown_func)(const char *, uid_t, gid_t) = chown; 18 19 #define OPT_STR ("Rh" USE_DESKTOP("vcfLHP")) 20 #define BIT_RECURSE 1 21 #define OPT_RECURSE (option_mask32 & 1) 22 #define OPT_NODEREF (option_mask32 & 2) 23 #define OPT_VERBOSE (USE_DESKTOP(option_mask32 & 0x04) SKIP_DESKTOP(0)) 24 #define OPT_CHANGED (USE_DESKTOP(option_mask32 & 0x08) SKIP_DESKTOP(0)) 25 #define OPT_QUIET (USE_DESKTOP(option_mask32 & 0x10) SKIP_DESKTOP(0)) 26 /* POSIX options 27 * -L traverse every symbolic link to a directory encountered 28 * -H if a command line argument is a symbolic link to a directory, traverse it 29 * -P do not traverse any symbolic links (default) 30 * We do not conform to the following: 31 * "Specifying more than one of -H, -L, and -P is not an error. 32 * The last option specified shall determine the behavior of the utility." */ 33 /* -L */ 34 #define BIT_TRAVERSE 0x20 35 #define OPT_TRAVERSE (USE_DESKTOP(option_mask32 & BIT_TRAVERSE) SKIP_DESKTOP(0)) 36 /* -H or -L */ 37 #define BIT_TRAVERSE_TOP (0x20|0x40) 38 #define OPT_TRAVERSE_TOP (USE_DESKTOP(option_mask32 & BIT_TRAVERSE_TOP) SKIP_DESKTOP(0)) 39 40 typedef int (*chown_fptr)(const char *, uid_t, gid_t); 41 42 static struct bb_uidgid_t ugid = { -1, -1 }; 24 43 25 44 static int fileAction(const char *fileName, struct stat *statbuf, 26 void ATTRIBUTE_UNUSED *junk)45 void *cf, int depth) 27 46 { 28 if (!chown_func(fileName, 29 (uid == (uid_t)-1) ? statbuf->st_uid : uid, 30 (gid == (gid_t)-1) ? statbuf->st_gid : gid)) { 47 uid_t u = (ugid.uid == (uid_t)-1) ? statbuf->st_uid : ugid.uid; 48 gid_t g = (ugid.gid == (gid_t)-1) ? statbuf->st_gid : ugid.gid; 49 50 if (!((chown_fptr)cf)(fileName, u, g)) { 51 if (OPT_VERBOSE 52 || (OPT_CHANGED && (statbuf->st_uid != u || statbuf->st_gid != g)) 53 ) { 54 printf("changed ownership of '%s' to %u:%u\n", 55 fileName, (unsigned)u, (unsigned)g); 56 } 31 57 return TRUE; 32 58 } 33 bb_perror_msg("%s", fileName); /* A filename could have % in it... */ 59 if (!OPT_QUIET) 60 bb_perror_msg("%s", fileName); /* A filename can have % in it... */ 34 61 return FALSE; 35 62 } 36 63 37 #define FLAG_R 1 38 #define FLAG_h 2 39 64 int chown_main(int argc, char **argv); 40 65 int chown_main(int argc, char **argv) 41 66 { 67 int retval = EXIT_SUCCESS; 42 68 int flags; 43 int retval = EXIT_SUCCESS; 44 char *groupName; 69 chown_fptr chown_func; 45 70 46 flags = bb_getopt_ulflags(argc, argv, "Rh"); 71 opt_complementary = "-2"; 72 getopt32(argv, OPT_STR); 73 argv += optind; 47 74 48 if (flags & FLAG_h) chown_func = lchown; 49 50 if (argc - optind < 2) { 51 bb_show_usage(); 75 /* This matches coreutils behavior (almost - see below) */ 76 chown_func = chown; 77 if (OPT_NODEREF 78 /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */ 79 USE_DESKTOP( || (option_mask32 & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE) 80 ) { 81 chown_func = lchown; 52 82 } 53 83 54 argv += optind; 84 flags = ACTION_DEPTHFIRST; /* match coreutils order */ 85 if (OPT_RECURSE) 86 flags |= ACTION_RECURSE; 87 if (OPT_TRAVERSE_TOP) 88 flags |= ACTION_FOLLOWLINKS_L0; /* -H/-L: follow links on depth 0 */ 89 if (OPT_TRAVERSE) 90 flags |= ACTION_FOLLOWLINKS; /* follow links if -L */ 55 91 56 /* First, check if there is a group name here */ 57 if ((groupName = strchr(*argv, '.')) == NULL) { 58 groupName = strchr(*argv, ':'); 59 } 60 61 /* Check for the username and groupname */ 62 if (groupName) { 63 *groupName++ = '\0'; 64 gid = get_ug_id(groupName, bb_xgetgrnam); 65 } 66 if (--groupName != *argv) uid = get_ug_id(*argv, bb_xgetpwnam); 67 ++argv; 92 parse_chown_usergroup_or_die(&ugid, argv[0]); 68 93 69 94 /* Ok, ready to do the deed now */ 95 argv++; 70 96 do { 71 if (! recursive_action (*argv, (flags & FLAG_R), FALSE, FALSE, 72 fileAction, fileAction, NULL)) { 97 if (!recursive_action(*argv, 98 flags, /* flags */ 99 fileAction, /* file action */ 100 fileAction, /* dir action */ 101 chown_func, /* user data */ 102 0) /* depth */ 103 ) { 73 104 retval = EXIT_FAILURE; 74 105 } … … 77 108 return retval; 78 109 } 110 111 /* 112 Testcase. Run in empty directory. 113 114 #!/bin/sh 115 t1="/tmp/busybox chown" 116 t2="/usr/bin/chown" 117 create() { 118 rm -rf $1; mkdir $1 119 ( 120 cd $1 || exit 1 121 mkdir dir dir2 122 >up 123 >file 124 >dir/file 125 >dir2/file 126 ln -s dir linkdir 127 ln -s file linkfile 128 ln -s ../up dir/linkup 129 ln -s ../dir2 dir/linkupdir2 130 ) 131 chown -R 0:0 $1 132 } 133 tst() { 134 create test1 135 create test2 136 echo "[$1]" >>test1.out 137 echo "[$1]" >>test2.out 138 (cd test1; $t1 $1) >>test1.out 2>&1 139 (cd test2; $t2 $1) >>test2.out 2>&1 140 (cd test1; ls -lnR) >out1 141 (cd test2; ls -lnR) >out2 142 echo "chown $1" >out.diff 143 if ! diff -u out1 out2 >>out.diff; then exit 1; fi 144 rm out.diff 145 } 146 tst_for_each() { 147 tst "$1 1:1 file" 148 tst "$1 1:1 dir" 149 tst "$1 1:1 linkdir" 150 tst "$1 1:1 linkfile" 151 } 152 echo "If script produced 'out.diff' file, then at least one testcase failed" 153 >test1.out 154 >test2.out 155 # These match coreutils 6.8: 156 tst_for_each "-v" 157 tst_for_each "-vR" 158 tst_for_each "-vRP" 159 tst_for_each "-vRL" 160 tst_for_each "-vRH" 161 tst_for_each "-vh" 162 tst_for_each "-vhR" 163 tst_for_each "-vhRP" 164 tst_for_each "-vhRL" 165 tst_for_each "-vhRH" 166 # Fix `name' in coreutils output 167 sed 's/`/'"'"'/g' -i test2.out 168 # Compare us with coreutils output 169 diff -u test1.out test2.out 170 171 */ -
branches/2.2.5/mindi-busybox/coreutils/chroot.c
r821 r1765 10 10 /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ 11 11 12 #include <stdlib.h> 13 #include <stdio.h> 14 #include <unistd.h> 15 #include <errno.h> 16 #include "busybox.h" 12 #include "libbb.h" 17 13 14 int chroot_main(int argc, char **argv); 18 15 int chroot_main(int argc, char **argv) 19 16 { … … 26 23 bb_perror_msg_and_die("cannot change root directory to %s", *argv); 27 24 } 28 bb_xchdir("/");25 xchdir("/"); 29 26 30 27 ++argv; 31 28 if (argc == 2) { 32 29 argv -= 2; 33 if (!(*argv = getenv("SHELL"))) { 34 *argv = (char *) DEFAULT_SHELL; 30 argv[0] = getenv("SHELL"); 31 if (!argv[0]) { 32 argv[0] = (char *) DEFAULT_SHELL; 35 33 } 36 34 argv[1] = (char *) "-i"; 37 35 } 38 36 39 execvp(*argv, argv);37 BB_EXECVP(*argv, argv); 40 38 bb_perror_msg_and_die("cannot execute %s", *argv); 41 39 } -
branches/2.2.5/mindi-busybox/coreutils/cksum.c
r821 r1765 4 4 * 5 5 * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms 6 * 6 * 7 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ 8 8 9 #include <stdio.h> 10 #include <unistd.h> 11 #include <fcntl.h> 12 #include "busybox.h" 9 #include "libbb.h" 13 10 14 int cksum_main(int argc, char **argv) { 15 16 uint32_t *crc32_table = bb_crc32_filltable(1); 11 int cksum_main(int argc, char **argv); 12 int cksum_main(int argc, char **argv) 13 { 14 uint32_t *crc32_table = crc32_filltable(NULL, 1); 17 15 18 16 FILE *fp; … … 21 19 int bytes_read; 22 20 char *cp; 23 RESERVE_CONFIG_BUFFER(buf, BUFSIZ); 21 24 22 int inp_stdin = (argc == optind) ? 1 : 0; 25 23 26 24 do { 27 fp = bb_wfopen_input((inp_stdin) ? bb_msg_standard_input : *++argv);28 25 fp = fopen_or_warn_stdin((inp_stdin) ? bb_msg_standard_input : *++argv); 26 29 27 crc = 0; 30 28 length = 0; 31 32 while ((bytes_read = fread(buf, 1, BUFSIZ, fp)) > 0) { 33 cp = buf; 29 30 #define read_buf bb_common_bufsiz1 31 while ((bytes_read = fread(read_buf, 1, BUFSIZ, fp)) > 0) { 32 cp = read_buf; 34 33 length += bytes_read; 35 34 while (bytes_read--) 36 35 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL]; 37 36 } 38 37 39 38 filesize = length; 40 39 41 40 for (; length; length >>= 8) 42 41 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL]; … … 44 43 45 44 if (inp_stdin) { 46 printf("%" PRIu32" %li\n", crc, filesize);45 printf("%" PRIu32 " %li\n", crc, filesize); 47 46 break; 48 47 } 49 50 printf("%" PRIu32" %li %s\n", crc, filesize, *argv);48 49 printf("%" PRIu32 " %li %s\n", crc, filesize, *argv); 51 50 fclose(fp); 52 } while (*(argv +1));53 54 return EXIT_SUCCESS;51 } while (*(argv + 1)); 52 53 fflush_stdout_and_exit(EXIT_SUCCESS); 55 54 } -
branches/2.2.5/mindi-busybox/coreutils/comm.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <unistd.h> 14 #include "busybox.h" 10 #include "libbb.h" 15 11 16 #define COMM_OPT_1 0x01 17 #define COMM_OPT_2 0x02 18 #define COMM_OPT_3 0x04 19 20 /* These three variables control behaviour if non-zero */ 21 22 static int only_file_1; 23 static int only_file_2; 24 static int both; 12 #define COMM_OPT_1 (1 << 0) 13 #define COMM_OPT_2 (1 << 1) 14 #define COMM_OPT_3 (1 << 2) 25 15 26 16 /* writeline outputs the input given, appropriately aligned according to class */ 27 static void writeline(char *line, int class )17 static void writeline(char *line, int class, int flags) 28 18 { 29 19 if (class == 0) { 30 if ( !only_file_1)20 if (flags & COMM_OPT_1) 31 21 return; 32 22 } else if (class == 1) { 33 if ( !only_file_2)23 if (flags & COMM_OPT_2) 34 24 return; 35 if ( only_file_1)25 if (!(flags & COMM_OPT_1)) 36 26 putchar('\t'); 37 } 38 else /*if (class == 2)*/ { 39 if (!both) 27 } else /*if (class == 2)*/ { 28 if (flags & COMM_OPT_3) 40 29 return; 41 if ( only_file_1)30 if (!(flags & COMM_OPT_1)) 42 31 putchar('\t'); 43 if ( only_file_2)32 if (!(flags & COMM_OPT_2)) 44 33 putchar('\t'); 45 34 } … … 47 36 } 48 37 49 /* This is the real core of the program - lines are compared here */ 50 static void cmp_files(char **infiles)38 int comm_main(int argc, char **argv); 39 int comm_main(int argc, char **argv) 51 40 { 52 41 #define LINE_LEN 100 … … 56 45 FILE *streams[2]; 57 46 int i; 47 unsigned flags; 48 49 opt_complementary = "=2"; 50 flags = getopt32(argv, "123"); 51 argv += optind; 58 52 59 53 for (i = 0; i < 2; ++i) { 60 streams[i] = ( (infiles[i][0] == '=' && infiles[i][1]) ? stdin : bb_xfopen(infiles[i], "r"));54 streams[i] = (argv[i][0] == '-' && !argv[i][1]) ? stdin : xfopen(argv[i], "r"); 61 55 fgets(thisline[i], LINE_LEN, streams[i]); 62 56 } 57 58 /* This is the real core of the program - lines are compared here */ 63 59 64 60 while (*thisline[0] || *thisline[1]) { … … 83 79 84 80 if (order == 0 && !i) 85 writeline(thisline[1], 2 );81 writeline(thisline[1], 2, flags); 86 82 else if (order > 0 && !(i & BB_EOF_1)) 87 writeline(thisline[1], 1 );83 writeline(thisline[1], 1, flags); 88 84 else if (order < 0 && !(i & BB_EOF_0)) 89 writeline(thisline[0], 0 );85 writeline(thisline[0], 0, flags); 90 86 91 87 if (i & BB_EOF_0 & BB_EOF_1) { … … 96 92 while (!feof(streams[i])) { 97 93 if ((order < 0 && i) || (order > 0 && !i)) 98 writeline(thisline[i], i );94 writeline(thisline[i], i, flags); 99 95 fgets(thisline[i], LINE_LEN, streams[i]); 100 96 } … … 109 105 } 110 106 111 fclose(streams[0]); 112 fclose(streams[1]); 107 if (ENABLE_FEATURE_CLEAN_UP) { 108 fclose(streams[0]); 109 fclose(streams[1]); 110 } 111 112 return EXIT_SUCCESS; 113 113 } 114 115 int comm_main(int argc, char **argv)116 {117 unsigned long flags;118 119 flags = bb_getopt_ulflags(argc, argv, "123");120 121 if (optind + 2 != argc)122 bb_show_usage();123 124 only_file_1 = !(flags & COMM_OPT_1);125 only_file_2 = !(flags & COMM_OPT_2);126 both = !(flags & COMM_OPT_3);127 128 cmp_files(argv + optind);129 exit(EXIT_SUCCESS);130 } -
branches/2.2.5/mindi-busybox/coreutils/cp.c
r821 r1765 4 4 * 5 5 * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> 6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> 6 7 * 7 8 * Licensed under GPL v2 or later, see file LICENSE in this tarball for details. 8 9 */ 9 10 10 /* BB_AUDIT SUSv3 defects - unsupported options -H, -L, and -P. */11 /* BB_AUDIT GNU defects - only extension options supported are -a and -d. */12 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ 13 12 … … 17 16 */ 18 17 19 #include <sys/types.h> 20 #include <sys/stat.h> 21 #include <unistd.h> 22 #include <fcntl.h> 23 #include <utime.h> 24 #include <errno.h> 25 #include <dirent.h> 26 #include <stdlib.h> 27 #include <assert.h> 28 #include "busybox.h" 18 #include "libbb.h" 29 19 #include "libcoreutils/coreutils.h" 30 20 21 /* This is a NOEXEC applet. Be very careful! */ 22 23 24 int cp_main(int argc, char **argv); 31 25 int cp_main(int argc, char **argv) 32 26 { … … 39 33 int flags; 40 34 int status = 0; 35 enum { 36 OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1), 37 OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)), 38 OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1), 39 OPT_H = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2), 40 OPT_L = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), 41 }; 41 42 42 flags = bb_getopt_ulflags(argc, argv, "pdRfiarPHL"); 43 44 if (flags & 32) { 45 flags |= (FILEUTILS_PRESERVE_STATUS | FILEUTILS_RECUR | FILEUTILS_DEREFERENCE); 46 } 47 if (flags & 64) { 48 /* Make -r a synonym for -R, 49 * -r was marked as obsolete in SUSv3, but is included for compatibility 50 */ 51 flags |= FILEUTILS_RECUR; 52 } 53 if (flags & 128) { 54 /* Make -P a synonym for -d, 55 * -d is the GNU option while -P is the POSIX 2003 option 56 */ 57 flags |= FILEUTILS_DEREFERENCE; 58 } 43 // Soft- and hardlinking don't mix 44 // -P and -d are the same (-P is POSIX, -d is GNU) 45 // -r and -R are the same 46 // -a = -pdR 47 opt_complementary = "l--s:s--l:Pd:rR:apdR"; 48 flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPHL"); 59 49 /* Default behavior of cp is to dereference, so we don't have to do 60 50 * anything special when we are given -L. 61 51 * The behavior of -H is *almost* like -L, but not quite, so let's 62 52 * just ignore it too for fun. 63 if (flags & 256 || flags & 512) { 64 ; 53 if (flags & OPT_L) ... 54 if (flags & OPT_H) ... // deref command-line params only 55 */ 56 57 #if ENABLE_SELINUX 58 if (flags & FILEUTILS_PRESERVE_SECURITY_CONTEXT) { 59 selinux_or_die(); 65 60 } 66 */ 61 #endif 67 62 68 63 flags ^= FILEUTILS_DEREFERENCE; /* The sense of this flag was reversed. */ … … 78 73 if (optind + 2 == argc) { 79 74 s_flags = cp_mv_stat2(*argv, &source_stat, 80 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); 81 if ((s_flags < 0) || ((d_flags = cp_mv_stat(last, &dest_stat)) < 0)) { 82 exit(EXIT_FAILURE); 83 } 75 (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); 76 if (s_flags < 0) 77 return EXIT_FAILURE; 78 d_flags = cp_mv_stat(last, &dest_stat); 79 if (d_flags < 0) 80 return EXIT_FAILURE; 81 84 82 /* ...if neither is a directory or... */ 85 83 if ( !((s_flags | d_flags) & 2) || 86 84 /* ...recursing, the 1st is a directory, and the 2nd doesn't exist... */ 87 /* ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) */ 88 /* Simplify the above since FILEUTILS_RECUR >> 1 == 2. */ 89 ((((flags & FILEUTILS_RECUR) >> 1) & s_flags) && !d_flags) 85 ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) 90 86 ) { 91 87 /* ...do a simple copy. */ 92 dest = last;88 dest = xstrdup(last); 93 89 goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */ 94 90 } … … 97 93 do { 98 94 dest = concat_path_file(last, bb_get_last_path_component(*argv)); 99 95 DO_COPY: 100 96 if (copy_file(*argv, dest, flags) < 0) { 101 97 status = 1; 102 98 } 103 if (*++argv == last) { 104 break; 105 } 106 free((void *) dest); 107 } while (1); 99 free((void*)dest); 100 } while (*++argv != last); 108 101 109 exit(status);102 return status; 110 103 } -
branches/2.2.5/mindi-busybox/coreutils/cut.c
r821 r1765 1 /* vi: set sw= 8 ts=8: */1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 3 * cut.c - minimalist version of cut … … 5 5 * Copyright (C) 1999,2000,2001 by Lineo, inc. 6 6 * Written by Mark Whitley <markw@codepoet.org> 7 * debloated by Bernhard Fischer 7 8 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 22 10 */ 23 11 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <string.h> 28 #include <limits.h> 29 #include "busybox.h" 12 #include "libbb.h" 13 14 /* This is a NOEXEC applet. Be very careful! */ 30 15 31 16 32 17 /* option vars */ 33 static const char optstring[] = "b:c:f:d:sn"; 34 #define OPT_BYTE_FLGS 1 35 #define OPT_CHAR_FLGS 2 36 #define OPT_FIELDS_FLGS 4 37 #define OPT_DELIM_FLGS 8 38 #define OPT_SUPRESS_FLGS 16 39 static char part; /* (b)yte, (c)har, (f)ields */ 40 static unsigned int supress_non_delimited_lines; 41 static char delim = '\t'; /* delimiter, default is tab */ 18 static const char optstring[] ALIGN1 = "b:c:f:d:sn"; 19 #define CUT_OPT_BYTE_FLGS (1<<0) 20 #define CUT_OPT_CHAR_FLGS (1<<1) 21 #define CUT_OPT_FIELDS_FLGS (1<<2) 22 #define CUT_OPT_DELIM_FLGS (1<<3) 23 #define CUT_OPT_SUPPRESS_FLGS (1<<4) 24 25 static char delim = '\t'; /* delimiter, default is tab */ 42 26 43 27 struct cut_list { … … 52 36 }; 53 37 54 static struct cut_list *cut_lists = NULL; /* growable array holding a series of lists */ 55 static unsigned int nlists = 0; /* number of elements in above list */ 38 /* growable array holding a series of lists */ 39 static struct cut_list *cut_lists; 40 static unsigned int nlists; /* number of elements in above list */ 56 41 57 42 58 43 static int cmpfunc(const void *a, const void *b) 59 44 { 60 struct cut_list *la = (struct cut_list *)a; 61 struct cut_list *lb = (struct cut_list *)b; 62 63 if (la->startpos > lb->startpos) 64 return 1; 65 if (la->startpos < lb->startpos) 66 return -1; 67 return 0; 45 return (((struct cut_list *) a)->startpos - 46 ((struct cut_list *) b)->startpos); 47 68 48 } 69 49 70 71 /* 72 * parse_lists() - parses a list and puts values into startpos and endpos. 73 * valid list formats: N, N-, N-M, -M 74 * more than one list can be separated by commas 75 */ 76 static void parse_lists(char *lists) 77 { 78 char *ltok = NULL; 79 char *ntok = NULL; 80 char *junk; 81 int s = 0, e = 0; 82 83 /* take apart the lists, one by one (they are separated with commas */ 84 while ((ltok = strsep(&lists, ",")) != NULL) { 85 86 /* it's actually legal to pass an empty list */ 87 if (strlen(ltok) == 0) 88 continue; 89 90 /* get the start pos */ 91 ntok = strsep(<ok, "-"); 92 if (ntok == NULL) { 93 fprintf(stderr, "Help ntok is null for starting position! What do I do?\n"); 94 } else if (strlen(ntok) == 0) { 95 s = BOL; 96 } else { 97 s = strtoul(ntok, &junk, 10); 98 if(*junk != '\0' || s < 0) 99 bb_error_msg_and_die("invalid byte or field list"); 100 101 /* account for the fact that arrays are zero based, while the user 102 * expects the first char on the line to be char # 1 */ 103 if (s != 0) 104 s--; 105 } 106 107 /* get the end pos */ 108 ntok = strsep(<ok, "-"); 109 if (ntok == NULL) { 110 e = NON_RANGE; 111 } else if (strlen(ntok) == 0) { 112 e = EOL; 113 } else { 114 e = strtoul(ntok, &junk, 10); 115 if(*junk != '\0' || e < 0) 116 bb_error_msg_and_die("invalid byte or field list"); 117 /* if the user specified and end position of 0, that means "til the 118 * end of the line */ 119 if (e == 0) 120 e = INT_MAX; 121 e--; /* again, arrays are zero based, lines are 1 based */ 122 if (e == s) 123 e = NON_RANGE; 124 } 125 126 /* if there's something left to tokenize, the user past an invalid list */ 127 if (ltok) 128 bb_error_msg_and_die("invalid byte or field list"); 129 130 /* add the new list */ 131 cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); 132 cut_lists[nlists-1].startpos = s; 133 cut_lists[nlists-1].endpos = e; 134 } 135 136 /* make sure we got some cut positions out of all that */ 137 if (nlists == 0) 138 bb_error_msg_and_die("missing list of positions"); 139 140 /* now that the lists are parsed, we need to sort them to make life easier 141 * on us when it comes time to print the chars / fields / lines */ 142 qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); 143 144 } 145 146 147 static void cut_line_by_chars(const char *line) 148 { 149 int c, l; 150 /* set up a list so we can keep track of what's been printed */ 151 char *printed = xcalloc(strlen(line), sizeof(char)); 152 153 /* print the chars specified in each cut list */ 154 for (c = 0; c < nlists; c++) { 155 l = cut_lists[c].startpos; 156 while (l < strlen(line)) { 157 if (!printed[l]) { 158 putchar(line[l]); 159 printed[l] = 'X'; 160 } 161 l++; 162 if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) 163 break; 164 } 165 } 166 putchar('\n'); /* cuz we were handed a chomped line */ 167 free(printed); 168 } 169 170 171 static void cut_line_by_fields(char *line) 172 { 173 int c, f; 174 int ndelim = -1; /* zero-based / one-based problem */ 175 int nfields_printed = 0; 176 char *field = NULL; 177 char d[2] = { delim, 0 }; 178 char *printed; 179 180 /* test the easy case first: does this line contain any delimiters? */ 181 if (strchr(line, delim) == NULL) { 182 if (!supress_non_delimited_lines) 183 puts(line); 184 return; 185 } 186 187 /* set up a list so we can keep track of what's been printed */ 188 printed = xcalloc(strlen(line), sizeof(char)); 189 190 /* process each list on this line, for as long as we've got a line to process */ 191 for (c = 0; c < nlists && line; c++) { 192 f = cut_lists[c].startpos; 193 do { 194 195 /* find the field we're looking for */ 196 while (line && ndelim < f) { 197 field = strsep(&line, d); 198 ndelim++; 199 } 200 201 /* we found it, and it hasn't been printed yet */ 202 if (field && ndelim == f && !printed[ndelim]) { 203 /* if this isn't our first time through, we need to print the 204 * delimiter after the last field that was printed */ 205 if (nfields_printed > 0) 206 putchar(delim); 207 fputs(field, stdout); 208 printed[ndelim] = 'X'; 209 nfields_printed++; 210 } 211 212 f++; 213 214 /* keep going as long as we have a line to work with, this is a 215 * list, and we're not at the end of that list */ 216 } while (line && cut_lists[c].endpos != NON_RANGE && f <= cut_lists[c].endpos); 217 } 218 219 /* if we printed anything at all, we need to finish it with a newline cuz 220 * we were handed a chomped line */ 221 putchar('\n'); 222 223 free(printed); 224 } 225 226 227 static void cut_file_by_lines(const char *line, unsigned int linenum) 228 { 229 static int c = 0; 230 static int l = -1; 231 232 /* I can't initialize this above cuz the "initializer isn't 233 * constant" *sigh* */ 234 if (l == -1) 235 l = cut_lists[c].startpos; 236 237 /* get out if we have no more lists to process or if the lines are lower 238 * than what we're interested in */ 239 if (c >= nlists || linenum < l) 240 return; 241 242 /* if the line we're looking for is lower than the one we were passed, it 243 * means we displayed it already, so move on */ 244 while (l < linenum) { 245 l++; 246 /* move on to the next list if we're at the end of this one */ 247 if (cut_lists[c].endpos == NON_RANGE || l > cut_lists[c].endpos) { 248 c++; 249 /* get out if there's no more lists to process */ 250 if (c >= nlists) 251 return; 252 l = cut_lists[c].startpos; 253 /* get out if the current line is lower than the one we just became 254 * interested in */ 255 if (linenum < l) 256 return; 257 } 258 } 259 260 /* If we made it here, it means we've found the line we're looking for, so print it */ 261 puts(line); 262 } 263 264 265 /* 266 * snippy-snip 267 */ 268 static void cut_file(FILE *file) 50 static void cut_file(FILE * file) 269 51 { 270 52 char *line = NULL; 271 unsigned int linenum = 0; 53 unsigned int linenum = 0; /* keep these zero-based to be consistent */ 272 54 273 55 /* go through every line in the file */ 274 while ((line = bb_get_chomped_line_from_file(file)) != NULL) { 56 while ((line = xmalloc_getline(file)) != NULL) { 57 58 /* set up a list so we can keep track of what's been printed */ 59 char * printed = xzalloc(strlen(line) * sizeof(char)); 60 char * orig_line = line; 61 unsigned int cl_pos = 0; 62 int spos; 275 63 276 64 /* cut based on chars/bytes XXX: only works when sizeof(char) == byte */ 277 if ((part & (OPT_CHAR_FLGS | OPT_BYTE_FLGS))) 278 cut_line_by_chars(line); 279 280 /* cut based on fields */ 281 else { 282 if (delim == '\n') 283 cut_file_by_lines(line, linenum); 284 else 285 cut_line_by_fields(line); 286 } 287 65 if (option_mask32 & (CUT_OPT_CHAR_FLGS | CUT_OPT_BYTE_FLGS)) { 66 /* print the chars specified in each cut list */ 67 for (; cl_pos < nlists; cl_pos++) { 68 spos = cut_lists[cl_pos].startpos; 69 while (spos < strlen(line)) { 70 if (!printed[spos]) { 71 printed[spos] = 'X'; 72 putchar(line[spos]); 73 } 74 spos++; 75 if (spos > cut_lists[cl_pos].endpos 76 || cut_lists[cl_pos].endpos == NON_RANGE) 77 break; 78 } 79 } 80 } else if (delim == '\n') { /* cut by lines */ 81 spos = cut_lists[cl_pos].startpos; 82 83 /* get out if we have no more lists to process or if the lines 84 * are lower than what we're interested in */ 85 if (linenum < spos || cl_pos >= nlists) 86 goto next_line; 87 88 /* if the line we're looking for is lower than the one we were 89 * passed, it means we displayed it already, so move on */ 90 while (spos < linenum) { 91 spos++; 92 /* go to the next list if we're at the end of this one */ 93 if (spos > cut_lists[cl_pos].endpos 94 || cut_lists[cl_pos].endpos == NON_RANGE) { 95 cl_pos++; 96 /* get out if there's no more lists to process */ 97 if (cl_pos >= nlists) 98 goto next_line; 99 spos = cut_lists[cl_pos].startpos; 100 /* get out if the current line is lower than the one 101 * we just became interested in */ 102 if (linenum < spos) 103 goto next_line; 104 } 105 } 106 107 /* If we made it here, it means we've found the line we're 108 * looking for, so print it */ 109 puts(line); 110 goto next_line; 111 } else { /* cut by fields */ 112 int ndelim = -1; /* zero-based / one-based problem */ 113 int nfields_printed = 0; 114 char *field = NULL; 115 const char delimiter[2] = { delim, 0 }; 116 117 /* does this line contain any delimiters? */ 118 if (strchr(line, delim) == NULL) { 119 if (!(option_mask32 & CUT_OPT_SUPPRESS_FLGS)) 120 puts(line); 121 goto next_line; 122 } 123 124 /* process each list on this line, for as long as we've got 125 * a line to process */ 126 for (; cl_pos < nlists && line; cl_pos++) { 127 spos = cut_lists[cl_pos].startpos; 128 do { 129 /* find the field we're looking for */ 130 while (line && ndelim < spos) { 131 field = strsep(&line, delimiter); 132 ndelim++; 133 } 134 135 /* we found it, and it hasn't been printed yet */ 136 if (field && ndelim == spos && !printed[ndelim]) { 137 /* if this isn't our first time through, we need to 138 * print the delimiter after the last field that was 139 * printed */ 140 if (nfields_printed > 0) 141 putchar(delim); 142 fputs(field, stdout); 143 printed[ndelim] = 'X'; 144 nfields_printed++; /* shouldn't overflow.. */ 145 } 146 147 spos++; 148 149 /* keep going as long as we have a line to work with, 150 * this is a list, and we're not at the end of that 151 * list */ 152 } while (spos <= cut_lists[cl_pos].endpos && line 153 && cut_lists[cl_pos].endpos != NON_RANGE); 154 } 155 } 156 /* if we printed anything at all, we need to finish it with a 157 * newline cuz we were handed a chomped line */ 158 putchar('\n'); 159 next_line: 288 160 linenum++; 289 free(line); 161 free(printed); 162 free(orig_line); 290 163 } 291 164 } 292 165 293 166 static const char _op_on_field[] ALIGN1 = " only when operating on fields"; 167 168 int cut_main(int argc, char **argv); 294 169 int cut_main(int argc, char **argv) 295 170 { 296 unsigned long opt; 297 char *sopt, *sdopt; 298 299 bb_opt_complementally = "b--bcf:c--bcf:f--bcf"; 300 opt = bb_getopt_ulflags(argc, argv, optstring, &sopt, &sopt, &sopt, &sdopt); 301 part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS); 302 if(part == 0) 303 bb_error_msg_and_die("you must specify a list of bytes, characters, or fields"); 304 if(opt & BB_GETOPT_ERROR) 305 bb_error_msg_and_die("only one type of list may be specified"); 306 parse_lists(sopt); 307 if((opt & (OPT_DELIM_FLGS))) { 308 if (strlen(sdopt) > 1) { 171 char *sopt, *ltok; 172 173 opt_complementary = "b--bcf:c--bcf:f--bcf"; 174 getopt32(argv, optstring, &sopt, &sopt, &sopt, <ok); 175 // argc -= optind; 176 argv += optind; 177 if (!(option_mask32 & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) 178 bb_error_msg_and_die("expected a list of bytes, characters, or fields"); 179 180 if (option_mask32 & CUT_OPT_DELIM_FLGS) { 181 if (strlen(ltok) > 1) { 309 182 bb_error_msg_and_die("the delimiter must be a single character"); 310 183 } 311 delim = sdopt[0]; 312 } 313 supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS; 184 delim = ltok[0]; 185 } 314 186 315 187 /* non-field (char or byte) cutting has some special handling */ 316 if (part != OPT_FIELDS_FLGS) { 317 if (supress_non_delimited_lines) { 318 bb_error_msg_and_die("suppressing non-delimited lines makes sense" 319 " only when operating on fields"); 188 if (!(option_mask32 & CUT_OPT_FIELDS_FLGS)) { 189 if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) { 190 bb_error_msg_and_die 191 ("suppressing non-delimited lines makes sense%s", 192 _op_on_field); 320 193 } 321 194 if (delim != '\t') { 322 bb_error_msg_and_die("a delimiter may be specified only when operating on fields"); 323 } 324 } 325 326 /* argv[(optind)..(argc-1)] should be names of file to process. If no 195 bb_error_msg_and_die 196 ("a delimiter may be specified%s", _op_on_field); 197 } 198 } 199 200 /* 201 * parse list and put values into startpos and endpos. 202 * valid list formats: N, N-, N-M, -M 203 * more than one list can be separated by commas 204 */ 205 { 206 char *ntok; 207 int s = 0, e = 0; 208 209 /* take apart the lists, one by one (they are separated with commas */ 210 while ((ltok = strsep(&sopt, ",")) != NULL) { 211 212 /* it's actually legal to pass an empty list */ 213 if (strlen(ltok) == 0) 214 continue; 215 216 /* get the start pos */ 217 ntok = strsep(<ok, "-"); 218 if (ntok == NULL) { 219 bb_error_msg 220 ("internal error: ntok is null for start pos!?\n"); 221 } else if (strlen(ntok) == 0) { 222 s = BOL; 223 } else { 224 s = xatoi_u(ntok); 225 /* account for the fact that arrays are zero based, while 226 * the user expects the first char on the line to be char #1 */ 227 if (s != 0) 228 s--; 229 } 230 231 /* get the end pos */ 232 ntok = strsep(<ok, "-"); 233 if (ntok == NULL) { 234 e = NON_RANGE; 235 } else if (strlen(ntok) == 0) { 236 e = EOL; 237 } else { 238 e = xatoi_u(ntok); 239 /* if the user specified and end position of 0, that means "til the 240 * end of the line */ 241 if (e == 0) 242 e = EOL; 243 e--; /* again, arrays are zero based, lines are 1 based */ 244 if (e == s) 245 e = NON_RANGE; 246 } 247 248 /* if there's something left to tokenize, the user passed 249 * an invalid list */ 250 if (ltok) 251 bb_error_msg_and_die("invalid byte or field list"); 252 253 /* add the new list */ 254 cut_lists = xrealloc(cut_lists, sizeof(struct cut_list) * (++nlists)); 255 cut_lists[nlists-1].startpos = s; 256 cut_lists[nlists-1].endpos = e; 257 } 258 259 /* make sure we got some cut positions out of all that */ 260 if (nlists == 0) 261 bb_error_msg_and_die("missing list of positions"); 262 263 /* now that the lists are parsed, we need to sort them to make life 264 * easier on us when it comes time to print the chars / fields / lines 265 */ 266 qsort(cut_lists, nlists, sizeof(struct cut_list), cmpfunc); 267 } 268 269 /* argv[0..argc-1] should be names of file to process. If no 327 270 * files were specified or '-' was specified, take input from stdin. 328 271 * Otherwise, we process all the files specified. */ 329 if (argv[ optind] == NULL || (strcmp(argv[optind], "-") == 0)) {272 if (argv[0] == NULL || LONE_DASH(argv[0])) { 330 273 cut_file(stdin); 331 } 332 else { 333 int i; 274 } else { 334 275 FILE *file; 335 for (i = optind; i < argc; i++) { 336 file = bb_wfopen(argv[i], "r"); 337 if(file) { 276 277 do { 278 file = fopen_or_warn(argv[0], "r"); 279 if (file) { 338 280 cut_file(file); 339 281 fclose(file); 340 282 } 341 } 342 } 343 283 } while (*++argv); 284 } 285 if (ENABLE_FEATURE_CLEAN_UP) 286 free(cut_lists); 344 287 return EXIT_SUCCESS; 345 288 } -
branches/2.2.5/mindi-busybox/coreutils/date.c
r821 r1765 6 6 * 7 7 * iso-format handling added by Robert Griebl <griebl@gmx.de> 8 * bugfixes and cleanup by Bernhard Fischer 8 9 * 9 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 11 */ 11 12 12 #include <stdlib.h> 13 #include <errno.h> 14 #include <unistd.h> 15 #include <time.h> 16 #include <stdio.h> 17 #include <string.h> 18 #include "busybox.h" 13 #include "libbb.h" 19 14 20 15 /* This 'date' command supports only 2 time setting formats, 21 16 all the GNU strftime stuff (its in libc, lets use it), 22 setting time using UTC and displaying i nt, as well as23 an RFC 822 complient date output for shell scripting17 setting time using UTC and displaying it, as well as 18 an RFC 2822 compliant date output for shell scripting 24 19 mail commands */ 25 20 … … 29 24 /* Default input handling to save surprising some people */ 30 25 31 static struct tm *date_conv_time(struct tm *tm_time, const char *t_string)32 {33 int nr;34 char *cp;35 36 nr = sscanf(t_string, "%2d%2d%2d%2d%d", &(tm_time->tm_mon),37 &(tm_time->tm_mday), &(tm_time->tm_hour), &(tm_time->tm_min),38 &(tm_time->tm_year));39 40 if (nr < 4 || nr > 5) {41 bb_error_msg_and_die(bb_msg_invalid_date, t_string);42 }43 44 cp = strchr(t_string, '.');45 if (cp) {46 nr = sscanf(cp + 1, "%2d", &(tm_time->tm_sec));47 if (nr != 1) {48 bb_error_msg_and_die(bb_msg_invalid_date, t_string);49 }50 }51 52 /* correct for century - minor Y2K problem here? */53 if (tm_time->tm_year >= 1900) {54 tm_time->tm_year -= 1900;55 }56 /* adjust date */57 tm_time->tm_mon -= 1;58 59 return (tm_time);60 61 }62 63 64 /* The new stuff for LRP */65 66 static struct tm *date_conv_ftime(struct tm *tm_time, const char *t_string)67 {68 struct tm t;69 70 /* Parse input and assign appropriately to tm_time */71 72 if (t = *tm_time, sscanf(t_string, "%d:%d:%d", &t.tm_hour, &t.tm_min,73 &t.tm_sec) == 3) {74 /* no adjustments needed */75 } else if (t = *tm_time, sscanf(t_string, "%d:%d", &t.tm_hour,76 &t.tm_min) == 2) {77 /* no adjustments needed */78 } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d:%d", &t.tm_mon,79 &t.tm_mday, &t.tm_hour,80 &t.tm_min, &t.tm_sec) == 5) {81 /* Adjust dates from 1-12 to 0-11 */82 t.tm_mon -= 1;83 } else if (t = *tm_time, sscanf(t_string, "%d.%d-%d:%d", &t.tm_mon,84 &t.tm_mday,85 &t.tm_hour, &t.tm_min) == 4) {86 /* Adjust dates from 1-12 to 0-11 */87 t.tm_mon -= 1;88 } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d:%d", &t.tm_year,89 &t.tm_mon, &t.tm_mday,90 &t.tm_hour, &t.tm_min,91 &t.tm_sec) == 6) {92 t.tm_year -= 1900; /* Adjust years */93 t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */94 } else if (t = *tm_time, sscanf(t_string, "%d.%d.%d-%d:%d", &t.tm_year,95 &t.tm_mon, &t.tm_mday,96 &t.tm_hour, &t.tm_min) == 5) {97 t.tm_year -= 1900; /* Adjust years */98 t.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */99 } else {100 bb_error_msg_and_die(bb_msg_invalid_date, t_string);101 }102 *tm_time = t;103 return (tm_time);104 }105 26 106 27 #define DATE_OPT_RFC2822 0x01 … … 112 33 #define DATE_OPT_HINT 0x40 113 34 35 static void maybe_set_utc(int opt) 36 { 37 if (opt & DATE_OPT_UTC) 38 putenv((char*)"TZ=UTC0"); 39 } 40 41 int date_main(int argc, char **argv); 114 42 int date_main(int argc, char **argv) 115 43 { 44 time_t tm; 45 struct tm tm_time; 46 unsigned opt; 47 int ifmt = -1; 116 48 char *date_str = NULL; 117 49 char *date_fmt = NULL; 118 int set_time;119 int utc;120 time_t tm;121 unsigned long opt;122 struct tm tm_time;123 50 char *filename = NULL; 124 125 int ifmt = 0;126 51 char *isofmt_arg; 127 52 char *hintfmt_arg; 128 53 129 bb_opt_complementally = "?:d--s:s--d"; 130 opt = bb_getopt_ulflags(argc, argv, "Rs:ud:r:" 131 USE_FEATURE_DATE_ISOFMT("I::D:"), 132 &date_str, &date_str, &filename 133 USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); 134 set_time = opt & DATE_OPT_SET; 135 utc = opt & DATE_OPT_UTC; 136 if (utc && putenv("TZ=UTC0") != 0) { 137 bb_error_msg_and_die(bb_msg_memory_exhausted); 138 } 139 140 if(ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { 54 opt_complementary = "d--s:s--d" 55 USE_FEATURE_DATE_ISOFMT(":R--I:I--R"); 56 opt = getopt32(argv, "Rs:ud:r:" 57 USE_FEATURE_DATE_ISOFMT("I::D:"), 58 &date_str, &date_str, &filename 59 USE_FEATURE_DATE_ISOFMT(, &isofmt_arg, &hintfmt_arg)); 60 maybe_set_utc(opt); 61 62 if (ENABLE_FEATURE_DATE_ISOFMT && (opt & DATE_OPT_TIMESPEC)) { 141 63 if (!isofmt_arg) { 142 ifmt = 1;64 ifmt = 0; /* default is date */ 143 65 } else { 144 char *isoformats[]={"date","hours","minutes","seconds"}; 145 for(ifmt = 4; ifmt;) 146 if(!strcmp(isofmt_arg,isoformats[--ifmt])) 147 break; 148 } 149 if (!ifmt) { 66 static const char *const isoformats[] = { 67 "date", "hours", "minutes", "seconds" 68 }; 69 70 for (ifmt = 0; ifmt < 4; ifmt++) 71 if (!strcmp(isofmt_arg, isoformats[ifmt])) 72 goto found; 73 /* parse error */ 150 74 bb_show_usage(); 75 found: ; 151 76 } 152 77 } … … 156 81 date_fmt = &argv[optind][1]; /* Skip over the '+' */ 157 82 } else if (date_str == NULL) { 158 set_time = 1;83 opt |= DATE_OPT_SET; 159 84 date_str = argv[optind]; 160 85 } … … 163 88 which depends on whether the clock is being set or read */ 164 89 165 if (filename) {90 if (filename) { 166 91 struct stat statbuf; 167 xstat(filename,&statbuf); 168 tm=statbuf.st_mtime; 169 } else time(&tm); 92 xstat(filename, &statbuf); 93 tm = statbuf.st_mtime; 94 } else 95 time(&tm); 170 96 memcpy(&tm_time, localtime(&tm), sizeof(tm_time)); 171 97 /* Zero out fields - take her back to midnight! */ … … 179 105 strptime(date_str, hintfmt_arg, &tm_time); 180 106 } else if (strchr(date_str, ':') != NULL) { 181 date_conv_ftime(&tm_time, date_str); 107 /* Parse input and assign appropriately to tm_time */ 108 109 if (sscanf(date_str, "%d:%d:%d", &tm_time.tm_hour, &tm_time.tm_min, 110 &tm_time.tm_sec) == 3) { 111 /* no adjustments needed */ 112 } else if (sscanf(date_str, "%d:%d", &tm_time.tm_hour, 113 &tm_time.tm_min) == 2) { 114 /* no adjustments needed */ 115 } else if (sscanf(date_str, "%d.%d-%d:%d:%d", &tm_time.tm_mon, 116 &tm_time.tm_mday, &tm_time.tm_hour, 117 &tm_time.tm_min, &tm_time.tm_sec) == 5) { 118 /* Adjust dates from 1-12 to 0-11 */ 119 tm_time.tm_mon -= 1; 120 } else if (sscanf(date_str, "%d.%d-%d:%d", &tm_time.tm_mon, 121 &tm_time.tm_mday, 122 &tm_time.tm_hour, &tm_time.tm_min) == 4) { 123 /* Adjust dates from 1-12 to 0-11 */ 124 tm_time.tm_mon -= 1; 125 } else if (sscanf(date_str, "%d.%d.%d-%d:%d:%d", &tm_time.tm_year, 126 &tm_time.tm_mon, &tm_time.tm_mday, 127 &tm_time.tm_hour, &tm_time.tm_min, 128 &tm_time.tm_sec) == 6) { 129 tm_time.tm_year -= 1900; /* Adjust years */ 130 tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ 131 } else if (sscanf(date_str, "%d.%d.%d-%d:%d", &tm_time.tm_year, 132 &tm_time.tm_mon, &tm_time.tm_mday, 133 &tm_time.tm_hour, &tm_time.tm_min) == 5) { 134 tm_time.tm_year -= 1900; /* Adjust years */ 135 tm_time.tm_mon -= 1; /* Adjust dates from 1-12 to 0-11 */ 136 } else { 137 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 138 } 182 139 } else { 183 date_conv_time(&tm_time, date_str); 140 int nr; 141 char *cp; 142 143 nr = sscanf(date_str, "%2d%2d%2d%2d%d", &tm_time.tm_mon, 144 &tm_time.tm_mday, &tm_time.tm_hour, &tm_time.tm_min, 145 &tm_time.tm_year); 146 147 if (nr < 4 || nr > 5) { 148 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 149 } 150 151 cp = strchr(date_str, '.'); 152 if (cp) { 153 nr = sscanf(cp + 1, "%2d", &tm_time.tm_sec); 154 if (nr != 1) { 155 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 156 } 157 } 158 159 /* correct for century - minor Y2K problem here? */ 160 if (tm_time.tm_year >= 1900) { 161 tm_time.tm_year -= 1900; 162 } 163 /* adjust date */ 164 tm_time.tm_mon -= 1; 184 165 } 185 166 … … 190 171 bb_error_msg_and_die(bb_msg_invalid_date, date_str); 191 172 } 192 if (utc && putenv("TZ=UTC0") != 0) { 193 bb_error_msg_and_die(bb_msg_memory_exhausted); 194 } 173 maybe_set_utc(opt); 195 174 196 175 /* if setting time, set it */ 197 if ( set_time&& stime(&tm) < 0) {176 if ((opt & DATE_OPT_SET) && stime(&tm) < 0) { 198 177 bb_perror_msg("cannot set date"); 199 178 } … … 203 182 204 183 /* Deal with format string */ 184 205 185 if (date_fmt == NULL) { 206 /* Start with the default case */ 207 208 date_fmt = (opt & DATE_OPT_RFC2822 ? 209 (utc ? "%a, %d %b %Y %H:%M:%S GMT" : 210 "%a, %d %b %Y %H:%M:%S %z") : 211 "%a %b %e %H:%M:%S %Z %Y"); 212 213 if (ENABLE_FEATURE_DATE_ISOFMT) { 214 if (ifmt == 4) 215 date_fmt = utc ? "%Y-%m-%dT%H:%M:%SZ" : "%Y-%m-%dT%H:%M:%S%z"; 216 else if (ifmt == 3) 217 date_fmt = utc ? "%Y-%m-%dT%H:%MZ" : "%Y-%m-%dT%H:%M%z"; 218 else if (ifmt == 2) 219 date_fmt = utc ? "%Y-%m-%dT%HZ" : "%Y-%m-%dT%H%z"; 220 else if (ifmt == 1) 221 date_fmt = "%Y-%m-%d"; 222 } 223 } 224 186 int i; 187 date_fmt = xzalloc(32); 188 if (ENABLE_FEATURE_DATE_ISOFMT && ifmt >= 0) { 189 strcpy(date_fmt, "%Y-%m-%d"); 190 if (ifmt > 0) { 191 i = 8; 192 date_fmt[i++] = 'T'; 193 date_fmt[i++] = '%'; 194 date_fmt[i++] = 'H'; 195 if (ifmt > 1) { 196 date_fmt[i++] = ':'; 197 date_fmt[i++] = '%'; 198 date_fmt[i++] = 'M'; 199 } 200 if (ifmt > 2) { 201 date_fmt[i++] = ':'; 202 date_fmt[i++] = '%'; 203 date_fmt[i++] = 'S'; 204 } 205 format_utc: 206 date_fmt[i++] = '%'; 207 date_fmt[i] = (opt & DATE_OPT_UTC) ? 'Z' : 'z'; 208 } 209 } else if (opt & DATE_OPT_RFC2822) { 210 /* Undo busybox.c for date -R */ 211 if (ENABLE_LOCALE_SUPPORT) 212 setlocale(LC_TIME, "C"); 213 strcpy(date_fmt, "%a, %d %b %Y %H:%M:%S "); 214 i = 22; 215 goto format_utc; 216 } else /* default case */ 217 date_fmt = (char*)"%a %b %e %H:%M:%S %Z %Y"; 218 } 219 220 #define date_buf bb_common_bufsiz1 225 221 if (*date_fmt == '\0') { 226 227 222 /* With no format string, just print a blank line */ 228 229 *bb_common_bufsiz1=0; 223 date_buf[0] = '\0'; 230 224 } else { 231 232 225 /* Handle special conversions */ 233 226 234 227 if (strncmp(date_fmt, "%f", 2) == 0) { 235 date_fmt = "%Y.%m.%d-%H:%M:%S";228 date_fmt = (char*)"%Y.%m.%d-%H:%M:%S"; 236 229 } 237 230 238 231 /* Generate output string */ 239 strftime( bb_common_bufsiz1, 200, date_fmt, &tm_time);240 } 241 puts( bb_common_bufsiz1);232 strftime(date_buf, sizeof(date_buf), date_fmt, &tm_time); 233 } 234 puts(date_buf); 242 235 243 236 return EXIT_SUCCESS; -
branches/2.2.5/mindi-busybox/coreutils/dd.c
r821 r1765 9 9 */ 10 10 11 #include <sys/types.h> 12 #include <sys/stat.h> 13 #include <stdlib.h> 14 #include <stdio.h> 15 #include <unistd.h> 16 #include <string.h> 17 #include <fcntl.h> 18 #include <signal.h> // For FEATURE_DD_SIGNAL_HANDLING 19 #include "busybox.h" 11 #include <signal.h> /* For FEATURE_DD_SIGNAL_HANDLING */ 12 #include "libbb.h" 13 14 /* This is a NOEXEC applet. Be very careful! */ 15 20 16 21 17 static const struct suffix_mult dd_suffixes[] = { … … 25 21 { "kD", 1000 }, 26 22 { "k", 1024 }, 23 { "K", 1024 }, /* compat with coreutils dd */ 27 24 { "MD", 1000000 }, 28 25 { "M", 1048576 }, 29 26 { "GD", 1000000000 }, 30 27 { "G", 1073741824 }, 31 { NULL, 0}28 { } 32 29 }; 33 30 34 static size_t out_full; 35 static size_t out_part; 36 static size_t in_full; 37 static size_t in_part; 38 39 static void dd_output_status(int cur_signal) 31 struct globals { 32 off_t out_full, out_part, in_full, in_part; 33 }; 34 #define G (*(struct globals*)&bb_common_bufsiz1) 35 /* We have to zero it out because of NOEXEC */ 36 #define INIT_G() memset(&G, 0, sizeof(G)) 37 38 39 static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal) 40 40 { 41 fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n", 42 (long)in_full, (long)in_part, 43 (long)out_full, (long)out_part); 41 /* Deliberately using %u, not %d */ 42 fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n" 43 "%"OFF_FMT"u+%"OFF_FMT"u records out\n", 44 G.in_full, G.in_part, 45 G.out_full, G.out_part); 44 46 } 45 47 48 static ssize_t full_write_or_warn(int fd, const void *buf, size_t len, 49 const char *const filename) 50 { 51 ssize_t n = full_write(fd, buf, len); 52 if (n < 0) 53 bb_perror_msg("writing '%s'", filename); 54 return n; 55 } 56 57 static bool write_and_stats(int fd, const void *buf, size_t len, size_t obs, 58 const char *filename) 59 { 60 ssize_t n = full_write_or_warn(fd, buf, len, filename); 61 if (n < 0) 62 return 1; 63 if (n == obs) 64 G.out_full++; 65 else if (n) /* > 0 */ 66 G.out_part++; 67 return 0; 68 } 69 70 #if ENABLE_LFS 71 #define XATOU_SFX xatoull_sfx 72 #else 73 #define XATOU_SFX xatoul_sfx 74 #endif 75 76 int dd_main(int argc, char **argv); 46 77 int dd_main(int argc, char **argv) 47 78 { 48 size_t count = -1, oc = 0, ibs = 512, obs = 512; 49 ssize_t n; 50 off_t seek = 0, skip = 0; 51 int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0, 52 oflag, ifd, ofd, i; 53 const char *infile = NULL, *outfile = NULL; 79 enum { 80 FLAG_SYNC = 1 << 0, 81 FLAG_NOERROR = 1 << 1, 82 FLAG_NOTRUNC = 1 << 2, 83 FLAG_TWOBUFS = 1 << 3, 84 FLAG_COUNT = 1 << 4, 85 }; 86 static const char keywords[] ALIGN1 = 87 "bs=\0""count=\0""seek=\0""skip=\0""if=\0""of=\0" 88 #if ENABLE_FEATURE_DD_IBS_OBS 89 "ibs=\0""obs=\0""conv=\0""notrunc\0""sync\0""noerror\0" 90 #endif 91 ; 92 enum { 93 OP_bs = 1, 94 OP_count, 95 OP_seek, 96 OP_skip, 97 OP_if, 98 OP_of, 99 #if ENABLE_FEATURE_DD_IBS_OBS 100 OP_ibs, 101 OP_obs, 102 OP_conv, 103 OP_conv_notrunc, 104 OP_conv_sync, 105 OP_conv_noerror, 106 #endif 107 }; 108 size_t ibs = 512, obs = 512; 109 ssize_t n, w; 54 110 char *ibuf, *obuf; 55 56 if (ENABLE_FEATURE_DD_SIGNAL_HANDLING) 57 { 58 struct sigaction sa; 59 60 memset(&sa, 0, sizeof(sa)); 61 sa.sa_handler = dd_output_status; 62 sa.sa_flags = SA_RESTART; 63 sigemptyset(&sa.sa_mask); 64 sigaction(SIGUSR1, &sa, 0); 65 } 66 67 for (i = 1; i < argc; i++) { 68 if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) { 69 ibs = bb_xparse_number(argv[i]+4, dd_suffixes); 70 twobufs_flag++; 71 } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) { 72 obs = bb_xparse_number(argv[i]+4, dd_suffixes); 73 twobufs_flag++; 74 } else if (!strncmp("bs=", argv[i], 3)) { 75 ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes); 76 } else if (!strncmp("count=", argv[i], 6)) 77 count = bb_xparse_number(argv[i]+6, dd_suffixes); 78 else if (!strncmp("seek=", argv[i], 5)) 79 seek = bb_xparse_number(argv[i]+5, dd_suffixes); 80 else if (!strncmp("skip=", argv[i], 5)) 81 skip = bb_xparse_number(argv[i]+5, dd_suffixes); 82 else if (!strncmp("if=", argv[i], 3)) 83 infile = argv[i]+3; 84 else if (!strncmp("of=", argv[i], 3)) 85 outfile = argv[i]+3; 86 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) { 87 ibuf = argv[i]+5; 88 while (1) { 89 if (!strncmp("notrunc", ibuf, 7)) { 90 trunc_flag = FALSE; 91 ibuf += 7; 92 } else if (!strncmp("sync", ibuf, 4)) { 93 sync_flag = TRUE; 94 ibuf += 4; 95 } else if (!strncmp("noerror", ibuf, 7)) { 96 noerror = TRUE; 97 ibuf += 7; 98 } else { 99 bb_error_msg_and_die(bb_msg_invalid_arg, argv[i]+5, "conv"); 111 /* And these are all zeroed at once! */ 112 struct { 113 int flags; 114 int ifd, ofd; 115 size_t oc; 116 off_t count; 117 off_t seek, skip; 118 const char *infile, *outfile; 119 #if ENABLE_FEATURE_DD_SIGNAL_HANDLING 120 struct sigaction sigact; 121 #endif 122 } Z; 123 #define flags (Z.flags ) 124 #define ifd (Z.ifd ) 125 #define ofd (Z.ofd ) 126 #define oc (Z.oc ) 127 #define count (Z.count ) 128 #define seek (Z.seek ) 129 #define skip (Z.skip ) 130 #define infile (Z.infile ) 131 #define outfile (Z.outfile) 132 #define sigact (Z.sigact ) 133 134 memset(&Z, 0, sizeof(Z)); 135 INIT_G(); 136 137 #if ENABLE_FEATURE_DD_SIGNAL_HANDLING 138 sigact.sa_handler = dd_output_status; 139 sigact.sa_flags = SA_RESTART; 140 sigemptyset(&sigact.sa_mask); 141 sigaction(SIGUSR1, &sigact, NULL); 142 #endif 143 144 for (n = 1; n < argc; n++) { 145 smalluint key_len; 146 smalluint what; 147 char *key; 148 char *arg = argv[n]; 149 150 //XXX:FIXME: we reject plain "dd --" This would cost ~20 bytes, so.. 151 //if (*arg == '-' && *++arg == '-' && !*++arg) continue; 152 key = strstr(arg, "="); 153 if (key == NULL) 154 bb_show_usage(); 155 key_len = key - arg + 1; 156 key = xstrndup(arg, key_len); 157 what = index_in_strings(keywords, key) + 1; 158 if (ENABLE_FEATURE_CLEAN_UP) 159 free(key); 160 if (what == 0) 161 bb_show_usage(); 162 arg += key_len; 163 /* Must fit into positive ssize_t */ 164 #if ENABLE_FEATURE_DD_IBS_OBS 165 if (what == OP_ibs) { 166 ibs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); 167 continue; 168 } 169 if (what == OP_obs) { 170 obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); 171 continue; 172 } 173 if (what == OP_conv) { 174 while (1) { 175 /* find ',', replace them with nil so we can use arg for 176 * index_in_strings() without copying. 177 * We rely on arg being non-null, else strchr would fault. 178 */ 179 key = strchr(arg, ','); 180 if (key) 181 *key = '\0'; 182 what = index_in_strings(keywords, arg) + 1; 183 if (what < OP_conv_notrunc) 184 bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv"); 185 if (what == OP_conv_notrunc) 186 flags |= FLAG_NOTRUNC; 187 if (what == OP_conv_sync) 188 flags |= FLAG_SYNC; 189 if (what == OP_conv_noerror) 190 flags |= FLAG_NOERROR; 191 if (!key) /* no ',' left, so this was the last specifier */ 192 break; 193 arg = key + 1; /* skip this keyword and ',' */ 100 194 } 101 if (ibuf[0] == '\0') break; 102 if (ibuf[0] == ',') ibuf++; 103 } 104 } else 105 bb_show_usage(); 106 } 107 ibuf = xmalloc(ibs); 108 109 if (twobufs_flag) obuf = xmalloc(obs); 110 else obuf = ibuf; 111 112 if (infile != NULL) { 113 ifd = bb_xopen(infile, O_RDONLY); 114 } else { 115 ifd = STDIN_FILENO; 195 continue; 196 } 197 #endif 198 if (what == OP_bs) { 199 ibs = obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); 200 continue; 201 } 202 /* These can be large: */ 203 if (what == OP_count) { 204 flags |= FLAG_COUNT; 205 count = XATOU_SFX(arg, dd_suffixes); 206 continue; 207 } 208 if (what == OP_seek) { 209 seek = XATOU_SFX(arg, dd_suffixes); 210 continue; 211 } 212 if (what == OP_skip) { 213 skip = XATOU_SFX(arg, dd_suffixes); 214 continue; 215 } 216 if (what == OP_if) { 217 infile = arg; 218 continue; 219 } 220 if (what == OP_of) 221 outfile = arg; 222 } 223 //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever 224 ibuf = obuf = xmalloc(ibs); 225 if (ibs != obs) { 226 flags |= FLAG_TWOBUFS; 227 obuf = xmalloc(obs); 228 } 229 if (infile != NULL) 230 ifd = xopen(infile, O_RDONLY); 231 else { 232 /* ifd = STDIN_FILENO; - it's zero and it's already there */ 116 233 infile = bb_msg_standard_input; 117 234 } 118 119 235 if (outfile != NULL) { 120 oflag = O_WRONLY | O_CREAT;121 122 if (!seek && trunc_flag) {236 int oflag = O_WRONLY | O_CREAT; 237 238 if (!seek && !(flags & FLAG_NOTRUNC)) 123 239 oflag |= O_TRUNC; 124 } 125 126 ofd = bb_xopen3(outfile, oflag, 0666); 127 128 if (seek && trunc_flag) { 240 241 ofd = xopen(outfile, oflag); 242 243 if (seek && !(flags & FLAG_NOTRUNC)) { 129 244 if (ftruncate(ofd, seek * obs) < 0) { 130 245 struct stat st; 131 246 132 if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) || 133 S_ISDIR (st.st_mode)) { 134 bb_perror_msg_and_die("%s", outfile); 135 } 247 if (fstat(ofd, &st) < 0 || S_ISREG(st.st_mode) || 248 S_ISDIR(st.st_mode)) 249 goto die_outfile; 136 250 } 137 251 } … … 140 254 outfile = bb_msg_standard_output; 141 255 } 142 143 256 if (skip) { 144 257 if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { … … 146 259 n = safe_read(ifd, ibuf, ibs); 147 260 if (n < 0) 148 bb_perror_msg_and_die("%s", infile);261 goto die_infile; 149 262 if (n == 0) 150 263 break; … … 152 265 } 153 266 } 154 155 267 if (seek) { 156 if (lseek(ofd, seek * obs, SEEK_CUR) < 0) { 157 bb_perror_msg_and_die("%s", outfile); 158 } 159 } 160 161 while (in_full + in_part != count) { 162 if (noerror) { 163 /* Pre-zero the buffer when doing the noerror thing */ 164 memset(ibuf, '\0', ibs); 165 } 166 268 if (lseek(ofd, seek * obs, SEEK_CUR) < 0) 269 goto die_outfile; 270 } 271 272 while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { 273 if (flags & FLAG_NOERROR) /* Pre-zero the buffer if conv=noerror */ 274 memset(ibuf, 0, ibs); 167 275 n = safe_read(ifd, ibuf, ibs); 168 if (n == 0) {276 if (n == 0) 169 277 break; 170 }171 278 if (n < 0) { 172 if ( noerror) {279 if (flags & FLAG_NOERROR) { 173 280 n = ibs; 174 281 bb_perror_msg("%s", infile); 175 } else { 176 bb_perror_msg_and_die("%s", infile); 177 } 178 } 179 if ((size_t)n == ibs) { 180 in_full++; 181 } else { 182 in_part++; 183 if (sync_flag) { 282 } else 283 goto die_infile; 284 } 285 if ((size_t)n == ibs) 286 G.in_full++; 287 else { 288 G.in_part++; 289 if (flags & FLAG_SYNC) { 184 290 memset(ibuf + n, '\0', ibs - n); 185 291 n = ibs; 186 292 } 187 293 } 188 if ( twobufs_flag) {294 if (flags & FLAG_TWOBUFS) { 189 295 char *tmp = ibuf; 190 296 while (n) { 191 297 size_t d = obs - oc; 192 298 193 if (d > n) d = n; 299 if (d > n) 300 d = n; 194 301 memcpy(obuf + oc, tmp, d); 195 302 n -= d; … … 197 304 oc += d; 198 305 if (oc == obs) { 199 if (bb_full_write(ofd, obuf, obs) < 0) { 200 bb_perror_msg_and_die("%s", outfile); 201 } 202 out_full++; 306 if (write_and_stats(ofd, obuf, obs, obs, outfile)) 307 goto out_status; 203 308 oc = 0; 204 309 } 205 310 } 206 } else { 207 if ((n = bb_full_write(ofd, ibuf, n)) < 0) { 208 bb_perror_msg_and_die("%s", outfile); 209 } 210 if (n == ibs) out_full++; 211 else out_part++; 212 } 213 } 214 311 } else if (write_and_stats(ofd, ibuf, n, obs, outfile)) 312 goto out_status; 313 } 314 215 315 if (ENABLE_FEATURE_DD_IBS_OBS && oc) { 216 if (bb_full_write(ofd, obuf, oc) < 0) { 217 bb_perror_msg_and_die("%s", outfile); 218 } 219 out_part++; 220 } 221 if (close (ifd) < 0) { 316 w = full_write_or_warn(ofd, obuf, oc, outfile); 317 if (w < 0) goto out_status; 318 if (w > 0) 319 G.out_part++; 320 } 321 if (close(ifd) < 0) { 322 die_infile: 222 323 bb_perror_msg_and_die("%s", infile); 223 324 } 224 325 225 if (close (ofd) < 0) { 326 if (close(ofd) < 0) { 327 die_outfile: 226 328 bb_perror_msg_and_die("%s", outfile); 227 329 } 228 330 out_status: 229 331 dd_output_status(0); 230 332 -
branches/2.2.5/mindi-busybox/coreutils/df.c
r821 r1765 19 19 */ 20 20 21 #include <stdio.h>22 #include <stdlib.h>23 #include <string.h>24 #include <unistd.h>25 21 #include <mntent.h> 26 22 #include <sys/vfs.h> 27 #include " busybox.h"23 #include "libbb.h" 28 24 29 #if ndef CONFIG_FEATURE_HUMAN_READABLE30 static long kscale(long b,long bs)25 #if !ENABLE_FEATURE_HUMAN_READABLE 26 static unsigned long kscale(unsigned long b, unsigned long bs) 31 27 { 32 return ( b * (long long) bs + KILOBYTE/2 ) / KILOBYTE;28 return (b * (unsigned long long) bs + 1024/2) / 1024; 33 29 } 34 30 #endif 35 31 32 int df_main(int argc, char **argv); 36 33 int df_main(int argc, char **argv) 37 34 { 38 long blocks_used;39 longblocks_percent_used;40 #if def CONFIG_FEATURE_HUMAN_READABLE41 unsigned long df_disp_hr = KILOBYTE;35 unsigned long blocks_used; 36 unsigned blocks_percent_used; 37 #if ENABLE_FEATURE_HUMAN_READABLE 38 unsigned df_disp_hr = 1024; 42 39 #endif 43 40 int status = EXIT_SUCCESS; 44 unsigned longopt;41 unsigned opt; 45 42 FILE *mount_table; 46 43 struct mntent *mount_entry; 47 44 struct statfs s; 48 static const char hdr_1k[] = "1k-blocks";/* default display is kilobytes */49 const char *disp_units_hdr = hdr_1k;45 /* default display is kilobytes */ 46 const char *disp_units_hdr = "1k-blocks"; 50 47 51 #if def CONFIG_FEATURE_HUMAN_READABLE52 bb_opt_complementally = "h-km:k-hm:m-hk";53 opt = bb_getopt_ulflags(argc,argv, "hmk");54 if (opt & 1) {55 56 48 #if ENABLE_FEATURE_HUMAN_READABLE 49 opt_complementary = "h-km:k-hm:m-hk"; 50 opt = getopt32(argv, "hmk"); 51 if (opt & 1) { 52 df_disp_hr = 0; 53 disp_units_hdr = " Size"; 57 54 } 58 if (opt & 2) {59 df_disp_hr = MEGABYTE;60 55 if (opt & 2) { 56 df_disp_hr = 1024*1024; 57 disp_units_hdr = "1M-blocks"; 61 58 } 62 59 #else 63 opt = bb_getopt_ulflags(argc,argv, "k");60 opt = getopt32(argv, "k"); 64 61 #endif 65 62 66 bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n",63 printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n", 67 64 "", disp_units_hdr); 68 65 … … 70 67 argv += optind; 71 68 if (optind >= argc) { 72 if (!(mount_table = setmntent(bb_path_mtab_file, "r"))) { 69 mount_table = setmntent(bb_path_mtab_file, "r"); 70 if (!mount_table) { 73 71 bb_perror_msg_and_die(bb_path_mtab_file); 74 72 } 75 73 } 76 74 77 do{75 while (1) { 78 76 const char *device; 79 77 const char *mount_point; 80 78 81 79 if (mount_table) { 82 if (!(mount_entry = getmntent(mount_table))) { 80 mount_entry = getmntent(mount_table); 81 if (!mount_entry) { 83 82 endmntent(mount_table); 84 83 break; 85 84 } 86 85 } else { 87 if (!(mount_point = *argv++)) { 86 mount_point = *argv++; 87 if (!mount_point) { 88 88 break; 89 89 } 90 if (!(mount_entry = find_mount_point(mount_point, bb_path_mtab_file))) { 91 bb_error_msg("%s: can't find mount point.", mount_point); 92 SET_ERROR: 90 mount_entry = find_mount_point(mount_point, bb_path_mtab_file); 91 if (!mount_entry) { 92 bb_error_msg("%s: can't find mount point", mount_point); 93 SET_ERROR: 93 94 status = EXIT_FAILURE; 94 95 continue; … … 108 109 blocks_percent_used = 0; 109 110 if (blocks_used + s.f_bavail) { 110 blocks_percent_used = ( ((long long) blocks_used) * 100111 112 111 blocks_percent_used = (blocks_used * 100ULL 112 + (blocks_used + s.f_bavail)/2 113 ) / (blocks_used + s.f_bavail); 113 114 } 114 115 … … 118 119 /* Adjusts device to be the real root device, 119 120 * or leaves device alone if it can't find it */ 120 if ((device = find_block_device("/")) == NULL) { 121 device = find_block_device("/"); 122 if (!device) { 121 123 goto SET_ERROR; 122 124 } 123 125 } 124 126 125 #ifdef CONFIG_FEATURE_HUMAN_READABLE 126 bb_printf("%-20s %9s ", device, 127 make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); 127 if (printf("\n%-20s" + 1, device) > 20) 128 printf("\n%-20s", ""); 129 #if ENABLE_FEATURE_HUMAN_READABLE 130 printf(" %9s ", 131 make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); 128 132 129 bb_printf("%9s ",130 make_human_readable_str((s.f_blocks - s.f_bfree),131 133 printf(" %9s " + 1, 134 make_human_readable_str((s.f_blocks - s.f_bfree), 135 s.f_bsize, df_disp_hr)); 132 136 133 bb_printf("%9s %3ld%% %s\n",134 135 137 printf("%9s %3u%% %s\n", 138 make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), 139 blocks_percent_used, mount_point); 136 140 #else 137 bb_printf("%-20s %9ld %9ld %9ld %3ld%% %s\n", 138 device, 139 kscale(s.f_blocks, s.f_bsize), 140 kscale(s.f_blocks-s.f_bfree, s.f_bsize), 141 kscale(s.f_bavail, s.f_bsize), 142 blocks_percent_used, mount_point); 141 printf(" %9lu %9lu %9lu %3u%% %s\n", 142 kscale(s.f_blocks, s.f_bsize), 143 kscale(s.f_blocks-s.f_bfree, s.f_bsize), 144 kscale(s.f_bavail, s.f_bsize), 145 blocks_percent_used, mount_point); 143 146 #endif 144 147 } 148 } 145 149 146 } while (1); 147 148 bb_fflush_stdout_and_exit(status); 150 fflush_stdout_and_exit(status); 149 151 } -
branches/2.2.5/mindi-busybox/coreutils/dirname.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */ 25 12 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include "busybox.h" 13 #include "libbb.h" 29 14 15 /* This is a NOFORK applet. Be very careful! */ 16 17 int dirname_main(int argc, char **argv); 30 18 int dirname_main(int argc, char **argv) 31 19 { … … 36 24 puts(dirname(argv[1])); 37 25 38 bb_fflush_stdout_and_exit(EXIT_SUCCESS);26 return fflush(stdout); 39 27 } -
branches/2.2.5/mindi-busybox/coreutils/dos2unix.c
r821 r1765 13 13 */ 14 14 15 #include <string.h> 16 #include <unistd.h> 17 #include <stdint.h> 18 #include <fcntl.h> 19 #include "busybox.h" 15 #include "libbb.h" 20 16 21 enum ConvType{17 enum { 22 18 CT_UNIX2DOS = 1, 23 19 CT_DOS2UNIX 24 } ConvType;20 }; 25 21 26 22 /* if fn is NULL then input is stdin and output is stdout */ 27 static int convert(char *fn )23 static int convert(char *fn, int conv_type) 28 24 { 29 25 FILE *in, *out; 30 26 int i; 27 #define name_buf bb_common_bufsiz1 31 28 29 in = stdin; 30 out = stdout; 32 31 if (fn != NULL) { 33 in = bb_xfopen(fn, "rw");32 in = xfopen(fn, "rw"); 34 33 /* 35 34 The file is then created with mode read/write and 36 35 permissions 0666 for glibc 2.0.6 and earlier or 37 0600 for glibc 2.0.7 andlater.36 0600 for glibc 2.0.7 and later. 38 37 */ 39 snprintf(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), "%sXXXXXX", fn); 40 /* 41 sizeof bb_common_bufsiz1 is 4096, so it should be big enough to 42 hold the full path. However if the output is truncated the 43 subsequent call to mkstemp would fail. 44 */ 45 if ((i = mkstemp(&bb_common_bufsiz1[0])) == -1 46 || chmod(bb_common_bufsiz1, 0600) == -1) { 38 snprintf(name_buf, sizeof(name_buf), "%sXXXXXX", fn); 39 i = mkstemp(&name_buf[0]); 40 if (i == -1 || chmod(name_buf, 0600) == -1) { 47 41 bb_perror_nomsg_and_die(); 48 42 } … … 50 44 if (!out) { 51 45 close(i); 52 remove(bb_common_bufsiz1); 46 remove(name_buf); 47 return -2; 53 48 } 54 } else {55 in = stdin;56 out = stdout;57 49 } 58 50 … … 61 53 continue; 62 54 if (i == '\n') { 63 if ( ConvType == CT_UNIX2DOS)55 if (conv_type == CT_UNIX2DOS) 64 56 fputc('\r', out); 65 57 fputc('\n', out); … … 72 64 if (fclose(in) < 0 || fclose(out) < 0) { 73 65 bb_perror_nomsg(); 74 remove( bb_common_bufsiz1);66 remove(name_buf); 75 67 return -2; 76 68 } … … 78 70 * should be true since we put them into the same directory 79 71 * so we _should_ be ok, but you never know... */ 80 if (rename( bb_common_bufsiz1, fn) < 0) {81 bb_perror_msg("cannot rename '%s' as '%s'", bb_common_bufsiz1, fn);72 if (rename(name_buf, fn) < 0) { 73 bb_perror_msg("cannot rename '%s' as '%s'", name_buf, fn); 82 74 return -1; 83 75 } … … 87 79 } 88 80 89 int dos2unix_main(int argc, char *argv[]) 81 int dos2unix_main(int argc, char **argv); 82 int dos2unix_main(int argc, char **argv) 90 83 { 91 int o ;84 int o, conv_type; 92 85 93 86 /* See if we are supposed to be doing dos2unix or unix2dos */ 94 if ( bb_applet_name[0] == 'd') {95 ConvType = CT_DOS2UNIX; /*2 */87 if (applet_name[0] == 'd') { 88 conv_type = CT_DOS2UNIX; /* 2 */ 96 89 } else { 97 ConvType = CT_UNIX2DOS; /*1 */90 conv_type = CT_UNIX2DOS; /* 1 */ 98 91 } 99 /* -u and -d are mutally exclusive */ 100 bb_opt_complementally = "?:u--d:d--u"; 101 /* process parameters */ 102 /* -u convert to unix */ 103 /* -d convert to dos */ 104 o = bb_getopt_ulflags(argc, argv, "du"); 92 93 /* -u convert to unix, -d convert to dos */ 94 opt_complementary = "u--d:d--u"; /* mutually exclusive */ 95 o = getopt32(argv, "du"); 105 96 106 97 /* Do the conversion requested by an argument else do the default 107 98 * conversion depending on our name. */ 108 99 if (o) 109 ConvType = o;100 conv_type = o; 110 101 111 if (optind < argc) { 112 while (optind < argc) 113 if ((o = convert(argv[optind++])) < 0) 114 break; 115 } else 116 o = convert(NULL); 102 do { 103 /* might be convert(NULL) if there is no filename given */ 104 o = convert(argv[optind], conv_type); 105 if (o < 0) 106 break; 107 optind++; 108 } while (optind < argc); 117 109 118 110 return o; -
branches/2.2.5/mindi-busybox/coreutils/du.c
r821 r1765 24 24 */ 25 25 26 #include <stdlib.h> 27 #include <limits.h> 28 #include <unistd.h> 29 #include <dirent.h> 30 #include <sys/stat.h> 31 #include "busybox.h" 32 33 #ifdef CONFIG_FEATURE_HUMAN_READABLE 34 # ifdef CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 35 static unsigned long disp_hr = KILOBYTE; 26 #include "libbb.h" 27 28 #if ENABLE_FEATURE_HUMAN_READABLE 29 # if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 30 static unsigned long disp_hr = 1024; 36 31 # else 37 32 static unsigned long disp_hr = 512; 38 33 # endif 39 #elif defined CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K40 static unsigned intdisp_k = 1;41 #else 42 static unsigned intdisp_k; /* bss inits to 0 */34 #elif ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 35 static unsigned disp_k = 1; 36 #else 37 static unsigned disp_k; /* bss inits to 0 */ 43 38 #endif 44 39 … … 46 41 static nlink_t count_hardlinks = 1; 47 42 48 static int status 49 #if EXIT_SUCCESS == 0 50 = EXIT_SUCCESS 51 #endif 52 ; 43 static int status; 53 44 static int print_files; 54 45 static int slink_depth; … … 58 49 59 50 60 static void print(long size, c har *filename)51 static void print(long size, const char *const filename) 61 52 { 62 53 /* TODO - May not want to defer error checking here. */ 63 #if def CONFIG_FEATURE_HUMAN_READABLE64 bb_printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr),65 54 #if ENABLE_FEATURE_HUMAN_READABLE 55 printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr), 56 filename); 66 57 #else 67 58 if (disp_k) { … … 69 60 size >>= 1; 70 61 } 71 bb_printf("%ld\t%s\n", size, filename);62 printf("%ld\t%s\n", size, filename); 72 63 #endif 73 64 } 74 65 75 66 /* tiny recursive du */ 76 static long du(c har *filename)67 static long du(const char *const filename) 77 68 { 78 69 struct stat statbuf; 79 70 long sum; 80 71 81 if ( (lstat(filename, &statbuf)) != 0) {72 if (lstat(filename, &statbuf) != 0) { 82 73 bb_perror_msg("%s", filename); 83 74 status = EXIT_FAILURE; … … 97 88 if (S_ISLNK(statbuf.st_mode)) { 98 89 if (slink_depth > du_depth) { /* -H or -L */ 99 if ( (stat(filename, &statbuf)) != 0) {90 if (stat(filename, &statbuf) != 0) { 100 91 bb_perror_msg("%s", filename); 101 92 status = EXIT_FAILURE; … … 111 102 if (statbuf.st_nlink > count_hardlinks) { 112 103 /* Add files/directories with links only once */ 113 if (is_in_ino_dev_hashtable(&statbuf , NULL)) {104 if (is_in_ino_dev_hashtable(&statbuf)) { 114 105 return 0; 115 106 } … … 122 113 char *newfile; 123 114 124 dir = bb_opendir(filename);115 dir = warn_opendir(filename); 125 116 if (!dir) { 126 117 status = EXIT_FAILURE; … … 136 127 137 128 newfile = concat_subpath_file(filename, name); 138 if (newfile == NULL)129 if (newfile == NULL) 139 130 continue; 140 131 ++du_depth; … … 153 144 } 154 145 146 int du_main(int argc, char **argv); 155 147 int du_main(int argc, char **argv) 156 148 { … … 159 151 int print_final_total; 160 152 char *smax_print_depth; 161 unsigned longopt;162 163 #if def CONFIG_FEATURE_DU_DEFUALT_BLOCKSIZE_1K153 unsigned opt; 154 155 #if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 164 156 if (getenv("POSIXLY_CORRECT")) { /* TODO - a new libbb function? */ 165 #if def CONFIG_FEATURE_HUMAN_READABLE157 #if ENABLE_FEATURE_HUMAN_READABLE 166 158 disp_hr = 512; 167 159 #else … … 171 163 #endif 172 164 173 /* Note: SUSv3 specifies that -a and -s options can 165 /* Note: SUSv3 specifies that -a and -s options cannot be used together 174 166 * in strictly conforming applications. However, it also says that some 175 167 * du implementations may produce output when -a and -s are used together. … … 177 169 * ignore -a. This is consistent with -s being equivalent to -d 0. 178 170 */ 179 #if def CONFIG_FEATURE_HUMAN_READABLE180 bb_opt_complementally = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s";181 opt = bb_getopt_ulflags(argc,argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth);182 if ((opt & (1 << 9))) {171 #if ENABLE_FEATURE_HUMAN_READABLE 172 opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; 173 opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &smax_print_depth); 174 if (opt & (1 << 9)) { 183 175 /* -h opt */ 184 176 disp_hr = 0; 185 177 } 186 if ((opt & (1 << 10))) {178 if (opt & (1 << 10)) { 187 179 /* -m opt */ 188 disp_hr = MEGABYTE;189 } 190 if ((opt & (1 << 2))) {180 disp_hr = 1024*1024; 181 } 182 if (opt & (1 << 2)) { 191 183 /* -k opt */ 192 disp_hr = KILOBYTE;193 } 194 #else 195 bb_opt_complementally = "H-L:L-H:s-d:d-s";196 opt = bb_getopt_ulflags(argc,argv, "aHkLsx" "d:" "lc", &smax_print_depth);197 #if ! defined CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K198 if ((opt & (1 << 2))) {184 disp_hr = 1024; 185 } 186 #else 187 opt_complementary = "H-L:L-H:s-d:d-s"; 188 opt = getopt32(argv, "aHkLsx" "d:" "lc", &smax_print_depth); 189 #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K 190 if (opt & (1 << 2)) { 199 191 /* -k opt */ 200 201 } 202 #endif 203 #endif 204 if ((opt & (1 << 0))) {192 disp_k = 1; 193 } 194 #endif 195 #endif 196 if (opt & (1 << 0)) { 205 197 /* -a opt */ 206 198 print_files = INT_MAX; 207 199 } 208 if ((opt & (1 << 1))) {200 if (opt & (1 << 1)) { 209 201 /* -H opt */ 210 202 slink_depth = 1; 211 203 } 212 if ((opt & (1 << 3))) {204 if (opt & (1 << 3)) { 213 205 /* -L opt */ 214 215 } 216 if ((opt & (1 << 4))) {206 slink_depth = INT_MAX; 207 } 208 if (opt & (1 << 4)) { 217 209 /* -s opt */ 218 219 210 max_print_depth = 0; 211 } 220 212 one_file_system = opt & (1 << 5); /* -x opt */ 221 if ((opt & (1 << 6))) {213 if (opt & (1 << 6)) { 222 214 /* -d opt */ 223 max_print_depth = bb_xgetularg10_bnd(smax_print_depth, 0, INT_MAX);224 } 225 if ((opt & (1 << 7))) {215 max_print_depth = xatoi_u(smax_print_depth); 216 } 217 if (opt & (1 << 7)) { 226 218 /* -l opt */ 227 count_hardlinks = INT_MAX;219 count_hardlinks = MAXINT(nlink_t); 228 220 } 229 221 print_final_total = opt & (1 << 8); /* -c opt */ … … 232 224 argv += optind; 233 225 if (optind >= argc) { 234 *--argv = ".";226 *--argv = (char*)"."; 235 227 if (slink_depth == 1) { 236 228 slink_depth = 0; … … 244 236 slink_depth = slink_depth_save; 245 237 } while (*++argv); 246 #ifdef CONFIG_FEATURE_CLEAN_UP 247 reset_ino_dev_hashtable(); 248 #endif 249 238 if (ENABLE_FEATURE_CLEAN_UP) 239 reset_ino_dev_hashtable(); 250 240 if (print_final_total) { 251 241 print(total, "total"); 252 242 } 253 243 254 bb_fflush_stdout_and_exit(status);244 fflush_stdout_and_exit(status); 255 245 } -
branches/2.2.5/mindi-busybox/coreutils/echo.c
r821 r1765 21 21 * trailing newline. SUSv3 specifies _no_ output after '\c'. 22 22 * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}. 23 * The previous version versiondid not allow 4-digit octals.23 * The previous version did not allow 4-digit octals. 24 24 */ 25 25 26 #include "libbb.h" 26 27 27 #include <stdio.h> 28 #include <string.h> 29 #include <stdlib.h> 30 #include "busybox.h" 31 32 int bb_echo(int ATTRIBUTE_UNUSED argc, char **argv) 28 int bb_echo(char **argv) 33 29 { 34 #ifndef CONFIG_FEATURE_FANCY_ECHO 35 #define eflag '\\' 36 ++argv; 30 const char *arg; 31 #if !ENABLE_FEATURE_FANCY_ECHO 32 enum { 33 eflag = '\\', 34 nflag = 1, /* 1 -- print '\n' */ 35 }; 36 arg = *++argv; 37 if (!arg) 38 goto newline_ret; 37 39 #else 38 40 const char *p; 39 intnflag = 1;40 inteflag = 0;41 char nflag = 1; 42 char eflag = 0; 41 43 42 while (*++argv && (**argv == '-')) { 44 while (1) { 45 arg = *++argv; 46 if (!arg) 47 goto newline_ret; 48 if (*arg != '-') 49 break; 50 43 51 /* If it appears that we are handling options, then make sure 44 52 * that all of the options specified are actually valid. 45 53 * Otherwise, the string should just be echoed. 46 54 */ 47 48 if (!* (p = *argv + 1)) {/* A single '-', so echo it. */55 p = arg + 1; 56 if (!*p) /* A single '-', so echo it. */ 49 57 goto just_echo; 50 }51 58 52 59 do { 53 if ( strrchr("neE", *p) == 0) {60 if (!strrchr("neE", *p)) 54 61 goto just_echo; 55 }56 62 } while (*++p); 57 63 58 64 /* All of the options in this arg are valid, so handle them. */ 59 p = *argv+ 1;65 p = arg + 1; 60 66 do { 61 if (*p == 'n') {67 if (*p == 'n') 62 68 nflag = 0; 63 } else if (*p == 'e') {69 if (*p == 'e') 64 70 eflag = '\\'; 65 } else {66 eflag = 0;67 }68 71 } while (*++p); 69 72 } 73 just_echo: 74 #endif 75 while (1) { 76 /* arg is already == *argv and isn't NULL */ 77 int c; 70 78 71 just_echo: 72 #endif 73 while (*argv) { 74 register int c; 75 76 while ((c = *(*argv)++)) { 79 if (!eflag) { 80 /* optimization for very common case */ 81 fputs(arg, stdout); 82 } else while ((c = *arg++)) { 77 83 if (c == eflag) { /* Check for escape seq. */ 78 if (* *argv== 'c') {84 if (*arg == 'c') { 79 85 /* '\c' means cancel newline and 80 86 * ignore all subsequent chars. */ 81 return 0;87 goto ret; 82 88 } 83 #if ndef CONFIG_FEATURE_FANCY_ECHO89 #if !ENABLE_FEATURE_FANCY_ECHO 84 90 /* SUSv3 specifies that octal escapes must begin with '0'. */ 85 if ( ((unsigned int)(**argv - '1')) >= 7)91 if ( (((unsigned char)*arg) - '1') >= 7) 86 92 #endif 87 93 { 88 94 /* Since SUSv3 mandates a first digit of 0, 4-digit octals 89 95 * of the form \0### are accepted. */ 90 if ( (**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) {91 (*argv)++;96 if (*arg == '0' && ((unsigned char)(arg[1]) - '0') < 8) { 97 arg++; 92 98 } 93 99 /* bb_process_escape_sequence can handle nul correctly */ 94 c = bb_process_escape_sequence( (const char **) argv);100 c = bb_process_escape_sequence(&arg); 95 101 } 96 102 } … … 98 104 } 99 105 100 if (*++argv) { 101 putchar(' '); 102 } 106 arg = *++argv; 107 if (!arg) 108 break; 109 putchar(' '); 103 110 } 104 111 105 #ifdef CONFIG_FEATURE_FANCY_ECHO 112 newline_ret: 106 113 if (nflag) { 107 114 putchar('\n'); 108 115 } 109 #else 110 putchar('\n'); 111 #endif 112 return 0; 116 ret: 117 return fflush(stdout); 113 118 } 114 119 120 /* This is a NOFORK applet. Be very careful! */ 121 122 int echo_main(int argc, char** argv); 115 123 int echo_main(int argc, char** argv) 116 124 { 117 (void)bb_echo(argc, argv); 118 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 125 return bb_echo(argv); 119 126 } 120 127 -
branches/2.2.5/mindi-busybox/coreutils/env.c
r821 r1765 6 6 * The Regents of the University of California. All rights reserved. 7 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 9 * 22 10 * Original copyright notice is retained at the end of this file. … … 39 27 * - multiple "-u unsetenv" support 40 28 * - GNU long option support 41 * - use bb_default_error_retval29 * - use xfunc_error_retval 42 30 */ 43 31 32 #include <getopt.h> /* struct option */ 33 extern char **environ; 44 34 45 #include <stdio.h> 46 #include <string.h> 47 #include <stdlib.h> 48 #include <errno.h> 49 #include <unistd.h> 50 #include <getopt.h> /* struct option */ 51 #include "busybox.h" 35 #include "libbb.h" 52 36 53 37 #if ENABLE_FEATURE_ENV_LONG_OPTIONS 54 static const struct option env_long_options[] = { 55 { "ignore-environment", 0, NULL, 'i' }, 56 { "unset", 1, NULL, 'u' }, 57 { 0, 0, 0, 0 } 58 }; 38 static const char env_longopts[] ALIGN1 = 39 "ignore-environment\0" No_argument "i" 40 "unset\0" Required_argument "u" 41 ; 59 42 #endif 60 43 44 int env_main(int argc, char** argv); 61 45 int env_main(int argc, char** argv) 62 46 { 63 static char *cleanenv[1] = { NULL }; 47 /* cleanenv was static - why? */ 48 char *cleanenv[1]; 49 char **ep; 50 unsigned opt; 51 llist_t *unset_env = NULL; 64 52 65 char **ep, *p; 66 unsigned long opt; 67 llist_t *unset_env = NULL; 68 extern char **environ; 69 70 bb_opt_complementally = "u::"; 53 opt_complementary = "u::"; 71 54 #if ENABLE_FEATURE_ENV_LONG_OPTIONS 72 bb_applet_long_options = env_long_options;55 applet_long_options = env_longopts; 73 56 #endif 74 75 opt = bb_getopt_ulflags(argc, argv, "+iu:", &unset_env); 76 57 opt = getopt32(argv, "+iu:", &unset_env); 77 58 argv += optind; 78 if (*argv && (argv[0][0] == '-') && !argv[0][1]) {59 if (*argv && LONE_DASH(argv[0])) { 79 60 opt |= 1; 80 61 ++argv; 81 62 } 82 83 if(opt & 1)63 if (opt & 1) { 64 cleanenv[0] = NULL; 84 65 environ = cleanenv; 85 else if(opt & 2){86 while (unset_env) {66 } else { 67 while (unset_env) { 87 68 unsetenv(unset_env->data); 88 69 unset_env = unset_env->link; … … 90 71 } 91 72 92 while (*argv && ( (p = strchr(*argv, '=')) != NULL)) {73 while (*argv && (strchr(*argv, '=') != NULL)) { 93 74 if (putenv(*argv) < 0) { 94 75 bb_perror_msg_and_die("putenv"); … … 98 79 99 80 if (*argv) { 100 execvp(*argv, argv);81 BB_EXECVP(*argv, argv); 101 82 /* SUSv3-mandated exit codes. */ 102 bb_default_error_retval = (errno == ENOENT) ? 127 : 126;83 xfunc_error_retval = (errno == ENOENT) ? 127 : 126; 103 84 bb_perror_msg_and_die("%s", *argv); 104 85 } … … 108 89 } 109 90 110 bb_fflush_stdout_and_exit(0);91 fflush_stdout_and_exit(0); 111 92 } 112 93 -
branches/2.2.5/mindi-busybox/coreutils/expr.c
r821 r1765 12 12 * - 64 math support 13 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, write to the Free Software 26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27 * 14 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 28 15 */ 29 16 … … 39 26 /* no getopt needed */ 40 27 41 #include <stdio.h> 42 #include <string.h> 43 #include <stdlib.h> 44 #include <regex.h> 45 #include <sys/types.h> 46 #include <errno.h> 47 #include "busybox.h" 48 28 #include "libbb.h" 29 #include "xregex.h" 49 30 50 31 /* The kinds of value we can have. */ … … 57 38 #if ENABLE_EXPR_MATH_SUPPORT_64 58 39 typedef int64_t arith_t; 40 59 41 #define PF_REZ "ll" 60 42 #define PF_REZ_TYPE (long long) … … 62 44 #else 63 45 typedef long arith_t; 46 64 47 #define PF_REZ "l" 65 48 #define PF_REZ_TYPE (long) … … 67 50 #endif 68 51 52 /* TODO: use bb_strtol[l]? It's easier to check for errors... */ 53 69 54 /* A value is.... */ 70 55 struct valinfo { 71 TYPE type; 72 union { 56 TYPE type; /* Which kind. */ 57 union { /* The value itself. */ 73 58 arith_t i; 74 59 char *s; … … 78 63 79 64 /* The arguments given to the program, minus the program name. */ 80 static char **args; 81 82 static VALUE *docolon (VALUE *sv, VALUE *pv); 83 static VALUE *eval (void); 84 static VALUE *int_value (arith_t i); 85 static VALUE *str_value (char *s); 86 static int nextarg (char *str); 87 static int null (VALUE *v); 88 static int toarith (VALUE *v); 89 static void freev (VALUE *v); 90 static void tostring (VALUE *v); 91 92 int expr_main (int argc, char **argv) 65 struct globals { 66 char **args; 67 }; 68 #define G (*(struct globals*)&bb_common_bufsiz1) 69 70 /* forward declarations */ 71 static VALUE *eval(void); 72 73 74 /* Return a VALUE for I. */ 75 76 static VALUE *int_value(arith_t i) 93 77 { 94 78 VALUE *v; 95 79 96 if (argc == 1) { 97 bb_error_msg_and_die("too few arguments"); 98 } 99 100 args = argv + 1; 101 102 v = eval (); 103 if (*args) 104 bb_error_msg_and_die ("syntax error"); 105 106 if (v->type == integer) 107 printf ("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); 108 else 109 puts (v->u.s); 110 111 exit (null (v)); 112 } 113 114 /* Return a VALUE for I. */ 115 116 static VALUE *int_value (arith_t i) 117 { 118 VALUE *v; 119 120 v = xmalloc (sizeof(VALUE)); 80 v = xmalloc(sizeof(VALUE)); 121 81 v->type = integer; 122 82 v->u.i = i; … … 126 86 /* Return a VALUE for S. */ 127 87 128 static VALUE *str_value (char *s)88 static VALUE *str_value(const char *s) 129 89 { 130 90 VALUE *v; 131 91 132 v = xmalloc 92 v = xmalloc(sizeof(VALUE)); 133 93 v->type = string; 134 v->u.s = bb_xstrdup(s);94 v->u.s = xstrdup(s); 135 95 return v; 136 96 } … … 138 98 /* Free VALUE V, including structure components. */ 139 99 140 static void freev (VALUE *v)100 static void freev(VALUE * v) 141 101 { 142 102 if (v->type == string) 143 free 144 free 103 free(v->u.s); 104 free(v); 145 105 } 146 106 147 107 /* Return nonzero if V is a null-string or zero-number. */ 148 108 149 static int null (VALUE *v) 150 { 151 switch (v->type) { 152 case integer: 153 return v->u.i == 0; 154 default: /* string: */ 155 return v->u.s[0] == '\0' || strcmp (v->u.s, "0") == 0; 156 } 109 static int null(VALUE * v) 110 { 111 if (v->type == integer) 112 return v->u.i == 0; 113 /* string: */ 114 return v->u.s[0] == '\0' || LONE_CHAR(v->u.s, '0'); 157 115 } 158 116 159 117 /* Coerce V to a string value (can't fail). */ 160 118 161 static void tostring (VALUE *v)119 static void tostring(VALUE * v) 162 120 { 163 121 if (v->type == integer) { 164 v->u.s = bb_xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i);122 v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); 165 123 v->type = string; 166 124 } … … 169 127 /* Coerce V to an integer value. Return 1 on success, 0 on failure. */ 170 128 171 static int toarith (VALUE *v)172 { 173 if (v->type == string) {129 static bool toarith(VALUE * v) 130 { 131 if (v->type == string) { 174 132 arith_t i; 175 133 char *e; … … 180 138 if ((v->u.s == e) || *e) 181 139 return 0; 182 free 140 free(v->u.s); 183 141 v->u.i = i; 184 142 v->type = integer; … … 190 148 STR must not be NULL. */ 191 149 192 static int 193 nextarg (char *str) 194 { 195 if (*args == NULL) 150 static bool nextarg(const char *str) 151 { 152 if (*G.args == NULL) 196 153 return 0; 197 return strcmp (*args, str) == 0;154 return strcmp(*G.args, str) == 0; 198 155 } 199 156 200 157 /* The comparison operator handling functions. */ 201 158 202 static int cmp_common (VALUE *l, VALUE *r, int op)159 static int cmp_common(VALUE * l, VALUE * r, int op) 203 160 { 204 161 int cmpval; 205 162 206 163 if (l->type == string || r->type == string) { 207 tostring (l); 208 tostring (r); 209 cmpval = strcmp (l->u.s, r->u.s); 210 } 164 tostring(l); 165 tostring(r); 166 cmpval = strcmp(l->u.s, r->u.s); 167 } else 168 cmpval = l->u.i - r->u.i; 169 if (op == '<') 170 return cmpval < 0; 171 if (op == ('L' + 'E')) 172 return cmpval <= 0; 173 if (op == '=') 174 return cmpval == 0; 175 if (op == '!') 176 return cmpval != 0; 177 if (op == '>') 178 return cmpval > 0; 179 /* >= */ 180 return cmpval >= 0; 181 } 182 183 /* The arithmetic operator handling functions. */ 184 185 static arith_t arithmetic_common(VALUE * l, VALUE * r, int op) 186 { 187 arith_t li, ri; 188 189 if (!toarith(l) || !toarith(r)) 190 bb_error_msg_and_die("non-numeric argument"); 191 li = l->u.i; 192 ri = r->u.i; 193 if ((op == '/' || op == '%') && ri == 0) 194 bb_error_msg_and_die("division by zero"); 195 if (op == '+') 196 return li + ri; 197 else if (op == '-') 198 return li - ri; 199 else if (op == '*') 200 return li * ri; 201 else if (op == '/') 202 return li / ri; 211 203 else 212 cmpval = l->u.i - r->u.i;213 switch(op) {214 case '<':215 return cmpval < 0;216 case ('L'+'E'):217 return cmpval <= 0;218 case '=':219 return cmpval == 0;220 case '!':221 return cmpval != 0;222 case '>':223 return cmpval > 0;224 default: /* >= */225 return cmpval >= 0;226 }227 }228 229 /* The arithmetic operator handling functions. */230 231 static arith_t arithmetic_common (VALUE *l, VALUE *r, int op)232 {233 arith_t li, ri;234 235 if (!toarith (l) || !toarith (r))236 bb_error_msg_and_die ("non-numeric argument");237 li = l->u.i;238 ri = r->u.i;239 if((op == '/' || op == '%') && ri == 0)240 bb_error_msg_and_die ( "division by zero");241 switch(op) {242 case '+':243 return li + ri;244 case '-':245 return li - ri;246 case '*':247 return li * ri;248 case '/':249 return li / ri;250 default:251 204 return li % ri; 252 }253 205 } 254 206 … … 257 209 PV is the VALUE for the rhs (the pattern). */ 258 210 259 static VALUE *docolon (VALUE *sv, VALUE *pv)211 static VALUE *docolon(VALUE * sv, VALUE * pv) 260 212 { 261 213 VALUE *v; … … 264 216 regmatch_t re_regs[NMATCH]; 265 217 266 tostring 267 tostring 218 tostring(sv); 219 tostring(pv); 268 220 269 221 if (pv->u.s[0] == '^') { 270 fprintf (stderr,"\222 bb_error_msg("\ 271 223 warning: unportable BRE: `%s': using `^' as the first character\n\ 272 of a basic regular expression is not portable; it is being ignored", 273 pv->u.s); 274 } 275 276 memset (&re_buffer, 0, sizeof (re_buffer)); 277 memset (re_regs, 0, sizeof (*re_regs)); 278 if( regcomp (&re_buffer, pv->u.s, 0) != 0 ) 279 bb_error_msg_and_die("Invalid regular expression"); 224 of a basic regular expression is not portable; it is being ignored", pv->u.s); 225 } 226 227 memset(&re_buffer, 0, sizeof(re_buffer)); 228 memset(re_regs, 0, sizeof(*re_regs)); 229 xregcomp(&re_buffer, pv->u.s, 0); 280 230 281 231 /* expr uses an anchored pattern match, so check that there was a 282 232 * match and that the match starts at offset 0. */ 283 if (regexec 284 233 if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && 234 re_regs[0].rm_so == 0) { 285 235 /* Were \(...\) used? */ 286 236 if (re_buffer.re_nsub > 0) { 287 237 sv->u.s[re_regs[1].rm_eo] = '\0'; 288 v = str_value (sv->u.s + re_regs[1].rm_so); 289 } 290 else 291 v = int_value (re_regs[0].rm_eo); 292 } 293 else { 238 v = str_value(sv->u.s + re_regs[1].rm_so); 239 } else 240 v = int_value(re_regs[0].rm_eo); 241 } else { 294 242 /* Match failed -- return the right kind of null. */ 295 243 if (re_buffer.re_nsub > 0) 296 v = str_value 244 v = str_value(""); 297 245 else 298 v = int_value (0); 299 } 246 v = int_value(0); 247 } 248 //FIXME: sounds like here is a bit missing: regfree(&re_buffer); 300 249 return v; 301 250 } … … 303 252 /* Handle bare operands and ( expr ) syntax. */ 304 253 305 static VALUE *eval7 254 static VALUE *eval7(void) 306 255 { 307 256 VALUE *v; 308 257 309 if (!*args) 310 bb_error_msg_and_die ( "syntax error"); 311 312 if (nextarg ("(")) { 313 args++; 314 v = eval (); 315 if (!nextarg (")")) 316 bb_error_msg_and_die ( "syntax error"); 317 args++; 318 return v; 258 if (!*G.args) 259 bb_error_msg_and_die("syntax error"); 260 261 if (nextarg("(")) { 262 G.args++; 263 v = eval(); 264 if (!nextarg(")")) 265 bb_error_msg_and_die("syntax error"); 266 G.args++; 267 return v; 268 } 269 270 if (nextarg(")")) 271 bb_error_msg_and_die("syntax error"); 272 273 return str_value(*G.args++); 274 } 275 276 /* Handle match, substr, index, length, and quote keywords. */ 277 278 static VALUE *eval6(void) 279 { 280 static const char keywords[] ALIGN1 = 281 "quote\0""length\0""match\0""index\0""substr\0"; 282 283 VALUE *r, *i1, *i2; 284 VALUE *l = l; /* silence gcc */ 285 VALUE *v = v; /* silence gcc */ 286 int key = *G.args ? index_in_strings(keywords, *G.args) + 1 : 0; 287 288 if (key == 0) /* not a keyword */ 289 return eval7(); 290 G.args++; /* We have a valid token, so get the next argument. */ 291 if (key == 1) { /* quote */ 292 if (!*G.args) 293 bb_error_msg_and_die("syntax error"); 294 return str_value(*G.args++); 295 } 296 if (key == 2) { /* length */ 297 r = eval6(); 298 tostring(r); 299 v = int_value(strlen(r->u.s)); 300 freev(r); 301 } else 302 l = eval6(); 303 304 if (key == 3) { /* match */ 305 r = eval6(); 306 v = docolon(l, r); 307 freev(l); 308 freev(r); 309 } 310 if (key == 4) { /* index */ 311 r = eval6(); 312 tostring(l); 313 tostring(r); 314 v = int_value(strcspn(l->u.s, r->u.s) + 1); 315 if (v->u.i == (arith_t) strlen(l->u.s) + 1) 316 v->u.i = 0; 317 freev(l); 318 freev(r); 319 } 320 if (key == 5) { /* substr */ 321 i1 = eval6(); 322 i2 = eval6(); 323 tostring(l); 324 if (!toarith(i1) || !toarith(i2) 325 || i1->u.i > (arith_t) strlen(l->u.s) 326 || i1->u.i <= 0 || i2->u.i <= 0) 327 v = str_value(""); 328 else { 329 v = xmalloc(sizeof(VALUE)); 330 v->type = string; 331 v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); 319 332 } 320 321 if (nextarg (")")) 322 bb_error_msg_and_die ( "syntax error"); 323 324 return str_value (*args++); 325 } 326 327 /* Handle match, substr, index, length, and quote keywords. */ 328 329 static VALUE *eval6 (void) 330 { 331 VALUE *l, *r, *v, *i1, *i2; 332 333 if (nextarg ("quote")) { 334 args++; 335 if (!*args) 336 bb_error_msg_and_die ( "syntax error"); 337 return str_value (*args++); 338 } 339 else if (nextarg ("length")) { 340 args++; 341 r = eval6 (); 342 tostring (r); 343 v = int_value (strlen (r->u.s)); 344 freev (r); 345 return v; 346 } 347 else if (nextarg ("match")) { 348 args++; 349 l = eval6 (); 350 r = eval6 (); 351 v = docolon (l, r); 352 freev (l); 353 freev (r); 354 return v; 355 } 356 else if (nextarg ("index")) { 357 args++; 358 l = eval6 (); 359 r = eval6 (); 360 tostring (l); 361 tostring (r); 362 v = int_value (strcspn (l->u.s, r->u.s) + 1); 363 if (v->u.i == (arith_t) strlen (l->u.s) + 1) 364 v->u.i = 0; 365 freev (l); 366 freev (r); 367 return v; 368 } 369 else if (nextarg ("substr")) { 370 args++; 371 l = eval6 (); 372 i1 = eval6 (); 373 i2 = eval6 (); 374 tostring (l); 375 if (!toarith (i1) || !toarith (i2) 376 || i1->u.i > (arith_t) strlen (l->u.s) 377 || i1->u.i <= 0 || i2->u.i <= 0) 378 v = str_value (""); 379 else { 380 v = xmalloc (sizeof(VALUE)); 381 v->type = string; 382 v->u.s = bb_xstrndup(l->u.s + i1->u.i - 1, i2->u.i); 383 } 384 freev (l); 385 freev (i1); 386 freev (i2); 387 return v; 388 } 389 else 390 return eval7 (); 333 freev(l); 334 freev(i1); 335 freev(i2); 336 } 337 return v; 338 391 339 } 392 340 … … 394 342 Calls docolon to do the real work. */ 395 343 396 static VALUE *eval5 344 static VALUE *eval5(void) 397 345 { 398 346 VALUE *l, *r, *v; 399 347 400 l = eval6 401 while (nextarg 402 args++;403 r = eval6 404 v = docolon 405 freev 406 freev 348 l = eval6(); 349 while (nextarg(":")) { 350 G.args++; 351 r = eval6(); 352 v = docolon(l, r); 353 freev(l); 354 freev(r); 407 355 l = v; 408 356 } … … 412 360 /* Handle *, /, % operators. */ 413 361 414 static VALUE *eval4 362 static VALUE *eval4(void) 415 363 { 416 364 VALUE *l, *r; … … 418 366 arith_t val; 419 367 420 l = eval5 368 l = eval5(); 421 369 while (1) { 422 if (nextarg 370 if (nextarg("*")) 423 371 op = '*'; 424 else if (nextarg 372 else if (nextarg("/")) 425 373 op = '/'; 426 else if (nextarg 374 else if (nextarg("%")) 427 375 op = '%'; 428 376 else 429 377 return l; 430 args++;431 r = eval5 432 val = arithmetic_common 433 freev 434 freev 435 l = int_value 378 G.args++; 379 r = eval5(); 380 val = arithmetic_common(l, r, op); 381 freev(l); 382 freev(r); 383 l = int_value(val); 436 384 } 437 385 } … … 439 387 /* Handle +, - operators. */ 440 388 441 static VALUE *eval3 389 static VALUE *eval3(void) 442 390 { 443 391 VALUE *l, *r; … … 445 393 arith_t val; 446 394 447 l = eval4 395 l = eval4(); 448 396 while (1) { 449 if (nextarg 397 if (nextarg("+")) 450 398 op = '+'; 451 else if (nextarg 399 else if (nextarg("-")) 452 400 op = '-'; 453 401 else 454 402 return l; 455 args++;456 r = eval4 457 val = arithmetic_common 458 freev 459 freev 460 l = int_value 403 G.args++; 404 r = eval4(); 405 val = arithmetic_common(l, r, op); 406 freev(l); 407 freev(r); 408 l = int_value(val); 461 409 } 462 410 } … … 464 412 /* Handle comparisons. */ 465 413 466 static VALUE *eval2 414 static VALUE *eval2(void) 467 415 { 468 416 VALUE *l, *r; … … 470 418 arith_t val; 471 419 472 l = eval3 420 l = eval3(); 473 421 while (1) { 474 if (nextarg 422 if (nextarg("<")) 475 423 op = '<'; 476 else if (nextarg 477 op = 'L' +'E';478 else if (nextarg ("=") || nextarg("=="))424 else if (nextarg("<=")) 425 op = 'L' + 'E'; 426 else if (nextarg("=") || nextarg("==")) 479 427 op = '='; 480 else if (nextarg 428 else if (nextarg("!=")) 481 429 op = '!'; 482 else if (nextarg 483 op = 'G' +'E';484 else if (nextarg 430 else if (nextarg(">=")) 431 op = 'G' + 'E'; 432 else if (nextarg(">")) 485 433 op = '>'; 486 434 else 487 435 return l; 488 args++;489 r = eval3 490 toarith 491 toarith 492 val = cmp_common 493 freev 494 freev 495 l = int_value 436 G.args++; 437 r = eval3(); 438 toarith(l); 439 toarith(r); 440 val = cmp_common(l, r, op); 441 freev(l); 442 freev(r); 443 l = int_value(val); 496 444 } 497 445 } … … 499 447 /* Handle &. */ 500 448 501 static VALUE *eval1 449 static VALUE *eval1(void) 502 450 { 503 451 VALUE *l, *r; 504 452 505 l = eval2 (); 506 while (nextarg ("&")) { 507 args++; 508 r = eval2 (); 509 if (null (l) || null (r)) { 510 freev (l); 511 freev (r); 512 l = int_value (0); 513 } 514 else 515 freev (r); 453 l = eval2(); 454 while (nextarg("&")) { 455 G.args++; 456 r = eval2(); 457 if (null(l) || null(r)) { 458 freev(l); 459 freev(r); 460 l = int_value(0); 461 } else 462 freev(r); 516 463 } 517 464 return l; … … 520 467 /* Handle |. */ 521 468 522 static VALUE *eval 469 static VALUE *eval(void) 523 470 { 524 471 VALUE *l, *r; 525 472 526 l = eval1 527 while (nextarg 528 args++;529 r = eval1 530 if (null 531 freev 473 l = eval1(); 474 while (nextarg("|")) { 475 G.args++; 476 r = eval1(); 477 if (null(l)) { 478 freev(l); 532 479 l = r; 533 } 534 else 535 freev (r); 480 } else 481 freev(r); 536 482 } 537 483 return l; 538 484 } 485 486 int expr_main(int argc, char **argv); 487 int expr_main(int argc, char **argv) 488 { 489 VALUE *v; 490 491 if (argc == 1) { 492 bb_error_msg_and_die("too few arguments"); 493 } 494 495 G.args = argv + 1; 496 497 v = eval(); 498 if (*G.args) 499 bb_error_msg_and_die("syntax error"); 500 501 if (v->type == integer) 502 printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); 503 else 504 puts(v->u.s); 505 506 fflush_stdout_and_exit(null(v)); 507 } -
branches/2.2.5/mindi-busybox/coreutils/false.c
r821 r1765 11 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/false.html */ 12 12 13 #include <stdlib.h> 14 #include "busybox.h" 13 #include "libbb.h" 15 14 15 /* This is a NOFORK applet. Be very careful! */ 16 17 int false_main(int ATTRIBUTE_UNUSED argc, char ATTRIBUTE_UNUSED **argv); 16 18 int false_main(int ATTRIBUTE_UNUSED argc, char ATTRIBUTE_UNUSED **argv) 17 19 { -
branches/2.2.5/mindi-busybox/coreutils/fold.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* fold -- wrap each input line to fit in specified width. 2 3 … … 10 11 */ 11 12 12 #include <ctype.h> 13 #include <errno.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include <sys/types.h> 18 #include <unistd.h> 19 #include "busybox.h" 13 #include "libbb.h" 20 14 21 15 static unsigned long flags; … … 45 39 } 46 40 41 int fold_main(int argc, char **argv); 47 42 int fold_main(int argc, char **argv) 48 43 { 44 char *line_out = NULL; 45 int allocated_out = 0; 49 46 char *w_opt; 50 47 int width = 80; … … 52 49 int errs = 0; 53 50 54 if (!ENABLE_DEBUG_YANK_SUSv2) {51 if (ENABLE_INCLUDE_SUSv2) { 55 52 /* Turn any numeric options into -w options. */ 56 53 for (i = 1; i < argc; i++) { … … 61 58 break; 62 59 if (isdigit(*a)) { 63 argv[i] = bb_xasprintf("-w%s", a);60 argv[i] = xasprintf("-w%s", a); 64 61 } 65 62 } … … 67 64 } 68 65 69 flags = bb_getopt_ulflags(argc,argv, "bsw:", &w_opt);66 flags = getopt32(argv, "bsw:", &w_opt); 70 67 if (flags & FLAG_WIDTH) 71 width = bb_xgetlarg(w_opt, 10, 1, 10000);68 width = xatoul_range(w_opt, 1, 10000); 72 69 73 70 argv += optind; 74 71 if (!*argv) { 75 *--argv = "-";72 *--argv = (char*)"-"; 76 73 } 77 74 78 75 do { 79 FILE *istream = bb_wfopen_input(*argv);76 FILE *istream = fopen_or_warn_stdin(*argv); 80 77 int c; 81 78 int column = 0; /* Screen column where next char will go. */ 82 79 int offset_out = 0; /* Index in `line_out' for next char. */ 83 static char *line_out = NULL;84 static int allocated_out = 0;85 80 86 81 if (istream == NULL) { … … 101 96 continue; 102 97 } 103 104 rescan: 98 rescan: 105 99 column = adjust_column(column, c); 106 100 … … 151 145 } 152 146 153 if (ferror(istream) || bb_fclose_nonstdin(istream)) {147 if (ferror(istream) || fclose_if_not_stdin(istream)) { 154 148 bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ 155 149 errs |= EXIT_FAILURE; … … 157 151 } while (*++argv); 158 152 159 bb_fflush_stdout_and_exit(errs);153 fflush_stdout_and_exit(errs); 160 154 } 161 /* vi: set sw=4 ts=4: */ -
branches/2.2.5/mindi-busybox/coreutils/head.c
r821 r1765 12 12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */ 13 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <limits.h> 17 #include <ctype.h> 18 #include <unistd.h> 19 #include "busybox.h" 14 #include "libbb.h" 20 15 21 static const char head_opts[] =16 static const char head_opts[] ALIGN1 = 22 17 "n:" 23 18 #if ENABLE_FEATURE_FANCY_HEAD … … 31 26 { "k", 1024 }, 32 27 { "m", 1024*1024 }, 33 { NULL, 0}28 { } 34 29 }; 35 30 #endif 36 37 static const char header_fmt_str[] = "\n==> %s <==\n";38 31 32 static const char header_fmt_str[] ALIGN1 = "\n==> %s <==\n"; 33 34 int head_main(int argc, char **argv); 39 35 int head_main(int argc, char **argv) 40 36 { … … 53 49 int retval = EXIT_SUCCESS; 54 50 55 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_HEAD51 #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD 56 52 /* Allow legacy syntax of an initial numeric option without -n. */ 57 if ((argc > 1) && (argv[1][0] == '-') 58 /* && (isdigit)(argv[1][1]) */ 59 && (((unsigned int)(argv[1][1] - '0')) <= 9) 53 if (argc > 1 && argv[1][0] == '-' 54 && isdigit(argv[1][1]) 60 55 ) { 61 56 --argc; … … 66 61 #endif 67 62 68 /* No size benefit in converting this to bb_getopt_ulflags*/63 /* No size benefit in converting this to getopt32 */ 69 64 while ((opt = getopt(argc, argv, head_opts)) > 0) { 70 switch (opt) {65 switch (opt) { 71 66 #if ENABLE_FEATURE_FANCY_HEAD 72 73 74 75 76 77 78 79 80 67 case 'q': 68 header_threshhold = INT_MAX; 69 break; 70 case 'v': 71 header_threshhold = -1; 72 break; 73 case 'c': 74 count_bytes = 1; 75 /* fall through */ 81 76 #endif 82 83 84 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_HEAD85 77 case 'n': 78 p = optarg; 79 #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD 80 GET_COUNT: 86 81 #endif 87 82 88 83 #if !ENABLE_FEATURE_FANCY_HEAD 89 count = bb_xgetularg10(p);84 count = xatoul(p); 90 85 #else 91 count = bb_xgetularg_bnd_sfx(p, 10, 92 0, ULONG_MAX, 93 head_suffixes); 86 count = xatoul_sfx(p, head_suffixes); 94 87 #endif 95 96 97 88 break; 89 default: 90 bb_show_usage(); 98 91 } 99 92 } … … 101 94 argv += optind; 102 95 if (!*argv) { 103 *--argv = "-";96 *--argv = (char*)"-"; 104 97 } 105 98 … … 120 113 121 114 do { 122 if ((fp = bb_wfopen_input(*argv)) != NULL) { 115 fp = fopen_or_warn_stdin(*argv); 116 if (fp) { 123 117 if (fp == stdin) { 124 118 *argv = (char *) bb_msg_standard_input; 125 119 } 126 120 if (header_threshhold) { 127 bb_printf(fmt, *argv);121 printf(fmt, *argv); 128 122 } 129 123 i = count; … … 134 128 putchar(c); 135 129 } 136 if ( bb_fclose_nonstdin(fp)) {130 if (fclose_if_not_stdin(fp)) { 137 131 bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */ 138 132 retval = EXIT_FAILURE; 139 133 } 140 bb_xferror_stdout();134 die_if_ferror_stdout(); 141 135 } 142 136 fmt = header_fmt_str; 143 137 } while (*++argv); 144 138 145 bb_fflush_stdout_and_exit(retval);139 fflush_stdout_and_exit(retval); 146 140 } -
branches/2.2.5/mindi-busybox/coreutils/hostid.c
r821 r1765 10 10 /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ 11 11 12 #include <stdlib.h> 13 #include <unistd.h> 14 #include "busybox.h" 12 #include "libbb.h" 15 13 14 /* This is a NOFORK applet. Be very careful! */ 15 16 int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv); 16 17 int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv) 17 18 { … … 20 21 } 21 22 22 bb_printf("%lx\n", gethostid());23 printf("%lx\n", gethostid()); 23 24 24 bb_fflush_stdout_and_exit(EXIT_SUCCESS);25 return fflush(stdout); 25 26 } -
branches/2.2.5/mindi-busybox/coreutils/id.c
r821 r1765 11 11 /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to 12 12 * be more similar to GNU id. 13 * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp> 13 14 */ 14 15 15 #include "busybox.h" 16 #include "pwd_.h" 17 #include <stdio.h> 18 #include <unistd.h> 19 #include <sys/types.h> 20 21 #ifdef CONFIG_SELINUX 22 #include <selinux/selinux.h> /* for is_selinux_enabled() */ 23 #endif 16 #include "libbb.h" 24 17 25 18 #define PRINT_REAL 1 … … 27 20 #define JUST_USER 4 28 21 #define JUST_GROUP 8 22 #if ENABLE_SELINUX 23 #define JUST_CONTEXT 16 24 #endif 29 25 30 static short printf_full(unsigned int id, const char *arg, const char prefix)26 static int printf_full(unsigned int id, const char *arg, const char prefix) 31 27 { 32 28 const char *fmt = "%cid=%u"; 33 short status=EXIT_FAILURE;29 int status = EXIT_FAILURE; 34 30 35 if (arg) {31 if (arg) { 36 32 fmt = "%cid=%u(%s)"; 37 status =EXIT_SUCCESS;33 status = EXIT_SUCCESS; 38 34 } 39 bb_printf(fmt, prefix, id, arg);35 printf(fmt, prefix, id, arg); 40 36 return status; 41 37 } 42 38 39 int id_main(int argc, char **argv); 43 40 int id_main(int argc, char **argv) 44 41 { … … 48 45 unsigned long flags; 49 46 short status; 50 47 #if ENABLE_SELINUX 48 security_context_t scontext; 49 #endif 51 50 /* Don't allow -n -r -nr -ug -rug -nug -rnug */ 52 51 /* Don't allow more than one username */ 53 bb_opt_complementally = "?1:?:u--g:g--u:r?ug:n?ug";54 flags = bb_getopt_ulflags(argc, argv, "rnug");52 opt_complementary = "?1:u--g:g--u:r?ug:n?ug" USE_SELINUX(":u--Z:Z--u:g--Z:Z--g"); 53 flags = getopt32(argv, "rnug" USE_SELINUX("Z")); 55 54 56 55 /* This values could be overwritten later */ … … 62 61 } 63 62 64 if (argv[optind]) {65 p =getpwnam(argv[optind]);66 /* bb_xgetpwnamis needed because it exits on failure */67 uid = bb_xgetpwnam(argv[optind]);63 if (argv[optind]) { 64 p = getpwnam(argv[optind]); 65 /* xuname2uid is needed because it exits on failure */ 66 uid = xuname2uid(argv[optind]); 68 67 gid = p->pw_gid; 69 68 /* in this case PRINT_REAL is the same */ 70 69 } 71 70 72 if (flags & (JUST_GROUP | JUST_USER)) {71 if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) { 73 72 /* JUST_GROUP and JUST_USER are mutually exclusive */ 74 if (flags & NAME_NOT_NUMBER) {75 /* bb_get pwuid and bb_getgrgid exit on failure soputs cannot segfault */76 puts((flags & JUST_USER) ? bb_getpwuid(NULL, uid, -1 ) : bb_getgrgid(NULL, gid, -1));73 if (flags & NAME_NOT_NUMBER) { 74 /* bb_getXXXid(-1) exit on failure, puts cannot segfault */ 75 puts((flags & JUST_USER) ? bb_getpwuid(NULL, -1, uid) : bb_getgrgid(NULL, -1, gid)); 77 76 } else { 78 bb_printf("%u\n",(flags & JUST_USER) ? uid : gid); 77 if (flags & JUST_USER) { 78 printf("%u\n", uid); 79 } 80 if (flags & JUST_GROUP) { 81 printf("%u\n", gid); 82 } 79 83 } 84 85 #if ENABLE_SELINUX 86 if (flags & JUST_CONTEXT) { 87 selinux_or_die(); 88 if (argc - optind == 1) { 89 bb_error_msg_and_die("user name can't be passed with -Z"); 90 } 91 92 if (getcon(&scontext)) { 93 bb_error_msg_and_die("can't get process context"); 94 } 95 printf("%s\n", scontext); 96 } 97 #endif 80 98 /* exit */ 81 bb_fflush_stdout_and_exit(EXIT_SUCCESS);99 fflush_stdout_and_exit(EXIT_SUCCESS); 82 100 } 83 101 84 102 /* Print full info like GNU id */ 85 /* bb_getpwuid doesn't exit on failure here*/86 status =printf_full(uid, bb_getpwuid(NULL, uid, 0), 'u');103 /* bb_getpwuid(0) doesn't exit on failure (returns NULL) */ 104 status = printf_full(uid, bb_getpwuid(NULL, 0, uid), 'u'); 87 105 putchar(' '); 88 /* bb_getgrgid doesn't exit on failure here */ 89 status|=printf_full(gid, bb_getgrgid(NULL, gid, 0), 'g'); 106 status |= printf_full(gid, bb_getgrgid(NULL, 0, gid), 'g'); 90 107 91 #ifdef CONFIG_SELINUX 92 if ( is_selinux_enabled() ) { 93 security_context_t mysid; 94 char context[80]; 95 int len = sizeof(context); 108 #if ENABLE_SELINUX 109 if (is_selinux_enabled()) { 110 security_context_t mysid; 111 const char *context; 96 112 97 getcon(&mysid); 98 context[0] = '\0'; 99 if (mysid) { 100 len = strlen(mysid)+1; 101 safe_strncpy(context, mysid, len); 102 freecon(mysid); 103 }else{ 104 safe_strncpy(context, "unknown",8); 105 } 106 bb_printf(" context=%s", context); 113 context = "unknown"; 114 getcon(&mysid); 115 if (mysid) { 116 context = alloca(strlen(mysid) + 1); 117 strcpy((char*)context, mysid); 118 freecon(mysid); 119 } 120 printf(" context=%s", context); 107 121 } 108 122 #endif 109 123 110 124 putchar('\n'); 111 bb_fflush_stdout_and_exit(status);125 fflush_stdout_and_exit(status); 112 126 } -
branches/2.2.5/mindi-busybox/coreutils/install.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * Copyright (C) 2003 by Glenn McGrath <bug1@iinet.net.au> 3 * Copyright (C) 2003 by Glenn McGrath 4 * SELinux support: by Yuichi Nakamura <ynakam@hitachisoft.jp> 3 5 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 * 6 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 18 7 * 19 8 * TODO: -d option, need a way of recursively making directories and changing … … 21 10 */ 22 11 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 #include <errno.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 12 #include <libgen.h> 29 13 #include <getopt.h> /* struct option */ 30 14 31 #include " busybox.h"15 #include "libbb.h" 32 16 #include "libcoreutils/coreutils.h" 33 17 34 #define INSTALL_OPT_CMD 135 #define INSTALL_OPT_DIRECTORY 236 #define INSTALL_OPT_PRESERVE_TIME 437 #define INSTALL_OPT_STRIP 838 #define INSTALL_OPT_GROUP 1639 #define INSTALL_OPT_MODE 3240 #define INSTALL_OPT_OWNER 6441 42 18 #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS 43 static const struct option install_long_options[] = { 44 { "directory", 0, NULL, 'd' }, 45 { "preserve-timestamps", 0, NULL, 'p' }, 46 { "strip", 0, NULL, 's' }, 47 { "group", 0, NULL, 'g' }, 48 { "mode", 0, NULL, 'm' }, 49 { "owner", 0, NULL, 'o' }, 50 { 0, 0, 0, 0 } 51 }; 52 #endif 53 19 static const char install_longopts[] ALIGN1 = 20 "directory\0" No_argument "d" 21 "preserve-timestamps\0" No_argument "p" 22 "strip\0" No_argument "s" 23 "group\0" No_argument "g" 24 "mode\0" No_argument "m" 25 "owner\0" No_argument "o" 26 /* autofs build insists of using -b --suffix=.orig */ 27 /* TODO? (short option for --suffix is -S) */ 28 #if ENABLE_SELINUX 29 "context\0" Required_argument "Z" 30 "preserve_context\0" No_argument "\xff" 31 "preserve-context\0" No_argument "\xff" 32 #endif 33 ; 34 #endif 35 36 37 #if ENABLE_SELINUX 38 static void setdefaultfilecon(const char *path) 39 { 40 struct stat s; 41 security_context_t scontext = NULL; 42 43 if (!is_selinux_enabled()) { 44 return; 45 } 46 if (lstat(path, &s) != 0) { 47 return; 48 } 49 50 if (matchpathcon(path, s.st_mode, &scontext) < 0) { 51 goto out; 52 } 53 if (strcmp(scontext, "<<none>>") == 0) { 54 goto out; 55 } 56 57 if (lsetfilecon(path, scontext) < 0) { 58 if (errno != ENOTSUP) { 59 bb_perror_msg("warning: failed to change context of %s to %s", path, scontext); 60 } 61 } 62 63 out: 64 freecon(scontext); 65 } 66 67 #endif 68 69 int install_main(int argc, char **argv); 54 70 int install_main(int argc, char **argv) 55 71 { 72 struct stat statbuf; 56 73 mode_t mode; 57 74 uid_t uid; 58 75 gid_t gid; 59 char *gid_str = "-1"; 60 char *uid_str = "-1"; 61 char *mode_str = "0755"; 76 char *arg, *last; 77 const char *gid_str; 78 const char *uid_str; 79 const char *mode_str; 62 80 int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; 63 int ret = EXIT_SUCCESS, flags, i, isdir; 81 int flags; 82 int ret = EXIT_SUCCESS; 83 int isdir; 84 #if ENABLE_SELINUX 85 security_context_t scontext; 86 bool use_default_selinux_context = 1; 87 #endif 88 enum { 89 OPT_c = 1 << 0, 90 OPT_v = 1 << 1, 91 OPT_b = 1 << 2, 92 OPT_DIRECTORY = 1 << 3, 93 OPT_PRESERVE_TIME = 1 << 4, 94 OPT_STRIP = 1 << 5, 95 OPT_GROUP = 1 << 6, 96 OPT_MODE = 1 << 7, 97 OPT_OWNER = 1 << 8, 98 #if ENABLE_SELINUX 99 OPT_SET_SECURITY_CONTEXT = 1 << 9, 100 OPT_PRESERVE_SECURITY_CONTEXT = 1 << 10, 101 #endif 102 }; 64 103 65 104 #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS 66 bb_applet_long_options = install_long_options; 67 #endif 68 bb_opt_complementally = "?:s--d:d--s"; 69 /* -c exists for backwards compatibility, its needed */ 70 flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* 'a' must be 2nd */ 105 applet_long_options = install_longopts; 106 #endif 107 opt_complementary = "s--d:d--s" USE_SELINUX(":Z--\xff:\xff--Z"); 108 /* -c exists for backwards compatibility, it's needed */ 109 /* -v is ignored ("print name of each created directory") */ 110 /* -b is ignored ("make a backup of each existing destination file") */ 111 flags = getopt32(argv, "cvb" "dpsg:m:o:" USE_SELINUX("Z:"), 112 &gid_str, &mode_str, &uid_str USE_SELINUX(, &scontext)); 113 argc -= optind; 114 argv += optind; 115 116 #if ENABLE_SELINUX 117 if (flags & (OPT_PRESERVE_SECURITY_CONTEXT|OPT_SET_SECURITY_CONTEXT)) { 118 selinux_or_die(); 119 use_default_selinux_context = 0; 120 if (flags & OPT_PRESERVE_SECURITY_CONTEXT) { 121 copy_flags |= FILEUTILS_PRESERVE_SECURITY_CONTEXT; 122 } 123 if (flags & OPT_SET_SECURITY_CONTEXT) { 124 setfscreatecon_or_die(scontext); 125 copy_flags |= FILEUTILS_SET_SECURITY_CONTEXT; 126 } 127 } 128 #endif 71 129 72 130 /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ 73 if (flags & INSTALL_OPT_PRESERVE_TIME) {131 if (flags & OPT_PRESERVE_TIME) { 74 132 copy_flags |= FILEUTILS_PRESERVE_STATUS; 75 133 } 76 bb_parse_mode(mode_str, &mode); 77 gid = get_ug_id(gid_str, bb_xgetgrnam); 78 uid = get_ug_id(uid_str, bb_xgetpwnam); 79 umask(0); 134 mode = 0666; 135 if (flags & OPT_MODE) 136 bb_parse_mode(mode_str, &mode); 137 uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); 138 gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); 139 if (flags & (OPT_OWNER|OPT_GROUP)) 140 umask(0); 80 141 81 142 /* Create directories 82 * don t use bb_make_directory() as it cant change uid or gid143 * don't use bb_make_directory() as it can't change uid or gid 83 144 * perhaps bb_make_directory() should be improved. 84 145 */ 85 if (flags & INSTALL_OPT_DIRECTORY) { 86 for (argv += optind; *argv; argv++) { 87 char *old_argv_ptr = *argv + 1; 88 char *argv_ptr; 89 do { 90 argv_ptr = strchr(old_argv_ptr, '/'); 91 old_argv_ptr = argv_ptr; 92 if (argv_ptr) { 93 *argv_ptr = '\0'; 94 old_argv_ptr++; 95 } 96 if (mkdir(*argv, mode) == -1) { 146 if (flags & OPT_DIRECTORY) { 147 while ((arg = *argv++) != NULL) { 148 char *slash = arg; 149 while (1) { 150 slash = strchr(slash + 1, '/'); 151 if (slash) 152 *slash = '\0'; 153 if (mkdir(arg, mode | 0111) == -1) { 97 154 if (errno != EEXIST) { 98 bb_perror_msg("c oulnt create %s", *argv);155 bb_perror_msg("cannot create %s", arg); 99 156 ret = EXIT_FAILURE; 100 157 break; 101 158 } 102 } 103 else if (lchown(*argv, uid, gid) == -1) { 104 bb_perror_msg("cannot change ownership of %s", *argv); 159 } /* dir was created, chown? */ 160 else if ((flags & (OPT_OWNER|OPT_GROUP)) 161 && lchown(arg, uid, gid) == -1 162 ) { 163 bb_perror_msg("cannot change ownership of %s", arg); 105 164 ret = EXIT_FAILURE; 106 165 break; 107 166 } 108 if (argv_ptr) { 109 *argv_ptr = '/'; 110 } 111 } while (old_argv_ptr); 112 } 113 return(ret); 114 } 115 116 { 117 struct stat statbuf; 118 isdir = lstat(argv[argc - 1], &statbuf)<0 119 ? 0 : S_ISDIR(statbuf.st_mode); 120 } 121 for (i = optind; i < argc - 1; i++) { 122 char *dest; 123 124 dest = argv[argc - 1]; 125 if (isdir) dest = concat_path_file(argv[argc - 1], basename(argv[i])); 126 ret |= copy_file(argv[i], dest, copy_flags); 167 if (!slash) 168 break; 169 *slash = '/'; 170 } 171 } 172 return ret; 173 } 174 175 if (argc < 2) 176 bb_show_usage(); 177 178 last = argv[argc - 1]; 179 argv[argc - 1] = NULL; 180 /* coreutils install resolves link in this case, don't use lstat */ 181 isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); 182 183 while ((arg = *argv++) != NULL) { 184 char *dest = last; 185 if (isdir) 186 dest = concat_path_file(last, basename(arg)); 187 if (copy_file(arg, dest, copy_flags)) { 188 /* copy is not made */ 189 ret = EXIT_FAILURE; 190 goto next; 191 } 127 192 128 193 /* Set the file mode */ 129 if ( chmod(dest, mode) == -1) {194 if ((flags & OPT_MODE) && chmod(dest, mode) == -1) { 130 195 bb_perror_msg("cannot change permissions of %s", dest); 131 196 ret = EXIT_FAILURE; 132 197 } 133 198 #if ENABLE_SELINUX 199 if (use_default_selinux_context) 200 setdefaultfilecon(dest); 201 #endif 134 202 /* Set the user and group id */ 135 if (lchown(dest, uid, gid) == -1) { 203 if ((flags & (OPT_OWNER|OPT_GROUP)) 204 && lchown(dest, uid, gid) == -1 205 ) { 136 206 bb_perror_msg("cannot change ownership of %s", dest); 137 207 ret = EXIT_FAILURE; 138 208 } 139 if (flags & INSTALL_OPT_STRIP) { 140 if (execlp("strip", "strip", dest, NULL) == -1) { 141 bb_error_msg("strip failed"); 209 if (flags & OPT_STRIP) { 210 char *args[3]; 211 args[0] = (char*)"strip"; 212 args[1] = dest; 213 args[2] = NULL; 214 if (spawn_and_wait(args)) { 215 bb_perror_msg("strip"); 142 216 ret = EXIT_FAILURE; 143 217 } 144 218 } 145 if(ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); 146 } 147 148 return(ret); 219 next: 220 if (ENABLE_FEATURE_CLEAN_UP && isdir) 221 free(dest); 222 } 223 224 return ret; 149 225 } -
branches/2.2.5/mindi-busybox/coreutils/length.c
r821 r1765 3 3 /* BB_AUDIT SUSv3 N/A -- Apparently a busybox (obsolete?) extension. */ 4 4 5 #include <stdlib.h> 6 #include <string.h> 7 #include <stdio.h> 8 #include "busybox.h" 5 #include "libbb.h" 9 6 7 /* This is a NOFORK applet. Be very careful! */ 8 9 int length_main(int argc, char **argv); 10 10 int length_main(int argc, char **argv) 11 11 { 12 if ((argc != 2) || 13 12 if ((argc != 2) || (**(++argv) == '-')) { 13 bb_show_usage(); 14 14 } 15 15 16 bb_printf("%lu\n", (unsigned long)strlen(*argv));16 printf("%u\n", (unsigned)strlen(*argv)); 17 17 18 bb_fflush_stdout_and_exit(EXIT_SUCCESS);18 return fflush(stdout); 19 19 } -
branches/2.2.5/mindi-busybox/coreutils/libcoreutils/coreutils.h
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. … … 8 9 typedef int (*stat_func)(const char *fn, struct stat *ps); 9 10 10 externint cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf);11 externint cp_mv_stat(const char *fn, struct stat *fn_stat);11 int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf); 12 int cp_mv_stat(const char *fn, struct stat *fn_stat); 12 13 13 externmode_t getopt_mk_fifo_nod(int argc, char **argv);14 mode_t getopt_mk_fifo_nod(int argc, char **argv); 14 15 15 16 #endif -
branches/2.2.5/mindi-busybox/coreutils/libcoreutils/cp_mv_stat.c
r821 r1765 21 21 */ 22 22 23 #include <errno.h>24 #include <sys/stat.h>25 23 #include "libbb.h" 26 24 #include "coreutils.h" … … 30 28 if (sf(fn, fn_stat) < 0) { 31 29 if (errno != ENOENT) { 32 bb_perror_msg(" unable to stat `%s'", fn);30 bb_perror_msg("cannot stat '%s'", fn); 33 31 return -1; 34 32 } -
branches/2.2.5/mindi-busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c
r821 r1765 21 21 */ 22 22 23 #include <sys/types.h>24 #include <sys/stat.h>25 #include <unistd.h>26 23 #include "libbb.h" 27 24 #include "coreutils.h" … … 31 28 mode_t mode = 0666; 32 29 char *smode = NULL; 33 34 bb_getopt_ulflags(argc, argv, "m:", &smode); 35 if(smode) { 30 #if ENABLE_SELINUX 31 security_context_t scontext; 32 #endif 33 int opt; 34 opt = getopt32(argv, "m:" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); 35 if (opt & 1) { 36 36 if (bb_parse_mode(smode, &mode)) 37 37 umask(0); 38 38 } 39 40 #if ENABLE_SELINUX 41 if (opt & 2) { 42 selinux_or_die(); 43 setfscreatecon_or_die(scontext); 44 } 45 #endif 46 39 47 return mode; 40 48 } -
branches/2.2.5/mindi-busybox/coreutils/ln.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 25 12 /* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */ 26 13 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <unistd.h> 30 #include <errno.h> 31 #include "busybox.h" 14 #include "libbb.h" 15 16 /* This is a NOEXEC applet. Be very careful! */ 17 32 18 33 19 #define LN_SYMLINK 1 … … 37 23 #define LN_SUFFIX 16 38 24 25 int ln_main(int argc, char **argv); 39 26 int ln_main(int argc, char **argv) 40 27 { … … 44 31 char *src_name; 45 32 char *src; 46 char *suffix = "~";33 char *suffix = (char*)"~"; 47 34 struct stat statbuf; 48 35 int (*link_func)(const char *, const char *); 49 36 50 flag = bb_getopt_ulflags(argc,argv, "sfnbS:", &suffix);37 flag = getopt32(argv, "sfnbS:", &suffix); 51 38 52 39 if (argc == optind) { … … 59 46 if (argc == optind + 1) { 60 47 *--argv = last; 61 last = bb_get_last_path_component( bb_xstrdup(last));48 last = bb_get_last_path_component(xstrdup(last)); 62 49 } 63 50 … … 67 54 68 55 if (is_directory(src, 69 (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE, 70 NULL)) { 71 src_name = bb_xstrdup(*argv); 56 (flag & LN_NODEREFERENCE) ^ LN_NODEREFERENCE, 57 NULL) 58 ) { 59 src_name = xstrdup(*argv); 72 60 src = concat_path_file(src, bb_get_last_path_component(src_name)); 73 61 free(src_name); … … 75 63 } 76 64 if (!(flag & LN_SYMLINK) && stat(*argv, &statbuf)) { 77 bb_perror_msg("%s", *argv); 78 status = EXIT_FAILURE; 79 free(src_name); 80 continue; 65 // coreutils: "ln dangling_symlink new_hardlink" works 66 if (lstat(*argv, &statbuf) || !S_ISLNK(statbuf.st_mode)) { 67 bb_perror_msg("%s", *argv); 68 status = EXIT_FAILURE; 69 free(src_name); 70 continue; 71 } 81 72 } 82 73 83 74 if (flag & LN_BACKUP) { 84 char *backup; 85 backup = bb_xasprintf("%s%s", src, suffix); 86 if (rename(src, backup) < 0 && errno != ENOENT) { 87 bb_perror_msg("%s", src); 88 status = EXIT_FAILURE; 89 free(backup); 90 continue; 91 } 75 char *backup; 76 backup = xasprintf("%s%s", src, suffix); 77 if (rename(src, backup) < 0 && errno != ENOENT) { 78 bb_perror_msg("%s", src); 79 status = EXIT_FAILURE; 92 80 free(backup); 93 /* 94 * When the source and dest are both hard links to the same 95 * inode, a rename may succeed even though nothing happened. 96 * Therefore, always unlink(). 97 */ 98 unlink(src); 81 continue; 82 } 83 free(backup); 84 /* 85 * When the source and dest are both hard links to the same 86 * inode, a rename may succeed even though nothing happened. 87 * Therefore, always unlink(). 88 */ 89 unlink(src); 99 90 } else if (flag & LN_FORCE) { 100 91 unlink(src); -
branches/2.2.5/mindi-busybox/coreutils/logname.c
r821 r1765 21 21 */ 22 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <unistd.h> 26 #include "busybox.h" 23 #include "libbb.h" 27 24 25 /* This is a NOFORK applet. Be very careful! */ 26 27 int logname_main(int argc, char ATTRIBUTE_UNUSED **argv); 28 28 int logname_main(int argc, char ATTRIBUTE_UNUSED **argv) 29 29 { 30 c onst char *p;30 char buf[128]; 31 31 32 32 if (argc > 1) { … … 34 34 } 35 35 36 if ((p = getlogin()) != NULL) { 37 puts(p); 38 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 36 /* Using _r function - avoid pulling in static buffer from libc */ 37 if (getlogin_r(buf, sizeof(buf)) == 0) { 38 puts(buf); 39 return fflush(stdout); 39 40 } 40 41 -
branches/2.2.5/mindi-busybox/coreutils/ls.c
r821 r1765 30 30 */ 31 31 32 #include <getopt.h> 33 #include "libbb.h" 34 35 /* This is a NOEXEC applet. Be very careful! */ 36 37 32 38 enum { 33 TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ 34 COLUMN_GAP = 2, /* includes the file type char */ 35 }; 36 37 /************************************************************************/ 38 39 #include "busybox.h" 40 #include <unistd.h> 41 #include <errno.h> 42 #include <string.h> 43 #include <fcntl.h> 44 #include <signal.h> 45 #include <getopt.h> /* struct option */ 46 #include <sys/ioctl.h> 47 #include <sys/sysmacros.h> /* major() and minor() */ 48 #include <time.h> 39 40 TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ 41 COLUMN_GAP = 2, /* includes the file type char */ 49 42 50 43 /* what is the overall style of the listing */ 51 #define STYLE_COLUMNS (1U<<21) /* fill columns */ 52 #define STYLE_LONG (2U<<21) /* one record per line, extended info */ 53 #define STYLE_SINGLE (3U<<21) /* one record per line */ 54 55 #define STYLE_MASK STYLE_SINGLE 56 #define STYLE_ONE_RECORD_FLAG STYLE_LONG 44 STYLE_COLUMNS = 1 << 21, /* fill columns */ 45 STYLE_LONG = 2 << 21, /* one record per line, extended info */ 46 STYLE_SINGLE = 3 << 21, /* one record per line */ 47 STYLE_MASK = STYLE_SINGLE, 57 48 58 49 /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ 59 50 /* what file information will be listed */ 60 #define LIST_INO (1U<<0) 61 #define LIST_BLOCKS (1U<<1) 62 #define LIST_MODEBITS (1U<<2) 63 #define LIST_NLINKS (1U<<3) 64 #define LIST_ID_NAME (1U<<4) 65 #define LIST_ID_NUMERIC (1U<<5) 66 #define LIST_CONTEXT (1U<<6) 67 #define LIST_SIZE (1U<<7) 68 #define LIST_DEV (1U<<8) 69 #define LIST_DATE_TIME (1U<<9) 70 #define LIST_FULLTIME (1U<<10) 71 #define LIST_FILENAME (1U<<11) 72 #define LIST_SYMLINK (1U<<12) 73 #define LIST_FILETYPE (1U<<13) 74 #define LIST_EXEC (1U<<14) 75 76 #define LIST_MASK ((LIST_EXEC << 1) - 1) 51 LIST_INO = 1 << 0, 52 LIST_BLOCKS = 1 << 1, 53 LIST_MODEBITS = 1 << 2, 54 LIST_NLINKS = 1 << 3, 55 LIST_ID_NAME = 1 << 4, 56 LIST_ID_NUMERIC = 1 << 5, 57 LIST_CONTEXT = 1 << 6, 58 LIST_SIZE = 1 << 7, 59 LIST_DEV = 1 << 8, 60 LIST_DATE_TIME = 1 << 9, 61 LIST_FULLTIME = 1 << 10, 62 LIST_FILENAME = 1 << 11, 63 LIST_SYMLINK = 1 << 12, 64 LIST_FILETYPE = 1 << 13, 65 LIST_EXEC = 1 << 14, 66 LIST_MASK = (LIST_EXEC << 1) - 1, 77 67 78 68 /* what files will be displayed */ 79 #define DISP_DIRNAME (1U<<15) /* 2 or more items? label directories */ 80 #define DISP_HIDDEN (1U<<16) /* show filenames starting with . */ 81 #define DISP_DOT (1U<<17) /* show . and .. */ 82 #define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */ 83 #define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */ 84 #define DISP_ROWS (1U<<20) /* print across rows */ 85 86 #define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1)) 87 88 // CONFIG_FEATURE_LS_SORTFILES 89 /* how will the files be sorted */ 90 #define SORT_ORDER_FORWARD 0 /* sort in reverse order */ 91 #define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */ 92 93 #define SORT_NAME 0 /* sort by file name */ 94 #define SORT_SIZE (1U<<28) /* sort by file size */ 95 #define SORT_ATIME (2U<<28) /* sort by last access time */ 96 #define SORT_CTIME (3U<<28) /* sort by last change time */ 97 #define SORT_MTIME (4U<<28) /* sort by last modification time */ 98 #define SORT_VERSION (5U<<28) /* sort by version */ 99 #define SORT_EXT (6U<<28) /* sort by file name extension */ 100 #define SORT_DIR (7U<<28) /* sort by file or directory */ 101 102 #define SORT_MASK (7U<<28) 69 DISP_DIRNAME = 1 << 15, /* 2 or more items? label directories */ 70 DISP_HIDDEN = 1 << 16, /* show filenames starting with . */ 71 DISP_DOT = 1 << 17, /* show . and .. */ 72 DISP_NOLIST = 1 << 18, /* show directory as itself, not contents */ 73 DISP_RECURSIVE = 1 << 19, /* show directory and everything below it */ 74 DISP_ROWS = 1 << 20, /* print across rows */ 75 DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1), 76 77 /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ 78 SORT_FORWARD = 0, /* sort in reverse order */ 79 SORT_REVERSE = 1 << 27, /* sort in reverse order */ 80 81 SORT_NAME = 0, /* sort by file name */ 82 SORT_SIZE = 1 << 28, /* sort by file size */ 83 SORT_ATIME = 2 << 28, /* sort by last access time */ 84 SORT_CTIME = 3 << 28, /* sort by last change time */ 85 SORT_MTIME = 4 << 28, /* sort by last modification time */ 86 SORT_VERSION = 5 << 28, /* sort by version */ 87 SORT_EXT = 6 << 28, /* sort by file name extension */ 88 SORT_DIR = 7 << 28, /* sort by file or directory */ 89 SORT_MASK = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES, 103 90 104 91 /* which of the three times will be used */ 105 #define TIME_CHANGE ((1U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) 106 #define TIME_ACCESS ((1U<<24) * ENABLE_FEATURE_LS_TIMESTAMPS) 107 #define TIME_MASK ((3U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) 108 109 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 110 #define FOLLOW_LINKS (1U<<25) 111 #endif 112 #ifdef CONFIG_FEATURE_HUMAN_READABLE 113 #define LS_DISP_HR (1U<<26) 114 #endif 115 116 #define LIST_SHORT (LIST_FILENAME) 117 #define LIST_ISHORT (LIST_INO | LIST_FILENAME) 118 #define LIST_LONG (LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ 119 LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK) 120 #define LIST_ILONG (LIST_INO | LIST_LONG) 121 122 #define SPLIT_DIR 1 123 #define SPLIT_FILE 0 124 #define SPLIT_SUBDIR 2 92 TIME_CHANGE = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, 93 TIME_ACCESS = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS, 94 TIME_MASK = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, 95 96 FOLLOW_LINKS = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS, 97 98 LS_DISP_HR = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE, 99 100 LIST_SHORT = LIST_FILENAME, 101 LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ 102 LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK, 103 104 SPLIT_DIR = 1, 105 SPLIT_FILE = 0, 106 SPLIT_SUBDIR = 2, 107 108 }; 125 109 126 110 #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) 127 111 #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) 128 129 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) 130 # define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) 131 #endif 132 133 /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ 134 #ifdef CONFIG_FEATURE_LS_COLOR 135 136 static int show_color = 0; 137 138 /* long option entry used only for --color, which has no short option 139 * equivalent. */ 140 static const struct option ls_color_opt[] = 141 { 142 {"color", optional_argument, NULL, 1}, 143 {NULL, 0, NULL, 0} 144 }; 145 112 #define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) 146 113 #define COLOR(mode) ("\000\043\043\043\042\000\043\043"\ 147 114 "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)]) 148 115 #define ATTR(mode) ("\00\00\01\00\01\00\01\00"\ 149 116 "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)]) 117 118 /* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ 119 #if ENABLE_FEATURE_LS_COLOR 120 static smallint show_color; 121 /* long option entry used only for --color, which has no short option 122 * equivalent */ 123 static const char ls_color_opt[] ALIGN1 = 124 "color\0" Optional_argument "\xff" /* no short equivalent */ 125 ; 126 #else 127 enum { show_color = 0 }; 150 128 #endif 151 129 … … 153 131 * a directory entry and its stat info are stored here 154 132 */ 155 struct dnode { 156 c har *name;/* the dir entry name */157 c har *fullname;/* the dir entry name */133 struct dnode { /* the basic node */ 134 const char *name; /* the dir entry name */ 135 const char *fullname; /* the dir entry name */ 158 136 int allocated; 159 struct stat dstat; /* the file stat info */ 160 #ifdef CONFIG_SELINUX 161 security_context_t sid; 162 #endif 163 struct dnode *next; /* point at the next node */ 137 struct stat dstat; /* the file stat info */ 138 USE_SELINUX(security_context_t sid;) 139 struct dnode *next; /* point at the next node */ 164 140 }; 165 141 typedef struct dnode dnode_t; … … 169 145 static int list_single(struct dnode *); 170 146 171 static unsigned intall_fmt;172 173 #if def CONFIG_FEATURE_AUTOWIDTH174 static int terminal_width = TERMINAL_WIDTH;175 static unsigned short tabstops = COLUMN_GAP;147 static unsigned all_fmt; 148 149 #if ENABLE_FEATURE_AUTOWIDTH 150 static unsigned tabstops = COLUMN_GAP; 151 static unsigned terminal_width = TERMINAL_WIDTH; 176 152 #else 177 #define tabstops COLUMN_GAP 178 #define terminal_width TERMINAL_WIDTH 153 enum { 154 tabstops = COLUMN_GAP, 155 terminal_width = TERMINAL_WIDTH, 156 }; 179 157 #endif 180 158 181 159 static int status = EXIT_SUCCESS; 182 160 183 static struct dnode *my_stat(c har *fullname, char *name)161 static struct dnode *my_stat(const char *fullname, const char *name, int force_follow) 184 162 { 185 163 struct stat dstat; 186 164 struct dnode *cur; 187 #ifdef CONFIG_SELINUX 188 security_context_t sid=NULL; 189 #endif 190 191 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 192 if (all_fmt & FOLLOW_LINKS) { 193 #ifdef CONFIG_SELINUX 165 USE_SELINUX(security_context_t sid = NULL;) 166 167 if ((all_fmt & FOLLOW_LINKS) || force_follow) { 168 #if ENABLE_SELINUX 194 169 if (is_selinux_enabled()) { 195 getfilecon(fullname, &sid);170 getfilecon(fullname, &sid); 196 171 } 197 172 #endif … … 201 176 return 0; 202 177 } 203 } else 204 #endif 205 { 206 #ifdef CONFIG_SELINUX 207 if (is_selinux_enabled()) { 208 lgetfilecon(fullname,&sid); 178 } else { 179 #if ENABLE_SELINUX 180 if (is_selinux_enabled()) { 181 lgetfilecon(fullname, &sid); 209 182 } 210 183 #endif … … 216 189 } 217 190 218 cur = (struct dnode *)xmalloc(sizeof(struct dnode));191 cur = xmalloc(sizeof(struct dnode)); 219 192 cur->fullname = fullname; 220 193 cur->name = name; 221 194 cur->dstat = dstat; 222 #ifdef CONFIG_SELINUX 223 cur->sid = sid; 224 #endif 195 USE_SELINUX(cur->sid = sid;) 225 196 return cur; 226 197 } 227 198 228 /*----------------------------------------------------------------------*/ 229 #ifdef CONFIG_FEATURE_LS_COLOR 199 #if ENABLE_FEATURE_LS_COLOR 230 200 static char fgcolor(mode_t mode) 231 201 { 232 202 /* Check wheter the file is existing (if so, color it red!) */ 233 if (errno == ENOENT) {203 if (errno == ENOENT) 234 204 return '\037'; 235 }236 205 if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) 237 206 return COLOR(0xF000); /* File is executable ... */ … … 239 208 } 240 209 241 /*----------------------------------------------------------------------*/242 210 static char bgcolor(mode_t mode) 243 211 { … … 248 216 #endif 249 217 250 /*----------------------------------------------------------------------*/ 251 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) 218 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 252 219 static char append_char(mode_t mode) 253 220 { … … 264 231 #endif 265 232 266 /*----------------------------------------------------------------------*/ 267 268 #define countdirs(A,B) count_dirs((A), (B), 1) 269 #define countsubdirs(A,B) count_dirs((A), (B), 0) 270 233 #define countdirs(A, B) count_dirs((A), (B), 1) 234 #define countsubdirs(A, B) count_dirs((A), (B), 0) 271 235 static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) 272 236 { 273 237 int i, dirs; 274 238 275 if ( dn == NULL || nfiles < 1)276 return (0);239 if (!dn) 240 return 0; 277 241 dirs = 0; 278 242 for (i = 0; i < nfiles; i++) { 279 if (S_ISDIR(dn[i]->dstat.st_mode) 280 && (notsubdirs || 281 ((dn[i]->name[0] != '.') || (dn[i]->name[1] 282 && ((dn[i]->name[1] != '.') 283 || dn[i]->name[2]))))) 243 const char *name; 244 if (!S_ISDIR(dn[i]->dstat.st_mode)) 245 continue; 246 name = dn[i]->name; 247 if (notsubdirs 248 || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) 249 ) { 284 250 dirs++; 285 } 286 return (dirs); 251 } 252 } 253 return dirs; 287 254 } 288 255 … … 293 260 294 261 if (dnp == NULL) 295 return (0);262 return 0; 296 263 nfiles = 0; 297 for (cur = dnp[0]; cur->next != NULL; cur = cur->next)264 for (cur = dnp[0]; cur->next; cur = cur->next) 298 265 nfiles++; 299 266 nfiles++; 300 return (nfiles);267 return nfiles; 301 268 } 302 269 … … 304 271 static struct dnode **dnalloc(int num) 305 272 { 306 struct dnode **p;307 308 273 if (num < 1) 309 return (NULL); 310 311 p = (struct dnode **) xcalloc((size_t) num, (size_t) (sizeof(struct dnode *))); 312 return (p); 313 } 314 315 #ifdef CONFIG_FEATURE_LS_RECURSIVE 274 return NULL; 275 276 return xzalloc(num * sizeof(struct dnode *)); 277 } 278 279 #if ENABLE_FEATURE_LS_RECURSIVE 316 280 static void dfree(struct dnode **dnp, int nfiles) 317 281 { … … 323 287 for (i = 0; i < nfiles; i++) { 324 288 struct dnode *cur = dnp[i]; 325 if (cur->allocated)326 free( cur->fullname); /* free the filename */289 if (cur->allocated) 290 free((char*)cur->fullname); /* free the filename */ 327 291 free(cur); /* free the dnode */ 328 292 } … … 330 294 } 331 295 #else 332 #define dfree(...) 296 #define dfree(...) ((void)0) 333 297 #endif 334 298 … … 339 303 340 304 if (dn == NULL || nfiles < 1) 341 return (NULL);305 return NULL; 342 306 343 307 /* count how many dirs and regular files there are */ … … 356 320 for (d = i = 0; i < nfiles; i++) { 357 321 if (S_ISDIR(dn[i]->dstat.st_mode)) { 358 if (which & (SPLIT_DIR|SPLIT_SUBDIR)) {359 if ((which & SPLIT_DIR)360 || ((dn[i]->name[0] != '.')361 || (dn[i]->name[1]362 && ((dn[i]->name[1] != '.')363 || dn[i]->name[2])))) {364 dnp[d++] = dn[i];365 }322 const char *name; 323 if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) 324 continue; 325 name = dn[i]->name; 326 if ((which & SPLIT_DIR) 327 || name[0]!='.' || (name[1] && (name[1]!='.' || name[2])) 328 ) { 329 dnp[d++] = dn[i]; 366 330 } 367 331 } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) { … … 369 333 } 370 334 } 371 return (dnp); 372 } 373 374 /*----------------------------------------------------------------------*/ 375 #ifdef CONFIG_FEATURE_LS_SORTFILES 335 return dnp; 336 } 337 338 #if ENABLE_FEATURE_LS_SORTFILES 376 339 static int sortcmp(const void *a, const void *b) 377 340 { 378 341 struct dnode *d1 = *(struct dnode **)a; 379 342 struct dnode *d2 = *(struct dnode **)b; 380 unsigned intsort_opts = all_fmt & SORT_MASK;343 unsigned sort_opts = all_fmt & SORT_MASK; 381 344 int dif; 382 345 383 dif = 0; /* assume SORT_NAME */ 346 dif = 0; /* assume SORT_NAME */ 347 // TODO: use pre-initialized function pointer 348 // instead of branch forest 384 349 if (sort_opts == SORT_SIZE) { 385 350 dif = (int) (d2->dstat.st_size - d1->dstat.st_size); … … 397 362 398 363 if (dif == 0) { 399 /* sort by name - may be a tie_breaker for time or size cmp */364 /* sort by name - may be a tie_breaker for time or size cmp */ 400 365 if (ENABLE_LOCALE_SUPPORT) dif = strcoll(d1->name, d2->name); 401 366 else dif = strcmp(d1->name, d2->name); 402 367 } 403 368 404 if (all_fmt & SORT_ ORDER_REVERSE) {369 if (all_fmt & SORT_REVERSE) { 405 370 dif = -dif; 406 371 } 407 return (dif); 408 } 409 410 /*----------------------------------------------------------------------*/ 372 return dif; 373 } 374 411 375 static void dnsort(struct dnode **dn, int size) 412 376 { 413 qsort(dn, size, sizeof *dn, sortcmp);377 qsort(dn, size, sizeof(*dn), sortcmp); 414 378 } 415 379 #else 416 #define sortcmp(a, b) 0 417 #define dnsort(dn, size) 418 #endif 419 420 421 /*----------------------------------------------------------------------*/ 380 #define dnsort(dn, size) ((void)0) 381 #endif 382 383 422 384 static void showfiles(struct dnode **dn, int nfiles) 423 385 { … … 430 392 return; 431 393 432 if (all_fmt & STYLE_ ONE_RECORD_FLAG) {394 if (all_fmt & STYLE_LONG) { 433 395 ncols = 1; 434 396 } else { 435 /* find the longest file name -use that as the column width */397 /* find the longest file name, use that as the column width */ 436 398 for (i = 0; i < nfiles; i++) { 437 int len = strlen(dn[i]->name) + 438 #ifdef CONFIG_SELINUX 439 ((all_fmt & LIST_CONTEXT) ? 33 : 0) + 440 #endif 441 ((all_fmt & LIST_INO) ? 8 : 0) + 442 ((all_fmt & LIST_BLOCKS) ? 5 : 0); 399 int len = strlen(dn[i]->name); 443 400 if (column_width < len) 444 401 column_width = len; 445 402 } 446 column_width += tabstops; 403 column_width += tabstops + 404 USE_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + ) 405 ((all_fmt & LIST_INO) ? 8 : 0) + 406 ((all_fmt & LIST_BLOCKS) ? 5 : 0); 447 407 ncols = (int) (terminal_width / column_width); 448 408 } … … 450 410 if (ncols > 1) { 451 411 nrows = nfiles / ncols; 452 if ( (nrows * ncols)< nfiles)412 if (nrows * ncols < nfiles) 453 413 nrows++; /* round up fractionals */ 454 414 } else { … … 466 426 if (column > 0) { 467 427 nexttab -= column; 468 while (nexttab--) { 469 putchar(' '); 470 column++; 471 } 472 } 428 printf("%*s", nexttab, ""); 429 column += nexttab; 430 } 473 431 nexttab = column + column_width; 474 432 column += list_single(dn[i]); 475 }433 } 476 434 } 477 435 putchar('\n'); … … 480 438 } 481 439 482 /*----------------------------------------------------------------------*/ 440 483 441 static void showdirs(struct dnode **dn, int ndirs, int first) 484 442 { … … 494 452 if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { 495 453 if (!first) 496 p rintf("\n");454 puts(""); 497 455 first = 0; 498 456 printf("%s:\n", dn[i]->fullname); … … 502 460 if (nfiles > 0) { 503 461 /* list all files at this level */ 504 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(subdnp, nfiles);462 dnsort(subdnp, nfiles); 505 463 showfiles(subdnp, nfiles); 506 464 if (ENABLE_FEATURE_LS_RECURSIVE) { … … 510 468 dndirs = countsubdirs(subdnp, nfiles); 511 469 if (dndirs > 0) { 512 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnd, dndirs);470 dnsort(dnd, dndirs); 513 471 showdirs(dnd, dndirs, 0); 514 472 /* free the array of dnode pointers to the dirs */ … … 523 481 } 524 482 525 /*----------------------------------------------------------------------*/ 483 526 484 static struct dnode **list_dir(const char *path) 527 485 { … … 532 490 533 491 if (path == NULL) 534 return (NULL);492 return NULL; 535 493 536 494 dn = NULL; 537 495 nfiles = 0; 538 dir = bb_opendir(path);496 dir = warn_opendir(path); 539 497 if (dir == NULL) { 540 498 status = EXIT_FAILURE; 541 return (NULL); /* could not open the dir */499 return NULL; /* could not open the dir */ 542 500 } 543 501 while ((entry = readdir(dir)) != NULL) { … … 546 504 /* are we going to list the file- it may be . or .. or a hidden file */ 547 505 if (entry->d_name[0] == '.') { 548 if ((entry->d_name[1] == 0 || ( 549 entry->d_name[1] == '.' 550 && entry->d_name[2] == 0)) 551 && !(all_fmt & DISP_DOT)) 506 if ((!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2])) 507 && !(all_fmt & DISP_DOT) 508 ) { 509 continue; 510 } 511 if (!(all_fmt & DISP_HIDDEN)) 512 continue; 513 } 514 fullname = concat_path_file(path, entry->d_name); 515 cur = my_stat(fullname, bb_basename(fullname), 0); 516 if (!cur) { 517 free(fullname); 552 518 continue; 553 if (!(all_fmt & DISP_HIDDEN)) 554 continue; 555 } 556 fullname = concat_path_file(path, entry->d_name); 557 cur = my_stat(fullname, strrchr(fullname, '/') + 1); 558 if (!cur) 559 continue; 519 } 560 520 cur->allocated = 1; 561 521 cur->next = dn; … … 566 526 567 527 /* now that we know how many files there are 568 ** allocate memory for an array to hold dnode pointers528 * allocate memory for an array to hold dnode pointers 569 529 */ 570 530 if (dn == NULL) 571 return (NULL);531 return NULL; 572 532 dnp = dnalloc(nfiles); 573 533 for (i = 0, cur = dn; i < nfiles; i++) { … … 576 536 } 577 537 578 return (dnp); 579 } 580 581 /*----------------------------------------------------------------------*/ 538 return dnp; 539 } 540 541 542 #if ENABLE_FEATURE_LS_TIMESTAMPS 543 /* Do time() just once. Saves one syscall per file for "ls -l" */ 544 /* Initialized in main() */ 545 static time_t current_time_t; 546 #endif 547 582 548 static int list_single(struct dnode *dn) 583 549 { 584 550 int i, column = 0; 585 551 586 #ifdef CONFIG_FEATURE_LS_USERNAME 587 char scratch[16]; 588 #endif 589 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS 552 #if ENABLE_FEATURE_LS_TIMESTAMPS 590 553 char *filetime; 591 554 time_t ttime, age; 592 555 #endif 593 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined (CONFIG_FEATURE_LS_COLOR)556 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 594 557 struct stat info; 595 558 char append; … … 597 560 598 561 if (dn->fullname == NULL) 599 return (0);600 601 #if def CONFIG_FEATURE_LS_TIMESTAMPS562 return 0; 563 564 #if ENABLE_FEATURE_LS_TIMESTAMPS 602 565 ttime = dn->dstat.st_mtime; /* the default time */ 603 566 if (all_fmt & TIME_ACCESS) … … 607 570 filetime = ctime(&ttime); 608 571 #endif 609 #if def CONFIG_FEATURE_LS_FILETYPES572 #if ENABLE_FEATURE_LS_FILETYPES 610 573 append = append_char(dn->dstat.st_mode); 611 574 #endif … … 614 577 switch (all_fmt & (1 << i)) { 615 578 case LIST_INO: 616 column += printf("%7ld ", (long int) dn->dstat.st_ino);579 column += printf("%7ld ", (long) dn->dstat.st_ino); 617 580 break; 618 581 case LIST_BLOCKS: 619 #if _FILE_OFFSET_BITS == 64 620 column += printf("%4lld ", (long long)dn->dstat.st_blocks >> 1); 621 #else 622 column += printf("%4ld ", dn->dstat.st_blocks >> 1); 623 #endif 582 column += printf("%4"OFF_FMT"d ", (off_t) dn->dstat.st_blocks >> 1); 624 583 break; 625 584 case LIST_MODEBITS: … … 630 589 break; 631 590 case LIST_ID_NAME: 632 #ifdef CONFIG_FEATURE_LS_USERNAME 633 bb_getpwuid(scratch, dn->dstat.st_uid, sizeof(scratch)); 634 printf("%-8.8s ", scratch); 635 bb_getgrgid(scratch, dn->dstat.st_gid, sizeof(scratch)); 636 printf("%-8.8s", scratch); 591 #if ENABLE_FEATURE_LS_USERNAME 592 printf("%-8.8s %-8.8s", 593 get_cached_username(dn->dstat.st_uid), 594 get_cached_groupname(dn->dstat.st_gid)); 637 595 column += 17; 638 596 break; … … 647 605 (int) minor(dn->dstat.st_rdev)); 648 606 } else { 649 #ifdef CONFIG_FEATURE_HUMAN_READABLE650 607 if (all_fmt & LS_DISP_HR) { 651 608 column += printf("%9s ", 652 make_human_readable_str(dn->dstat.st_size, 1, 0)); 653 } else 654 #endif 655 { 656 #if _FILE_OFFSET_BITS == 64 657 column += printf("%9lld ", (long long) dn->dstat.st_size); 658 #else 659 column += printf("%9ld ", dn->dstat.st_size); 660 #endif 609 make_human_readable_str(dn->dstat.st_size, 1, 0)); 610 } else { 611 column += printf("%9"OFF_FMT"d ", (off_t) dn->dstat.st_size); 661 612 } 662 613 } 663 614 break; 664 #if def CONFIG_FEATURE_LS_TIMESTAMPS615 #if ENABLE_FEATURE_LS_TIMESTAMPS 665 616 case LIST_FULLTIME: 666 617 printf("%24.24s ", filetime); … … 669 620 case LIST_DATE_TIME: 670 621 if ((all_fmt & LIST_FULLTIME) == 0) { 671 age = time(NULL) - ttime; 622 /* current_time_t ~== time(NULL) */ 623 age = current_time_t - ttime; 672 624 printf("%6.6s ", filetime + 4); 673 625 if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { … … 681 633 break; 682 634 #endif 683 #if def CONFIG_SELINUX635 #if ENABLE_SELINUX 684 636 case LIST_CONTEXT: 685 637 { … … 688 640 689 641 if (dn->sid) { 690 /* I assume sid initilized with NULL*/691 len = strlen(dn->sid)+1;692 693 694 } else {695 642 /* I assume sid initilized with NULL */ 643 len = strlen(dn->sid) + 1; 644 safe_strncpy(context, dn->sid, len); 645 freecon(dn->sid); 646 } else { 647 safe_strncpy(context, "unknown", 8); 696 648 } 697 649 printf("%-32s ", context); … … 701 653 #endif 702 654 case LIST_FILENAME: 703 #ifdef CONFIG_FEATURE_LS_COLOR704 655 errno = 0; 656 #if ENABLE_FEATURE_LS_COLOR 705 657 if (show_color && !lstat(dn->fullname, &info)) { 706 658 printf("\033[%d;%dm", bgcolor(info.st_mode), 707 659 fgcolor(info.st_mode)); 708 660 } 709 661 #endif 710 662 column += printf("%s", dn->name); 711 #ifdef CONFIG_FEATURE_LS_COLOR712 663 if (show_color) { 713 664 printf("\033[0m"); 714 665 } 715 #endif716 666 break; 717 667 case LIST_SYMLINK: 718 668 if (S_ISLNK(dn->dstat.st_mode)) { 719 char *lpath = xreadlink(dn->fullname); 720 721 if (lpath) { 722 printf(" -> "); 723 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined (CONFIG_FEATURE_LS_COLOR) 724 if (!stat(dn->fullname, &info)) { 725 append = append_char(info.st_mode); 726 } 727 #endif 728 #ifdef CONFIG_FEATURE_LS_COLOR 729 if (show_color) { 730 errno = 0; 731 printf("\033[%d;%dm", bgcolor(info.st_mode), 732 fgcolor(info.st_mode)); 733 } 734 #endif 735 column += printf("%s", lpath) + 4; 736 #ifdef CONFIG_FEATURE_LS_COLOR 737 if (show_color) { 738 printf("\033[0m"); 739 } 740 #endif 741 free(lpath); 669 char *lpath = xmalloc_readlink_or_warn(dn->fullname); 670 if (!lpath) break; 671 printf(" -> "); 672 #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 673 if (!stat(dn->fullname, &info)) { 674 append = append_char(info.st_mode); 742 675 } 743 } 744 break; 745 #ifdef CONFIG_FEATURE_LS_FILETYPES 676 #endif 677 #if ENABLE_FEATURE_LS_COLOR 678 if (show_color) { 679 errno = 0; 680 printf("\033[%d;%dm", bgcolor(info.st_mode), 681 fgcolor(info.st_mode)); 682 } 683 #endif 684 column += printf("%s", lpath) + 4; 685 if (show_color) { 686 printf("\033[0m"); 687 } 688 free(lpath); 689 } 690 break; 691 #if ENABLE_FEATURE_LS_FILETYPES 746 692 case LIST_FILETYPE: 747 if (append != '\0') {748 p rintf("%1c",append);693 if (append) { 694 putchar(append); 749 695 column++; 750 696 } … … 756 702 return column; 757 703 } 758 759 /*----------------------------------------------------------------------*/760 704 761 705 /* "[-]Cadil1", POSIX mandated options, busybox always supports */ … … 767 711 /* "[-]K", SELinux mandated options, busybox optionally supports */ 768 712 /* "[-]e", I think we made this one up */ 769 770 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS 771 # define LS_STR_TIMESTAMPS "cetu" 772 #else 773 # define LS_STR_TIMESTAMPS "" 774 #endif 775 776 #ifdef CONFIG_FEATURE_LS_FILETYPES 777 # define LS_STR_FILETYPES "Fp" 778 #else 779 # define LS_STR_FILETYPES "" 780 #endif 781 782 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 783 # define LS_STR_FOLLOW_LINKS "L" 784 #else 785 # define LS_STR_FOLLOW_LINKS "" 786 #endif 787 788 #ifdef CONFIG_FEATURE_LS_RECURSIVE 789 # define LS_STR_RECURSIVE "R" 790 #else 791 # define LS_STR_RECURSIVE "" 792 #endif 793 794 #ifdef CONFIG_FEATURE_HUMAN_READABLE 795 # define LS_STR_HUMAN_READABLE "h" 796 #else 797 # define LS_STR_HUMAN_READABLE "" 798 #endif 799 800 #ifdef CONFIG_SELINUX 801 # define LS_STR_SELINUX "K" 802 #else 803 # define LS_STR_SELINUX "" 804 #endif 805 806 #ifdef CONFIG_FEATURE_AUTOWIDTH 807 # define LS_STR_AUTOWIDTH "T:w:" 808 #else 809 # define LS_STR_AUTOWIDTH "" 810 #endif 811 812 static const char ls_options[]="Cadil1gnsxAk" \ 813 LS_STR_TIMESTAMPS \ 814 USE_FEATURE_LS_SORTFILES("SXrv") \ 815 LS_STR_FILETYPES \ 816 LS_STR_FOLLOW_LINKS \ 817 LS_STR_RECURSIVE \ 818 LS_STR_HUMAN_READABLE \ 819 LS_STR_SELINUX \ 820 LS_STR_AUTOWIDTH; 821 822 #define LIST_MASK_TRIGGER 0 823 #define STYLE_MASK_TRIGGER STYLE_MASK 824 #define SORT_MASK_TRIGGER SORT_MASK 825 #define DISP_MASK_TRIGGER DISP_ROWS 713 static const char ls_options[] ALIGN1 = 714 "Cadil1gnsxAk" 715 USE_FEATURE_LS_TIMESTAMPS("cetu") 716 USE_FEATURE_LS_SORTFILES("SXrv") 717 USE_FEATURE_LS_FILETYPES("Fp") 718 USE_FEATURE_LS_FOLLOWLINKS("L") 719 USE_FEATURE_LS_RECURSIVE("R") 720 USE_FEATURE_HUMAN_READABLE("h") 721 USE_SELINUX("K") 722 USE_FEATURE_AUTOWIDTH("T:w:") 723 USE_SELINUX("Z"); 724 725 enum { 726 LIST_MASK_TRIGGER = 0, 727 STYLE_MASK_TRIGGER = STYLE_MASK, 728 DISP_MASK_TRIGGER = DISP_ROWS, 729 SORT_MASK_TRIGGER = SORT_MASK, 730 }; 826 731 827 732 static const unsigned opt_flags[] = { 828 LIST_SHORT | STYLE_COLUMNS, /* C */ 829 DISP_HIDDEN | DISP_DOT, /* a */ 830 DISP_NOLIST, /* d */ 831 LIST_INO, /* i */ 832 LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ 833 LIST_SHORT | STYLE_SINGLE, /* 1 */ 834 0, /* g - ingored */ 835 LIST_ID_NUMERIC, /* n */ 836 LIST_BLOCKS, /* s */ 837 DISP_ROWS, /* x */ 838 DISP_HIDDEN, /* A */ 839 #ifdef CONFIG_SELINUX 840 LIST_CONTEXT, /* k */ 841 #else 842 0, /* k - ingored */ 843 #endif 844 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS 845 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ 846 LIST_FULLTIME, /* e */ 847 ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ 848 TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ 849 #endif 850 #ifdef CONFIG_FEATURE_LS_SORTFILES 851 SORT_SIZE, /* S */ 852 SORT_EXT, /* X */ 853 SORT_ORDER_REVERSE, /* r */ 854 SORT_VERSION, /* v */ 855 #endif 856 #ifdef CONFIG_FEATURE_LS_FILETYPES 857 LIST_FILETYPE | LIST_EXEC, /* F */ 858 LIST_FILETYPE, /* p */ 859 #endif 860 #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS 861 FOLLOW_LINKS, /* L */ 862 #endif 863 #ifdef CONFIG_FEATURE_LS_RECURSIVE 864 DISP_RECURSIVE, /* R */ 865 #endif 866 #ifdef CONFIG_FEATURE_HUMAN_READABLE 867 LS_DISP_HR, /* h */ 868 #endif 869 #ifdef CONFIG_SELINUX 733 LIST_SHORT | STYLE_COLUMNS, /* C */ 734 DISP_HIDDEN | DISP_DOT, /* a */ 735 DISP_NOLIST, /* d */ 736 LIST_INO, /* i */ 737 LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ 738 LIST_SHORT | STYLE_SINGLE, /* 1 */ 739 0, /* g - ingored */ 740 LIST_ID_NUMERIC, /* n */ 741 LIST_BLOCKS, /* s */ 742 DISP_ROWS, /* x */ 743 DISP_HIDDEN, /* A */ 744 ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ 745 #if ENABLE_FEATURE_LS_TIMESTAMPS 746 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ 747 LIST_FULLTIME, /* e */ 748 ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ 749 TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ 750 #endif 751 #if ENABLE_FEATURE_LS_SORTFILES 752 SORT_SIZE, /* S */ 753 SORT_EXT, /* X */ 754 SORT_REVERSE, /* r */ 755 SORT_VERSION, /* v */ 756 #endif 757 #if ENABLE_FEATURE_LS_FILETYPES 758 LIST_FILETYPE | LIST_EXEC, /* F */ 759 LIST_FILETYPE, /* p */ 760 #endif 761 #if ENABLE_FEATURE_LS_FOLLOWLINKS 762 FOLLOW_LINKS, /* L */ 763 #endif 764 #if ENABLE_FEATURE_LS_RECURSIVE 765 DISP_RECURSIVE, /* R */ 766 #endif 767 #if ENABLE_FEATURE_HUMAN_READABLE 768 LS_DISP_HR, /* h */ 769 #endif 770 #if ENABLE_SELINUX 870 771 LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ 871 772 #endif 872 #ifdef CONFIG_FEATURE_AUTOWIDTH 873 0, 0, /* T, w - ignored */ 773 #if ENABLE_FEATURE_AUTOWIDTH 774 0, 0, /* T, w - ignored */ 775 #endif 776 #if ENABLE_SELINUX 777 LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ 874 778 #endif 875 779 (1U<<31) … … 877 781 878 782 879 /*----------------------------------------------------------------------*/ 880 783 /* THIS IS A "SAFE" APPLET, main() MAY BE CALLED INTERNALLY FROM SHELL */ 784 /* BE CAREFUL! */ 785 786 int ls_main(int argc, char **argv); 881 787 int ls_main(int argc, char **argv) 882 788 { … … 886 792 struct dnode *dn; 887 793 struct dnode *cur; 888 longopt;794 unsigned opt; 889 795 int nfiles = 0; 890 796 int dnfiles; … … 894 800 int i; 895 801 char **av; 896 #ifdef CONFIG_FEATURE_AUTOWIDTH 897 char *tabstops_str = NULL;898 char *terminal_width_str = NULL;899 #endif 900 #if def CONFIG_FEATURE_LS_COLOR901 char *color_opt;802 USE_FEATURE_AUTOWIDTH(char *tabstops_str = NULL;) 803 USE_FEATURE_AUTOWIDTH(char *terminal_width_str = NULL;) 804 USE_FEATURE_LS_COLOR(char *color_opt;) 805 806 #if ENABLE_FEATURE_LS_TIMESTAMPS 807 time(¤t_time_t); 902 808 #endif 903 809 904 810 all_fmt = LIST_SHORT | 905 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_ ORDER_FORWARD));906 907 #if def CONFIG_FEATURE_AUTOWIDTH908 /* Obtain the terminal width .*/909 get_terminal_width_height(STD OUT_FILENO, &terminal_width, NULL);811 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD)); 812 813 #if ENABLE_FEATURE_AUTOWIDTH 814 /* Obtain the terminal width */ 815 get_terminal_width_height(STDIN_FILENO, &terminal_width, NULL); 910 816 /* Go one less... */ 911 817 terminal_width--; 912 818 #endif 913 819 914 #ifdef CONFIG_FEATURE_LS_COLOR915 bb_applet_long_options = ls_color_opt;916 #endif917 918 820 /* process options */ 919 #ifdef CONFIG_FEATURE_AUTOWIDTH 920 opt = bb_getopt_ulflags(argc, argv, ls_options, &tabstops_str, &terminal_width_str 921 #ifdef CONFIG_FEATURE_LS_COLOR 922 , &color_opt 923 #endif 924 ); 925 if (tabstops_str) { 926 tabstops = atoi(tabstops_str); 927 } 928 if (terminal_width_str) { 929 terminal_width = atoi(terminal_width_str); 930 } 821 USE_FEATURE_LS_COLOR(applet_long_options = ls_color_opt;) 822 #if ENABLE_FEATURE_AUTOWIDTH 823 opt = getopt32(argv, ls_options, &tabstops_str, &terminal_width_str 824 USE_FEATURE_LS_COLOR(, &color_opt)); 825 if (tabstops_str) 826 tabstops = xatou(tabstops_str); 827 if (terminal_width_str) 828 terminal_width = xatou(terminal_width_str); 931 829 #else 932 opt = bb_getopt_ulflags(argc, argv, ls_options 933 #ifdef CONFIG_FEATURE_LS_COLOR 934 , &color_opt 935 #endif 936 ); 830 opt = getopt32(argv, ls_options USE_FEATURE_LS_COLOR(, &color_opt)); 937 831 #endif 938 832 for (i = 0; opt_flags[i] != (1U<<31); i++) { 939 833 if (opt & (1 << i)) { 940 unsigned intflags = opt_flags[i];941 942 if (flags & LIST_MASK_TRIGGER) {834 unsigned flags = opt_flags[i]; 835 836 if (flags & LIST_MASK_TRIGGER) 943 837 all_fmt &= ~LIST_MASK; 944 } 945 if (flags & STYLE_MASK_TRIGGER) { 838 if (flags & STYLE_MASK_TRIGGER) 946 839 all_fmt &= ~STYLE_MASK; 947 } 948 if (ENABLE_FEATURE_LS_SORTFILES && (flags & SORT_MASK_TRIGGER)) { 840 if (flags & SORT_MASK_TRIGGER) 949 841 all_fmt &= ~SORT_MASK; 950 } 951 if (flags & DISP_MASK_TRIGGER) { 842 if (flags & DISP_MASK_TRIGGER) 952 843 all_fmt &= ~DISP_MASK; 953 } 954 if (flags & TIME_MASK) { 844 if (flags & TIME_MASK) 955 845 all_fmt &= ~TIME_MASK; 956 } 957 if (flags & LIST_CONTEXT) { 846 if (flags & LIST_CONTEXT) 958 847 all_fmt |= STYLE_SINGLE; 959 } 960 #ifdef CONFIG_FEATURE_HUMAN_READABLE 961 if (opt == 'l') { 962 all_fmt &= ~LS_DISP_HR; 963 } 964 #endif 848 /* huh?? opt cannot be 'l' */ 849 //if (LS_DISP_HR && opt == 'l') 850 // all_fmt &= ~LS_DISP_HR; 965 851 all_fmt |= flags; 966 852 } 967 853 } 968 854 969 #ifdef CONFIG_FEATURE_LS_COLOR 970 { 971 /* find color bit value - last position for short getopt */ 972 973 #if CONFIG_FEATURE_LS_COLOR_IS_DEFAULT 974 char *p; 975 976 if ((p = getenv ("LS_COLORS")) != NULL && 977 (*p == '\0' || (strcmp(p, "none") == 0))) { 978 ; 979 } else if (isatty(STDOUT_FILENO)) { 855 #if ENABLE_FEATURE_LS_COLOR 856 /* find color bit value - last position for short getopt */ 857 if (ENABLE_FEATURE_LS_COLOR_IS_DEFAULT && isatty(STDOUT_FILENO)) { 858 char *p = getenv("LS_COLORS"); 859 /* LS_COLORS is unset, or (not empty && not "none") ? */ 860 if (!p || (p[0] && strcmp(p, "none"))) 980 861 show_color = 1; 981 } 982 #endif 983 984 if((opt & (1 << i))) { /* next flag after short options */ 985 if (color_opt == NULL || strcmp("always", color_opt) == 0) 986 show_color = 1; 987 else if (color_opt != NULL && strcmp("never", color_opt) == 0) 988 show_color = 0; 989 else if (color_opt != NULL && strcmp("auto", color_opt) == 0 && isatty(STDOUT_FILENO)) 990 show_color = 1; 991 } 862 } 863 if (opt & (1 << i)) { /* next flag after short options */ 864 if (!color_opt || !strcmp("always", color_opt)) 865 show_color = 1; 866 else if (color_opt && !strcmp("never", color_opt)) 867 show_color = 0; 868 else if (color_opt && !strcmp("auto", color_opt) && isatty(STDOUT_FILENO)) 869 show_color = 1; 992 870 } 993 871 #endif 994 872 995 873 /* sort out which command line options take precedence */ 996 #ifdef CONFIG_FEATURE_LS_RECURSIVE 997 if (all_fmt & DISP_NOLIST) 874 if (ENABLE_FEATURE_LS_RECURSIVE && (all_fmt & DISP_NOLIST)) 998 875 all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ 999 #endif1000 876 if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) { 1001 877 if (all_fmt & TIME_CHANGE) … … 1006 882 if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ 1007 883 all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); 1008 #ifdef CONFIG_FEATURE_LS_USERNAME 1009 if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) 1010 all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ 1011 #endif 884 if (ENABLE_FEATURE_LS_USERNAME) 885 if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) 886 all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ 1012 887 1013 888 /* choose a display format */ … … 1024 899 ac = argc - optind; /* how many cmd line args are left */ 1025 900 if (ac < 1) { 1026 static const char * 901 static const char *const dotdir[] = { "." }; 1027 902 1028 903 av = (char **) dotdir; … … 1036 911 all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */ 1037 912 1038 /* stuff the command line file names into a ndnode array */913 /* stuff the command line file names into a dnode array */ 1039 914 dn = NULL; 1040 915 for (oi = 0; oi < ac; oi++) { 1041 cur = my_stat(av[oi], av[oi]); 916 /* ls w/o -l follows links on command line */ 917 cur = my_stat(av[oi], av[oi], !(all_fmt & STYLE_LONG)); 1042 918 if (!cur) 1043 919 continue; … … 1049 925 1050 926 /* now that we know how many files there are 1051 ** allocate memory for an array to hold dnode pointers927 * allocate memory for an array to hold dnode pointers 1052 928 */ 1053 929 dnp = dnalloc(nfiles); … … 1058 934 1059 935 if (all_fmt & DISP_NOLIST) { 1060 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnp, nfiles);936 dnsort(dnp, nfiles); 1061 937 if (nfiles > 0) 1062 938 showfiles(dnp, nfiles); … … 1067 943 dnfiles = nfiles - dndirs; 1068 944 if (dnfiles > 0) { 1069 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnf, dnfiles);945 dnsort(dnf, dnfiles); 1070 946 showfiles(dnf, dnfiles); 1071 947 if (ENABLE_FEATURE_CLEAN_UP) … … 1073 949 } 1074 950 if (dndirs > 0) { 1075 if (ENABLE_FEATURE_LS_SORTFILES)dnsort(dnd, dndirs);951 dnsort(dnd, dndirs); 1076 952 showdirs(dnd, dndirs, dnfiles == 0); 1077 953 if (ENABLE_FEATURE_CLEAN_UP) … … 1081 957 if (ENABLE_FEATURE_CLEAN_UP) 1082 958 dfree(dnp, nfiles); 1083 return (status);1084 } 959 return status; 960 } -
branches/2.2.5/mindi-busybox/coreutils/md5_sha1_sum.c
r902 r1765 7 7 */ 8 8 9 #include <fcntl.h> 10 #include <limits.h> 11 #include <stdio.h> 12 #include <stdint.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <unistd.h> 16 17 #include "busybox.h" 9 #include "libbb.h" 18 10 19 11 typedef enum { HASH_SHA1, HASH_MD5 } hash_algo_t; … … 25 17 /* This might be useful elsewhere */ 26 18 static unsigned char *hash_bin_to_hex(unsigned char *hash_value, 27 unsigned charhash_length)19 unsigned hash_length) 28 20 { 29 int x, len, max; 30 unsigned char *hex_value; 31 32 max = (hash_length * 2) + 2; 33 hex_value = xmalloc(max); 34 for (x = len = 0; x < hash_length; x++) { 35 len += snprintf((char*)(hex_value + len), max - len, "%02x", hash_value[x]); 36 } 37 return (hex_value); 21 /* xzalloc zero-terminates */ 22 char *hex_value = xzalloc((hash_length * 2) + 1); 23 bin2hex(hex_value, (char*)hash_value, hash_length); 24 return hex_value; 38 25 } 39 26 … … 50 37 void (*final)(void*, void*); 51 38 52 if (strcmp(filename, "-") == 0) { 53 src_fd = STDIN_FILENO; 54 } else if(0 > (src_fd = open(filename, O_RDONLY))) { 55 bb_perror_msg("%s", filename); 56 return NULL; 39 src_fd = STDIN_FILENO; 40 if (NOT_LONE_DASH(filename)) { 41 src_fd = open_or_warn(filename, O_RDONLY); 42 if (src_fd < 0) { 43 return NULL; 44 } 57 45 } 58 46 … … 72 60 } 73 61 74 while (0 < (count = read(src_fd, in_buf, 4096))) {62 while (0 < (count = safe_read(src_fd, in_buf, 4096))) { 75 63 update(in_buf, count, &context); 76 64 } … … 90 78 } 91 79 92 /* This could become a common function for md5 as well, by using md5_stream */ 93 static int hash_files(int argc, char **argv, hash_algo_t hash_algo)80 int md5_sha1_sum_main(int argc, char **argv); 81 int md5_sha1_sum_main(int argc, char **argv) 94 82 { 95 83 int return_value = EXIT_SUCCESS; 96 84 uint8_t *hash_value; 97 unsigned int flags; 85 unsigned flags; 86 hash_algo_t hash_algo = ENABLE_MD5SUM 87 ? (ENABLE_SHA1SUM ? (applet_name[0] == 'm' ? HASH_MD5 : HASH_SHA1) : HASH_MD5) 88 : HASH_SHA1; 98 89 99 90 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) 100 flags = bb_getopt_ulflags(argc,argv, "scw");91 flags = getopt32(argv, "scw"); 101 92 else optind = 1; 102 93 … … 104 95 if (flags & FLAG_SILENT) { 105 96 bb_error_msg_and_die 106 (" the -s option is meaningful only when verifying checksums");97 ("-%c is meaningful only when verifying checksums", 's'); 107 98 } else if (flags & FLAG_WARN) { 108 99 bb_error_msg_and_die 109 (" the -w option is meaningful only when verifying checksums");100 ("-%c is meaningful only when verifying checksums", 'w'); 110 101 } 111 102 } 112 103 113 104 if (argc == optind) { 114 argv[argc++] = "-";105 argv[argc++] = (char*)"-"; 115 106 } 116 107 117 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && flags & FLAG_CHECK) {108 if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) { 118 109 FILE *pre_computed_stream; 119 110 int count_total = 0; … … 127 118 } 128 119 129 if (strcmp(file_ptr, "-") == 0) { 130 pre_computed_stream = stdin; 131 } else { 132 pre_computed_stream = bb_xfopen(file_ptr, "r"); 120 pre_computed_stream = stdin; 121 if (NOT_LONE_DASH(file_ptr)) { 122 pre_computed_stream = xfopen(file_ptr, "r"); 133 123 } 134 124 135 while ((line = bb_get_chomped_line_from_file(pre_computed_stream)) != NULL) {125 while ((line = xmalloc_getline(pre_computed_stream)) != NULL) { 136 126 char *filename_ptr; 137 127 138 128 count_total++; 139 129 filename_ptr = strstr(line, " "); 130 /* handle format for binary checksums */ 131 if (filename_ptr == NULL) { 132 filename_ptr = strstr(line, " *"); 133 } 140 134 if (filename_ptr == NULL) { 141 135 if (flags & FLAG_WARN) { 142 bb_error_msg(" Invalid format");136 bb_error_msg("invalid format"); 143 137 } 144 138 count_failed++; … … 169 163 count_failed, count_total); 170 164 } 171 if (bb_fclose_nonstdin(pre_computed_stream) == EOF) { 172 bb_perror_msg_and_die("Couldnt close file %s", file_ptr); 165 /* 166 if (fclose_if_not_stdin(pre_computed_stream) == EOF) { 167 bb_perror_msg_and_die("cannot close file %s", file_ptr); 173 168 } 169 */ 174 170 } else { 175 171 while (optind < argc) { … … 185 181 } 186 182 } 187 return (return_value);183 return return_value; 188 184 } 189 190 #ifdef CONFIG_MD5SUM191 int md5sum_main(int argc, char **argv)192 {193 return (hash_files(argc, argv, HASH_MD5));194 }195 #endif196 197 #ifdef CONFIG_SHA1SUM198 int sha1sum_main(int argc, char **argv)199 {200 return (hash_files(argc, argv, HASH_SHA1));201 }202 #endif -
branches/2.2.5/mindi-busybox/coreutils/mkdir.c
r821 r1765 5 5 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 30 17 */ 31 18 32 #include <stdlib.h> 33 #include <unistd.h> 19 /* Nov 28, 2006 Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support. 20 */ 21 34 22 #include <getopt.h> /* struct option */ 35 #include "busybox.h" 23 #include "libbb.h" 24 25 /* This is a NOFORK applet. Be very careful! */ 36 26 37 27 #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS 38 static const struct option mkdir_long_options[] = { 39 { "mode", 1, NULL, 'm' }, 40 { "parents", 0, NULL, 'p' }, 41 { 0, 0, 0, 0 } 42 }; 28 static const char mkdir_longopts[] ALIGN1 = 29 "mode\0" Required_argument "m" 30 "parents\0" No_argument "p" 31 #if ENABLE_SELINUX 32 "context\0" Required_argument "Z" 33 #endif 34 ; 43 35 #endif 44 36 45 int mkdir_main (int argc, char **argv) 37 int mkdir_main(int argc, char **argv); 38 int mkdir_main(int argc, char **argv) 46 39 { 47 40 mode_t mode = (mode_t)(-1); 48 41 int status = EXIT_SUCCESS; 49 42 int flags = 0; 50 unsigned longopt;43 unsigned opt; 51 44 char *smode; 45 #if ENABLE_SELINUX 46 security_context_t scontext; 47 #endif 52 48 53 49 #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS 54 bb_applet_long_options = mkdir_long_options;50 applet_long_options = mkdir_longopts; 55 51 #endif 56 opt = bb_getopt_ulflags(argc, argv, "m:p", &smode);57 if (opt & 1) {58 59 if (!bb_parse_mode 60 bb_error_msg_and_die ("invalid mode `%s'", smode);52 opt = getopt32(argv, "m:p" USE_SELINUX("Z:"), &smode USE_SELINUX(,&scontext)); 53 if (opt & 1) { 54 mode = 0777; 55 if (!bb_parse_mode(smode, &mode)) { 56 bb_error_msg_and_die("invalid mode '%s'", smode); 61 57 } 62 58 } 63 if (opt & 2)59 if (opt & 2) 64 60 flags |= FILEUTILS_RECUR; 61 #if ENABLE_SELINUX 62 if (opt & 4) { 63 selinux_or_die(); 64 setfscreatecon_or_die(scontext); 65 } 66 #endif 65 67 66 68 if (optind == argc) { -
branches/2.2.5/mindi-busybox/coreutils/mkfifo.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/mkfifo.html */ 25 12 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include <sys/types.h> 29 #include "busybox.h" 13 #include "libbb.h" 30 14 #include "libcoreutils/coreutils.h" 31 15 16 int mkfifo_main(int argc, char **argv); 32 17 int mkfifo_main(int argc, char **argv) 33 18 { … … 37 22 mode = getopt_mk_fifo_nod(argc, argv); 38 23 39 if (!*(argv += optind)) { 24 argv += optind; 25 if (!*argv) { 40 26 bb_show_usage(); 41 27 } -
branches/2.2.5/mindi-busybox/coreutils/mknod.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 10 /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ 24 11 25 #include <stdlib.h>26 #include <string.h>27 #include <sys/stat.h>28 12 #include <sys/sysmacros.h> // For makedev 29 #include <unistd.h> 30 #include " busybox.h"13 14 #include "libbb.h" 31 15 #include "libcoreutils/coreutils.h" 32 16 33 static const char modes_chars[] = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };17 static const char modes_chars[] ALIGN1 = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 }; 34 18 static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK }; 35 19 20 int mknod_main(int argc, char **argv); 36 21 int mknod_main(int argc, char **argv) 37 22 { … … 49 34 dev = 0; 50 35 if ((*name != 'p') && ((argc -= 2) == 2)) { 51 /* Autodetect what the system supports; the xe macros should36 /* Autodetect what the system supports; these macros should 52 37 * optimize out to two constants. */ 53 dev = makedev( bb_xgetularg10_bnd(argv[2], 0, major(UINT_MAX)),54 bb_xgetularg10_bnd(argv[3], 0, minor(UINT_MAX)));38 dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)), 39 xatoul_range(argv[3], 0, minor(UINT_MAX))); 55 40 } 56 41 -
branches/2.2.5/mindi-busybox/coreutils/mv.c
r821 r1765 4 4 * 5 5 * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu> 6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp> 6 7 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 9 */ 22 10 … … 28 16 #include <sys/types.h> 29 17 #include <sys/stat.h> 30 #include <unistd.h>31 18 #include <dirent.h> 32 #include <errno.h>33 #include <stdlib.h>34 19 #include <getopt.h> /* struct option */ 35 #include " busybox.h"20 #include "libbb.h" 36 21 #include "libcoreutils/coreutils.h" 37 22 38 23 #if ENABLE_FEATURE_MV_LONG_OPTIONS 39 static const struct option mv_long_options[] = { 40 { "interactive", 0, NULL, 'i' }, 41 { "force", 0, NULL, 'f' }, 42 { 0, 0, 0, 0 } 43 }; 24 static const char mv_longopts[] ALIGN1 = 25 "interactive\0" No_argument "i" 26 "force\0" No_argument "f" 27 ; 44 28 #endif 45 29 … … 47 31 #define OPT_FILEUTILS_INTERACTIVE 2 48 32 49 static const char fmt[] = "cannot overwrite %sdirectory with %sdirectory"; 33 static const char fmt[] ALIGN1 = 34 "cannot overwrite %sdirectory with %sdirectory"; 50 35 36 int mv_main(int argc, char **argv); 51 37 int mv_main(int argc, char **argv) 52 38 { … … 57 43 int dest_exists; 58 44 int status = 0; 45 int copy_flag = 0; 59 46 60 47 #if ENABLE_FEATURE_MV_LONG_OPTIONS 61 bb_applet_long_options = mv_long_options;48 applet_long_options = mv_longopts; 62 49 #endif 63 bb_opt_complementally = "f-i:i-f";64 flags = bb_getopt_ulflags(argc,argv, "fi");50 opt_complementary = "f-i:i-f"; 51 flags = getopt32(argv, "fi"); 65 52 if (optind + 2 > argc) { 66 53 bb_show_usage(); … … 71 58 72 59 if (optind + 2 == argc) { 73 if ((dest_exists = cp_mv_stat(last, &dest_stat)) < 0) { 60 dest_exists = cp_mv_stat(last, &dest_stat); 61 if (dest_exists < 0) { 74 62 return 1; 75 63 } … … 83 71 do { 84 72 dest = concat_path_file(last, bb_get_last_path_component(*argv)); 85 86 if ( (dest_exists = cp_mv_stat(dest, &dest_stat))< 0) {73 dest_exists = cp_mv_stat(dest, &dest_stat); 74 if (dest_exists < 0) { 87 75 goto RET_1; 88 76 } … … 93 81 ((access(dest, W_OK) < 0 && isatty(0)) || 94 82 (flags & OPT_FILEUTILS_INTERACTIVE))) { 95 if (fprintf(stderr, "mv: overwrite `%s'? ", dest) < 0) {83 if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { 96 84 goto RET_1; /* Ouch! fprintf failed! */ 97 85 } … … 106 94 if (errno != EXDEV || 107 95 (source_exists = cp_mv_stat(*argv, &source_stat)) < 1) { 108 bb_perror_msg(" unable to rename `%s'", *argv);96 bb_perror_msg("cannot rename '%s'", *argv); 109 97 } else { 110 98 if (dest_exists) { … … 121 109 } 122 110 if (unlink(dest) < 0) { 123 bb_perror_msg("cannot remove `%s'", dest);111 bb_perror_msg("cannot remove '%s'", dest); 124 112 goto RET_1; 125 113 } 126 114 } 127 if ((copy_file(*argv, dest, 128 FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS) >= 0) && 115 copy_flag = FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS; 116 #if ENABLE_SELINUX 117 copy_flag |= FILEUTILS_PRESERVE_SECURITY_CONTEXT; 118 #endif 119 if ((copy_file(*argv, dest, copy_flag) >= 0) && 129 120 (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) { 130 121 goto RET_0; … … 140 131 } while (*++argv != last); 141 132 142 return (status);133 return status; 143 134 } -
branches/2.2.5/mindi-busybox/coreutils/nice.c
r821 r1765 5 5 * Copyright (C) 2005 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <stdio.h>24 #include <stdlib.h>25 #include <string.h>26 #include <limits.h>27 #include <errno.h>28 #include <unistd.h>29 10 #include <sys/resource.h> 30 #include " busybox.h"11 #include "libbb.h" 31 12 32 static inline int int_add_no_wrap(int a, int b) 33 { 34 int s = a + b; 35 36 if (b < 0) { 37 if (s > a) s = INT_MIN; 38 } else { 39 if (s < a) s = INT_MAX; 40 } 41 42 return s; 43 } 44 13 int nice_main(int argc, char **argv); 45 14 int nice_main(int argc, char **argv) 46 15 { 47 static const char Xetpriority_msg[] = "cannot %cet priority";48 49 16 int old_priority, adjustment; 50 17 51 errno = 0; /* Needed for getpriority error detection. */52 18 old_priority = getpriority(PRIO_PROCESS, 0); 53 if (errno) {54 bb_perror_msg_and_die(Xetpriority_msg, 'g');55 }56 19 57 20 if (!*++argv) { /* No args, so (GNU) output current nice value. */ 58 bb_printf("%d\n", old_priority);59 bb_fflush_stdout_and_exit(EXIT_SUCCESS);21 printf("%d\n", old_priority); 22 fflush_stdout_and_exit(EXIT_SUCCESS); 60 23 } 61 24 62 25 adjustment = 10; /* Set default adjustment. */ 63 26 64 if ((argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { /* "-n" */ 27 if (argv[0][0] == '-') { 28 if (argv[0][1] == 'n') { /* -n */ 29 if (argv[0][2]) { /* -nNNNN (w/o space) */ 30 argv[0] += 2; argv--; argc++; 31 } 32 } else { /* -NNN (NNN may be negative) == -n NNN */ 33 argv[0] += 1; argv--; argc++; 34 } 65 35 if (argc < 4) { /* Missing priority and/or utility! */ 66 36 bb_show_usage(); 67 37 } 68 adjustment = bb_xgetlarg(argv[1], 10, INT_MIN, INT_MAX);38 adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2); 69 39 argv += 2; 70 40 } 71 41 72 { /* Set our priority. Handle integer wrapping for old + adjust.*/73 int new_priority = int_add_no_wrap(old_priority, adjustment);42 { /* Set our priority. */ 43 int prio = old_priority + adjustment; 74 44 75 if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) {76 bb_perror_msg_and_die( Xetpriority_msg, 's');45 if (setpriority(PRIO_PROCESS, 0, prio) < 0) { 46 bb_perror_msg_and_die("setpriority(%d)", prio); 77 47 } 78 48 } 79 49 80 execvp(*argv, argv); /* Now exec the desired program. */50 BB_EXECVP(*argv, argv); /* Now exec the desired program. */ 81 51 82 52 /* The exec failed... */ 83 bb_default_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */53 xfunc_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */ 84 54 bb_perror_msg_and_die("%s", *argv); 85 55 } -
branches/2.2.5/mindi-busybox/coreutils/nohup.c
r821 r1765 1 /* vi: setts=4: */1 /* vi: set sw=4 ts=4: */ 2 2 /* nohup - invoke a utility immune to hangups. 3 * 3 * 4 4 * Busybox version based on nohup specification at 5 5 * http://www.opengroup.org/onlinepubs/007904975/utilities/nohup.html 6 * 6 * 7 7 * Copyright 2006 Rob Landley <rob@landley.net> 8 * 8 * Copyright 2006 Bernhard Fischer 9 * 9 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 11 */ 11 12 12 #include <fcntl.h> 13 #include <signal.h> 14 #include <unistd.h> 15 #include "busybox.h" 13 #include "libbb.h" 16 14 17 int nohup_main(int argc, char *argv[]) 15 int nohup_main(int argc, char **argv); 16 int nohup_main(int argc, char **argv) 18 17 { 19 int temp, nullfd; 20 char *nohupout = "nohup.out", *home = NULL; 18 int nullfd; 19 const char *nohupout; 20 char *home = NULL; 21 21 22 // I have no idea why the standard cares about this.22 xfunc_error_retval = 127; 23 23 24 bb_default_error_retval = 127;24 if (argc < 2) bb_show_usage(); 25 25 26 if (argc<2) bb_show_usage(); 26 nullfd = xopen(bb_dev_null, O_WRONLY|O_APPEND); 27 /* If stdin is a tty, detach from it. */ 28 if (isatty(STDIN_FILENO)) 29 dup2(nullfd, STDIN_FILENO); 27 30 28 nullfd = bb_xopen(bb_dev_null, O_WRONLY|O_APPEND); 29 // If stdin is a tty, detach from it. 30 31 if (isatty(0)) dup2(nullfd, 0); 32 33 // Redirect stdout to nohup.out, either in "." or in "$HOME". 34 35 if (isatty(1)) { 36 close(1); 31 nohupout = "nohup.out"; 32 /* Redirect stdout to nohup.out, either in "." or in "$HOME". */ 33 if (isatty(STDOUT_FILENO)) { 34 close(STDOUT_FILENO); 37 35 if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) { 38 36 home = getenv("HOME"); 39 37 if (home) { 40 home= concat_path_file(home, nohupout);41 bb_xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR);38 nohupout = concat_path_file(home, nohupout); 39 xopen3(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR); 42 40 } 43 41 } 44 } else dup2(nullfd, 1);42 } else dup2(nullfd, STDOUT_FILENO); 45 43 46 // If we have a tty on strderr, announce filename and redirect to stdout. 47 // Else redirect to /dev/null. 44 /* If we have a tty on stderr, announce filename and redirect to stdout. 45 * Else redirect to /dev/null. 46 */ 47 if (isatty(STDERR_FILENO)) { 48 bb_error_msg("appending to %s", nohupout); 49 dup2(STDOUT_FILENO, STDERR_FILENO); 50 } else dup2(nullfd, STDERR_FILENO); 48 51 49 temp = isatty(2); 50 if (temp) fdprintf(2,"Writing to %s\n", home ? home : nohupout); 51 dup2(temp ? 1 : nullfd, 2); 52 close(nullfd); 53 signal (SIGHUP, SIG_IGN); 52 if (nullfd > 2) 53 close(nullfd); 54 signal(SIGHUP, SIG_IGN); 54 55 55 // Exec our new program. 56 57 execvp(argv[1],argv+1); 58 if (ENABLE_FEATURE_CLEAN_UP) free(home); 59 bb_error_msg_and_die("exec %s",argv[1]); 56 BB_EXECVP(argv[1], argv+1); 57 if (ENABLE_FEATURE_CLEAN_UP && home) 58 free((char*)nohupout); 59 bb_perror_msg_and_die("%s", argv[1]); 60 60 } -
branches/2.2.5/mindi-busybox/coreutils/od.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * od implementation for busybox … … 6 7 * The Regents of the University of California. All rights reserved. 7 8 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 10 * 22 11 * Original copyright notice is retained at the end of this file. 23 12 */ 24 13 25 #include <ctype.h> 26 #include <string.h> 14 15 #include "libbb.h" 16 #if ENABLE_DESKTOP 17 /* This one provides -t (busybox's own build script needs it) */ 18 #include "od_bloaty.c" 19 #else 27 20 #include <getopt.h> 28 #include <stdlib.h> 29 #include "busybox.h" 21 30 22 #include "dump.h" 31 23 32 #define isdecdigit(c) (isdigit)(c)24 #define isdecdigit(c) isdigit(c) 33 25 #define ishexdigit(c) (isxdigit)(c) 34 26 … … 36 28 odoffset(int argc, char ***argvp) 37 29 { 38 registerchar *num, *p;30 char *num, *p; 39 31 int base; 40 32 char *end; … … 140 132 } 141 133 142 static const char * 134 static const char *const add_strings[] = { 143 135 "16/1 \"%3_u \" \"\\n\"", /* a */ 144 136 "8/2 \" %06o \" \"\\n\"", /* B, o */ … … 156 148 }; 157 149 158 static const char od_opts[] = "aBbcDdeFfHhIiLlOoXxv";159 160 static const char od_o2si[] = {150 static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxv"; 151 152 static const char od_o2si[] ALIGN1 = { 161 153 0, 1, 2, 3, 5, 162 154 4, 6, 6, 7, 8, … … 165 157 }; 166 158 159 int od_main(int argc, char **argv); 167 160 int od_main(int argc, char **argv) 168 161 { … … 199 192 odoffset(argc, &argv); 200 193 201 return (bb_dump_dump(argv));194 return bb_dump_dump(argv); 202 195 } 196 #endif /* ENABLE_DESKTOP */ 203 197 204 198 /*- -
branches/2.2.5/mindi-busybox/coreutils/printenv.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * printenv implementation for busybox … … 5 6 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org> 6 7 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 9 */ 22 10 23 #include <stdio.h> 24 #include <string.h> 25 #include <stdlib.h> 26 #include "busybox.h" 11 #include "libbb.h" 12 extern char **environ; 27 13 14 int printenv_main(int argc, char **argv); 28 15 int printenv_main(int argc, char **argv) 29 16 { 30 extern char **environ;31 int e = 0;32 33 17 /* no variables specified, show whole env */ 34 if (argc == 1) 18 if (argc == 1) { 19 int e = 0; 35 20 while (environ[e]) 36 21 puts(environ[e++]); 37 38 /* search for specified variables and print them out if found */ 39 else { 40 int i; 41 size_t l; 22 } else { 23 /* search for specified variables and print them out if found */ 42 24 char *arg, *env; 43 25 44 for (i=1; (arg = argv[i]); ++i) 45 for (; (env = environ[e]); ++e) { 46 l = strlen(arg); 47 if (!strncmp(env, arg, l) && env[l] == '=') 48 puts(env + l + 1); 49 } 26 while ((arg = *++argv) != NULL) { 27 env = getenv(arg); 28 if (env) 29 puts(env); 30 } 50 31 } 51 32 52 bb_fflush_stdout_and_exit(0);33 fflush_stdout_and_exit(0); 53 34 } -
branches/2.2.5/mindi-busybox/coreutils/printf.c
r821 r1765 31 31 %b = print an argument string, interpreting backslash escapes 32 32 33 The `format' argument is re-used as many times as necessary33 The 'format' argument is re-used as many times as necessary 34 34 to convert all of the given arguments. 35 35 … … 39 39 // 19990508 Busy Boxed! Dave Cinege 40 40 41 #include <unistd.h> 42 #include <stdio.h> 43 #include <sys/types.h> 44 #include <string.h> 45 #include <errno.h> 46 #include <stdlib.h> 47 #include <fcntl.h> 48 #include <ctype.h> 49 #include <assert.h> 50 #include "busybox.h" 51 52 static int print_formatted (char *format, int argc, char **argv); 53 static void print_direc (char *start, size_t length, 54 int field_width, int precision, char *argument); 55 56 typedef int (*converter)(char *arg, void *result); 57 static void multiconvert(char *arg, void *result, converter convert) 58 { 59 char s[16]; 41 #include "libbb.h" 42 43 typedef void (*converter)(const char *arg, void *result); 44 45 static void multiconvert(const char *arg, void *result, converter convert) 46 { 47 char s[sizeof(int)*3 + 2]; 48 60 49 if (*arg == '"' || *arg == '\'') { 61 sprintf(s,"%d",(unsigned)*(++arg)); 62 arg=s; 63 } 64 if(convert(arg,result)) fprintf(stderr, "%s", arg); 65 } 66 67 static unsigned long xstrtoul(char *arg) 50 sprintf(s, "%d", (unsigned char)arg[1]); 51 arg = s; 52 } 53 convert(arg, result); 54 /* if there was conversion error, print unconverted string */ 55 if (errno) 56 fputs(arg, stderr); 57 } 58 59 static void conv_strtoul(const char *arg, void *result) 60 { 61 *(unsigned long*)result = bb_strtoul(arg, NULL, 0); 62 } 63 static void conv_strtol(const char *arg, void *result) 64 { 65 *(long*)result = bb_strtol(arg, NULL, 0); 66 } 67 static void conv_strtod(const char *arg, void *result) 68 { 69 char *end; 70 /* Well, this one allows leading whitespace... so what */ 71 /* What I like much less is that "-" is accepted too! :( */ 72 *(double*)result = strtod(arg, &end); 73 if (end[0]) errno = ERANGE; 74 } 75 76 static unsigned long my_xstrtoul(const char *arg) 68 77 { 69 78 unsigned long result; 70 71 multiconvert(arg,&result, (converter)safe_strtoul); 79 multiconvert(arg, &result, conv_strtoul); 72 80 return result; 73 81 } 74 82 75 static long xstrtol(char *arg)83 static long my_xstrtol(const char *arg) 76 84 { 77 85 long result; 78 multiconvert(arg, &result, (converter)safe_strtol);86 multiconvert(arg, &result, conv_strtol); 79 87 return result; 80 88 } 81 89 82 static double xstrtod(char *arg)90 static double my_xstrtod(const char *arg) 83 91 { 84 92 double result; 85 multiconvert(arg, &result, (converter)safe_strtod);93 multiconvert(arg, &result, conv_strtod); 86 94 return result; 87 95 } … … 100 108 } 101 109 102 int printf_main(int argc, char **argv) 103 { 104 char *format; 105 int args_used; 106 107 if (argc <= 1 || **(argv + 1) == '-') { 108 bb_show_usage(); 109 } 110 111 format = argv[1]; 112 argc -= 2; 113 argv += 2; 114 115 do { 116 args_used = print_formatted(format, argc, argv); 117 argc -= args_used; 118 argv += args_used; 119 } 120 while (args_used > 0 && argc > 0); 121 122 /* 123 if (argc > 0) 124 fprintf(stderr, "excess args ignored"); 125 */ 126 127 return EXIT_SUCCESS; 110 static void print_direc(char *start, size_t length, int field_width, int precision, 111 const char *argument) 112 { 113 char *p; /* Null-terminated copy of % directive. */ 114 115 p = xmalloc((unsigned) (length + 1)); 116 strncpy(p, start, length); 117 p[length] = 0; 118 119 switch (p[length - 1]) { 120 case 'd': 121 case 'i': 122 if (field_width < 0) { 123 if (precision < 0) 124 printf(p, my_xstrtol(argument)); 125 else 126 printf(p, precision, my_xstrtol(argument)); 127 } else { 128 if (precision < 0) 129 printf(p, field_width, my_xstrtol(argument)); 130 else 131 printf(p, field_width, precision, my_xstrtol(argument)); 132 } 133 break; 134 case 'o': 135 case 'u': 136 case 'x': 137 case 'X': 138 if (field_width < 0) { 139 if (precision < 0) 140 printf(p, my_xstrtoul(argument)); 141 else 142 printf(p, precision, my_xstrtoul(argument)); 143 } else { 144 if (precision < 0) 145 printf(p, field_width, my_xstrtoul(argument)); 146 else 147 printf(p, field_width, precision, my_xstrtoul(argument)); 148 } 149 break; 150 case 'f': 151 case 'e': 152 case 'E': 153 case 'g': 154 case 'G': 155 if (field_width < 0) { 156 if (precision < 0) 157 printf(p, my_xstrtod(argument)); 158 else 159 printf(p, precision, my_xstrtod(argument)); 160 } else { 161 if (precision < 0) 162 printf(p, field_width, my_xstrtod(argument)); 163 else 164 printf(p, field_width, precision, my_xstrtod(argument)); 165 } 166 break; 167 case 'c': 168 printf(p, *argument); 169 break; 170 case 's': 171 if (field_width < 0) { 172 if (precision < 0) 173 printf(p, argument); 174 else 175 printf(p, precision, argument); 176 } else { 177 if (precision < 0) 178 printf(p, field_width, argument); 179 else 180 printf(p, field_width, precision, argument); 181 } 182 break; 183 } 184 185 free(p); 128 186 } 129 187 130 188 /* Print the text in FORMAT, using ARGV (with ARGC elements) for 131 arguments to any `%' directives.189 arguments to any '%' directives. 132 190 Return the number of elements of ARGV used. */ 133 191 134 192 static int print_formatted(char *format, int argc, char **argv) 135 193 { 136 int save_argc = argc; 137 char *f; /* Pointer into `format'. */138 char *direc_start; 139 size_t direc_length; 140 int field_width; 141 int precision; 194 int save_argc = argc; /* Preserve original value. */ 195 char *f; /* Pointer into 'format'. */ 196 char *direc_start; /* Start of % directive. */ 197 size_t direc_length; /* Length of % directive. */ 198 int field_width; /* Arg to first '*', or -1 if none. */ 199 int precision; /* Arg to second '*', or -1 if none. */ 142 200 143 201 for (f = format; *f; ++f) { … … 167 225 ++direc_length; 168 226 if (argc > 0) { 169 field_width = xstrtoul(*argv);227 field_width = my_xstrtoul(*argv); 170 228 ++argv; 171 229 --argc; 172 230 } else 173 231 field_width = 0; 174 } else 232 } else { 175 233 while (isdigit(*f)) { 176 234 ++f; 177 235 ++direc_length; 178 236 } 237 } 179 238 if (*f == '.') { 180 239 ++f; … … 184 243 ++direc_length; 185 244 if (argc > 0) { 186 precision = xstrtoul(*argv);245 precision = my_xstrtoul(*argv); 187 246 ++argv; 188 247 --argc; … … 200 259 } 201 260 /* 202 203 204 261 if (!strchr ("diouxXfeEgGcs", *f)) 262 fprintf(stderr, "%%%c: invalid directive", *f); 263 */ 205 264 ++direc_length; 206 265 if (argc > 0) { … … 213 272 precision, ""); 214 273 break; 215 216 274 case '\\': 217 275 if (*++f == 'c') … … 220 278 f--; 221 279 break; 222 223 280 default: 224 281 putchar(*f); … … 229 286 } 230 287 231 static void 232 print_direc(char *start, size_t length, int field_width, int precision, 233 char *argument) 234 { 235 char *p; /* Null-terminated copy of % directive. */ 236 237 p = xmalloc((unsigned) (length + 1)); 238 strncpy(p, start, length); 239 p[length] = 0; 240 241 switch (p[length - 1]) { 242 case 'd': 243 case 'i': 244 if (field_width < 0) { 245 if (precision < 0) 246 printf(p, xstrtol(argument)); 247 else 248 printf(p, precision, xstrtol(argument)); 249 } else { 250 if (precision < 0) 251 printf(p, field_width, xstrtol(argument)); 252 else 253 printf(p, field_width, precision, xstrtol(argument)); 254 } 255 break; 256 257 case 'o': 258 case 'u': 259 case 'x': 260 case 'X': 261 if (field_width < 0) { 262 if (precision < 0) 263 printf(p, xstrtoul(argument)); 264 else 265 printf(p, precision, xstrtoul(argument)); 266 } else { 267 if (precision < 0) 268 printf(p, field_width, xstrtoul(argument)); 269 else 270 printf(p, field_width, precision, xstrtoul(argument)); 271 } 272 break; 273 274 case 'f': 275 case 'e': 276 case 'E': 277 case 'g': 278 case 'G': 279 if (field_width < 0) { 280 if (precision < 0) 281 printf(p, xstrtod(argument)); 282 else 283 printf(p, precision, xstrtod(argument)); 284 } else { 285 if (precision < 0) 286 printf(p, field_width, xstrtod(argument)); 287 else 288 printf(p, field_width, precision, xstrtod(argument)); 289 } 290 break; 291 292 case 'c': 293 printf(p, *argument); 294 break; 295 296 case 's': 297 if (field_width < 0) { 298 if (precision < 0) 299 printf(p, argument); 300 else 301 printf(p, precision, argument); 302 } else { 303 if (precision < 0) 304 printf(p, field_width, argument); 305 else 306 printf(p, field_width, precision, argument); 307 } 308 break; 309 } 310 311 free(p); 312 } 288 int printf_main(int argc, char **argv); 289 int printf_main(int argc, char **argv) 290 { 291 char *format; 292 int args_used; 293 294 if (argc <= 1 || argv[1][0] == '-') { 295 bb_show_usage(); 296 } 297 298 format = argv[1]; 299 argc -= 2; 300 argv += 2; 301 302 do { 303 args_used = print_formatted(format, argc, argv); 304 argc -= args_used; 305 argv += args_used; 306 } while (args_used > 0 && argc > 0); 307 308 /* if (argc > 0) 309 fprintf(stderr, "excess args ignored"); 310 */ 311 312 return EXIT_SUCCESS; 313 } -
branches/2.2.5/mindi-busybox/coreutils/pwd.c
r821 r1765 5 5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include "busybox.h" 10 #include "libbb.h" 26 11 12 /* This is a NOFORK applet. Be very careful! */ 13 14 int pwd_main(int argc, char **argv); 27 15 int pwd_main(int argc, char **argv) 28 16 { 29 17 char *buf; 30 18 31 if ((buf = xgetcwd(NULL)) != NULL) { 19 buf = xrealloc_getcwd_or_warn(NULL); 20 if (buf != NULL) { 32 21 puts(buf); 33 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 22 free(buf); 23 return fflush(stdout); 34 24 } 35 25 -
branches/2.2.5/mindi-busybox/coreutils/realpath.c
r821 r1765 6 6 * 7 7 * Now does proper error checking on output and returns a failure exit code 8 * if one or more paths can 8 * if one or more paths cannot be resolved. 9 9 * 10 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 11 11 */ 12 12 13 #include <limits.h> 14 #include <stdlib.h> 15 #include "busybox.h" 13 #include "libbb.h" 16 14 15 int realpath_main(int argc, char **argv); 17 16 int realpath_main(int argc, char **argv) 18 17 { … … 45 44 #endif 46 45 47 bb_fflush_stdout_and_exit(retval);46 fflush_stdout_and_exit(retval); 48 47 } -
branches/2.2.5/mindi-busybox/coreutils/rm.c
r821 r1765 5 5 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu> 6 6 * 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 22 8 */ 23 9 … … 30 16 */ 31 17 32 #include <unistd.h> 33 #include "busybox.h" 18 #include "libbb.h" 34 19 20 /* This is a NOFORK applet. Be very careful! */ 21 22 int rm_main(int argc, char **argv); 35 23 int rm_main(int argc, char **argv) 36 24 { 37 25 int status = 0; 38 26 int flags = 0; 39 unsigned longopt;27 unsigned opt; 40 28 41 bb_opt_complementally = "f-i:i-f"; 42 opt = bb_getopt_ulflags(argc, argv, "fiRr"); 43 if(opt & 1) 44 flags |= FILEUTILS_FORCE; 45 if(opt & 2) 29 opt_complementary = "f-i:i-f"; 30 opt = getopt32(argv, "fiRr"); 31 argv += optind; 32 if (opt & 1) 33 flags |= FILEUTILS_FORCE; 34 if (opt & 2) 46 35 flags |= FILEUTILS_INTERACTIVE; 47 if (opt & 12)36 if (opt & 12) 48 37 flags |= FILEUTILS_RECUR; 49 38 50 if (* (argv += optind)!= NULL) {39 if (*argv != NULL) { 51 40 do { 52 41 const char *base = bb_get_last_path_component(*argv); 53 42 54 if ( (base[0] == '.') && (!base[1] || ((base[1] == '.') && !base[2]))) {55 bb_error_msg("cannot remove `.' or `..'");43 if (DOT_OR_DOTDOT(base)) { 44 bb_error_msg("cannot remove '.' or '..'"); 56 45 } else if (remove_file(*argv, flags) >= 0) { 57 46 continue; -
branches/2.2.5/mindi-busybox/coreutils/rmdir.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */ 25 12 26 #include <stdlib.h>27 #include <unistd.h>28 13 #include <libgen.h> 29 #include " busybox.h"14 #include "libbb.h" 30 15 16 /* This is a NOFORK applet. Be very careful! */ 17 18 19 int rmdir_main(int argc, char **argv); 31 20 int rmdir_main(int argc, char **argv) 32 21 { … … 36 25 char *path; 37 26 38 flags = bb_getopt_ulflags(argc, argv, "p"); 39 27 flags = getopt32(argv, "p"); 40 28 argv += optind; 41 29 … … 50 38 do_dot = (*path == '.'); 51 39 52 do{40 while (1) { 53 41 if (rmdir(path) < 0) { 54 bb_perror_msg(" `%s'", path); /* Match gnu rmdir msg. */42 bb_perror_msg("'%s'", path); /* Match gnu rmdir msg. */ 55 43 status = EXIT_FAILURE; 56 44 } else if (flags) { … … 60 48 * returns "." if there are no parents. We must distinguish 61 49 * this from the case of the original path starting with '.'. 62 */50 */ 63 51 if (do_dot || (*path != '.') || path[1]) { 64 52 continue; … … 66 54 } 67 55 break; 68 } while (1);56 } 69 57 70 58 } while (*++argv); -
branches/2.2.5/mindi-busybox/coreutils/seq.c
r821 r1765 8 8 */ 9 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include "busybox.h" 10 #include "libbb.h" 13 11 12 /* This is a NOFORK applet. Be very careful! */ 13 14 15 int seq_main(int argc, char **argv); 14 16 int seq_main(int argc, char **argv) 15 17 { 16 double last, first,increment, i;17 18 first= increment = 1;18 double last, increment, i; 19 20 i = increment = 1; 19 21 switch (argc) { 20 22 case 4: 21 increment =atof(argv[2]);23 increment = atof(argv[2]); 22 24 case 3: 23 first=atof(argv[1]);25 i = atof(argv[1]); 24 26 case 2: 25 last =atof(argv[argc-1]);27 last = atof(argv[argc-1]); 26 28 break; 27 29 default: … … 30 32 31 33 /* You should note that this is pos-5.0.91 semantics, -- FK. */ 32 for (i = first; 33 (increment > 0 && i <= last) || (increment < 0 && i >=last); 34 i += increment) 35 { 34 while ((increment > 0 && i <= last) || (increment < 0 && i >= last)) { 36 35 printf("%g\n", i); 36 i += increment; 37 37 } 38 38 39 return EXIT_SUCCESS;39 return fflush(stdout); 40 40 } -
branches/2.2.5/mindi-busybox/coreutils/sleep.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 32 19 */ 33 20 34 #include <stdlib.h> 35 #include <limits.h> 36 #include <unistd.h> 37 #include "busybox.h" 21 #include "libbb.h" 38 22 39 #ifdef CONFIG_FEATURE_FANCY_SLEEP 40 static const struct suffix_mult sleep_suffixes[] = { 23 /* This is a NOFORK applet. Be very careful! */ 24 25 26 #if ENABLE_FEATURE_FANCY_SLEEP 27 static const struct suffix_mult sfx[] = { 41 28 { "s", 1 }, 42 29 { "m", 60 }, 43 30 { "h", 60*60 }, 44 31 { "d", 24*60*60 }, 45 { NULL, 0}32 { } 46 33 }; 47 34 #endif 48 35 36 int sleep_main(int argc, char **argv); 49 37 int sleep_main(int argc, char **argv) 50 38 { 51 unsigned intduration;39 unsigned duration; 52 40 53 #if def CONFIG_FEATURE_FANCY_SLEEP41 #if ENABLE_FEATURE_FANCY_SLEEP 54 42 55 43 if (argc < 2) { … … 60 48 duration = 0; 61 49 do { 62 duration += bb_xgetularg_bnd_sfx(*argv, 10, 63 0, UINT_MAX-duration, 64 sleep_suffixes); 50 duration += xatoul_range_sfx(*argv, 0, UINT_MAX-duration, sfx); 65 51 } while (*++argv); 66 52 67 #else /* CONFIG_FEATURE_FANCY_SLEEP */53 #else /* FEATURE_FANCY_SLEEP */ 68 54 69 55 if (argc != 2) { … … 71 57 } 72 58 73 #if UINT_MAX == ULONG_MAX 74 duration = bb_xgetularg10(argv[1]); 75 #else 76 duration = bb_xgetularg10_bnd(argv[1], 0, UINT_MAX); 77 #endif 59 duration = xatou(argv[1]); 78 60 79 #endif /* CONFIG_FEATURE_FANCY_SLEEP */61 #endif /* FEATURE_FANCY_SLEEP */ 80 62 81 63 if (sleep(duration)) { -
branches/2.2.5/mindi-busybox/coreutils/sort.c
r821 r1765 6 6 * 7 7 * MAINTAINER: Rob Landley <rob@landley.net> 8 * 8 * 9 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 10 * … … 13 13 */ 14 14 15 #include <ctype.h> 16 #include <math.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <time.h> 21 #include <unistd.h> 22 #include "busybox.h" 23 24 static int global_flags; 15 #include "libbb.h" 16 17 /* This is a NOEXEC applet. Be very careful! */ 18 25 19 26 20 /* … … 30 24 31 25 /* These are sort types */ 32 #define FLAG_n 1 /* Numeric sort */ 33 #define FLAG_g 2 /* Sort using strtod() */ 34 #define FLAG_M 4 /* Sort date */ 26 static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:t:"; 27 enum { 28 FLAG_n = 1, /* Numeric sort */ 29 FLAG_g = 2, /* Sort using strtod() */ 30 FLAG_M = 4, /* Sort date */ 35 31 /* ucsz apply to root level only, not keys. b at root level implies bb */ 36 #define FLAG_u 8/* Unique */37 #define FLAG_c 16/* Check: no output, exit(!ordered) */38 #define FLAG_s 32/* Stable sort, no ascii fallback at end */39 #define FLAG_z 64/* Input is null terminated, not \n */32 FLAG_u = 8, /* Unique */ 33 FLAG_c = 0x10, /* Check: no output, exit(!ordered) */ 34 FLAG_s = 0x20, /* Stable sort, no ascii fallback at end */ 35 FLAG_z = 0x40, /* Input is null terminated, not \n */ 40 36 /* These can be applied to search keys, the previous four can't */ 41 #define FLAG_b 128 /* Ignore leading blanks */ 42 #define FLAG_r 256 /* Reverse */ 43 #define FLAG_d 512 /* Ignore !(isalnum()|isspace()) */ 44 #define FLAG_f 1024 /* Force uppercase */ 45 #define FLAG_i 2048 /* Ignore !isprint() */ 46 #define FLAG_bb 32768 /* Ignore trailing blanks */ 47 48 49 #ifdef CONFIG_FEATURE_SORT_BIG 37 FLAG_b = 0x80, /* Ignore leading blanks */ 38 FLAG_r = 0x100, /* Reverse */ 39 FLAG_d = 0x200, /* Ignore !(isalnum()|isspace()) */ 40 FLAG_f = 0x400, /* Force uppercase */ 41 FLAG_i = 0x800, /* Ignore !isprint() */ 42 FLAG_m = 0x1000, /* ignored: merge already sorted files; do not sort */ 43 FLAG_S = 0x2000, /* ignored: -S, --buffer-size=SIZE */ 44 FLAG_T = 0x4000, /* ignored: -T, --temporary-directory=DIR */ 45 FLAG_o = 0x8000, 46 FLAG_k = 0x10000, 47 FLAG_t = 0x20000, 48 FLAG_bb = 0x80000000, /* Ignore trailing blanks */ 49 }; 50 51 #if ENABLE_FEATURE_SORT_BIG 50 52 static char key_separator; 51 53 52 static struct sort_key 53 { 54 static struct sort_key { 54 55 struct sort_key *next_key; /* linked list */ 55 unsigned shortrange[4]; /* start word, start char, end word, end char */56 intflags;56 unsigned range[4]; /* start word, start char, end word, end char */ 57 unsigned flags; 57 58 } *key_list; 58 59 59 60 static char *get_key(char *str, struct sort_key *key, int flags) 60 61 { 61 int start =0,end,len,i,j;62 int start = 0, end = 0, len, i, j; 62 63 63 64 /* Special case whole string, so we don't have to make a copy */ 64 if(key->range[0]==1 && !key->range[1] && !key->range[2] && !key->range[3] 65 && !(flags&(FLAG_b&FLAG_d&FLAG_f&FLAG_i&FLAG_bb))) return str; 66 /* Find start of key on first pass, end on second pass*/ 67 len=strlen(str); 68 69 for(j=0;j<2;j++) { 70 if(!key->range[2*j]) end=len; 65 if (key->range[0] == 1 && !key->range[1] && !key->range[2] && !key->range[3] 66 && !(flags & (FLAG_b | FLAG_d | FLAG_f | FLAG_i | FLAG_bb)) 67 ) { 68 return str; 69 } 70 71 /* Find start of key on first pass, end on second pass */ 72 len = strlen(str); 73 for (j = 0; j < 2; j++) { 74 if (!key->range[2*j]) 75 end = len; 71 76 /* Loop through fields */ 72 77 else { 73 end=0; 74 for(i=1;i<key->range[2*j]+j;i++) { 75 /* Skip leading blanks or first separator */ 76 if(str[end]) { 77 if(!key_separator && isspace(str[end])) 78 while(isspace(str[end])) end++; 79 } 80 /* Skip body of key */ 81 for(;str[end];end++) { 82 if(key_separator) { 83 if(str[end]==key_separator) break; 84 } else if(isspace(str[end])) break; 78 end = 0; 79 for (i = 1; i < key->range[2*j] + j; i++) { 80 if (key_separator) { 81 /* Skip body of key and separator */ 82 while (str[end]) { 83 if (str[end++] == key_separator) 84 break; 85 } 86 } else { 87 /* Skip leading blanks */ 88 while (isspace(str[end])) 89 end++; 90 /* Skip body of key */ 91 while (str[end]) { 92 if (isspace(str[end])) 93 break; 94 end++; 95 } 85 96 } 86 97 } 87 98 } 88 if(!j) start=end; 89 } 90 /* Key with explicit separator starts after separator */ 91 if(key_separator && str[start]==key_separator) start++; 99 if (!j) start = end; 100 } 92 101 /* Strip leading whitespace if necessary */ 93 if(flags&FLAG_b) while(isspace(str[start])) start++; 102 //XXX: skip_whitespace() 103 if (flags & FLAG_b) 104 while (isspace(str[start])) start++; 94 105 /* Strip trailing whitespace if necessary */ 95 if(flags&FLAG_bb) while(end>start && isspace(str[end-1])) end--; 106 if (flags & FLAG_bb) 107 while (end > start && isspace(str[end-1])) end--; 96 108 /* Handle offsets on start and end */ 97 if (key->range[3]) {98 end +=key->range[3]-1;99 if (end>len) end=len;100 } 101 if (key->range[1]) {102 start +=key->range[1]-1;103 if (start>len) start=len;109 if (key->range[3]) { 110 end += key->range[3] - 1; 111 if (end > len) end = len; 112 } 113 if (key->range[1]) { 114 start += key->range[1] - 1; 115 if (start > len) start = len; 104 116 } 105 117 /* Make the copy */ 106 if (end<start) end=start;107 str =bb_xstrndup(str+start,end-start);118 if (end < start) end = start; 119 str = xstrndup(str+start, end-start); 108 120 /* Handle -d */ 109 if(flags&FLAG_d) { 110 for(start=end=0;str[end];end++) 111 if(isspace(str[end]) || isalnum(str[end])) str[start++]=str[end]; 112 str[start]=0; 121 if (flags & FLAG_d) { 122 for (start = end = 0; str[end]; end++) 123 if (isspace(str[end]) || isalnum(str[end])) 124 str[start++] = str[end]; 125 str[start] = '\0'; 113 126 } 114 127 /* Handle -i */ 115 if(flags&FLAG_i) { 116 for(start=end=0;str[end];end++) 117 if(isprint(str[end])) str[start++]=str[end]; 118 str[start]=0; 128 if (flags & FLAG_i) { 129 for (start = end = 0; str[end]; end++) 130 if (isprint(str[end])) 131 str[start++] = str[end]; 132 str[start] = '\0'; 119 133 } 120 134 /* Handle -f */ 121 if(flags*FLAG_f) for(i=0;str[i];i++) str[i]=toupper(str[i]); 135 if (flags & FLAG_f) 136 for (i = 0; str[i]; i++) 137 str[i] = toupper(str[i]); 122 138 123 139 return str; … … 126 142 static struct sort_key *add_key(void) 127 143 { 128 struct sort_key **pkey=&key_list; 129 while(*pkey) pkey=&((*pkey)->next_key); 130 return *pkey=xcalloc(1,sizeof(struct sort_key)); 144 struct sort_key **pkey = &key_list; 145 while (*pkey) 146 pkey = &((*pkey)->next_key); 147 return *pkey = xzalloc(sizeof(struct sort_key)); 131 148 } 132 149 133 #define GET_LINE(fp) (global_flags&FLAG_z) ? bb_get_chunk_from_file(fp,NULL) \ 134 : bb_get_chomped_line_from_file(fp) 150 #define GET_LINE(fp) \ 151 ((option_mask32 & FLAG_z) \ 152 ? bb_get_chunk_from_file(fp, NULL) \ 153 : xmalloc_getline(fp)) 135 154 #else 136 #define GET_LINE(fp) bb_get_chomped_line_from_file(fp)155 #define GET_LINE(fp) xmalloc_getline(fp) 137 156 #endif 138 157 … … 140 159 static int compare_keys(const void *xarg, const void *yarg) 141 160 { 142 int flags =global_flags,retval=0;143 char *x, *y;144 145 #if def CONFIG_FEATURE_SORT_BIG161 int flags = option_mask32, retval = 0; 162 char *x, *y; 163 164 #if ENABLE_FEATURE_SORT_BIG 146 165 struct sort_key *key; 147 166 148 for (key=key_list;!retval && key;key=key->next_key) {149 flags =(key->flags) ? key->flags : global_flags;167 for (key = key_list; !retval && key; key = key->next_key) { 168 flags = key->flags ? key->flags : option_mask32; 150 169 /* Chop out and modify key chunks, handling -dfib */ 151 x =get_key(*(char **)xarg,key,flags);152 y =get_key(*(char **)yarg,key,flags);170 x = get_key(*(char **)xarg, key, flags); 171 y = get_key(*(char **)yarg, key, flags); 153 172 #else 154 173 /* This curly bracket serves no purpose but to match the nesting 155 level of the for () loop we're not using */174 level of the for () loop we're not using */ 156 175 { 157 x =*(char **)xarg;158 y =*(char **)yarg;176 x = *(char **)xarg; 177 y = *(char **)yarg; 159 178 #endif 160 179 /* Perform actual comparison */ 161 switch(flags&7) { 162 default: 163 bb_error_msg_and_die("Unknown sort type."); 164 break; 165 /* Ascii sort */ 166 case 0: 167 retval=strcmp(x,y); 168 break; 169 #ifdef CONFIG_FEATURE_SORT_BIG 170 case FLAG_g: 171 { 172 char *xx,*yy; 173 double dx=strtod(x,&xx), dy=strtod(y,&yy); 174 /* not numbers < NaN < -infinity < numbers < +infinity) */ 175 if(x==xx) retval=(y==yy ? 0 : -1); 176 else if(y==yy) retval=1; 177 /* Check for isnan */ 178 else if(dx != dx) retval = (dy != dy) ? 0 : -1; 179 else if(dy != dy) retval = 1; 180 /* Check for infinity. Could underflow, but it avoids libm. */ 181 else if(1.0/dx == 0.0) { 182 if(dx<0) retval=((1.0/dy == 0.0 && dy<0) ? 0 : -1); 183 else retval=((1.0/dy == 0.0 && dy>0) ? 0 : 1); 184 } else if(1.0/dy == 0.0) retval=dy<0 ? 1 : -1; 185 else retval=dx>dy ? 1 : (dx<dy ? -1 : 0); 186 break; 187 } 188 case FLAG_M: 189 { 190 struct tm thyme; 191 int dx; 192 char *xx,*yy; 193 194 xx=strptime(x,"%b",&thyme); 195 dx=thyme.tm_mon; 196 yy=strptime(y,"%b",&thyme); 197 if(!xx) retval=(!yy ? 0 : -1); 198 else if(!yy) retval=1; 199 else retval=(dx==thyme.tm_mon ? 0 : dx-thyme.tm_mon); 200 break; 201 } 202 /* Full floating point version of -n */ 203 case FLAG_n: 204 { 205 double dx=atof(x),dy=atof(y); 206 retval=dx>dy ? 1 : (dx<dy ? -1 : 0); 207 break; 208 } 209 } 180 switch (flags & 7) { 181 default: 182 bb_error_msg_and_die("unknown sort type"); 183 break; 184 /* Ascii sort */ 185 case 0: 186 #if ENABLE_LOCALE_SUPPORT 187 retval = strcoll(x, y); 188 #else 189 retval = strcmp(x, y); 190 #endif 191 break; 192 #if ENABLE_FEATURE_SORT_BIG 193 case FLAG_g: { 194 char *xx, *yy; 195 double dx = strtod(x, &xx); 196 double dy = strtod(y, &yy); 197 /* not numbers < NaN < -infinity < numbers < +infinity) */ 198 if (x == xx) 199 retval = (y == yy ? 0 : -1); 200 else if (y == yy) 201 retval = 1; 202 /* Check for isnan */ 203 else if (dx != dx) 204 retval = (dy != dy) ? 0 : -1; 205 else if (dy != dy) 206 retval = 1; 207 /* Check for infinity. Could underflow, but it avoids libm. */ 208 else if (1.0 / dx == 0.0) { 209 if (dx < 0) 210 retval = (1.0 / dy == 0.0 && dy < 0) ? 0 : -1; 211 else 212 retval = (1.0 / dy == 0.0 && dy > 0) ? 0 : 1; 213 } else if (1.0 / dy == 0.0) 214 retval = (dy < 0) ? 1 : -1; 215 else 216 retval = (dx > dy) ? 1 : ((dx < dy) ? -1 : 0); 217 break; 218 } 219 case FLAG_M: { 220 struct tm thyme; 221 int dx; 222 char *xx, *yy; 223 224 xx = strptime(x, "%b", &thyme); 225 dx = thyme.tm_mon; 226 yy = strptime(y, "%b", &thyme); 227 if (!xx) 228 retval = (!yy) ? 0 : -1; 229 else if (!yy) 230 retval = 1; 231 else 232 retval = (dx == thyme.tm_mon) ? 0 : dx - thyme.tm_mon; 233 break; 234 } 235 /* Full floating point version of -n */ 236 case FLAG_n: { 237 double dx = atof(x); 238 double dy = atof(y); 239 retval = (dx > dy) ? 1 : ((dx < dy) ? -1 : 0); 240 break; 241 } 242 } /* switch */ 210 243 /* Free key copies. */ 211 if (x!=*(char **)xarg) free(x);212 if (y!=*(char **)yarg) free(y);213 if(retval) break;244 if (x != *(char **)xarg) free(x); 245 if (y != *(char **)yarg) free(y); 246 /* if (retval) break; - done by for () anyway */ 214 247 #else 215 /* Integer version of -n for tiny systems */ 216 case FLAG_n: 217 retval=atoi(x)-atoi(y); 218 break; 219 } 220 #endif 221 } 248 /* Integer version of -n for tiny systems */ 249 case FLAG_n: 250 retval = atoi(x) - atoi(y); 251 break; 252 } /* switch */ 253 #endif 254 } /* for */ 255 222 256 /* Perform fallback sort if necessary */ 223 if(!retval && !(global_flags&FLAG_s)) 224 retval=strcmp(*(char **)xarg, *(char **)yarg); 225 //dprintf(2,"reverse=%d\n",flags&FLAG_r); 226 return ((flags&FLAG_r)?-1:1)*retval; 257 if (!retval && !(option_mask32 & FLAG_s)) 258 retval = strcmp(*(char **)xarg, *(char **)yarg); 259 260 if (flags & FLAG_r) return -retval; 261 return retval; 227 262 } 228 263 264 #if ENABLE_FEATURE_SORT_BIG 265 static unsigned str2u(char **str) 266 { 267 unsigned long lu; 268 if (!isdigit((*str)[0])) 269 bb_error_msg_and_die("bad field specification"); 270 lu = strtoul(*str, str, 10); 271 if ((sizeof(long) > sizeof(int) && lu > INT_MAX) || !lu) 272 bb_error_msg_and_die("bad field specification"); 273 return lu; 274 } 275 #endif 276 277 int sort_main(int argc, char **argv); 229 278 int sort_main(int argc, char **argv) 230 279 { 231 FILE *fp,*outfile=NULL; 232 int linecount=0,i,flag; 233 char *line,**lines=NULL,*optlist="ngMucszbrdfimS:T:o:k:t:"; 234 int c; 235 236 bb_default_error_retval = 2; 280 FILE *fp, *outfile = stdout; 281 char *line, **lines = NULL; 282 char *str_ignored, *str_o, *str_t; 283 llist_t *lst_k = NULL; 284 int i, flag; 285 int linecount = 0; 286 287 xfunc_error_retval = 2; 288 237 289 /* Parse command line options */ 238 while((c=getopt(argc,argv,optlist))>0) { 239 line=strchr(optlist,c); 240 if(!line) bb_show_usage(); 241 switch(*line) { 242 #ifdef CONFIG_FEATURE_SORT_BIG 243 case 'o': 244 if(outfile) bb_error_msg_and_die("Too many -o."); 245 outfile=bb_xfopen(optarg,"w"); 246 break; 247 case 't': 248 if(key_separator || optarg[1]) 249 bb_error_msg_and_die("Too many -t."); 250 key_separator=*optarg; 251 break; 252 /* parse sort key */ 253 case 'k': 254 { 255 struct sort_key *key=add_key(); 256 char *temp, *temp2; 257 258 temp=optarg; 259 for(i=0;*temp;) { 260 /* Start of range */ 261 key->range[2*i]=(unsigned short)strtol(temp,&temp,10); 262 if(*temp=='.') 263 key->range[(2*i)+1]=(unsigned short)strtol(temp+1,&temp,10); 264 for(;*temp;temp++) { 265 if(*temp==',' && !i++) { 266 temp++; 267 break; 268 } /* no else needed: fall through to syntax error 269 because comma isn't in optlist */ 270 temp2=strchr(optlist,*temp); 271 flag=(1<<(temp2-optlist)); 272 if(!temp2 || (flag>FLAG_M && flag<FLAG_b)) 273 bb_error_msg_and_die("Unknown key option."); 274 /* b after , means strip _trailing_ space */ 275 if(i && flag==FLAG_b) flag=FLAG_bb; 276 key->flags|=flag; 277 } 278 } 279 break; 290 /* -o and -t can be given at most once */ 291 opt_complementary = "o--o:t--t:" /* -t, -o: maximum one of each */ 292 "k::"; /* -k takes list */ 293 getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); 294 #if ENABLE_FEATURE_SORT_BIG 295 if (option_mask32 & FLAG_o) outfile = xfopen(str_o, "w"); 296 if (option_mask32 & FLAG_t) { 297 if (!str_t[0] || str_t[1]) 298 bb_error_msg_and_die("bad -t parameter"); 299 key_separator = str_t[0]; 300 } 301 /* parse sort key */ 302 while (lst_k) { 303 enum { 304 FLAG_allowed_for_k = 305 FLAG_n | /* Numeric sort */ 306 FLAG_g | /* Sort using strtod() */ 307 FLAG_M | /* Sort date */ 308 FLAG_b | /* Ignore leading blanks */ 309 FLAG_r | /* Reverse */ 310 FLAG_d | /* Ignore !(isalnum()|isspace()) */ 311 FLAG_f | /* Force uppercase */ 312 FLAG_i | /* Ignore !isprint() */ 313 0 314 }; 315 struct sort_key *key = add_key(); 316 char *str_k = lst_k->data; 317 const char *temp2; 318 319 i = 0; /* i==0 before comma, 1 after (-k3,6) */ 320 while (*str_k) { 321 /* Start of range */ 322 /* Cannot use bb_strtou - suffix can be a letter */ 323 key->range[2*i] = str2u(&str_k); 324 if (*str_k == '.') { 325 str_k++; 326 key->range[2*i+1] = str2u(&str_k); 280 327 } 281 #endif 282 default: 283 global_flags|=(1<<(line-optlist)); 284 /* global b strips leading and trailing spaces */ 285 if(global_flags&FLAG_b) global_flags|=FLAG_bb; 286 break; 287 } 288 } 328 while (*str_k) { 329 if (*str_k == ',' && !i++) { 330 str_k++; 331 break; 332 } /* no else needed: fall through to syntax error 333 because comma isn't in OPT_STR */ 334 temp2 = strchr(OPT_STR, *str_k); 335 if (!temp2) 336 bb_error_msg_and_die("unknown key option"); 337 flag = 1 << (temp2 - OPT_STR); 338 if (flag & ~FLAG_allowed_for_k) 339 bb_error_msg_and_die("unknown sort type"); 340 /* b after ',' means strip _trailing_ space */ 341 if (i && flag == FLAG_b) flag = FLAG_bb; 342 key->flags |= flag; 343 str_k++; 344 } 345 } 346 /* leaking lst_k... */ 347 lst_k = lst_k->link; 348 } 349 #endif 350 /* global b strips leading and trailing spaces */ 351 if (option_mask32 & FLAG_b) option_mask32 |= FLAG_bb; 352 289 353 /* Open input files and read data */ 290 for(i=argv[optind] ? optind : optind-1;argv[i];i++) { 291 if(i<optind || (*argv[i]=='-' && !argv[i][1])) fp=stdin; 292 else fp=bb_xfopen(argv[i],"r"); 293 for(;;) { 294 line=GET_LINE(fp); 295 if(!line) break; 296 if(!(linecount&63)) 297 lines=xrealloc(lines, sizeof(char *)*(linecount+64)); 298 lines[linecount++]=line; 354 for (i = argv[optind] ? optind : optind-1; argv[i]; i++) { 355 fp = stdin; 356 if (i >= optind && NOT_LONE_DASH(argv[i])) 357 fp = xfopen(argv[i], "r"); 358 for (;;) { 359 line = GET_LINE(fp); 360 if (!line) break; 361 if (!(linecount & 63)) 362 lines = xrealloc(lines, sizeof(char *) * (linecount + 64)); 363 lines[linecount++] = line; 299 364 } 300 365 fclose(fp); 301 366 } 302 #if def CONFIG_FEATURE_SORT_BIG367 #if ENABLE_FEATURE_SORT_BIG 303 368 /* if no key, perform alphabetic sort */ 304 if(!key_list) add_key()->range[0]=1; 369 if (!key_list) 370 add_key()->range[0] = 1; 305 371 /* handle -c */ 306 if (global_flags&FLAG_c) {307 int j =(global_flags&FLAG_u) ? -1 : 0;308 for (i=1;i<linecount;i++)309 if (compare_keys(&lines[i-1],&lines[i])>j) {310 fprintf(stderr, "Check line %d\n",i);372 if (option_mask32 & FLAG_c) { 373 int j = (option_mask32 & FLAG_u) ? -1 : 0; 374 for (i = 1; i < linecount; i++) 375 if (compare_keys(&lines[i-1], &lines[i]) > j) { 376 fprintf(stderr, "Check line %d\n", i); 311 377 return 1; 312 378 } … … 315 381 #endif 316 382 /* Perform the actual sort */ 317 qsort(lines, linecount,sizeof(char *),compare_keys);383 qsort(lines, linecount, sizeof(char *), compare_keys); 318 384 /* handle -u */ 319 if(global_flags&FLAG_u) { 320 for(flag=0,i=1;i<linecount;i++) { 321 if(!compare_keys(&lines[flag],&lines[i])) free(lines[i]); 322 else lines[++flag]=lines[i]; 323 } 324 if(linecount) linecount=flag+1; 385 if (option_mask32 & FLAG_u) { 386 flag = 0; 387 /* coreutils 6.3 drop lines for which only key is the same */ 388 /* -- disabling last-resort compare... */ 389 option_mask32 |= FLAG_s; 390 for (i = 1; i < linecount; i++) { 391 if (!compare_keys(&lines[flag], &lines[i])) 392 free(lines[i]); 393 else 394 lines[++flag] = lines[i]; 395 } 396 if (linecount) linecount = flag+1; 325 397 } 326 398 /* Print it */ 327 if(!outfile) outfile=stdout; 328 for(i=0;i<linecount;i++) fprintf(outfile,"%s\n",lines[i]); 329 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 399 for (i = 0; i < linecount; i++) 400 fprintf(outfile, "%s\n", lines[i]); 401 402 fflush_stdout_and_exit(EXIT_SUCCESS); 330 403 } -
branches/2.2.5/mindi-busybox/coreutils/stat.c
r821 r1765 1 /* vi: set ts=4:*/1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 3 * stat -- display file or file system status … … 6 6 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org> 7 7 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org> 8 * Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp> 8 9 * 9 10 * Written by Michael Meskes … … 13 14 */ 14 15 15 #include <stdio.h> 16 #include <stdint.h> 17 #include <sys/types.h> 18 #include <pwd.h> 19 #include <grp.h> 20 #include <sys/vfs.h> 21 #include <time.h> 22 #include <getopt.h> /* optind */ 23 #include <sys/stat.h> 24 #include <sys/statfs.h> 25 #include <sys/statvfs.h> 26 #include <string.h> 27 #include "busybox.h" 16 #include "libbb.h" 28 17 29 18 /* vars to control behavior */ 30 #define OPT_TERSE 2 31 #define OPT_DEREFERENCE 4 32 static long flags; 33 34 static char const *file_type(struct stat const *st) 19 #define OPT_FILESYS (1<<0) 20 #define OPT_TERSE (1<<1) 21 #define OPT_DEREFERENCE (1<<2) 22 #define OPT_SELINUX (1<<3) 23 24 static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1; 25 26 static char const * file_type(struct stat const *st) 35 27 { 36 28 /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 … … 57 49 static char const *human_time(time_t t) 58 50 { 51 /* Old 59 52 static char *str; 60 53 str = ctime(&t); 61 54 str[strlen(str)-1] = '\0'; 62 55 return str; 56 */ 57 /* coreutils 6.3 compat: */ 58 59 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t)); 60 return buf; 63 61 } 64 62 … … 73 71 static const struct types { 74 72 long type; 75 const char * fs;73 const char *const fs; 76 74 } humantypes[] = { 77 75 { 0xADFF, "affs" }, … … 112 110 { 0, "UNKNOWN" } 113 111 }; 114 for (i =0; humantypes[i].type; ++i)112 for (i = 0; humantypes[i].type; ++i) 115 113 if (humantypes[i].type == f_type) 116 114 break; … … 118 116 } 119 117 120 #if def CONFIG_FEATURE_STAT_FORMAT118 #if ENABLE_FEATURE_STAT_FORMAT 121 119 /* print statfs info */ 122 static void print_statfs(char *pformat, size_t buf_len, char m, 123 char const *filename, void const *data) 120 static void print_statfs(char *pformat, const size_t buf_len, const char m, 121 const char *const filename, void const *data 122 USE_SELINUX(, security_context_t scontext)) 124 123 { 125 124 struct statfs const *statfsbuf = data; 126 127 switch (m) { 128 case 'n': 125 if (m == 'n') { 129 126 strncat(pformat, "s", buf_len); 130 127 printf(pformat, filename); 131 break; 132 case 'i': 128 } else if (m == 'i') { 133 129 strncat(pformat, "Lx", buf_len); 134 130 printf(pformat, statfsbuf->f_fsid); 135 break; 136 case 'l': 131 } else if (m == 'l') { 137 132 strncat(pformat, "lu", buf_len); 138 133 printf(pformat, statfsbuf->f_namelen); 139 break; 140 case 't': 134 } else if (m == 't') { 141 135 strncat(pformat, "lx", buf_len); 142 printf(pformat, (unsigned long int) (statfsbuf->f_type)); /* no equiv. */ 143 break; 144 case 'T': 136 printf(pformat, (unsigned long) (statfsbuf->f_type)); /* no equiv */ 137 } else if (m == 'T') { 145 138 strncat(pformat, "s", buf_len); 146 139 printf(pformat, human_fstype(statfsbuf->f_type)); 147 break; 148 case 'b': 140 } else if (m == 'b') { 149 141 strncat(pformat, "jd", buf_len); 150 142 printf(pformat, (intmax_t) (statfsbuf->f_blocks)); 151 break; 152 case 'f': 143 } else if (m == 'f') { 153 144 strncat(pformat, "jd", buf_len); 154 145 printf(pformat, (intmax_t) (statfsbuf->f_bfree)); 155 break; 156 case 'a': 146 } else if (m == 'a') { 157 147 strncat(pformat, "jd", buf_len); 158 148 printf(pformat, (intmax_t) (statfsbuf->f_bavail)); 159 break; 160 case 'S': 161 case 's': 149 } else if (m == 's' || m == 'S') { 162 150 strncat(pformat, "lu", buf_len); 163 printf(pformat, (unsigned long int) (statfsbuf->f_bsize)); 164 break; 165 case 'c': 151 printf(pformat, (unsigned long) (statfsbuf->f_bsize)); 152 } else if (m == 'c') { 166 153 strncat(pformat, "jd", buf_len); 167 154 printf(pformat, (intmax_t) (statfsbuf->f_files)); 168 break; 169 case 'd': 155 } else if (m == 'd') { 170 156 strncat(pformat, "jd", buf_len); 171 157 printf(pformat, (intmax_t) (statfsbuf->f_ffree)); 172 break; 173 default: 158 #if ENABLE_SELINUX 159 } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) { 160 strncat(pformat, "s", buf_len); 161 printf(scontext); 162 #endif 163 } else { 174 164 strncat(pformat, "c", buf_len); 175 165 printf(pformat, m); 176 break;177 166 } 178 167 } 179 168 180 169 /* print stat info */ 181 static void print_stat(char *pformat, size_t buf_len, char m, 182 char const *filename, void const *data) 170 static void print_stat(char *pformat, const size_t buf_len, const char m, 171 const char *const filename, void const *data 172 USE_SELINUX(, security_context_t scontext)) 183 173 { 184 174 #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) … … 187 177 struct group *gw_ent; 188 178 189 switch (m) { 190 case 'n': 179 if (m == 'n') { 191 180 strncat(pformat, "s", buf_len); 192 181 printf(pformat, filename); 193 break; 194 case 'N': 182 } else if (m == 'N') { 195 183 strncat(pformat, "s", buf_len); 196 184 if (S_ISLNK(statbuf->st_mode)) { 197 char *linkname = x readlink(filename);185 char *linkname = xmalloc_readlink_or_warn(filename); 198 186 if (linkname == NULL) { 199 187 bb_perror_msg("cannot read symbolic link '%s'", filename); … … 207 195 printf(pformat, filename); 208 196 } 209 break; 210 case 'd': 197 } else if (m == 'd') { 211 198 strncat(pformat, "ju", buf_len); 212 199 printf(pformat, (uintmax_t) statbuf->st_dev); 213 break; 214 case 'D': 200 } else if (m == 'D') { 215 201 strncat(pformat, "jx", buf_len); 216 202 printf(pformat, (uintmax_t) statbuf->st_dev); 217 break; 218 case 'i': 203 } else if (m == 'i') { 219 204 strncat(pformat, "ju", buf_len); 220 205 printf(pformat, (uintmax_t) statbuf->st_ino); 221 break; 222 case 'a': 206 } else if (m == 'a') { 223 207 strncat(pformat, "lo", buf_len); 224 printf(pformat, (unsigned long int) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO))); 225 break; 226 case 'A': 208 printf(pformat, (unsigned long) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO))); 209 } else if (m == 'A') { 227 210 strncat(pformat, "s", buf_len); 228 211 printf(pformat, bb_mode_string(statbuf->st_mode)); 229 break; 230 case 'f': 212 } else if (m == 'f') { 231 213 strncat(pformat, "lx", buf_len); 232 printf(pformat, (unsigned long int) statbuf->st_mode); 233 break; 234 case 'F': 214 printf(pformat, (unsigned long) statbuf->st_mode); 215 } else if (m == 'F') { 235 216 strncat(pformat, "s", buf_len); 236 217 printf(pformat, file_type(statbuf)); 237 break; 238 case 'h': 218 } else if (m == 'h') { 239 219 strncat(pformat, "lu", buf_len); 240 printf(pformat, (unsigned long int) statbuf->st_nlink); 241 break; 242 case 'u': 220 printf(pformat, (unsigned long) statbuf->st_nlink); 221 } else if (m == 'u') { 243 222 strncat(pformat, "lu", buf_len); 244 printf(pformat, (unsigned long int) statbuf->st_uid); 245 break; 246 case 'U': 223 printf(pformat, (unsigned long) statbuf->st_uid); 224 } else if (m == 'U') { 247 225 strncat(pformat, "s", buf_len); 248 226 setpwent(); 249 227 pw_ent = getpwuid(statbuf->st_uid); 250 228 printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN"); 251 break; 252 case 'g': 229 } else if (m == 'g') { 253 230 strncat(pformat, "lu", buf_len); 254 printf(pformat, (unsigned long int) statbuf->st_gid); 255 break; 256 case 'G': 231 printf(pformat, (unsigned long) statbuf->st_gid); 232 } else if (m == 'G') { 257 233 strncat(pformat, "s", buf_len); 258 234 setgrent(); 259 235 gw_ent = getgrgid(statbuf->st_gid); 260 236 printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); 261 break; 262 case 't': 237 } else if (m == 't') { 263 238 strncat(pformat, "lx", buf_len); 264 printf(pformat, (unsigned long int) major(statbuf->st_rdev)); 265 break; 266 case 'T': 239 printf(pformat, (unsigned long) major(statbuf->st_rdev)); 240 } else if (m == 'T') { 267 241 strncat(pformat, "lx", buf_len); 268 printf(pformat, (unsigned long int) minor(statbuf->st_rdev)); 269 break; 270 case 's': 242 printf(pformat, (unsigned long) minor(statbuf->st_rdev)); 243 } else if (m == 's') { 271 244 strncat(pformat, "ju", buf_len); 272 245 printf(pformat, (uintmax_t) (statbuf->st_size)); 273 break; 274 case 'B': 246 } else if (m == 'B') { 275 247 strncat(pformat, "lu", buf_len); 276 printf(pformat, (unsigned long int) 512); //ST_NBLOCKSIZE 277 break; 278 case 'b': 248 printf(pformat, (unsigned long) 512); //ST_NBLOCKSIZE 249 } else if (m == 'b') { 279 250 strncat(pformat, "ju", buf_len); 280 251 printf(pformat, (uintmax_t) statbuf->st_blocks); 281 break; 282 case 'o': 252 } else if (m == 'o') { 283 253 strncat(pformat, "lu", buf_len); 284 printf(pformat, (unsigned long int) statbuf->st_blksize); 285 break; 286 case 'x': 254 printf(pformat, (unsigned long) statbuf->st_blksize); 255 } else if (m == 'x') { 287 256 strncat(pformat, "s", buf_len); 288 257 printf(pformat, human_time(statbuf->st_atime)); 289 break; 290 case 'X': 258 } else if (m == 'X') { 291 259 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); 292 printf(pformat, (unsigned long int) statbuf->st_atime); 293 break; 294 case 'y': 260 printf(pformat, (unsigned long) statbuf->st_atime); 261 } else if (m == 'y') { 295 262 strncat(pformat, "s", buf_len); 296 263 printf(pformat, human_time(statbuf->st_mtime)); 297 break; 298 case 'Y': 264 } else if (m == 'Y') { 299 265 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); 300 printf(pformat, (unsigned long int) statbuf->st_mtime); 301 break; 302 case 'z': 266 printf(pformat, (unsigned long) statbuf->st_mtime); 267 } else if (m == 'z') { 303 268 strncat(pformat, "s", buf_len); 304 269 printf(pformat, human_time(statbuf->st_ctime)); 305 break; 306 case 'Z': 270 } else if (m == 'Z') { 307 271 strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len); 308 printf(pformat, (unsigned long int) statbuf->st_ctime); 309 break; 310 default: 272 printf(pformat, (unsigned long) statbuf->st_ctime); 273 #if ENABLE_SELINUX 274 } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) { 275 strncat(pformat, "s", buf_len); 276 printf(pformat, scontext); 277 #endif 278 } else { 311 279 strncat(pformat, "c", buf_len); 312 280 printf(pformat, m); 313 break;314 281 } 315 282 } 316 283 317 284 static void print_it(char const *masterformat, char const *filename, 318 void (*print_func) (char *, size_t, char, char const *, void const *), 319 void const *data) 285 void (*print_func) (char *, size_t, char, char const *, void const * 286 USE_SELINUX(, security_context_t scontext)), 287 void const *data USE_SELINUX(, security_context_t scontext) ) 320 288 { 321 289 char *b; 322 290 323 291 /* create a working copy of the format string */ 324 char *format = bb_xstrdup(masterformat);325 326 /* Add 2 to accom modate our conversion of the stat `%s' format string327 * to the printf `%llu' one. */292 char *format = xstrdup(masterformat); 293 294 /* Add 2 to accomodate our conversion of the stat '%s' format string 295 * to the printf '%llu' one. */ 328 296 size_t n_alloc = strlen(format) + 2 + 1; 329 297 char *dest = xmalloc(n_alloc); … … 331 299 b = format; 332 300 while (b) { 301 size_t len; 333 302 char *p = strchr(b, '%'); 334 if (p != NULL) { 335 size_t len; 336 *p++ = '\0'; 337 fputs(b, stdout); 338 339 len = strspn(p, "#-+.I 0123456789"); 340 dest[0] = '%'; 341 memcpy(dest + 1, p, len); 342 dest[1 + len] = 0; 343 p += len; 344 345 b = p + 1; 346 switch (*p) { 347 case '\0': 348 b = NULL; 349 /* fall through */ 350 case '%': 351 putchar('%'); 352 break; 353 default: 354 print_func(dest, n_alloc, *p, filename, data); 355 break; 356 } 357 358 } else { 359 fputs(b, stdout); 303 if (!p) { 304 /* coreutils 6.3 always print <cr> at the end */ 305 /*fputs(b, stdout);*/ 306 puts(b); 307 break; 308 } 309 *p++ = '\0'; 310 fputs(b, stdout); 311 312 len = strspn(p, "#-+.I 0123456789"); 313 dest[0] = '%'; 314 memcpy(dest + 1, p, len); 315 dest[1 + len] = 0; 316 p += len; 317 318 b = p + 1; 319 switch (*p) { 320 case '\0': 360 321 b = NULL; 322 /* fall through */ 323 case '%': 324 putchar('%'); 325 break; 326 default: 327 print_func(dest, n_alloc, *p, filename, data USE_SELINUX(,scontext)); 328 break; 361 329 } 362 330 } … … 368 336 369 337 /* Stat the file system and print what we find. */ 370 static intdo_statfs(char const *filename, char const *format)338 static bool do_statfs(char const *filename, char const *format) 371 339 { 372 340 struct statfs statfsbuf; 373 341 #if ENABLE_SELINUX 342 security_context_t scontext = NULL; 343 344 if (option_mask32 & OPT_SELINUX) { 345 if ((option_mask32 & OPT_DEREFERENCE 346 ? lgetfilecon(filename, &scontext) 347 : getfilecon(filename, &scontext) 348 ) < 0 349 ) { 350 bb_perror_msg(filename); 351 return 0; 352 } 353 } 354 #endif 374 355 if (statfs(filename, &statfsbuf) != 0) { 375 356 bb_perror_msg("cannot read file system information for '%s'", filename); … … 377 358 } 378 359 379 #if def CONFIG_FEATURE_STAT_FORMAT360 #if ENABLE_FEATURE_STAT_FORMAT 380 361 if (format == NULL) 381 format = (flags & OPT_TERSE 362 #if !ENABLE_SELINUX 363 format = (option_mask32 & OPT_TERSE 382 364 ? "%n %i %l %t %s %b %f %a %c %d\n" 383 365 : " File: \"%n\"\n" … … 385 367 "Block size: %-10s\n" 386 368 "Blocks: Total: %-10b Free: %-10f Available: %a\n" 387 "Inodes: Total: %-10c Free: %d \n");388 print_it(format, filename, print_statfs, &statfsbuf );369 "Inodes: Total: %-10c Free: %d"); 370 print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); 389 371 #else 390 391 format = (flags & OPT_TERSE 372 format = (option_mask32 & OPT_TERSE 373 ? (option_mask32 & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n": 374 "%n %i %l %t %s %b %f %a %c %d\n") 375 : (option_mask32 & OPT_SELINUX ? 376 " File: \"%n\"\n" 377 " ID: %-8i Namelen: %-7l Type: %T\n" 378 "Block size: %-10s\n" 379 "Blocks: Total: %-10b Free: %-10f Available: %a\n" 380 "Inodes: Total: %-10c Free: %d" 381 " S_context: %C\n": 382 " File: \"%n\"\n" 383 " ID: %-8i Namelen: %-7l Type: %T\n" 384 "Block size: %-10s\n" 385 "Blocks: Total: %-10b Free: %-10f Available: %a\n" 386 "Inodes: Total: %-10c Free: %d\n") 387 ); 388 print_it(format, filename, print_statfs, &statfsbuf USE_SELINUX(, scontext)); 389 #endif /* SELINUX */ 390 #else /* FEATURE_STAT_FORMAT */ 391 format = (option_mask32 & OPT_TERSE 392 392 ? "%s %llx %lu " 393 393 : " File: \"%s\"\n" … … 398 398 statfsbuf.f_namelen); 399 399 400 if ( flags& OPT_TERSE)401 printf("%lx ", (unsigned long int) (statfsbuf.f_type));400 if (option_mask32 & OPT_TERSE) 401 printf("%lx ", (unsigned long) (statfsbuf.f_type)); 402 402 else 403 403 printf("Type: %s\n", human_fstype(statfsbuf.f_type)); 404 404 405 format = (flags & OPT_TERSE 405 #if !ENABLE_SELINUX 406 format = (option_mask32 & OPT_TERSE 406 407 ? "%lu %ld %ld %ld %ld %ld\n" 407 408 : "Block size: %-10lu\n" … … 409 410 "Inodes: Total: %-10jd Free: %jd\n"); 410 411 printf(format, 411 (unsigned long int) (statfsbuf.f_bsize),412 (unsigned long) (statfsbuf.f_bsize), 412 413 (intmax_t) (statfsbuf.f_blocks), 413 414 (intmax_t) (statfsbuf.f_bfree), … … 415 416 (intmax_t) (statfsbuf.f_files), 416 417 (intmax_t) (statfsbuf.f_ffree)); 417 #endif 418 418 #else 419 format = (option_mask32 & OPT_TERSE 420 ? (option_mask32 & OPT_SELINUX ? "%lu %ld %ld %ld %ld %ld %C\n": 421 "%lu %ld %ld %ld %ld %ld\n") 422 : (option_mask32 & OPT_SELINUX ? 423 "Block size: %-10lu\n" 424 "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" 425 "Inodes: Total: %-10jd Free: %jd" 426 "S_context: %C\n": 427 "Block size: %-10lu\n" 428 "Blocks: Total: %-10jd Free: %-10jd Available: %jd\n" 429 "Inodes: Total: %-10jd Free: %jd\n")); 430 printf(format, 431 (unsigned long) (statfsbuf.f_bsize), 432 (intmax_t) (statfsbuf.f_blocks), 433 (intmax_t) (statfsbuf.f_bfree), 434 (intmax_t) (statfsbuf.f_bavail), 435 (intmax_t) (statfsbuf.f_files), 436 (intmax_t) (statfsbuf.f_ffree), 437 scontext); 438 439 if (scontext) 440 freecon(scontext); 441 #endif 442 #endif /* FEATURE_STAT_FORMAT */ 419 443 return 1; 420 444 } 421 445 422 446 /* stat the file and print what we find */ 423 static intdo_stat(char const *filename, char const *format)447 static bool do_stat(char const *filename, char const *format) 424 448 { 425 449 struct stat statbuf; 426 427 if ((flags & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) { 450 #if ENABLE_SELINUX 451 security_context_t scontext = NULL; 452 453 if (option_mask32 & OPT_SELINUX) { 454 if ((option_mask32 & OPT_DEREFERENCE 455 ? lgetfilecon(filename, &scontext) 456 : getfilecon(filename, &scontext) 457 ) < 0 458 ) { 459 bb_perror_msg(filename); 460 return 0; 461 } 462 } 463 #endif 464 if ((option_mask32 & OPT_DEREFERENCE ? stat : lstat) (filename, &statbuf) != 0) { 428 465 bb_perror_msg("cannot stat '%s'", filename); 429 466 return 0; 430 467 } 431 468 432 #if def CONFIG_FEATURE_STAT_FORMAT469 #if ENABLE_FEATURE_STAT_FORMAT 433 470 if (format == NULL) { 434 if (flags & OPT_TERSE) { 435 format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"; 471 #if !ENABLE_SELINUX 472 if (option_mask32 & OPT_TERSE) { 473 format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o"; 436 474 } else { 437 475 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { … … 452 490 } 453 491 } 454 }455 print_it(format, filename, print_stat, &statbuf);456 492 #else 457 if (flags & OPT_TERSE) { 458 printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu\n", 493 if (option_mask32 & OPT_TERSE) { 494 format = (option_mask32 & OPT_SELINUX ? 495 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n": 496 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"); 497 } else { 498 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { 499 format = (option_mask32 & OPT_SELINUX ? 500 " File: \"%N\"\n" 501 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 502 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" 503 " Device type: %t,%T\n" 504 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 505 " S_Context: %C\n" 506 "Access: %x\n" "Modify: %y\n" "Change: %z\n": 507 " File: \"%N\"\n" 508 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 509 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" 510 " Device type: %t,%T\n" 511 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 512 "Access: %x\n" "Modify: %y\n" "Change: %z\n"); 513 } else { 514 format = (option_mask32 & OPT_SELINUX ? 515 " File: \"%N\"\n" 516 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 517 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 518 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 519 "S_Context: %C\n" 520 "Access: %x\n" "Modify: %y\n" "Change: %z\n": 521 " File: \"%N\"\n" 522 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 523 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 524 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 525 "Access: %x\n" "Modify: %y\n" "Change: %z\n"); 526 } 527 } 528 #endif 529 } 530 print_it(format, filename, print_stat, &statbuf USE_SELINUX(, scontext)); 531 #else /* FEATURE_STAT_FORMAT */ 532 if (option_mask32 & OPT_TERSE) { 533 printf("%s %ju %ju %lx %lu %lu %jx %ju %lu %lx %lx %lu %lu %lu %lu" 534 SKIP_SELINUX("\n"), 459 535 filename, 460 536 (uintmax_t) (statbuf.st_size), 461 537 (uintmax_t) statbuf.st_blocks, 462 (unsigned long int) statbuf.st_mode,463 (unsigned long int) statbuf.st_uid,464 (unsigned long int) statbuf.st_gid,538 (unsigned long) statbuf.st_mode, 539 (unsigned long) statbuf.st_uid, 540 (unsigned long) statbuf.st_gid, 465 541 (uintmax_t) statbuf.st_dev, 466 542 (uintmax_t) statbuf.st_ino, 467 (unsigned long int) statbuf.st_nlink,468 (unsigned long int) major(statbuf.st_rdev),469 (unsigned long int) minor(statbuf.st_rdev),470 (unsigned long int) statbuf.st_atime,471 (unsigned long int) statbuf.st_mtime,472 (unsigned long int) statbuf.st_ctime,473 (unsigned long int) statbuf.st_blksize543 (unsigned long) statbuf.st_nlink, 544 (unsigned long) major(statbuf.st_rdev), 545 (unsigned long) minor(statbuf.st_rdev), 546 (unsigned long) statbuf.st_atime, 547 (unsigned long) statbuf.st_mtime, 548 (unsigned long) statbuf.st_ctime, 549 (unsigned long) statbuf.st_blksize 474 550 ); 551 #if ENABLE_SELINUX 552 if (option_mask32 & OPT_SELINUX) 553 printf(" %lc\n", *scontext); 554 else 555 putchar('\n'); 556 #endif 475 557 } else { 476 558 char *linkname = NULL; … … 484 566 485 567 if (S_ISLNK(statbuf.st_mode)) 486 linkname = x readlink(filename);568 linkname = xmalloc_readlink_or_warn(filename); 487 569 if (linkname) 488 570 printf(" File: \"%s\" -> \"%s\"\n", filename, linkname); … … 494 576 (uintmax_t) (statbuf.st_size), 495 577 (uintmax_t) statbuf.st_blocks, 496 (unsigned long int) statbuf.st_blksize,578 (unsigned long) statbuf.st_blksize, 497 579 file_type(&statbuf), 498 580 (uintmax_t) statbuf.st_dev, 499 581 (uintmax_t) statbuf.st_dev, 500 582 (uintmax_t) statbuf.st_ino, 501 (unsigned long int) statbuf.st_nlink);583 (unsigned long) statbuf.st_nlink); 502 584 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) 503 585 printf(" Device type: %lx,%lx\n", 504 (unsigned long int) major(statbuf.st_rdev),505 (unsigned long int) minor(statbuf.st_rdev));586 (unsigned long) major(statbuf.st_rdev), 587 (unsigned long) minor(statbuf.st_rdev)); 506 588 else 507 589 putchar('\n'); 508 printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n" 509 "Access: %s\n" "Modify: %s\n" "Change: %s\n", 510 (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), 590 printf("Access: (%04lo/%10.10s) Uid: (%5lu/%8s) Gid: (%5lu/%8s)\n", 591 (unsigned long) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)), 511 592 bb_mode_string(statbuf.st_mode), 512 (unsigned long int) statbuf.st_uid,593 (unsigned long) statbuf.st_uid, 513 594 (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN", 514 (unsigned long int) statbuf.st_gid, 515 (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN", 595 (unsigned long) statbuf.st_gid, 596 (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN"); 597 #if ENABLE_SELINUX 598 printf(" S_Context: %lc\n", *scontext); 599 #endif 600 printf("Access: %s\n" "Modify: %s\n" "Change: %s\n", 516 601 human_time(statbuf.st_atime), 517 602 human_time(statbuf.st_mtime), 518 603 human_time(statbuf.st_ctime)); 519 604 } 520 #endif 605 #endif /* FEATURE_STAT_FORMAT */ 521 606 return 1; 522 607 } 523 608 609 int stat_main(int argc, char **argv); 524 610 int stat_main(int argc, char **argv) 525 611 { 612 char *format = NULL; 526 613 int i; 527 char *format = NULL;528 614 int ok = 1; 529 int (*statfunc)(char const *, char const *) = do_stat; 530 531 flags = bb_getopt_ulflags(argc, argv, "ftL" 532 USE_FEATURE_STAT_FORMAT("c:", &format) 615 bool (*statfunc)(char const *, char const *) = do_stat; 616 617 getopt32(argv, "ftL" 618 USE_SELINUX("Z") 619 USE_FEATURE_STAT_FORMAT("c:", &format) 533 620 ); 534 621 535 if ( flags & 1)/* -f */622 if (option_mask32 & OPT_FILESYS) /* -f */ 536 623 statfunc = do_statfs; 537 624 if (argc == optind) /* files */ 538 625 bb_show_usage(); 539 626 627 #if ENABLE_SELINUX 628 if (option_mask32 & OPT_SELINUX) { 629 selinux_or_die(); 630 } 631 #endif /* ENABLE_SELINUX */ 540 632 for (i = optind; i < argc; ++i) 541 633 ok &= statfunc(argv[i], format); -
branches/2.2.5/mindi-busybox/coreutils/stty.c
r821 r1765 22 22 */ 23 23 24 //#define TEST 25 26 #include "busybox.h" 27 #include <stddef.h> 28 #include <termios.h> 29 #include <sys/ioctl.h> 30 31 #include <sys/param.h> 32 #include <unistd.h> 33 34 #ifndef STDIN_FILENO 35 # define STDIN_FILENO 0 36 #endif 37 38 #ifndef STDOUT_FILENO 39 # define STDOUT_FILENO 1 40 #endif 41 42 #include <stdlib.h> 43 #include <string.h> 44 #include <assert.h> 45 #include <ctype.h> 46 #include <errno.h> 47 #include <limits.h> 48 #include <fcntl.h> 49 50 #define STREQ(a, b) (strcmp ((a), (b)) == 0) 51 24 #include "libbb.h" 52 25 53 26 #ifndef _POSIX_VDISABLE … … 56 29 57 30 #define Control(c) ((c) & 0x1f) 58 /* Canonical values for control characters .*/31 /* Canonical values for control characters */ 59 32 #ifndef CINTR 60 # define CINTR Control 33 # define CINTR Control('c') 61 34 #endif 62 35 #ifndef CQUIT … … 67 40 #endif 68 41 #ifndef CKILL 69 # define CKILL Control 42 # define CKILL Control('u') 70 43 #endif 71 44 #ifndef CEOF 72 # define CEOF Control 45 # define CEOF Control('d') 73 46 #endif 74 47 #ifndef CEOL … … 76 49 #endif 77 50 #ifndef CSTART 78 # define CSTART Control 51 # define CSTART Control('q') 79 52 #endif 80 53 #ifndef CSTOP 81 # define CSTOP Control 54 # define CSTOP Control('s') 82 55 #endif 83 56 #ifndef CSUSP 84 # define CSUSP Control 57 # define CSUSP Control('z') 85 58 #endif 86 59 #if defined(VEOL2) && !defined(CEOL2) 87 60 # define CEOL2 _POSIX_VDISABLE 88 61 #endif 89 /* ISC renamed swtch to susp for termios, but we'll accept either name .*/62 /* ISC renamed swtch to susp for termios, but we'll accept either name */ 90 63 #if defined(VSUSP) && !defined(VSWTCH) 91 64 # define VSWTCH VSUSP … … 96 69 #endif 97 70 98 /* SunOS 5.3 loses (^Z doesn't work) if `swtch' is the same as `susp'.99 So the default is to disable `swtch.' */100 #if defined (__sparc__) && defined(__svr4__)71 /* SunOS 5.3 loses (^Z doesn't work) if 'swtch' is the same as 'susp'. 72 So the default is to disable 'swtch.' */ 73 #if defined(__sparc__) && defined(__svr4__) 101 74 # undef CSWTCH 102 75 # define CSWTCH _POSIX_VDISABLE 103 76 #endif 104 77 105 #if defined(VWERSE) && !defined 78 #if defined(VWERSE) && !defined(VWERASE) /* AIX-3.2.5 */ 106 79 # define VWERASE VWERSE 107 80 #endif 108 #if defined(VDSUSP) && !defined 109 # define CDSUSP Control 81 #if defined(VDSUSP) && !defined(CDSUSP) 82 # define CDSUSP Control('y') 110 83 #endif 111 84 #if !defined(VREPRINT) && defined(VRPRNT) /* Irix 4.0.5 */ … … 113 86 #endif 114 87 #if defined(VREPRINT) && !defined(CRPRNT) 115 # define CRPRNT Control 88 # define CRPRNT Control('r') 116 89 #endif 117 90 #if defined(VWERASE) && !defined(CWERASE) 118 # define CWERASE Control 91 # define CWERASE Control('w') 119 92 #endif 120 93 #if defined(VLNEXT) && !defined(CLNEXT) 121 # define CLNEXT Control 94 # define CLNEXT Control('v') 122 95 #endif 123 96 #if defined(VDISCARD) && !defined(VFLUSHO) … … 137 110 #endif 138 111 #if defined(VFLUSHO) && !defined(CFLUSHO) 139 # define CFLUSHO Control 112 # define CFLUSHO Control('o') 140 113 #endif 141 114 #if defined(VSTATUS) && !defined(CSTATUS) 142 # define CSTATUS Control 143 #endif 144 145 /* Which speeds to set .*/115 # define CSTATUS Control('t') 116 #endif 117 118 /* Which speeds to set */ 146 119 enum speed_setting { 147 120 input_speed, output_speed, both_speeds 148 121 }; 149 122 150 /* Which member(s) of `struct termios' a mode uses.*/151 enum mode_type{123 /* Which member(s) of 'struct termios' a mode uses */ 124 enum { 152 125 /* Do NOT change the order or values, as mode_type_flag() 153 * depends on them .*/126 * depends on them */ 154 127 control, input, output, local, combination 155 128 }; 156 129 157 158 static const char evenp [] = "evenp"; 159 static const char raw [] = "raw"; 160 static const char stty_min [] = "min"; 161 static const char stty_time [] = "time"; 162 static const char stty_swtch[] = "swtch"; 163 static const char stty_eol [] = "eol"; 164 static const char stty_eof [] = "eof"; 165 static const char parity [] = "parity"; 166 static const char stty_oddp [] = "oddp"; 167 static const char stty_nl [] = "nl"; 168 static const char stty_ek [] = "ek"; 169 static const char stty_sane [] = "sane"; 170 static const char cbreak [] = "cbreak"; 171 static const char stty_pass8[] = "pass8"; 172 static const char litout [] = "litout"; 173 static const char cooked [] = "cooked"; 174 static const char decctlq [] = "decctlq"; 175 static const char stty_tabs [] = "tabs"; 176 static const char stty_lcase[] = "lcase"; 177 static const char stty_LCASE[] = "LCASE"; 178 static const char stty_crt [] = "crt"; 179 static const char stty_dec [] = "dec"; 180 181 182 /* Flags for `struct mode_info'. */ 183 #define SANE_SET 1 /* Set in `sane' mode. */ 184 #define SANE_UNSET 2 /* Unset in `sane' mode. */ 185 #define REV 4 /* Can be turned off by prepending `-'. */ 186 #define OMIT 8 /* Don't display value. */ 187 188 /* Each mode. */ 130 static const char evenp [] ALIGN1 = "evenp"; 131 static const char raw [] ALIGN1 = "raw"; 132 static const char stty_min [] ALIGN1 = "min"; 133 static const char stty_time [] ALIGN1 = "time"; 134 static const char stty_swtch[] ALIGN1 = "swtch"; 135 static const char stty_eol [] ALIGN1 = "eol"; 136 static const char stty_eof [] ALIGN1 = "eof"; 137 static const char parity [] ALIGN1 = "parity"; 138 static const char stty_oddp [] ALIGN1 = "oddp"; 139 static const char stty_nl [] ALIGN1 = "nl"; 140 static const char stty_ek [] ALIGN1 = "ek"; 141 static const char stty_sane [] ALIGN1 = "sane"; 142 static const char cbreak [] ALIGN1 = "cbreak"; 143 static const char stty_pass8[] ALIGN1 = "pass8"; 144 static const char litout [] ALIGN1 = "litout"; 145 static const char cooked [] ALIGN1 = "cooked"; 146 static const char decctlq [] ALIGN1 = "decctlq"; 147 static const char stty_tabs [] ALIGN1 = "tabs"; 148 static const char stty_lcase[] ALIGN1 = "lcase"; 149 static const char stty_LCASE[] ALIGN1 = "LCASE"; 150 static const char stty_crt [] ALIGN1 = "crt"; 151 static const char stty_dec [] ALIGN1 = "dec"; 152 153 /* Flags for 'struct mode_info' */ 154 #define SANE_SET 1 /* Set in 'sane' mode */ 155 #define SANE_UNSET 2 /* Unset in 'sane' mode */ 156 #define REV 4 /* Can be turned off by prepending '-' */ 157 #define OMIT 8 /* Don't display value */ 158 159 /* Each mode */ 189 160 struct mode_info { 190 const char * name; /* Name given on command line.*/191 /* enum mode_type type;*/192 c har type; /* Which structure element to change.*/193 char flags; /* Setting and display options.*/194 unsigned short mask; /* Other bits to turn off for this mode.*/195 unsigned long bits; /* Bits to set for this mode.*/161 const char *const name; /* Name given on command line */ 162 const unsigned char type; /* Which structure element to change */ 163 const unsigned char flags; /* Setting and display options */ 164 /* were using short here, but ppc32 was unhappy: */ 165 const tcflag_t mask; /* Other bits to turn off for this mode */ 166 const tcflag_t bits; /* Bits to set for this mode */ 196 167 }; 197 168 169 /* We can optimize it further by using name[8] instead of char *name */ 170 /* but beware of "if (info->name == evenp)" checks! */ 171 /* Need to replace them with "if (info == &mode_info[EVENP_INDX])" */ 172 198 173 #define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B } 199 174 200 static const struct 175 static const struct mode_info mode_info[] = { 201 176 MI_ENTRY("parenb", control, REV, PARENB, 0 ), 202 177 MI_ENTRY("parodd", control, REV, PARODD, 0 ), … … 333 308 MI_ENTRY(decctlq, combination, REV | OMIT, 0, 0 ), 334 309 #endif 335 #if defined (TABDLY) || defined(OXTABS)310 #if defined(TABDLY) || defined(OXTABS) 336 311 MI_ENTRY(stty_tabs, combination, REV | OMIT, 0, 0 ), 337 312 #endif … … 345 320 346 321 enum { 347 NUM_mode_info = 348 (sizeof(mode_info) / sizeof(struct mode_info)) 322 NUM_mode_info = ARRAY_SIZE(mode_info) 349 323 }; 350 324 351 /* Control character settings .*/325 /* Control character settings */ 352 326 struct control_info { 353 const char * name; /* Name given on command line.*/354 unsigned char saneval; /* Value to set for `stty sane'.*/355 unsigned char offset; /* Offset in c_cc.*/327 const char *const name; /* Name given on command line */ 328 const unsigned char saneval; /* Value to set for 'stty sane' */ 329 const unsigned char offset; /* Offset in c_cc */ 356 330 }; 357 331 358 /* Control characters .*/359 360 static const struct 332 /* Control characters */ 333 334 static const struct control_info control_info[] = { 361 335 {"intr", CINTR, VINTR}, 362 336 {"quit", CQUIT, VQUIT}, … … 392 366 {"status", CSTATUS, VSTATUS}, 393 367 #endif 394 /* These must be last because of the display routines .*/368 /* These must be last because of the display routines */ 395 369 {stty_min, 1, VMIN}, 396 370 {stty_time, 0, VTIME}, … … 398 372 399 373 enum { 400 NUM_control_info = 401 (sizeof(control_info) / sizeof(struct control_info)) 374 NUM_control_info = ARRAY_SIZE(control_info) 402 375 }; 403 376 404 #define EMT(t) ((enum mode_type)(t)) 405 406 static const char * visible(unsigned int ch); 407 static int recover_mode(char *arg, struct termios *mode); 408 static int screen_columns(void); 409 static int set_mode(const struct mode_info *info, 410 int reversed, struct termios *mode); 411 static speed_t string_to_baud(const char *arg); 412 static tcflag_t* mode_type_flag(enum mode_type type, struct termios *mode); 413 static void display_all(struct termios *mode); 414 static void display_changed(struct termios *mode); 415 static void display_recoverable(struct termios *mode); 416 static void display_speed(struct termios *mode, int fancy); 417 static void display_window_size(int fancy); 418 static void sane_mode(struct termios *mode); 419 static void set_control_char(const struct control_info *info, 420 const char *arg, struct termios *mode); 421 static void set_speed(enum speed_setting type, 422 const char *arg, struct termios *mode); 423 static void set_window_size(int rows, int cols); 424 425 static const char *device_name; 426 427 static ATTRIBUTE_NORETURN void perror_on_device(const char *fmt) 377 /* The width of the screen, for output wrapping */ 378 unsigned max_col = 80; /* default */ 379 380 struct globals { 381 /* Current position, to know when to wrap */ 382 unsigned current_col; 383 char buf[10]; 384 }; 385 #define G (*(struct globals*)&bb_common_bufsiz1) 386 387 static const char *device_name = bb_msg_standard_input; 388 389 /* Return a string that is the printable representation of character CH */ 390 /* Adapted from 'cat' by Torbjorn Granlund */ 391 static const char *visible(unsigned ch) 392 { 393 char *bpout = G.buf; 394 395 if (ch == _POSIX_VDISABLE) 396 return "<undef>"; 397 398 if (ch >= 128) { 399 ch -= 128; 400 *bpout++ = 'M'; 401 *bpout++ = '-'; 402 } 403 404 if (ch < 32) { 405 *bpout++ = '^'; 406 *bpout++ = ch + 64; 407 } else if (ch < 127) { 408 *bpout++ = ch; 409 } else { 410 *bpout++ = '^'; 411 *bpout++ = '?'; 412 } 413 414 *bpout = '\0'; 415 return G.buf; 416 } 417 418 static tcflag_t *mode_type_flag(unsigned type, const struct termios *mode) 419 { 420 static const unsigned char tcflag_offsets[] ALIGN1 = { 421 offsetof(struct termios, c_cflag), /* control */ 422 offsetof(struct termios, c_iflag), /* input */ 423 offsetof(struct termios, c_oflag), /* output */ 424 offsetof(struct termios, c_lflag) /* local */ 425 }; 426 427 if (type <= local) { 428 return (tcflag_t*) (((char*)mode) + tcflag_offsets[type]); 429 } 430 return NULL; 431 } 432 433 static void set_speed_or_die(enum speed_setting type, const char *const arg, 434 struct termios * const mode) 435 { 436 speed_t baud; 437 438 baud = tty_value_to_baud(xatou(arg)); 439 440 if (type != output_speed) { /* either input or both */ 441 cfsetispeed(mode, baud); 442 } 443 if (type != input_speed) { /* either output or both */ 444 cfsetospeed(mode, baud); 445 } 446 } 447 448 static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt) 428 449 { 429 450 bb_perror_msg_and_die(fmt, device_name); 430 451 } 431 452 432 433 /* The width of the screen, for output wrapping. */ 434 static int max_col; 435 436 /* Current position, to know when to wrap. */ 437 static int current_col; 453 static void perror_on_device(const char *fmt) 454 { 455 bb_perror_msg(fmt, device_name); 456 } 438 457 439 458 /* Print format string MESSAGE and optional args. 440 459 Wrap to next line first if it won't fit. 441 Print a space first unless MESSAGE will start a new line. */ 442 460 Print a space first unless MESSAGE will start a new line */ 443 461 static void wrapf(const char *message, ...) 444 462 { 463 char buf[128]; 445 464 va_list args; 446 char buf[1024]; /* Plenty long for our needs. */447 465 int buflen; 448 466 449 467 va_start(args, message); 450 vsprintf(buf, message, args);468 buflen = vsnprintf(buf, sizeof(buf), message, args); 451 469 va_end(args); 452 buflen = strlen(buf); 453 if (current_col + (current_col > 0) + buflen >= max_col) { 454 putchar('\n'); 455 current_col = 0; 456 } 457 if (current_col > 0) { 458 putchar(' '); 459 current_col++; 470 /* We seem to be called only with suitable lengths, but check if 471 somebody failed to adhere to this assumption just to be sure. */ 472 if (!buflen || buflen >= sizeof(buf)) return; 473 474 if (G.current_col > 0) { 475 G.current_col++; 476 if (buf[0] != '\n') { 477 if (G.current_col + buflen >= max_col) { 478 putchar('\n'); 479 G.current_col = 0; 480 } else 481 putchar(' '); 482 } 460 483 } 461 484 fputs(buf, stdout); 462 current_col += buflen; 463 } 464 465 static const struct suffix_mult stty_suffixes[] = { 466 {"b", 512 }, 467 {"k", 1024}, 468 {"B", 1024}, 469 {NULL, 0 } 470 }; 471 472 #ifndef TEST 473 int stty_main(int argc, char **argv) 474 #else 475 int main(int argc, char **argv) 476 #endif 477 { 478 struct termios mode; 479 void (*output_func)(struct termios *); 480 int optc; 481 int require_set_attr; 482 int speed_was_set; 483 int verbose_output; 484 int recoverable_output; 485 int k; 486 int noargs = 1; 487 char * file_name = NULL; 488 489 output_func = display_changed; 490 verbose_output = 0; 491 recoverable_output = 0; 492 493 /* Don't print error messages for unrecognized options. */ 494 opterr = 0; 495 496 while ((optc = getopt(argc, argv, "agF:")) != -1) { 497 switch (optc) { 498 case 'a': 499 verbose_output = 1; 500 output_func = display_all; 501 break; 502 503 case 'g': 504 recoverable_output = 1; 505 output_func = display_recoverable; 506 break; 507 508 case 'F': 509 if (file_name) 510 bb_error_msg_and_die("only one device may be specified"); 511 file_name = optarg; 512 break; 513 514 default: /* unrecognized option */ 515 noargs = 0; 516 break; 517 } 518 519 if (noargs == 0) 520 break; 521 } 522 523 if (optind < argc) 524 noargs = 0; 525 526 /* Specifying both -a and -g gets an error. */ 527 if (verbose_output & recoverable_output) 528 bb_error_msg_and_die ("verbose and stty-readable output styles are mutually exclusive"); 529 530 /* Specifying any other arguments with -a or -g gets an error. */ 531 if (~noargs & (verbose_output | recoverable_output)) 532 bb_error_msg_and_die ("modes may not be set when specifying an output style"); 533 534 /* FIXME: it'd be better not to open the file until we've verified 535 that all arguments are valid. Otherwise, we could end up doing 536 only some of the requested operations and then failing, probably 537 leaving things in an undesirable state. */ 538 539 if (file_name) { 540 int fdflags; 541 542 device_name = file_name; 543 fclose(stdin); 544 bb_xopen(device_name, O_RDONLY | O_NONBLOCK); 545 if ((fdflags = fcntl(STDIN_FILENO, F_GETFL)) == -1 546 || fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 547 perror_on_device("%s: couldn't reset non-blocking mode"); 548 } else { 549 device_name = bb_msg_standard_input; 550 } 551 552 /* Initialize to all zeroes so there is no risk memcmp will report a 553 spurious difference in an uninitialized portion of the structure. */ 554 memset(&mode, 0, sizeof(mode)); 555 if (tcgetattr(STDIN_FILENO, &mode)) 556 perror_on_device("%s"); 557 558 if (verbose_output | recoverable_output | noargs) { 559 max_col = screen_columns(); 560 current_col = 0; 561 output_func(&mode); 562 return EXIT_SUCCESS; 563 } 564 565 speed_was_set = 0; 566 require_set_attr = 0; 567 k = 0; 568 while (++k < argc) { 569 int match_found = 0; 570 int reversed = 0; 571 int i; 572 573 if (argv[k][0] == '-') { 574 char *find_dev_opt; 575 576 ++argv[k]; 577 578 /* Handle "-a", "-ag", "-aF/dev/foo", "-aF /dev/foo", etc. 579 Find the options that have been parsed. This is really 580 gross, but it's needed because stty SETTINGS look like options to 581 getopt(), so we need to work around things in a really horrible 582 way. If any new options are ever added to stty, the short option 583 MUST NOT be a letter which is the first letter of one of the 584 possible stty settings. 585 */ 586 find_dev_opt = strchr(argv[k], 'F'); /* find -*F* */ 587 if(find_dev_opt) { 588 if(find_dev_opt[1]==0) /* -*F /dev/foo */ 589 k++; /* skip /dev/foo */ 590 continue; /* else -*F/dev/foo - no skip */ 591 } 592 if(argv[k][0]=='a' || argv[k][0]=='g') 593 continue; 594 /* Is not options - is reverse params */ 595 reversed = 1; 596 } 597 for (i = 0; i < NUM_mode_info; ++i) 598 if (STREQ(argv[k], mode_info[i].name)) { 599 match_found = set_mode(&mode_info[i], reversed, &mode); 600 require_set_attr = 1; 601 break; 602 } 603 604 if (match_found == 0 && reversed) 605 bb_error_msg_and_die("invalid argument `%s'", --argv[k]); 606 607 if (match_found == 0) 608 for (i = 0; i < NUM_control_info; ++i) 609 if (STREQ(argv[k], control_info[i].name)) { 610 if (k == argc - 1) 611 bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); 612 match_found = 1; 613 ++k; 614 set_control_char(&control_info[i], argv[k], &mode); 615 require_set_attr = 1; 616 break; 617 } 618 619 if (match_found == 0) { 620 if (STREQ(argv[k], "ispeed")) { 621 if (k == argc - 1) 622 bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); 623 ++k; 624 set_speed(input_speed, argv[k], &mode); 625 speed_was_set = 1; 626 require_set_attr = 1; 627 } else if (STREQ(argv[k], "ospeed")) { 628 if (k == argc - 1) 629 bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); 630 ++k; 631 set_speed(output_speed, argv[k], &mode); 632 speed_was_set = 1; 633 require_set_attr = 1; 634 } 635 #ifdef TIOCGWINSZ 636 else if (STREQ(argv[k], "rows")) { 637 if (k == argc - 1) 638 bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); 639 ++k; 640 set_window_size((int) bb_xparse_number(argv[k], stty_suffixes), 641 -1); 642 } else if (STREQ(argv[k], "cols") || STREQ(argv[k], "columns")) { 643 if (k == argc - 1) 644 bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); 645 ++k; 646 set_window_size(-1, 647 (int) bb_xparse_number(argv[k], stty_suffixes)); 648 } else if (STREQ(argv[k], "size")) { 649 max_col = screen_columns(); 650 current_col = 0; 651 display_window_size(0); 652 } 653 #endif 654 #ifdef HAVE_C_LINE 655 else if (STREQ(argv[k], "line")) { 656 if (k == argc - 1) 657 bb_error_msg_and_die(bb_msg_requires_arg, argv[k]); 658 ++k; 659 mode.c_line = bb_xparse_number(argv[k], stty_suffixes); 660 require_set_attr = 1; 661 } 662 #endif 663 else if (STREQ(argv[k], "speed")) { 664 max_col = screen_columns(); 665 display_speed(&mode, 0); 666 } else if (recover_mode(argv[k], &mode) == 1) 667 require_set_attr = 1; 668 else if (string_to_baud(argv[k]) != (speed_t) - 1) { 669 set_speed(both_speeds, argv[k], &mode); 670 speed_was_set = 1; 671 require_set_attr = 1; 672 } else 673 bb_error_msg_and_die("invalid argument `%s'", argv[k]); 674 } 675 } 676 677 if (require_set_attr) { 678 struct termios new_mode; 679 680 if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode)) 681 perror_on_device("%s"); 682 683 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if 684 it performs *any* of the requested operations. This means it 685 can report `success' when it has actually failed to perform 686 some proper subset of the requested operations. To detect 687 this partial failure, get the current terminal attributes and 688 compare them to the requested ones. */ 689 690 /* Initialize to all zeroes so there is no risk memcmp will report a 691 spurious difference in an uninitialized portion of the structure. */ 692 memset(&new_mode, 0, sizeof(new_mode)); 693 if (tcgetattr(STDIN_FILENO, &new_mode)) 694 perror_on_device("%s"); 695 696 /* Normally, one shouldn't use memcmp to compare structures that 697 may have `holes' containing uninitialized data, but we have been 698 careful to initialize the storage of these two variables to all 699 zeroes. One might think it more efficient simply to compare the 700 modified fields, but that would require enumerating those fields -- 701 and not all systems have the same fields in this structure. */ 702 703 if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) { 704 #ifdef CIBAUD 705 /* SunOS 4.1.3 (at least) has the problem that after this sequence, 706 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2); 707 sometimes (m1 != m2). The only difference is in the four bits 708 of the c_cflag field corresponding to the baud rate. To save 709 Sun users a little confusion, don't report an error if this 710 happens. But suppress the error only if we haven't tried to 711 set the baud rate explicitly -- otherwise we'd never give an 712 error for a true failure to set the baud rate. */ 713 714 new_mode.c_cflag &= (~CIBAUD); 715 if (speed_was_set || memcmp(&mode, &new_mode, sizeof(mode)) != 0) 716 #endif 717 perror_on_device ("%s: unable to perform all requested operations"); 718 } 719 } 720 721 return EXIT_SUCCESS; 722 } 723 724 /* Return 0 if not applied because not reversible; otherwise return 1. */ 725 726 static int 727 set_mode(const struct mode_info *info, int reversed, struct termios *mode) 728 { 729 tcflag_t *bitsp; 730 731 if (reversed && (info->flags & REV) == 0) 732 return 0; 733 734 bitsp = mode_type_flag(EMT(info->type), mode); 735 736 if (bitsp == NULL) { 737 /* Combination mode. */ 738 if (info->name == evenp || info->name == parity) { 739 if (reversed) 740 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 741 else 742 mode->c_cflag = 743 (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7; 744 } else if (info->name == stty_oddp) { 745 if (reversed) 746 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 747 else 748 mode->c_cflag = 749 (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB; 750 } else if (info->name == stty_nl) { 751 if (reversed) { 752 mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR; 753 mode->c_oflag = (mode->c_oflag 754 #ifdef ONLCR 755 | ONLCR 756 #endif 757 ) 758 #ifdef OCRNL 759 & ~OCRNL 760 #endif 761 #ifdef ONLRET 762 & ~ONLRET 763 #endif 764 ; 765 } else { 766 mode->c_iflag = mode->c_iflag & ~ICRNL; 767 #ifdef ONLCR 768 mode->c_oflag = mode->c_oflag & ~ONLCR; 769 #endif 770 } 771 } else if (info->name == stty_ek) { 772 mode->c_cc[VERASE] = CERASE; 773 mode->c_cc[VKILL] = CKILL; 774 } else if (info->name == stty_sane) 775 sane_mode(mode); 776 else if (info->name == cbreak) { 777 if (reversed) 778 mode->c_lflag |= ICANON; 779 else 780 mode->c_lflag &= ~ICANON; 781 } else if (info->name == stty_pass8) { 782 if (reversed) { 783 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; 784 mode->c_iflag |= ISTRIP; 785 } else { 786 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 787 mode->c_iflag &= ~ISTRIP; 788 } 789 } else if (info->name == litout) { 790 if (reversed) { 791 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; 792 mode->c_iflag |= ISTRIP; 793 mode->c_oflag |= OPOST; 794 } else { 795 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 796 mode->c_iflag &= ~ISTRIP; 797 mode->c_oflag &= ~OPOST; 798 } 799 } else if (info->name == raw || info->name == cooked) { 800 if ((info->name[0] == 'r' && reversed) 801 || (info->name[0] == 'c' && !reversed)) { 802 /* Cooked mode. */ 803 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; 804 mode->c_oflag |= OPOST; 805 mode->c_lflag |= ISIG | ICANON; 806 #if VMIN == VEOF 807 mode->c_cc[VEOF] = CEOF; 808 #endif 809 #if VTIME == VEOL 810 mode->c_cc[VEOL] = CEOL; 811 #endif 812 } else { 813 /* Raw mode. */ 814 mode->c_iflag = 0; 815 mode->c_oflag &= ~OPOST; 816 mode->c_lflag &= ~(ISIG | ICANON 817 #ifdef XCASE 818 | XCASE 819 #endif 820 ); 821 mode->c_cc[VMIN] = 1; 822 mode->c_cc[VTIME] = 0; 823 } 824 } 825 #ifdef IXANY 826 else if (info->name == decctlq) { 827 if (reversed) 828 mode->c_iflag |= IXANY; 829 else 830 mode->c_iflag &= ~IXANY; 831 } 832 #endif 833 #ifdef TABDLY 834 else if (info->name == stty_tabs) { 835 if (reversed) 836 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; 837 else 838 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; 839 } 840 #else 841 # ifdef OXTABS 842 else if (info->name == stty_tabs) { 843 if (reversed) 844 mode->c_oflag = mode->c_oflag | OXTABS; 845 else 846 mode->c_oflag = mode->c_oflag & ~OXTABS; 847 } 848 # endif 849 #endif 850 #if defined(XCASE) && defined(IUCLC) && defined(OLCUC) 851 else if (info->name == stty_lcase || info->name == stty_LCASE) { 852 if (reversed) { 853 mode->c_lflag &= ~XCASE; 854 mode->c_iflag &= ~IUCLC; 855 mode->c_oflag &= ~OLCUC; 856 } else { 857 mode->c_lflag |= XCASE; 858 mode->c_iflag |= IUCLC; 859 mode->c_oflag |= OLCUC; 860 } 861 } 862 #endif 863 else if (info->name == stty_crt) 864 mode->c_lflag |= ECHOE 865 #ifdef ECHOCTL 866 | ECHOCTL 867 #endif 868 #ifdef ECHOKE 869 | ECHOKE 870 #endif 871 ; 872 else if (info->name == stty_dec) { 873 mode->c_cc[VINTR] = 3; /* ^C */ 874 mode->c_cc[VERASE] = 127; /* DEL */ 875 mode->c_cc[VKILL] = 21; /* ^U */ 876 mode->c_lflag |= ECHOE 877 #ifdef ECHOCTL 878 | ECHOCTL 879 #endif 880 #ifdef ECHOKE 881 | ECHOKE 882 #endif 883 ; 884 #ifdef IXANY 885 mode->c_iflag &= ~IXANY; 886 #endif 887 } 888 } else if (reversed) 889 *bitsp = *bitsp & ~((unsigned long)info->mask) & ~info->bits; 890 else 891 *bitsp = (*bitsp & ~((unsigned long)info->mask)) | info->bits; 892 893 return 1; 894 } 895 896 static void 897 set_control_char(const struct control_info *info, const char *arg, 898 struct termios *mode) 899 { 900 unsigned char value; 901 902 if (info->name == stty_min || info->name == stty_time) 903 value = bb_xparse_number(arg, stty_suffixes); 904 else if (arg[0] == '\0' || arg[1] == '\0') 905 value = arg[0]; 906 else if (STREQ(arg, "^-") || STREQ(arg, "undef")) 907 value = _POSIX_VDISABLE; 908 else if (arg[0] == '^' && arg[1] != '\0') { /* Ignore any trailing junk. */ 909 if (arg[1] == '?') 910 value = 127; 911 else 912 value = arg[1] & ~0140; /* Non-letters get weird results. */ 913 } else 914 value = bb_xparse_number(arg, stty_suffixes); 915 mode->c_cc[info->offset] = value; 916 } 917 918 static void 919 set_speed(enum speed_setting type, const char *arg, struct termios *mode) 920 { 921 speed_t baud; 922 923 baud = string_to_baud(arg); 924 925 if (type != output_speed) { /* either input or both */ 926 cfsetispeed(mode, baud); 927 } 928 if (type != input_speed) { /* either output or both */ 929 cfsetospeed(mode, baud); 930 } 931 } 932 933 #ifdef TIOCGWINSZ 934 935 static int get_win_size(int fd, struct winsize *win) 936 { 937 int err = ioctl(fd, TIOCGWINSZ, (char *) win); 938 939 return err; 940 } 941 942 static void 943 set_window_size(int rows, int cols) 944 { 945 struct winsize win; 946 947 if (get_win_size(STDIN_FILENO, &win)) { 948 if (errno != EINVAL) 949 perror_on_device("%s"); 485 G.current_col += buflen; 486 if (buf[buflen-1] == '\n') 487 G.current_col = 0; 488 } 489 490 static void set_window_size(const int rows, const int cols) 491 { 492 struct winsize win = { 0, 0, 0, 0}; 493 494 if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win)) { 495 if (errno != EINVAL) { 496 goto bail; 497 } 950 498 memset(&win, 0, sizeof(win)); 951 499 } … … 956 504 win.ws_col = cols; 957 505 958 # ifdef TIOCSSIZE959 /* Alexander Dupuy <dupuy@cs.columbia.edu> wrote:960 The following code deals with a bug in the SunOS 4.x (and 3.x?) kernel.961 This comment from sys/ttold.h describes Sun's twisted logic - a better962 test would have been (ts_lines > 64k || ts_cols > 64k || ts_cols == 0).963 At any rate, the problem is gone in Solaris 2.x. */964 965 if (win.ws_row == 0 || win.ws_col == 0) {966 struct ttysize ttysz;967 968 ttysz.ts_lines = win.ws_row;969 ttysz.ts_cols = win.ws_col;970 971 win.ws_row = win.ws_col = 1;972 973 if ((ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win) != 0)974 || (ioctl(STDIN_FILENO, TIOCSSIZE, (char *) &ttysz) != 0)) {975 perror_on_device("%s");976 }977 return;978 }979 # endif980 981 506 if (ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win)) 507 bail: 982 508 perror_on_device("%s"); 983 509 } 984 510 985 static void display_window_size( int fancy)986 { 987 const char *fmt_str = "%s " "\0" "%s: no size information for this device";988 struct winsize win;989 990 if (get_ win_size(STDIN_FILENO, &win)) {511 static void display_window_size(const int fancy) 512 { 513 const char *fmt_str = "%s\0%s: no size information for this device"; 514 unsigned width, height; 515 516 if (get_terminal_width_height(STDIN_FILENO, &width, &height)) { 991 517 if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) { 992 518 perror_on_device(fmt_str); … … 994 520 } else { 995 521 wrapf(fancy ? "rows %d; columns %d;" : "%d %d\n", 996 win.ws_row, win.ws_col); 997 if (!fancy) 998 current_col = 0; 999 } 1000 } 1001 #endif 1002 1003 static int screen_columns(void) 1004 { 1005 int columns; 1006 const char *s; 1007 1008 #ifdef TIOCGWINSZ 1009 struct winsize win; 1010 1011 /* With Solaris 2.[123], this ioctl fails and errno is set to 1012 EINVAL for telnet (but not rlogin) sessions. 1013 On ISC 3.0, it fails for the console and the serial port 1014 (but it works for ptys). 1015 It can also fail on any system when stdout isn't a tty. 1016 In case of any failure, just use the default. */ 1017 if (get_win_size(STDOUT_FILENO, &win) == 0 && win.ws_col > 0) 1018 return win.ws_col; 1019 #endif 1020 1021 columns = 80; 1022 if ((s = getenv("COLUMNS"))) { 1023 columns = atoi(s); 1024 } 1025 return columns; 1026 } 1027 1028 static tcflag_t *mode_type_flag(enum mode_type type, struct termios *mode) 1029 { 1030 static const unsigned char tcflag_offsets[] = { 1031 offsetof(struct termios, c_cflag), /* control */ 1032 offsetof(struct termios, c_iflag), /* input */ 1033 offsetof(struct termios, c_oflag), /* output */ 1034 offsetof(struct termios, c_lflag) /* local */ 1035 }; 1036 1037 if (((unsigned int) type) <= local) { 1038 return (tcflag_t *)(((char *) mode) + tcflag_offsets[(int)type]); 1039 } 1040 return NULL; 1041 } 1042 1043 static void display_changed(struct termios *mode) 522 height, width); 523 } 524 } 525 526 static const struct suffix_mult stty_suffixes[] = { 527 { "b", 512 }, 528 { "k", 1024 }, 529 { "B", 1024 }, 530 { } 531 }; 532 533 static const struct mode_info *find_mode(const char *name) 1044 534 { 1045 535 int i; 1046 int empty_line; 1047 tcflag_t *bitsp; 1048 unsigned long mask; 1049 enum mode_type prev_type = control; 1050 1051 display_speed(mode, 1); 1052 #ifdef HAVE_C_LINE 1053 wrapf("line = %d;", mode->c_line); 1054 #endif 1055 putchar('\n'); 1056 current_col = 0; 1057 1058 empty_line = 1; 1059 for (i = 0; control_info[i].name != stty_min; ++i) { 1060 if (mode->c_cc[control_info[i].offset] == control_info[i].saneval) 1061 continue; 1062 /* If swtch is the same as susp, don't print both. */ 1063 #if VSWTCH == VSUSP 1064 if (control_info[i].name == stty_swtch) 1065 continue; 1066 #endif 1067 /* If eof uses the same slot as min, only print whichever applies. */ 1068 #if VEOF == VMIN 1069 if ((mode->c_lflag & ICANON) == 0 1070 && (control_info[i].name == stty_eof 1071 || control_info[i].name == stty_eol)) continue; 1072 #endif 1073 1074 empty_line = 0; 1075 wrapf("%s = %s;", control_info[i].name, 1076 visible(mode->c_cc[control_info[i].offset])); 1077 } 1078 if ((mode->c_lflag & ICANON) == 0) { 1079 wrapf("min = %d; time = %d;\n", (int) mode->c_cc[VMIN], 1080 (int) mode->c_cc[VTIME]); 1081 } else if (empty_line == 0) 1082 putchar('\n'); 1083 current_col = 0; 1084 1085 empty_line = 1; 1086 for (i = 0; i < NUM_mode_info; ++i) { 1087 if (mode_info[i].flags & OMIT) 1088 continue; 1089 if (EMT(mode_info[i].type) != prev_type) { 1090 if (empty_line == 0) { 1091 putchar('\n'); 1092 current_col = 0; 1093 empty_line = 1; 1094 } 1095 prev_type = EMT(mode_info[i].type); 1096 } 1097 1098 bitsp = mode_type_flag(EMT(mode_info[i].type), mode); 1099 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; 1100 if ((*bitsp & mask) == mode_info[i].bits) { 1101 if (mode_info[i].flags & SANE_UNSET) { 1102 wrapf("%s", mode_info[i].name); 1103 empty_line = 0; 1104 } 1105 } 1106 else if ((mode_info[i].flags & (SANE_SET | REV)) == 1107 (SANE_SET | REV)) { 1108 wrapf("-%s", mode_info[i].name); 1109 empty_line = 0; 1110 } 1111 } 1112 if (empty_line == 0) 1113 putchar('\n'); 1114 current_col = 0; 1115 } 1116 1117 static void 1118 display_all(struct termios *mode) 536 for (i = 0; i < NUM_mode_info; ++i) 537 if (!strcmp(name, mode_info[i].name)) 538 return &mode_info[i]; 539 return 0; 540 } 541 542 static const struct control_info *find_control(const char *name) 1119 543 { 1120 544 int i; 1121 tcflag_t *bitsp; 1122 unsigned long mask; 1123 enum mode_type prev_type = control; 1124 1125 display_speed(mode, 1); 1126 #ifdef TIOCGWINSZ 1127 display_window_size(1); 1128 #endif 1129 #ifdef HAVE_C_LINE 1130 wrapf("line = %d;", mode->c_line); 1131 #endif 1132 putchar('\n'); 1133 current_col = 0; 1134 1135 for (i = 0; control_info[i].name != stty_min; ++i) { 1136 /* If swtch is the same as susp, don't print both. */ 1137 #if VSWTCH == VSUSP 1138 if (control_info[i].name == stty_swtch) 1139 continue; 1140 #endif 1141 /* If eof uses the same slot as min, only print whichever applies. */ 1142 #if VEOF == VMIN 1143 if ((mode->c_lflag & ICANON) == 0 1144 && (control_info[i].name == stty_eof 1145 || control_info[i].name == stty_eol)) continue; 1146 #endif 1147 wrapf("%s = %s;", control_info[i].name, 1148 visible(mode->c_cc[control_info[i].offset])); 1149 } 1150 #if VEOF == VMIN 1151 if ((mode->c_lflag & ICANON) == 0) 1152 #endif 1153 wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]); 1154 if (current_col != 0) 1155 putchar('\n'); 1156 current_col = 0; 1157 1158 for (i = 0; i < NUM_mode_info; ++i) { 1159 if (mode_info[i].flags & OMIT) 1160 continue; 1161 if (EMT(mode_info[i].type) != prev_type) { 1162 putchar('\n'); 1163 current_col = 0; 1164 prev_type = EMT(mode_info[i].type); 1165 } 1166 1167 bitsp = mode_type_flag(EMT(mode_info[i].type), mode); 1168 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; 1169 if ((*bitsp & mask) == mode_info[i].bits) 1170 wrapf("%s", mode_info[i].name); 1171 else if (mode_info[i].flags & REV) 1172 wrapf("-%s", mode_info[i].name); 1173 } 1174 putchar('\n'); 1175 current_col = 0; 1176 } 1177 1178 static void display_speed(struct termios *mode, int fancy) 1179 { 1180 unsigned long ispeed, ospeed; 1181 const char *fmt_str = 1182 "%lu %lu\n\0" "ispeed %lu baud; ospeed %lu baud;\0" 1183 "%lu\n\0" "\0\0\0\0" "speed %lu baud;"; 1184 1185 ospeed = ispeed = cfgetispeed(mode); 1186 if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) { 1187 ispeed = ospeed; /* in case ispeed was 0 */ 1188 fmt_str += 43; 1189 } 1190 if (fancy) { 1191 fmt_str += 9; 1192 } 1193 wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed)); 1194 if (!fancy) 1195 current_col = 0; 1196 } 1197 1198 static void display_recoverable(struct termios *mode) 1199 { 1200 int i; 1201 1202 printf("%lx:%lx:%lx:%lx", 1203 (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, 1204 (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); 1205 for (i = 0; i < NCCS; ++i) 1206 printf(":%x", (unsigned int) mode->c_cc[i]); 1207 putchar('\n'); 1208 } 1209 1210 static int recover_mode(char *arg, struct termios *mode) 545 for (i = 0; i < NUM_control_info; ++i) 546 if (!strcmp(name, control_info[i].name)) 547 return &control_info[i]; 548 return 0; 549 } 550 551 enum { 552 param_need_arg = 0x80, 553 param_line = 1 | 0x80, 554 param_rows = 2 | 0x80, 555 param_cols = 3 | 0x80, 556 param_columns = 4 | 0x80, 557 param_size = 5, 558 param_speed = 6, 559 param_ispeed = 7 | 0x80, 560 param_ospeed = 8 | 0x80, 561 }; 562 563 static int find_param(const char *const name) 564 { 565 static const char params[] ALIGN1 = 566 "line\0" /* 1 */ 567 "rows\0" /* 2 */ 568 "cols\0" /* 3 */ 569 "columns\0" /* 4 */ 570 "size\0" /* 5 */ 571 "speed\0" /* 6 */ 572 "ispeed\0" 573 "ospeed\0"; 574 int i = index_in_strings(params, name) + 1; 575 if (i == 0) 576 return 0; 577 if (i != 5 && i != 6) 578 i |= 0x80; 579 return i; 580 } 581 582 static int recover_mode(const char *arg, struct termios *mode) 1211 583 { 1212 584 int i, n; 1213 unsigned intchr;585 unsigned chr; 1214 586 unsigned long iflag, oflag, cflag, lflag; 1215 587 1216 588 /* Scan into temporaries since it is too much trouble to figure out 1217 the right format for `tcflag_t'.*/589 the right format for 'tcflag_t' */ 1218 590 if (sscanf(arg, "%lx:%lx:%lx:%lx%n", 1219 591 &iflag, &oflag, &cflag, &lflag, &n) != 4) … … 1231 603 } 1232 604 1233 /* Fail if there are too many fields .*/605 /* Fail if there are too many fields */ 1234 606 if (*arg != '\0') 1235 607 return 0; … … 1238 610 } 1239 611 1240 static speed_t string_to_baud(const char *arg) 1241 { 1242 return tty_value_to_baud(bb_xparse_number(arg, 0)); 612 static void display_recoverable(const struct termios *mode, 613 int ATTRIBUTE_UNUSED dummy) 614 { 615 int i; 616 printf("%lx:%lx:%lx:%lx", 617 (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag, 618 (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag); 619 for (i = 0; i < NCCS; ++i) 620 printf(":%x", (unsigned int) mode->c_cc[i]); 621 putchar('\n'); 622 } 623 624 static void display_speed(const struct termios *mode, int fancy) 625 { 626 //01234567 8 9 627 const char *fmt_str = "%lu %lu\n\0ispeed %lu baud; ospeed %lu baud;"; 628 unsigned long ispeed, ospeed; 629 630 ospeed = ispeed = cfgetispeed(mode); 631 if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) { 632 ispeed = ospeed; /* in case ispeed was 0 */ 633 //0123 4 5 6 7 8 9 634 fmt_str = "%lu\n\0\0\0\0\0speed %lu baud;"; 635 } 636 if (fancy) fmt_str += 9; 637 wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed)); 638 } 639 640 static void do_display(const struct termios *mode, const int all) 641 { 642 int i; 643 tcflag_t *bitsp; 644 unsigned long mask; 645 int prev_type = control; 646 647 display_speed(mode, 1); 648 if (all) 649 display_window_size(1); 650 #ifdef HAVE_C_LINE 651 wrapf("line = %d;\n", mode->c_line); 652 #else 653 wrapf("\n"); 654 #endif 655 656 for (i = 0; control_info[i].name != stty_min; ++i) { 657 /* If swtch is the same as susp, don't print both */ 658 #if VSWTCH == VSUSP 659 if (control_info[i].name == stty_swtch) 660 continue; 661 #endif 662 /* If eof uses the same slot as min, only print whichever applies */ 663 #if VEOF == VMIN 664 if ((mode->c_lflag & ICANON) == 0 665 && (control_info[i].name == stty_eof 666 || control_info[i].name == stty_eol)) continue; 667 #endif 668 wrapf("%s = %s;", control_info[i].name, 669 visible(mode->c_cc[control_info[i].offset])); 670 } 671 #if VEOF == VMIN 672 if ((mode->c_lflag & ICANON) == 0) 673 #endif 674 wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]); 675 if (G.current_col) wrapf("\n"); 676 677 for (i = 0; i < NUM_mode_info; ++i) { 678 if (mode_info[i].flags & OMIT) 679 continue; 680 if (mode_info[i].type != prev_type) { 681 /* wrapf("\n"); */ 682 if (G.current_col) wrapf("\n"); 683 prev_type = mode_info[i].type; 684 } 685 686 bitsp = mode_type_flag(mode_info[i].type, mode); 687 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits; 688 if ((*bitsp & mask) == mode_info[i].bits) { 689 if (all || (mode_info[i].flags & SANE_UNSET)) 690 wrapf("%s", mode_info[i].name); 691 } else { 692 if ((all && mode_info[i].flags & REV) || 693 (!all && 694 (mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV))) 695 wrapf("-%s", mode_info[i].name); 696 } 697 } 698 if (G.current_col) wrapf("\n"); 1243 699 } 1244 700 … … 1258 714 for (i = 0; i < NUM_mode_info; ++i) { 1259 715 if (mode_info[i].flags & SANE_SET) { 1260 bitsp = mode_type_flag( EMT(mode_info[i].type), mode);716 bitsp = mode_type_flag(mode_info[i].type, mode); 1261 717 *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask)) 1262 718 | mode_info[i].bits; 1263 719 } else if (mode_info[i].flags & SANE_UNSET) { 1264 bitsp = mode_type_flag( EMT(mode_info[i].type), mode);720 bitsp = mode_type_flag(mode_info[i].type, mode); 1265 721 *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask) 1266 722 & ~mode_info[i].bits; … … 1269 725 } 1270 726 1271 /* Return a string that is the printable representation of character CH. */ 1272 /* Adapted from `cat' by Torbjorn Granlund. */ 1273 1274 static const char *visible(unsigned int ch) 1275 { 1276 static char buf[10]; 1277 char *bpout = buf; 1278 1279 if (ch == _POSIX_VDISABLE) { 1280 return "<undef>"; 1281 } 1282 1283 if (ch >= 128) { 1284 ch -= 128; 1285 *bpout++ = 'M'; 1286 *bpout++ = '-'; 1287 } 1288 1289 if (ch < 32) { 1290 *bpout++ = '^'; 1291 *bpout++ = ch + 64; 1292 } else if (ch < 127) { 1293 *bpout++ = ch; 1294 } else { 1295 *bpout++ = '^'; 1296 *bpout++ = '?'; 1297 } 1298 1299 *bpout = '\0'; 1300 return (const char *) buf; 1301 } 1302 1303 #ifdef TEST 1304 1305 const char *bb_applet_name = "stty"; 1306 1307 #endif 727 /* Save set_mode from #ifdef forest plague */ 728 #ifndef ONLCR 729 #define ONLCR 0 730 #endif 731 #ifndef OCRNL 732 #define OCRNL 0 733 #endif 734 #ifndef ONLRET 735 #define ONLRET 0 736 #endif 737 #ifndef XCASE 738 #define XCASE 0 739 #endif 740 #ifndef IXANY 741 #define IXANY 0 742 #endif 743 #ifndef TABDLY 744 #define TABDLY 0 745 #endif 746 #ifndef OXTABS 747 #define OXTABS 0 748 #endif 749 #ifndef IUCLC 750 #define IUCLC 0 751 #endif 752 #ifndef OLCUC 753 #define OLCUC 0 754 #endif 755 #ifndef ECHOCTL 756 #define ECHOCTL 0 757 #endif 758 #ifndef ECHOKE 759 #define ECHOKE 0 760 #endif 761 762 static void set_mode(const struct mode_info *info, int reversed, 763 struct termios *mode) 764 { 765 tcflag_t *bitsp; 766 767 bitsp = mode_type_flag(info->type, mode); 768 769 if (bitsp) { 770 if (reversed) 771 *bitsp = *bitsp & ~info->mask & ~info->bits; 772 else 773 *bitsp = (*bitsp & ~info->mask) | info->bits; 774 return; 775 } 776 777 /* Combination mode */ 778 if (info->name == evenp || info->name == parity) { 779 if (reversed) 780 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 781 else 782 mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7; 783 } else if (info->name == stty_oddp) { 784 if (reversed) 785 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 786 else 787 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB; 788 } else if (info->name == stty_nl) { 789 if (reversed) { 790 mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR; 791 mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET; 792 } else { 793 mode->c_iflag = mode->c_iflag & ~ICRNL; 794 if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR; 795 } 796 } else if (info->name == stty_ek) { 797 mode->c_cc[VERASE] = CERASE; 798 mode->c_cc[VKILL] = CKILL; 799 } else if (info->name == stty_sane) { 800 sane_mode(mode); 801 } 802 else if (info->name == cbreak) { 803 if (reversed) 804 mode->c_lflag |= ICANON; 805 else 806 mode->c_lflag &= ~ICANON; 807 } else if (info->name == stty_pass8) { 808 if (reversed) { 809 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; 810 mode->c_iflag |= ISTRIP; 811 } else { 812 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 813 mode->c_iflag &= ~ISTRIP; 814 } 815 } else if (info->name == litout) { 816 if (reversed) { 817 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB; 818 mode->c_iflag |= ISTRIP; 819 mode->c_oflag |= OPOST; 820 } else { 821 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8; 822 mode->c_iflag &= ~ISTRIP; 823 mode->c_oflag &= ~OPOST; 824 } 825 } else if (info->name == raw || info->name == cooked) { 826 if ((info->name[0] == 'r' && reversed) 827 || (info->name[0] == 'c' && !reversed)) { 828 /* Cooked mode */ 829 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON; 830 mode->c_oflag |= OPOST; 831 mode->c_lflag |= ISIG | ICANON; 832 #if VMIN == VEOF 833 mode->c_cc[VEOF] = CEOF; 834 #endif 835 #if VTIME == VEOL 836 mode->c_cc[VEOL] = CEOL; 837 #endif 838 } else { 839 /* Raw mode */ 840 mode->c_iflag = 0; 841 mode->c_oflag &= ~OPOST; 842 mode->c_lflag &= ~(ISIG | ICANON | XCASE); 843 mode->c_cc[VMIN] = 1; 844 mode->c_cc[VTIME] = 0; 845 } 846 } 847 else if (IXANY && info->name == decctlq) { 848 if (reversed) 849 mode->c_iflag |= IXANY; 850 else 851 mode->c_iflag &= ~IXANY; 852 } 853 else if (TABDLY && info->name == stty_tabs) { 854 if (reversed) 855 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; 856 else 857 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; 858 } 859 else if (OXTABS && info->name == stty_tabs) { 860 if (reversed) 861 mode->c_oflag |= OXTABS; 862 else 863 mode->c_oflag &= ~OXTABS; 864 } 865 else if (XCASE && IUCLC && OLCUC 866 && (info->name == stty_lcase || info->name == stty_LCASE)) { 867 if (reversed) { 868 mode->c_lflag &= ~XCASE; 869 mode->c_iflag &= ~IUCLC; 870 mode->c_oflag &= ~OLCUC; 871 } else { 872 mode->c_lflag |= XCASE; 873 mode->c_iflag |= IUCLC; 874 mode->c_oflag |= OLCUC; 875 } 876 } 877 else if (info->name == stty_crt) { 878 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; 879 } 880 else if (info->name == stty_dec) { 881 mode->c_cc[VINTR] = 3; /* ^C */ 882 mode->c_cc[VERASE] = 127; /* DEL */ 883 mode->c_cc[VKILL] = 21; /* ^U */ 884 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; 885 if (IXANY) mode->c_iflag &= ~IXANY; 886 } 887 } 888 889 static void set_control_char_or_die(const struct control_info *info, 890 const char *arg, struct termios *mode) 891 { 892 unsigned char value; 893 894 if (info->name == stty_min || info->name == stty_time) 895 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); 896 else if (arg[0] == '\0' || arg[1] == '\0') 897 value = arg[0]; 898 else if (!strcmp(arg, "^-") || !strcmp(arg, "undef")) 899 value = _POSIX_VDISABLE; 900 else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */ 901 value = arg[1] & 0x1f; /* Non-letters get weird results */ 902 if (arg[1] == '?') 903 value = 127; 904 } else 905 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes); 906 mode->c_cc[info->offset] = value; 907 } 908 909 #define STTY_require_set_attr (1<<0) 910 #define STTY_speed_was_set (1<<1) 911 #define STTY_verbose_output (1<<2) 912 #define STTY_recoverable_output (1<<3) 913 #define STTY_noargs (1<<4) 914 int stty_main(int argc, char **argv); 915 int stty_main(int argc, char **argv) 916 { 917 struct termios mode; 918 void (*output_func)(const struct termios *, const int); 919 const char *file_name = NULL; 920 int display_all = 0; 921 int stty_state; 922 int k; 923 924 stty_state = STTY_noargs; 925 output_func = do_display; 926 927 /* First pass: only parse/verify command line params */ 928 k = 0; 929 while (argv[++k]) { 930 const struct mode_info *mp; 931 const struct control_info *cp; 932 const char *arg = argv[k]; 933 const char *argnext = argv[k+1]; 934 int param; 935 936 if (arg[0] == '-') { 937 int i; 938 mp = find_mode(arg+1); 939 if (mp) { 940 if (!(mp->flags & REV)) 941 goto invalid_argument; 942 stty_state &= ~STTY_noargs; 943 continue; 944 } 945 /* It is an option - parse it */ 946 i = 0; 947 while (arg[++i]) { 948 switch (arg[i]) { 949 case 'a': 950 stty_state |= STTY_verbose_output; 951 output_func = do_display; 952 display_all = 1; 953 break; 954 case 'g': 955 stty_state |= STTY_recoverable_output; 956 output_func = display_recoverable; 957 break; 958 case 'F': 959 if (file_name) 960 bb_error_msg_and_die("only one device may be specified"); 961 file_name = &arg[i+1]; /* "-Fdevice" ? */ 962 if (!file_name[0]) { /* nope, "-F device" */ 963 int p = k+1; /* argv[p] is argnext */ 964 file_name = argnext; 965 if (!file_name) 966 bb_error_msg_and_die(bb_msg_requires_arg, "-F"); 967 /* remove -F param from arg[vc] */ 968 --argc; 969 while (argv[p]) { argv[p] = argv[p+1]; ++p; } 970 } 971 goto end_option; 972 default: 973 goto invalid_argument; 974 } 975 } 976 end_option: 977 continue; 978 } 979 980 mp = find_mode(arg); 981 if (mp) { 982 stty_state &= ~STTY_noargs; 983 continue; 984 } 985 986 cp = find_control(arg); 987 if (cp) { 988 if (!argnext) 989 bb_error_msg_and_die(bb_msg_requires_arg, arg); 990 /* called for the side effect of xfunc death only */ 991 set_control_char_or_die(cp, argnext, &mode); 992 stty_state &= ~STTY_noargs; 993 ++k; 994 continue; 995 } 996 997 param = find_param(arg); 998 if (param & param_need_arg) { 999 if (!argnext) 1000 bb_error_msg_and_die(bb_msg_requires_arg, arg); 1001 ++k; 1002 } 1003 1004 switch (param) { 1005 #ifdef HAVE_C_LINE 1006 case param_line: 1007 # ifndef TIOCGWINSZ 1008 xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes); 1009 break; 1010 # endif /* else fall-through */ 1011 #endif 1012 #ifdef TIOCGWINSZ 1013 case param_rows: 1014 case param_cols: 1015 case param_columns: 1016 xatoul_range_sfx(argnext, 1, INT_MAX, stty_suffixes); 1017 break; 1018 case param_size: 1019 #endif 1020 case param_speed: 1021 break; 1022 case param_ispeed: 1023 /* called for the side effect of xfunc death only */ 1024 set_speed_or_die(input_speed, argnext, &mode); 1025 break; 1026 case param_ospeed: 1027 /* called for the side effect of xfunc death only */ 1028 set_speed_or_die(output_speed, argnext, &mode); 1029 break; 1030 default: 1031 if (recover_mode(arg, &mode) == 1) break; 1032 if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) break; 1033 invalid_argument: 1034 bb_error_msg_and_die("invalid argument '%s'", arg); 1035 } 1036 stty_state &= ~STTY_noargs; 1037 } 1038 1039 /* Specifying both -a and -g is an error */ 1040 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) == 1041 (STTY_verbose_output | STTY_recoverable_output)) 1042 bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive"); 1043 /* Specifying -a or -g with non-options is an error */ 1044 if (!(stty_state & STTY_noargs) && 1045 (stty_state & (STTY_verbose_output | STTY_recoverable_output))) 1046 bb_error_msg_and_die("modes may not be set when specifying an output style"); 1047 1048 /* Now it is safe to start doing things */ 1049 if (file_name) { 1050 int fd, fdflags; 1051 device_name = file_name; 1052 fd = xopen(device_name, O_RDONLY | O_NONBLOCK); 1053 if (fd != STDIN_FILENO) { 1054 dup2(fd, STDIN_FILENO); 1055 close(fd); 1056 } 1057 fdflags = fcntl(STDIN_FILENO, F_GETFL); 1058 if (fdflags < 0 || 1059 fcntl(STDIN_FILENO, F_SETFL, fdflags & ~O_NONBLOCK) < 0) 1060 perror_on_device_and_die("%s: cannot reset non-blocking mode"); 1061 } 1062 1063 /* Initialize to all zeroes so there is no risk memcmp will report a 1064 spurious difference in an uninitialized portion of the structure */ 1065 memset(&mode, 0, sizeof(mode)); 1066 if (tcgetattr(STDIN_FILENO, &mode)) 1067 perror_on_device_and_die("%s"); 1068 1069 if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { 1070 get_terminal_width_height(STDOUT_FILENO, &max_col, NULL); 1071 output_func(&mode, display_all); 1072 return EXIT_SUCCESS; 1073 } 1074 1075 /* Second pass: perform actions */ 1076 k = 0; 1077 while (argv[++k]) { 1078 const struct mode_info *mp; 1079 const struct control_info *cp; 1080 const char *arg = argv[k]; 1081 const char *argnext = argv[k+1]; 1082 int param; 1083 1084 if (arg[0] == '-') { 1085 mp = find_mode(arg+1); 1086 if (mp) { 1087 set_mode(mp, 1 /* reversed */, &mode); 1088 stty_state |= STTY_require_set_attr; 1089 } 1090 /* It is an option - already parsed. Skip it */ 1091 continue; 1092 } 1093 1094 mp = find_mode(arg); 1095 if (mp) { 1096 set_mode(mp, 0 /* non-reversed */, &mode); 1097 stty_state |= STTY_require_set_attr; 1098 continue; 1099 } 1100 1101 cp = find_control(arg); 1102 if (cp) { 1103 ++k; 1104 set_control_char_or_die(cp, argnext, &mode); 1105 stty_state |= STTY_require_set_attr; 1106 continue; 1107 } 1108 1109 param = find_param(arg); 1110 if (param & param_need_arg) { 1111 ++k; 1112 } 1113 1114 switch (param) { 1115 #ifdef HAVE_C_LINE 1116 case param_line: 1117 mode.c_line = xatoul_sfx(argnext, stty_suffixes); 1118 stty_state |= STTY_require_set_attr; 1119 break; 1120 #endif 1121 #ifdef TIOCGWINSZ 1122 case param_cols: 1123 set_window_size(-1, xatoul_sfx(argnext, stty_suffixes)); 1124 break; 1125 case param_size: 1126 display_window_size(0); 1127 break; 1128 case param_rows: 1129 set_window_size(xatoul_sfx(argnext, stty_suffixes), -1); 1130 break; 1131 #endif 1132 case param_speed: 1133 display_speed(&mode, 0); 1134 break; 1135 case param_ispeed: 1136 set_speed_or_die(input_speed, argnext, &mode); 1137 stty_state |= (STTY_require_set_attr | STTY_speed_was_set); 1138 break; 1139 case param_ospeed: 1140 set_speed_or_die(output_speed, argnext, &mode); 1141 stty_state |= (STTY_require_set_attr | STTY_speed_was_set); 1142 break; 1143 default: 1144 if (recover_mode(arg, &mode) == 1) 1145 stty_state |= STTY_require_set_attr; 1146 else /* true: if (tty_value_to_baud(xatou(arg)) != (speed_t) -1) */{ 1147 set_speed_or_die(both_speeds, arg, &mode); 1148 stty_state |= (STTY_require_set_attr | STTY_speed_was_set); 1149 } /* else - impossible (caught in the first pass): 1150 bb_error_msg_and_die("invalid argument '%s'", arg); */ 1151 } 1152 } 1153 1154 if (stty_state & STTY_require_set_attr) { 1155 struct termios new_mode; 1156 1157 if (tcsetattr(STDIN_FILENO, TCSADRAIN, &mode)) 1158 perror_on_device_and_die("%s"); 1159 1160 /* POSIX (according to Zlotnick's book) tcsetattr returns zero if 1161 it performs *any* of the requested operations. This means it 1162 can report 'success' when it has actually failed to perform 1163 some proper subset of the requested operations. To detect 1164 this partial failure, get the current terminal attributes and 1165 compare them to the requested ones */ 1166 1167 /* Initialize to all zeroes so there is no risk memcmp will report a 1168 spurious difference in an uninitialized portion of the structure */ 1169 memset(&new_mode, 0, sizeof(new_mode)); 1170 if (tcgetattr(STDIN_FILENO, &new_mode)) 1171 perror_on_device_and_die("%s"); 1172 1173 if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) { 1174 #ifdef CIBAUD 1175 /* SunOS 4.1.3 (at least) has the problem that after this sequence, 1176 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2); 1177 sometimes (m1 != m2). The only difference is in the four bits 1178 of the c_cflag field corresponding to the baud rate. To save 1179 Sun users a little confusion, don't report an error if this 1180 happens. But suppress the error only if we haven't tried to 1181 set the baud rate explicitly -- otherwise we'd never give an 1182 error for a true failure to set the baud rate */ 1183 1184 new_mode.c_cflag &= (~CIBAUD); 1185 if ((stty_state & STTY_speed_was_set) 1186 || memcmp(&mode, &new_mode, sizeof(mode)) != 0) 1187 #endif 1188 perror_on_device_and_die("%s: cannot perform all requested operations"); 1189 } 1190 } 1191 1192 return EXIT_SUCCESS; 1193 } -
branches/2.2.5/mindi-busybox/coreutils/sum.c
r821 r1765 11 11 * Taken from coreutils and turned into a busybox applet by Mike Frysinger 12 12 * 13 * Licensed under the GPL v2 , see the file LICENSE in this tarball.13 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 14 14 */ 15 15 16 #include <stdio.h> 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 #include <fcntl.h> 20 #include <unistd.h> 16 #include "libbb.h" 21 17 22 #include "busybox.h" 18 enum { SUM_BSD, PRINT_NAME, SUM_SYSV }; 23 19 24 /* 1 if any of the files read were the standard input */ 25 static int have_read_stdin; 26 27 /* make a little more readable and avoid using strcmp for just 2 bytes */ 28 #define IS_STDIN(s) (s[0] == '-' && s[1] == '\0') 29 30 /* Calculate and print the rotated checksum and the size in 1K blocks 31 of file FILE, or of the standard input if FILE is "-". 32 If PRINT_NAME is >1, print FILE next to the checksum and size. 33 The checksum varies depending on sizeof (int). 34 Return 1 if successful. */ 35 static int bsd_sum_file(const char *file, int print_name) 20 /* BSD: calculate and print the rotated checksum and the size in 1K blocks 21 The checksum varies depending on sizeof (int). */ 22 /* SYSV: calculate and print the checksum and the size in 512-byte blocks */ 23 /* Return 1 if successful. */ 24 static unsigned sum_file(const char *file, const unsigned type) 36 25 { 37 FILE *fp; 38 int checksum = 0; /* The checksum mod 2^16. */ 39 uintmax_t total_bytes = 0; /* The number of bytes. */ 40 int ch; /* Each character read. */ 41 42 if (IS_STDIN(file)) { 43 fp = stdin; 44 have_read_stdin = 1; 45 } else { 46 fp = bb_wfopen(file, "r"); 47 if (fp == NULL) 48 return 0; 49 } 50 51 while ((ch = getc(fp)) != EOF) { 52 ++total_bytes; 53 checksum = (checksum >> 1) + ((checksum & 1) << 15); 54 checksum += ch; 55 checksum &= 0xffff; /* Keep it within bounds. */ 56 } 57 58 if (ferror(fp)) { 59 bb_perror_msg(file); 60 bb_fclose_nonstdin(fp); 61 return 0; 62 } 63 64 if (bb_fclose_nonstdin(fp) == EOF) { 65 bb_perror_msg(file); 66 return 0; 67 } 68 69 printf("%05d %5ju ", checksum, (total_bytes+1023)/1024); 70 if (print_name > 1) 71 puts(file); 72 else 73 printf("\n"); 74 75 return 1; 76 } 77 78 /* Calculate and print the checksum and the size in 512-byte blocks 79 of file FILE, or of the standard input if FILE is "-". 80 If PRINT_NAME is >0, print FILE next to the checksum and size. 81 Return 1 if successful. */ 82 #define MY_BUF_SIZE 8192 83 static int sysv_sum_file(const char *file, int print_name) 84 { 85 RESERVE_CONFIG_BUFFER(buf, MY_BUF_SIZE); 86 int fd; 26 #define buf bb_common_bufsiz1 87 27 uintmax_t total_bytes = 0; 28 int fd = 0, r; 88 29 89 30 /* The sum of all the input bytes, modulo (UINT_MAX + 1). */ 90 unsigned ints = 0;31 unsigned s = 0; 91 32 92 if (IS_STDIN(file)) { 93 fd = 0; 94 have_read_stdin = 1; 95 } else { 33 if (NOT_LONE_DASH(file)) { 96 34 fd = open(file, O_RDONLY); 97 35 if (fd == -1) 98 goto re lease_and_ret;36 goto ret_bad; 99 37 } 100 38 101 39 while (1) { 102 size_t bytes_read = safe_read(fd, buf, MY_BUF_SIZE);40 size_t bytes_read = safe_read(fd, buf, BUFSIZ); 103 41 104 if (bytes_read == 0) 105 break; 106 107 if (bytes_read == -1) { 108 release_and_ret: 42 if ((ssize_t)bytes_read <= 0) { 43 r = (fd && close(fd) != 0); 44 if (!bytes_read && !r) 45 /* no error */ 46 break; 47 ret_bad: 109 48 bb_perror_msg(file); 110 RELEASE_CONFIG_BUFFER(buf);111 if (!IS_STDIN(file))112 close(fd);113 49 return 0; 114 50 } 115 51 116 52 total_bytes += bytes_read; 117 while (bytes_read--) 118 s += buf[bytes_read]; 53 if (type >= SUM_SYSV) { 54 do s += buf[--bytes_read]; while (bytes_read); 55 } else { 56 r = 0; 57 do { 58 s = (s >> 1) + ((s & 1) << 15); 59 s += buf[r++]; 60 s &= 0xffff; /* Keep it within bounds. */ 61 } while (--bytes_read); 62 } 119 63 } 120 64 121 if (!IS_STDIN(file) && close(fd) == -1) 122 goto release_and_ret; 123 else 124 RELEASE_CONFIG_BUFFER(buf); 125 126 { 127 int r = (s & 0xffff) + ((s & 0xffffffff) >> 16); 65 if (type < PRINT_NAME) 66 file = ""; 67 if (type >= SUM_SYSV) { 68 r = (s & 0xffff) + ((s & 0xffffffff) >> 16); 128 69 s = (r & 0xffff) + (r >> 16); 129 130 printf("%d %ju ", s, (total_bytes+511)/512); 131 } 132 puts(print_name ? file : ""); 133 70 printf("%d %ju %s\n", s, (total_bytes+511)/512, file); 71 } else 72 printf("%05d %5ju %s\n", s, (total_bytes+1023)/1024, file); 134 73 return 1; 74 #undef buf 135 75 } 136 76 77 int sum_main(int argc, char **argv); 137 78 int sum_main(int argc, char **argv) 138 79 { 139 int flags; 140 int ok; 141 int (*sum_func)(const char *, int) = bsd_sum_file; 80 unsigned n; 81 unsigned type = SUM_BSD; 142 82 143 /* give the bsd func priority over sysv func */ 144 flags = bb_getopt_ulflags(argc, argv, "sr"); 145 if (flags & 1) 146 sum_func = sysv_sum_file; 147 if (flags & 2) 148 sum_func = bsd_sum_file; 83 n = getopt32(argv, "sr"); 84 if (n & 1) type = SUM_SYSV; 85 /* give the bsd priority over sysv func */ 86 if (n & 2) type = SUM_BSD; 149 87 150 have_read_stdin = 0; 151 if ((argc - optind) == 0) 152 ok = sum_func("-", 0); 153 else 154 for (ok = 1; optind < argc; optind++) 155 ok &= sum_func(argv[optind], 1); 156 157 if (have_read_stdin && fclose(stdin) == EOF) 158 bb_perror_msg_and_die("-"); 159 160 exit(ok ? EXIT_SUCCESS : EXIT_FAILURE); 88 if (argc == optind) { 89 /* Do not print the name */ 90 n = sum_file("-", type); 91 } else { 92 /* Need to print the name if either 93 - more than one file given 94 - doing sysv */ 95 type += argc - 1 > optind || type == SUM_SYSV; 96 for (n = 1; optind < argc; optind++) 97 n &= sum_file(argv[optind], type); 98 } 99 return !n; 161 100 } -
branches/2.2.5/mindi-busybox/coreutils/sync.c
r821 r1765 5 5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 10 /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ 24 11 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include "busybox.h" 12 #include "libbb.h" 28 13 14 /* This is a NOFORK applet. Be very careful! */ 15 16 int sync_main(int argc, char **argv); 29 17 int sync_main(int argc, char **argv) 30 18 { … … 33 21 sync(); 34 22 35 return (EXIT_SUCCESS);23 return EXIT_SUCCESS; 36 24 } -
branches/2.2.5/mindi-busybox/coreutils/tail.c
r821 r1765 25 25 */ 26 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <ctype.h> 31 #include <unistd.h> 32 #include <fcntl.h> 33 #include <sys/stat.h> 34 #include "busybox.h" 27 #include "libbb.h" 35 28 36 29 static const struct suffix_mult tail_suffixes[] = { 37 30 { "b", 512 }, 38 31 { "k", 1024 }, 39 { "m", 10 48576},40 { NULL, 0}32 { "m", 1024*1024 }, 33 { } 41 34 }; 42 35 43 static int status; 36 struct globals { 37 bool status; 38 }; 39 #define G (*(struct globals*)&bb_common_bufsiz1) 44 40 45 41 static void tail_xprint_header(const char *fmt, const char *filename) 46 42 { 47 /* If we get an output error, there is really no sense in continuing. */ 48 if (dprintf(STDOUT_FILENO, fmt, filename) < 0) { 43 if (fdprintf(STDOUT_FILENO, fmt, filename) < 0) 49 44 bb_perror_nomsg_and_die(); 50 }51 }52 53 /* len should probably be size_t */54 static void tail_xbb_full_write(const char *buf, size_t len)55 {56 /* If we get a write error, there is really no sense in continuing. */57 if (bb_full_write(STDOUT_FILENO, buf, len) < 0) {58 bb_perror_nomsg_and_die();59 }60 45 } 61 46 … … 63 48 { 64 49 ssize_t r; 65 off_t current, end;50 off_t current, end; 66 51 struct stat sbuf; 67 52 … … 70 55 end = sbuf.st_size; 71 56 lseek(fd, end < current ? 0 : current, SEEK_SET); 72 if ((r = safe_read(fd, buf, count)) < 0) { 57 r = safe_read(fd, buf, count); 58 if (r < 0) { 73 59 bb_perror_msg(bb_msg_read_error); 74 status = EXIT_FAILURE;60 G.status = EXIT_FAILURE; 75 61 } 76 62 … … 78 64 } 79 65 80 static const char tail_opts[] = 81 "fn:c:" 82 #if ENABLE_FEATURE_FANCY_TAIL 83 "qs:v" 84 #endif 85 ; 86 87 static const char header_fmt[] = "\n==> %s <==\n"; 88 66 static const char header_fmt[] ALIGN1 = "\n==> %s <==\n"; 67 68 static unsigned eat_num(const char *p) 69 { 70 if (*p == '-') p++; 71 else if (*p == '+') { p++; G.status = EXIT_FAILURE; } 72 return xatou_sfx(p, tail_suffixes); 73 } 74 75 int tail_main(int argc, char **argv); 89 76 int tail_main(int argc, char **argv) 90 77 { 91 long count = 10; 92 unsigned int sleep_period = 1; 93 int from_top = 0; 94 int follow = 0; 78 unsigned count = 10; 79 unsigned sleep_period = 1; 80 bool from_top; 95 81 int header_threshhold = 1; 96 int count_bytes = 0; 82 const char *str_c, *str_n; 83 USE_FEATURE_FANCY_TAIL(const char *str_s;) 97 84 98 85 char *tailbuf; … … 100 87 int taillen = 0; 101 88 int newline = 0; 102 103 int *fds, nfiles, nread, nwrite, seen, i, opt; 89 int nfiles, nread, nwrite, seen, i, opt; 90 91 int *fds; 104 92 char *s, *buf; 105 93 const char *fmt; 106 94 107 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_TAIL95 #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL 108 96 /* Allow legacy syntax of an initial numeric option without -n. */ 109 if (argc >=2 && ((argv[1][0] == '+') || ((argv[1][0] == '-') 110 /* && (isdigit)(argv[1][1]) */ 111 && (((unsigned int)(argv[1][1] - '0')) <= 9)))) 112 { 113 optind = 2; 114 optarg = argv[1]; 115 goto GET_COUNT; 116 } 97 if (argc >= 2 && (argv[1][0] == '+' || argv[1][0] == '-') 98 && isdigit(argv[1][1]) 99 ) { 100 /* replacing arg[0] with "-n" can segfault, so... */ 101 argv[1] = xasprintf("-n%s", argv[1]); 102 #if 0 /* If we ever decide to make tail NOFORK */ 103 char *s = alloca(strlen(argv[1]) + 3); 104 sprintf(s, "-n%s", argv[1]); 105 argv[1] = s; 117 106 #endif 118 119 while ((opt = getopt(argc, argv, tail_opts)) > 0) { 120 switch (opt) { 121 case 'f': 122 follow = 1; 123 break; 124 case 'c': 125 count_bytes = 1; 126 /* FALLS THROUGH */ 127 case 'n': 128 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_TAIL 129 GET_COUNT: 107 } 130 108 #endif 131 count = bb_xgetlarg10_sfx(optarg, tail_suffixes); 132 /* Note: Leading whitespace is an error trapped above. */ 133 if (*optarg == '+') { 134 from_top = 1; 135 } else { 136 from_top = 0; 137 } 138 if (count < 0) { 139 count = -count; 140 } 141 break; 109 110 opt = getopt32(argv, "fc:n:" USE_FEATURE_FANCY_TAIL("qs:v"), 111 &str_c, &str_n USE_FEATURE_FANCY_TAIL(,&str_s)); 112 #define FOLLOW (opt & 0x1) 113 #define COUNT_BYTES (opt & 0x2) 114 //if (opt & 0x1) // -f 115 if (opt & 0x2) count = eat_num(str_c); // -c 116 if (opt & 0x4) count = eat_num(str_n); // -n 142 117 #if ENABLE_FEATURE_FANCY_TAIL 143 case 'q': 144 header_threshhold = INT_MAX; 145 break; 146 case 's': 147 sleep_period =bb_xgetularg10_bnd(optarg, 0, UINT_MAX); 148 break; 149 case 'v': 150 header_threshhold = 0; 151 break; 118 if (opt & 0x8) header_threshhold = INT_MAX; // -q 119 if (opt & 0x10) sleep_period = xatou(str_s); // -s 120 if (opt & 0x20) header_threshhold = 0; // -v 152 121 #endif 153 default: 154 bb_show_usage(); 155 } 156 } 122 argc -= optind; 123 argv += optind; 124 from_top = G.status; 157 125 158 126 /* open all the files */ 159 fds = (int *)xmalloc(sizeof(int) * (argc - optind + 1)); 160 161 argv += optind; 127 fds = xmalloc(sizeof(int) * (argc + 1)); 162 128 nfiles = i = 0; 163 164 if ( (argc -= optind)== 0) {129 G.status = EXIT_SUCCESS; 130 if (argc == 0) { 165 131 struct stat statbuf; 166 132 167 133 if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) { 168 follow = 0; 169 } 170 /* --argv; */ 134 opt &= ~1; /* clear FOLLOW */ 135 } 171 136 *argv = (char *) bb_msg_standard_input; 172 goto DO_STDIN; 173 } 174 137 } 175 138 do { 176 if ((argv[i][0] == '-') && !argv[i][1]) { 177 DO_STDIN: 178 fds[nfiles] = STDIN_FILENO; 179 } else if ((fds[nfiles] = open(argv[i], O_RDONLY)) < 0) { 180 bb_perror_msg("%s", argv[i]); 181 status = EXIT_FAILURE; 139 FILE* fil = fopen_or_warn_stdin(argv[i]); 140 if (!fil) { 141 G.status = EXIT_FAILURE; 182 142 continue; 183 143 } 184 argv[nfiles] = argv[i];185 ++nfiles;144 fds[nfiles] = fileno(fil); 145 argv[nfiles++] = argv[i]; 186 146 } while (++i < argc); 187 147 188 if (!nfiles) {148 if (!nfiles) 189 149 bb_error_msg_and_die("no files"); 190 }191 150 192 151 tailbufsize = BUFSIZ; 193 152 194 153 /* tail the files */ 195 if (from_top < count_bytes) { /* Each is 0 or 1, so true iff 0 < 1. */ 196 /* Hence, !from_top && count_bytes */ 154 if (!from_top && COUNT_BYTES) { 197 155 if (tailbufsize < count) { 198 156 tailbufsize = count + BUFSIZ; … … 210 168 * Beware of backing up too far. See example in wc.c. 211 169 */ 212 if ( (!(count|from_top)) && (lseek(fds[i], 0, SEEK_END) >= 0)) {170 if (!(count | from_top) && lseek(fds[i], 0, SEEK_END) >= 0) { 213 171 continue; 214 172 } … … 228 186 nwrite = nread; 229 187 if (seen < count) { 230 if ( count_bytes) {188 if (COUNT_BYTES) { 231 189 nwrite -= (count - seen); 232 190 seen = count; … … 235 193 do { 236 194 --nwrite; 237 if ( (*s++ == '\n') && (++seen == count)) {195 if (*s++ == '\n' && ++seen == count) { 238 196 break; 239 197 } … … 241 199 } 242 200 } 243 tail_xbb_full_write(buf + nread - nwrite, nwrite);201 xwrite(STDOUT_FILENO, buf + nread - nwrite, nwrite); 244 202 } else if (count) { 245 if ( count_bytes) {203 if (COUNT_BYTES) { 246 204 taillen += nread; 247 205 if (taillen > count) { … … 263 221 newline += nbuf; 264 222 taillen += nread; 265 266 223 } else { 267 224 int extra = 0; 268 if (buf[nread-1] != '\n') { 225 226 if (buf[nread-1] != '\n') 269 227 extra = 1; 270 }271 272 228 k = newline + nbuf + extra - count; 273 229 s = tailbuf; … … 278 234 ++s; 279 235 } 280 281 236 taillen += nread - (s - tailbuf); 282 237 memmove(tailbuf, s, taillen); … … 293 248 294 249 if (!from_top) { 295 tail_xbb_full_write(tailbuf, taillen);250 xwrite(STDOUT_FILENO, tailbuf, taillen); 296 251 } 297 252 … … 303 258 fmt = NULL; 304 259 305 while (follow) {260 if (FOLLOW) while (1) { 306 261 sleep(sleep_period); 307 262 i = 0; … … 315 270 fmt = NULL; 316 271 } 317 tail_xbb_full_write(buf, nread);272 xwrite(STDOUT_FILENO, buf, nread); 318 273 } 319 274 } while (++i < nfiles); 320 275 } 321 322 return status; 323 } 276 if (ENABLE_FEATURE_CLEAN_UP) { 277 free(fds); 278 } 279 return G.status; 280 } -
branches/2.2.5/mindi-busybox/coreutils/tee.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ 25 12 26 #include <stdio.h> 27 #include <stdlib.h> 13 #include "libbb.h" 28 14 #include <signal.h> 29 #include <unistd.h>30 #include "busybox.h"31 15 16 int tee_main(int argc, char **argv); 32 17 int tee_main(int argc, char **argv) 33 18 { 34 19 const char *mode = "w\0a"; 35 20 FILE **files; 36 FILE ** p;37 char ** filenames;38 int flags;39 int retval = EXIT_SUCCESS;40 #if def CONFIG_FEATURE_TEE_USE_BLOCK_IO21 FILE **fp; 22 char **names; 23 char **np; 24 char retval; 25 #if ENABLE_FEATURE_TEE_USE_BLOCK_IO 41 26 ssize_t c; 42 27 # define buf bb_common_bufsiz1 … … 44 29 int c; 45 30 #endif 31 retval = getopt32(argv, "ia"); /* 'a' must be 2nd */ 32 argc -= optind; 33 argv += optind; 46 34 47 flags = bb_getopt_ulflags(argc, argv, "ia"); /* 'a' must be 2nd*/35 mode += (retval & 2); /* Since 'a' is the 2nd option... */ 48 36 49 mode += (flags & 2); /* Since 'a' is the 2nd option... */ 50 51 if (flags & 1) { 52 signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction.*/ 37 if (retval & 1) { 38 signal(SIGINT, SIG_IGN); /* TODO - switch to sigaction. */ 53 39 } 54 40 retval = EXIT_SUCCESS; 55 41 /* gnu tee ignores SIGPIPE in case one of the output files is a pipe 56 42 * that doesn't consume all its input. Good idea... */ 57 signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction.*/43 signal(SIGPIPE, SIG_IGN); /* TODO - switch to sigaction. */ 58 44 59 45 /* Allocate an array of FILE *'s, with one extra for a sentinal. */ 60 p = files = (FILE **)xmalloc(sizeof(FILE *) * (argc - optind + 2)); 61 *p = stdout; 62 argv += optind - 1; 63 filenames = argv - 1; 64 *filenames = (char *) bb_msg_standard_input; /* for later */ 46 fp = files = xzalloc(sizeof(FILE *) * (argc + 2)); 47 np = names = argv - 1; 48 49 files[0] = stdout; 65 50 goto GOT_NEW_FILE; 66 67 51 do { 68 if ((*p = bb_wfopen(*argv, mode)) == NULL) { 52 *fp = fopen_or_warn(*argv, mode); 53 if (*fp == NULL) { 69 54 retval = EXIT_FAILURE; 70 55 continue; 71 56 } 72 filenames[(int)(p - files)] = *argv; 73 GOT_NEW_FILE: 74 setbuf(*p, NULL); /* tee must not buffer output. */ 75 ++p; 76 } while (*++argv); 57 *np = *argv++; 58 GOT_NEW_FILE: 59 setbuf(*fp++, NULL); /* tee must not buffer output. */ 60 np++; 61 } while (*argv); 62 /* names[0] will be filled later */ 77 63 78 *p = NULL; /* Store the sentinal value. */ 79 80 #ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO 64 #if ENABLE_FEATURE_TEE_USE_BLOCK_IO 81 65 while ((c = safe_read(STDIN_FILENO, buf, BUFSIZ)) > 0) { 82 for (p=files ; *p ; p++) { 83 fwrite(buf, 1, c, *p); 84 } 66 fp = files; 67 do 68 fwrite(buf, 1, c, *fp++); 69 while (*fp); 85 70 } 86 87 if (c < 0) { /* Make sure read errors are signaled. */ 71 if (c < 0) { /* Make sure read errors are signaled. */ 88 72 retval = EXIT_FAILURE; 89 73 } 90 91 74 #else 92 75 setvbuf(stdout, NULL, _IONBF, 0); 93 76 while ((c = getchar()) != EOF) { 94 for (p=files ; *p ; p++) { 95 putc(c, *p); 96 } 77 fp = files; 78 do 79 putc(c, *fp++); 80 while (*fp); 97 81 } 98 82 #endif … … 102 86 * file table is stdout, we can save one "if ferror" test by 103 87 * setting the first entry to stdin and checking stdout error 104 * status with bb_fflush_stdout_and_exit()... although fflush()ing88 * status with fflush_stdout_and_exit()... although fflush()ing 105 89 * is unnecessary here. */ 106 107 p = files; 108 *p = stdin; 109 do { /* Now check for (input and) output errors. */ 90 np = names; 91 fp = files; 92 names[0] = (char *) bb_msg_standard_input; 93 files[0] = stdin; 94 do { /* Now check for input and output errors. */ 110 95 /* Checking ferror should be sufficient, but we may want to fclose. 111 96 * If we do, remember not to close stdin! */ 112 bb_xferror(*p, filenames[(int)(p - files)]);113 } while (* ++p);97 die_if_ferror(*fp++, *np++); 98 } while (*fp); 114 99 115 bb_fflush_stdout_and_exit(retval);100 fflush_stdout_and_exit(retval); 116 101 } -
branches/2.2.5/mindi-busybox/coreutils/test.c
r902 r1765 13 13 * modified by Erik Andersen <andersen@codepoet.org> to be used 14 14 * in busybox. 15 * modified by Bernhard Fischer to be useable (i.e. a bit less bloaty). 15 16 * 16 17 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. … … 20 21 */ 21 22 22 #include "busybox.h" 23 #include <unistd.h> 24 #include <ctype.h> 25 #include <errno.h> 26 #include <string.h> 23 #include "libbb.h" 27 24 #include <setjmp.h> 25 26 /* This is a NOEXEC applet. Be very careful! */ 27 28 28 29 29 /* test(1) accepts the following grammar: … … 86 86 OPERAND 87 87 }; 88 88 #define is_int_op(a) (((unsigned char)((a) - INTEQ)) <= 5) 89 #define is_str_op(a) (((unsigned char)((a) - STREZ)) <= 5) 90 #define is_file_op(a) (((unsigned char)((a) - FILNT)) <= 2) 91 #define is_file_access(a) (((unsigned char)((a) - FILRD)) <= 2) 92 #define is_file_type(a) (((unsigned char)((a) - FILREG)) <= 5) 93 #define is_file_bit(a) (((unsigned char)((a) - FILSUID)) <= 2) 89 94 enum token_types { 90 95 UNOP, … … 96 101 97 102 static const struct t_op { 98 c onst char *op_text;99 shortop_num, op_type;103 char op_text[4]; 104 unsigned char op_num, op_type; 100 105 } ops[] = { 101 { 102 "-r", FILRD, UNOP}, { 103 "-w", FILWR, UNOP}, { 104 "-x", FILEX, UNOP}, { 105 "-e", FILEXIST, UNOP}, { 106 "-f", FILREG, UNOP}, { 107 "-d", FILDIR, UNOP}, { 108 "-c", FILCDEV, UNOP}, { 109 "-b", FILBDEV, UNOP}, { 110 "-p", FILFIFO, UNOP}, { 111 "-u", FILSUID, UNOP}, { 112 "-g", FILSGID, UNOP}, { 113 "-k", FILSTCK, UNOP}, { 114 "-s", FILGZ, UNOP}, { 115 "-t", FILTT, UNOP}, { 116 "-z", STREZ, UNOP}, { 117 "-n", STRNZ, UNOP}, { 118 "-h", FILSYM, UNOP}, /* for backwards compat */ 119 { 120 "-O", FILUID, UNOP}, { 121 "-G", FILGID, UNOP}, { 122 "-L", FILSYM, UNOP}, { 123 "-S", FILSOCK, UNOP}, { 124 "=", STREQ, BINOP}, { 125 "==", STREQ, BINOP}, { 126 "!=", STRNE, BINOP}, { 127 "<", STRLT, BINOP}, { 128 ">", STRGT, BINOP}, { 129 "-eq", INTEQ, BINOP}, { 130 "-ne", INTNE, BINOP}, { 131 "-ge", INTGE, BINOP}, { 132 "-gt", INTGT, BINOP}, { 133 "-le", INTLE, BINOP}, { 134 "-lt", INTLT, BINOP}, { 135 "-nt", FILNT, BINOP}, { 136 "-ot", FILOT, BINOP}, { 137 "-ef", FILEQ, BINOP}, { 138 "!", UNOT, BUNOP}, { 139 "-a", BAND, BBINOP}, { 140 "-o", BOR, BBINOP}, { 141 "(", LPAREN, PAREN}, { 142 ")", RPAREN, PAREN}, { 143 0, 0, 0} 106 { "-r", FILRD , UNOP }, 107 { "-w", FILWR , UNOP }, 108 { "-x", FILEX , UNOP }, 109 { "-e", FILEXIST, UNOP }, 110 { "-f", FILREG , UNOP }, 111 { "-d", FILDIR , UNOP }, 112 { "-c", FILCDEV , UNOP }, 113 { "-b", FILBDEV , UNOP }, 114 { "-p", FILFIFO , UNOP }, 115 { "-u", FILSUID , UNOP }, 116 { "-g", FILSGID , UNOP }, 117 { "-k", FILSTCK , UNOP }, 118 { "-s", FILGZ , UNOP }, 119 { "-t", FILTT , UNOP }, 120 { "-z", STREZ , UNOP }, 121 { "-n", STRNZ , UNOP }, 122 { "-h", FILSYM , UNOP }, /* for backwards compat */ 123 124 { "-O" , FILUID , UNOP }, 125 { "-G" , FILGID , UNOP }, 126 { "-L" , FILSYM , UNOP }, 127 { "-S" , FILSOCK, UNOP }, 128 { "=" , STREQ , BINOP }, 129 { "==" , STREQ , BINOP }, 130 { "!=" , STRNE , BINOP }, 131 { "<" , STRLT , BINOP }, 132 { ">" , STRGT , BINOP }, 133 { "-eq", INTEQ , BINOP }, 134 { "-ne", INTNE , BINOP }, 135 { "-ge", INTGE , BINOP }, 136 { "-gt", INTGT , BINOP }, 137 { "-le", INTLE , BINOP }, 138 { "-lt", INTLT , BINOP }, 139 { "-nt", FILNT , BINOP }, 140 { "-ot", FILOT , BINOP }, 141 { "-ef", FILEQ , BINOP }, 142 { "!" , UNOT , BUNOP }, 143 { "-a" , BAND , BBINOP }, 144 { "-o" , BOR , BBINOP }, 145 { "(" , LPAREN , PAREN }, 146 { ")" , RPAREN , PAREN }, 144 147 }; 145 148 146 #ifdef CONFIG_FEATURE_TEST_64 149 150 #if ENABLE_FEATURE_TEST_64 147 151 typedef int64_t arith_t; 148 152 #else … … 150 154 #endif 151 155 156 /* Cannot eliminate these static data (do the G trick) 157 * because of test_main usage from other applets */ 152 158 static char **t_wp; 153 159 static struct t_op const *t_wp_op; 154 160 static gid_t *group_array; 155 161 static int ngroups; 162 static jmp_buf leaving; 156 163 157 164 static enum token t_lex(char *s); … … 163 170 static int filstat(char *nm, enum token mode); 164 171 static arith_t getn(const char *s); 172 /* UNUSED 165 173 static int newerf(const char *f1, const char *f2); 166 174 static int olderf(const char *f1, const char *f2); 167 175 static int equalf(const char *f1, const char *f2); 176 */ 168 177 static int test_eaccess(char *path, int mode); 169 178 static int is_a_group_member(gid_t gid); 170 179 static void initialize_group_array(void); 171 180 172 static jmp_buf leaving; 173 174 int bb_test(int argc, char **argv) 181 int test_main(int argc, char **argv) 175 182 { 176 183 int res; 177 178 if (strcmp(argv[0], "[") == 0) { 179 if (strcmp(argv[--argc], "]")) { 180 bb_error_msg("missing ]"); 181 return 2; 182 } 183 argv[argc] = NULL; 184 } else if (strcmp(argv[0], "[[") == 0) { 185 if (strcmp(argv[--argc], "]]")) { 186 bb_error_msg("missing ]]"); 187 return 2; 184 const char *arg0; 185 bool _off; 186 187 arg0 = bb_basename(argv[0]); 188 if (arg0[0] == '[') { 189 --argc; 190 if (!arg0[1]) { /* "[" ? */ 191 if (NOT_LONE_CHAR(argv[argc], ']')) { 192 bb_error_msg("missing ]"); 193 return 2; 194 } 195 } else { /* assuming "[[" */ 196 if (strcmp(argv[argc], "]]") != 0) { 197 bb_error_msg("missing ]]"); 198 return 2; 199 } 188 200 } 189 201 argv[argc] = NULL; … … 202 214 * prevails... 203 215 */ 204 216 ngroups = 0; 205 217 206 218 /* Implement special cases from POSIX.2, section 4.62.4 */ 207 switch (argc) { 208 case 1: 219 if (argc == 1) 209 220 return 1; 210 case 2:221 if (argc == 2) 211 222 return *argv[1] == '\0'; 212 case 3: 213 if (argv[1][0] == '!' && argv[1][1] == '\0') { 223 //assert(argc); 224 /* remember if we saw argc==4 which wants *no* '!' test */ 225 _off = argc - 4; 226 if (_off ? 227 (LONE_CHAR(argv[1], '!')) 228 : (argv[1][0] != '!' || argv[1][1] != '\0')) 229 { 230 if (argc == 3) 214 231 return *argv[2] != '\0'; 232 233 t_lex(argv[2 + _off]); 234 if (t_wp_op && t_wp_op->op_type == BINOP) { 235 t_wp = &argv[1 + _off]; 236 return binop() == _off; 215 237 } 216 break; 217 case 4: 218 if (argv[1][0] != '!' || argv[1][1] != '\0') { 219 if (t_lex(argv[2]), t_wp_op && t_wp_op->op_type == BINOP) { 220 t_wp = &argv[1]; 221 return binop() == 0; 222 } 223 } 224 break; 225 case 5: 226 if (argv[1][0] == '!' && argv[1][1] == '\0') { 227 if (t_lex(argv[3]), t_wp_op && t_wp_op->op_type == BINOP) { 228 t_wp = &argv[2]; 229 return binop() != 0; 230 } 231 } 232 break; 233 } 234 238 } 235 239 t_wp = &argv[1]; 236 240 res = !oexpr(t_lex(*t_wp)); … … 243 247 } 244 248 249 static void syntax(const char *op, const char *msg) ATTRIBUTE_NORETURN; 245 250 static void syntax(const char *op, const char *msg) 246 251 { … … 248 253 bb_error_msg("%s: %s", op, msg); 249 254 } else { 250 bb_error_msg("%s ", msg);255 bb_error_msg("%s: %s"+4, msg); 251 256 } 252 257 longjmp(leaving, 2); … … 300 305 if (*++t_wp == NULL) 301 306 syntax(t_wp_op->op_text, "argument expected"); 302 switch (n) { 303 case STREZ: 304 return strlen(*t_wp) == 0; 305 case STRNZ: 306 return strlen(*t_wp) != 0; 307 case FILTT: 307 if (n == STREZ) 308 return t_wp[0][0] == '\0'; 309 if (n == STRNZ) 310 return t_wp[0][0] != '\0'; 311 if (n == FILTT) 308 312 return isatty(getn(*t_wp)); 309 default: 310 return filstat(*t_wp, n); 311 } 312 } 313 314 if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { 313 return filstat(*t_wp, n); 314 } 315 316 t_lex(t_wp[1]); 317 if (t_wp_op && t_wp_op->op_type == BINOP) { 315 318 return binop(); 316 319 } 317 320 318 return strlen(*t_wp) > 0;321 return t_wp[0][0] != '\0'; 319 322 } 320 323 … … 323 326 const char *opnd1, *opnd2; 324 327 struct t_op const *op; 328 arith_t val1, val2; 325 329 326 330 opnd1 = *t_wp; … … 328 332 op = t_wp_op; 329 333 330 if ((opnd2 = *++t_wp) == (char *) 0) 334 opnd2 = *++t_wp; 335 if (opnd2 == NULL) 331 336 syntax(op->op_text, "argument expected"); 332 337 333 switch (op->op_num) { 334 case STREQ: 335 return strcmp(opnd1, opnd2) == 0; 336 case STRNE: 337 return strcmp(opnd1, opnd2) != 0; 338 case STRLT: 339 return strcmp(opnd1, opnd2) < 0; 340 case STRGT: 341 return strcmp(opnd1, opnd2) > 0; 342 case INTEQ: 343 return getn(opnd1) == getn(opnd2); 344 case INTNE: 345 return getn(opnd1) != getn(opnd2); 346 case INTGE: 347 return getn(opnd1) >= getn(opnd2); 348 case INTGT: 349 return getn(opnd1) > getn(opnd2); 350 case INTLE: 351 return getn(opnd1) <= getn(opnd2); 352 case INTLT: 353 return getn(opnd1) < getn(opnd2); 354 case FILNT: 355 return newerf(opnd1, opnd2); 356 case FILOT: 357 return olderf(opnd1, opnd2); 358 case FILEQ: 359 return equalf(opnd1, opnd2); 360 } 361 /* NOTREACHED */ 362 return 1; 338 if (is_int_op(op->op_num)) { 339 val1 = getn(opnd1); 340 val2 = getn(opnd2); 341 if (op->op_num == INTEQ) 342 return val1 == val2; 343 if (op->op_num == INTNE) 344 return val1 != val2; 345 if (op->op_num == INTGE) 346 return val1 >= val2; 347 if (op->op_num == INTGT) 348 return val1 > val2; 349 if (op->op_num == INTLE) 350 return val1 <= val2; 351 if (op->op_num == INTLT) 352 return val1 < val2; 353 } 354 if (is_str_op(op->op_num)) { 355 val1 = strcmp(opnd1, opnd2); 356 if (op->op_num == STREQ) 357 return val1 == 0; 358 if (op->op_num == STRNE) 359 return val1 != 0; 360 if (op->op_num == STRLT) 361 return val1 < 0; 362 if (op->op_num == STRGT) 363 return val1 > 0; 364 } 365 /* We are sure that these three are by now the only binops we didn't check 366 * yet, so we do not check if the class is correct: 367 */ 368 /* if (is_file_op(op->op_num)) */ 369 { 370 struct stat b1, b2; 371 372 if (stat(opnd1, &b1) || stat(opnd2, &b2)) 373 return 0; /* false, since at least one stat failed */ 374 if (op->op_num == FILNT) 375 return b1.st_mtime > b2.st_mtime; 376 if (op->op_num == FILOT) 377 return b1.st_mtime < b2.st_mtime; 378 if (op->op_num == FILEQ) 379 return b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino; 380 } 381 return 1; /* NOTREACHED */ 363 382 } 364 383 … … 366 385 { 367 386 struct stat s; 368 unsigned int i;387 int i = i; /* gcc 3.x thinks it can be used uninitialized */ 369 388 370 389 if (mode == FILSYM) { … … 380 399 if (stat(nm, &s) != 0) 381 400 return 0; 382 383 switch (mode) { 384 case FILRD: 385 return test_eaccess(nm, R_OK) == 0; 386 case FILWR: 387 return test_eaccess(nm, W_OK) == 0; 388 case FILEX: 389 return test_eaccess(nm, X_OK) == 0; 390 case FILEXIST: 401 if (mode == FILEXIST) 391 402 return 1; 392 case FILREG: 393 i = S_IFREG; 394 goto filetype; 395 case FILDIR: 396 i = S_IFDIR; 397 goto filetype; 398 case FILCDEV: 399 i = S_IFCHR; 400 goto filetype; 401 case FILBDEV: 402 i = S_IFBLK; 403 goto filetype; 404 case FILFIFO: 403 if (is_file_access(mode)) { 404 if (mode == FILRD) 405 i = R_OK; 406 if (mode == FILWR) 407 i = W_OK; 408 if (mode == FILEX) 409 i = X_OK; 410 return test_eaccess(nm, i) == 0; 411 } 412 if (is_file_type(mode)) { 413 if (mode == FILREG) 414 i = S_IFREG; 415 if (mode == FILDIR) 416 i = S_IFDIR; 417 if (mode == FILCDEV) 418 i = S_IFCHR; 419 if (mode == FILBDEV) 420 i = S_IFBLK; 421 if (mode == FILFIFO) { 405 422 #ifdef S_IFIFO 406 i = S_IFIFO; 407 goto filetype; 423 i = S_IFIFO; 408 424 #else 409 return 0;425 return 0; 410 426 #endif 411 case FILSOCK: 427 } 428 if (mode == FILSOCK) { 412 429 #ifdef S_IFSOCK 413 i = S_IFSOCK; 414 goto filetype; 430 i = S_IFSOCK; 415 431 #else 416 return 0;432 return 0; 417 433 #endif 418 case FILSUID: 419 i = S_ISUID; 420 goto filebit; 421 case FILSGID: 422 i = S_ISGID; 423 goto filebit; 424 case FILSTCK: 425 i = S_ISVTX; 426 goto filebit; 427 case FILGZ: 434 } 435 filetype: 436 return ((s.st_mode & S_IFMT) == i); 437 } 438 if (is_file_bit(mode)) { 439 if (mode == FILSUID) 440 i = S_ISUID; 441 if (mode == FILSGID) 442 i = S_ISGID; 443 if (mode == FILSTCK) 444 i = S_ISVTX; 445 return ((s.st_mode & i) != 0); 446 } 447 if (mode == FILGZ) 428 448 return s.st_size > 0L; 429 case FILUID:449 if (mode == FILUID) 430 450 return s.st_uid == geteuid(); 431 case FILGID:451 if (mode == FILGID) 432 452 return s.st_gid == getegid(); 433 default: 434 return 1; 435 } 436 437 filetype: 438 return ((s.st_mode & S_IFMT) == i); 439 440 filebit: 441 return ((s.st_mode & i) != 0); 453 return 1; /* NOTREACHED */ 442 454 } 443 455 444 456 static enum token t_lex(char *s) 445 457 { 446 struct t_op const *op = ops;447 448 if (s == 0) {449 t_wp_op = (struct t_op *) 0;458 const struct t_op *op; 459 460 t_wp_op = NULL; 461 if (s == NULL) { 450 462 return EOI; 451 463 } 452 while (op->op_text) { 464 465 op = ops; 466 do { 453 467 if (strcmp(s, op->op_text) == 0) { 454 468 t_wp_op = op; … … 456 470 } 457 471 op++; 458 } 459 t_wp_op = (struct t_op *) 0; 472 } while (op < ops + ARRAY_SIZE(ops)); 473 460 474 return OPERAND; 461 475 } 462 476 463 477 /* atoi with error detection */ 478 //XXX: FIXME: duplicate of existing libbb function? 464 479 static arith_t getn(const char *s) 465 480 { 466 481 char *p; 467 #if def CONFIG_FEATURE_TEST_64482 #if ENABLE_FEATURE_TEST_64 468 483 long long r; 469 484 #else … … 472 487 473 488 errno = 0; 474 #if def CONFIG_FEATURE_TEST_64489 #if ENABLE_FEATURE_TEST_64 475 490 r = strtoll(s, &p, 10); 476 491 #else … … 487 502 } 488 503 504 /* UNUSED 489 505 static int newerf(const char *f1, const char *f2) 490 506 { … … 511 527 b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino); 512 528 } 529 */ 513 530 514 531 /* Do the same thing access(2) does, but use the effective uid and gid, … … 521 538 522 539 if (stat(path, &st) < 0) 523 return (-1);540 return -1; 524 541 525 542 if (euid == 0) { 526 543 /* Root can read or write any file. */ 527 544 if (mode != X_OK) 528 return (0);545 return 0; 529 546 530 547 /* Root can execute any file that has any one of the execute 531 548 bits set. */ 532 549 if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) 533 return (0);550 return 0; 534 551 } 535 552 … … 540 557 541 558 if (st.st_mode & mode) 542 return (0);543 544 return (-1);559 return 0; 560 561 return -1; 545 562 } 546 563 … … 549 566 ngroups = getgroups(0, NULL); 550 567 if (ngroups > 0) { 551 group_array = xmalloc(ngroups * sizeof(gid_t)); 568 /* FIXME: ash tries so hard to not die on OOM, 569 * and we spoil it with just one xrealloc here */ 570 /* We realloc, because test_main can be entered repeatedly by shell. 571 * Testcase (ash): 'while true; do test -x some_file; done' 572 * and watch top. (some_file must have owner != you) */ 573 group_array = xrealloc(group_array, ngroups * sizeof(gid_t)); 552 574 getgroups(ngroups, group_array); 553 575 } … … 555 577 556 578 /* Return non-zero if GID is one that we have in our groups list. */ 579 //XXX: FIXME: duplicate of existing libbb function? 580 // see toplevel TODO file: 581 // possible code duplication ingroup() and is_a_group_member() 557 582 static int is_a_group_member(gid_t gid) 558 583 { 559 registerint i;584 int i; 560 585 561 586 /* Short-circuit if possible, maybe saving a call to getgroups(). */ 562 587 if (gid == getgid() || gid == getegid()) 563 return (1);588 return 1; 564 589 565 590 if (ngroups == 0) … … 569 594 for (i = 0; i < ngroups; i++) 570 595 if (gid == group_array[i]) 571 return (1); 572 573 return (0); 574 } 575 576 577 /* applet entry point */ 578 579 int test_main(int argc, char **argv) 580 { 581 exit(bb_test(argc, argv)); 582 } 583 596 return 1; 597 598 return 0; 599 } -
branches/2.2.5/mindi-busybox/coreutils/touch.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 31 18 */ 32 19 33 #include <stdio.h> 34 #include <sys/types.h> 35 #include <fcntl.h> 36 #include <utime.h> 37 #include <errno.h> 38 #include <unistd.h> 39 #include <stdlib.h> 40 #include "busybox.h" 20 #include "libbb.h" 41 21 22 /* This is a NOFORK applet. Be very careful! */ 23 24 int touch_main(int argc, char **argv); 42 25 int touch_main(int argc, char **argv) 43 26 { 44 27 int fd; 45 int flags;46 28 int status = EXIT_SUCCESS; 47 48 flags = bb_getopt_ulflags(argc, argv, "c"); 29 int flags = getopt32(argv, "c"); 49 30 50 31 argv += optind; … … 56 37 do { 57 38 if (utime(*argv, NULL)) { 58 if (errno == ENOENT) { /* no such file */59 if (flags & 1) { /* Creation is disabled, so ignore. */39 if (errno == ENOENT) { /* no such file */ 40 if (flags) { /* Creation is disabled, so ignore. */ 60 41 continue; 61 42 } -
branches/2.2.5/mindi-busybox/coreutils/tr.c
r821 r1765 16 16 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 17 17 */ 18 19 #include "busybox.h" 20 21 // Even with -funsigned-char, gcc still complains about char as an array index. 22 23 #define GCC4_IS_STUPID int 18 /* http://www.opengroup.org/onlinepubs/009695399/utilities/tr.html 19 * TODO: xdigit, graph, print 20 */ 21 #include "libbb.h" 24 22 25 23 #define ASCII 0377 26 24 27 /* some "globals" shared across this file */ 28 static char com_fl, del_fl, sq_fl; 29 /* these last are pointers to static buffers declared in tr_main */ 30 static char *poutput, *pvector, *pinvec, *poutvec; 31 32 static void convert(void) 33 { 34 int read_chars = 0, in_index = 0, out_index = 0, c, coded, last = -1; 35 36 for (;;) { 37 // If we're out of input, flush output and read more input. 38 39 if (in_index == read_chars) { 40 if (out_index) { 41 if (write(1, (char *) poutput, out_index) != out_index) 42 bb_error_msg_and_die(bb_msg_write_error); 43 out_index = 0; 44 } 45 46 if ((read_chars = read(0, bb_common_bufsiz1, BUFSIZ)) <= 0) { 47 if (write(1, (char *) poutput, out_index) != out_index) 48 bb_error_msg(bb_msg_write_error); 49 exit(0); 50 } 51 in_index = 0; 52 } 53 c = bb_common_bufsiz1[in_index++]; 54 coded = pvector[c]; 55 if (del_fl && pinvec[c]) 56 continue; 57 if (sq_fl && last == coded && (pinvec[c] || poutvec[coded])) 58 continue; 59 poutput[out_index++] = last = coded; 60 } 61 62 /* NOTREACHED */ 63 } 64 65 static void map(char *string1, unsigned int string1_len, 66 char *string2, unsigned int string2_len) 25 #define TR_OPT_complement (1<<0) 26 #define TR_OPT_delete (1<<1) 27 #define TR_OPT_squeeze_reps (1<<2) 28 29 static void map(char *pvector, 30 unsigned char *string1, unsigned int string1_len, 31 unsigned char *string2, unsigned int string2_len) 67 32 { 68 33 char last = '0'; … … 71 36 for (j = 0, i = 0; i < string1_len; i++) { 72 37 if (string2_len <= j) 73 pvector[ (GCC4_IS_STUPID)string1[i]] = last;38 pvector[string1[i]] = last; 74 39 else 75 pvector[ (GCC4_IS_STUPID)string1[i]] = last = string2[j++];40 pvector[string1[i]] = last = string2[j++]; 76 41 } 77 42 } … … 85 50 { 86 51 char *buffer_start = buffer; 87 int i, ac; 88 52 unsigned i; /* XXX: FIXME: use unsigned char? */ 53 unsigned char ac; 54 #define CLO ":]\0" 55 static const char classes[] ALIGN1 = 56 "alpha"CLO "alnum"CLO "digit"CLO "lower"CLO "upper"CLO "space"CLO 57 "blank"CLO "punct"CLO "cntrl"CLO; 58 #define CLASS_invalid 0 /* we increment the retval */ 59 #define CLASS_alpha 1 60 #define CLASS_alnum 2 61 #define CLASS_digit 3 62 #define CLASS_lower 4 63 #define CLASS_upper 5 64 #define CLASS_space 6 65 #define CLASS_blank 7 66 #define CLASS_punct 8 67 #define CLASS_cntrl 9 68 //#define CLASS_xdigit 10 69 //#define CLASS_graph 11 70 //#define CLASS_print 12 89 71 while (*arg) { 90 72 if (*arg == '\\') { … … 93 75 } else if (*(arg+1) == '-') { 94 76 ac = *(arg+2); 95 if (ac == 0) {77 if (ac == 0) { 96 78 *buffer++ = *arg++; 97 79 continue; … … 105 87 i = *arg++; 106 88 if (ENABLE_FEATURE_TR_CLASSES && i == ':') { 107 if (strncmp(arg, "alpha", 5) == 0) { 89 smalluint j; 90 { /* not really pretty.. */ 91 char *tmp = xstrndup(arg, 7); // warning: xdigit needs 8, not 7 92 j = index_in_strings(classes, tmp) + 1; 93 free(tmp); 94 } 95 if (j == CLASS_alnum || j == CLASS_digit) { 96 for (i = '0'; i <= '9'; i++) 97 *buffer++ = i; 98 } 99 if (j == CLASS_alpha || j == CLASS_alnum || j == CLASS_upper) { 108 100 for (i = 'A'; i <= 'Z'; i++) 109 101 *buffer++ = i; 102 } 103 if (j == CLASS_alpha || j == CLASS_alnum || j == CLASS_lower) { 110 104 for (i = 'a'; i <= 'z'; i++) 111 105 *buffer++ = i; 112 106 } 113 else if (strncmp(arg, "alnum", 5) == 0) { 114 for (i = '0'; i <= '9'; i++) 115 *buffer++ = i; 116 for (i = 'A'; i <= 'Z'; i++) 117 *buffer++ = i; 118 for (i = 'a'; i <= 'z'; i++) 119 *buffer++ = i; 120 } 121 else if (strncmp(arg, "digit", 5) == 0) 122 for (i = '0'; i <= '9'; i++) 123 *buffer++ = i; 124 else if (strncmp(arg, "lower", 5) == 0) 125 for (i = 'a'; i <= 'z'; i++) 126 *buffer++ = i; 127 else if (strncmp(arg, "upper", 5) == 0) 128 for (i = 'A'; i <= 'Z'; i++) 129 *buffer++ = i; 130 else if (strncmp(arg, "space", 5) == 0) { 131 const char s[] = "\t\n\v\f\r "; 132 strcat((char*)buffer, s); 133 buffer += sizeof(s) - 1; 134 } 135 else if (strncmp(arg, "blank", 5) == 0) { 107 if (j == CLASS_space || j == CLASS_blank) { 136 108 *buffer++ = '\t'; 109 if (j == CLASS_space) { 110 *buffer++ = '\n'; 111 *buffer++ = '\v'; 112 *buffer++ = '\f'; 113 *buffer++ = '\r'; 114 } 137 115 *buffer++ = ' '; 138 116 } 139 /* gcc gives a warning if braces aren't used here */ 140 else if (strncmp(arg, "punct", 5) == 0) { 117 if (j == CLASS_punct || j == CLASS_cntrl) { 141 118 for (i = 0; i <= ASCII; i++) 142 if (isprint(i) && (!isalnum(i)) && (!isspace(i))) 119 if ((j == CLASS_punct && 120 isprint(i) && (!isalnum(i)) && (!isspace(i))) || 121 (j == CLASS_cntrl && iscntrl(i))) 143 122 *buffer++ = i; 144 123 } 145 else if (strncmp(arg, "cntrl", 5) == 0) { 146 for (i = 0; i <= ASCII; i++) 147 if (iscntrl(i)) 148 *buffer++ = i; 149 } 150 else { 124 if (j == CLASS_invalid) { 151 125 *buffer++ = '['; 152 126 *buffer++ = ':'; … … 157 131 if (ENABLE_FEATURE_TR_EQUIV && i == '=') { 158 132 *buffer++ = *arg; 159 /* skip the closing =] */ 160 arg += 3; 133 arg += 3; /* Skip the closing =] */ 161 134 continue; 162 135 } … … 169 142 while (i <= ac) 170 143 *buffer++ = i++; 171 arg++; 144 arg++; /* Skip the assumed ']' */ 172 145 } else 173 146 *buffer++ = *arg++; 174 147 } 175 176 148 return (buffer - buffer_start); 177 149 } … … 179 151 static int complement(char *buffer, int buffer_len) 180 152 { 181 register short i, j, ix;153 int i, j, ix; 182 154 char conv[ASCII + 2]; 183 155 … … 194 166 } 195 167 168 int tr_main(int argc, char **argv); 196 169 int tr_main(int argc, char **argv) 197 170 { 198 registerunsigned char *ptr;199 int output_length =0, input_length;171 unsigned char *ptr; 172 int output_length = 0, input_length; 200 173 int idx = 1; 201 174 int i; 202 RESERVE_CONFIG_BUFFER(output, BUFSIZ); 175 smalluint flags = 0; 176 size_t read_chars = 0, in_index = 0, out_index = 0, c, coded, last = -1; 177 RESERVE_CONFIG_UBUFFER(output, BUFSIZ); 203 178 RESERVE_CONFIG_BUFFER(vector, ASCII+1); 204 179 RESERVE_CONFIG_BUFFER(invec, ASCII+1); 205 180 RESERVE_CONFIG_BUFFER(outvec, ASCII+1); 206 181 207 /* ... but make them available globally */208 poutput = output;209 pvector = vector;210 pinvec = invec;211 poutvec = outvec;212 213 182 if (argc > 1 && argv[idx][0] == '-') { 214 183 for (ptr = (unsigned char *) &argv[idx][1]; *ptr; ptr++) { 215 switch (*ptr) { 216 case 'c': 217 com_fl = TRUE; 218 break; 219 case 'd': 220 del_fl = TRUE; 221 break; 222 case 's': 223 sq_fl = TRUE; 224 break; 225 default: 184 if (*ptr == 'c') 185 flags |= TR_OPT_complement; 186 else if (*ptr == 'd') 187 flags |= TR_OPT_delete; 188 else if (*ptr == 's') 189 flags |= TR_OPT_squeeze_reps; 190 else 226 191 bb_show_usage(); 227 }228 192 } 229 193 idx++; … … 234 198 } 235 199 200 #define tr_buf bb_common_bufsiz1 236 201 if (argv[idx] != NULL) { 237 input_length = expand(argv[idx++], bb_common_bufsiz1);238 if ( com_fl)239 input_length = complement( bb_common_bufsiz1, input_length);202 input_length = expand(argv[idx++], tr_buf); 203 if (flags & TR_OPT_complement) 204 input_length = complement(tr_buf, input_length); 240 205 if (argv[idx] != NULL) { 241 206 if (*argv[idx] == '\0') 242 207 bb_error_msg_and_die("STRING2 cannot be empty"); 243 208 output_length = expand(argv[idx], output); 244 map( bb_common_bufsiz1, input_length, output, output_length);209 map(vector, tr_buf, input_length, output, output_length); 245 210 } 246 211 for (i = 0; i < input_length; i++) 247 invec[( GCC4_IS_STUPID)bb_common_bufsiz1[i]] = TRUE;212 invec[(unsigned char)tr_buf[i]] = TRUE; 248 213 for (i = 0; i < output_length; i++) 249 outvec[(GCC4_IS_STUPID)output[i]] = TRUE; 250 } 251 convert(); 252 return (0); 253 } 214 outvec[output[i]] = TRUE; 215 } 216 217 for (;;) { 218 /* If we're out of input, flush output and read more input. */ 219 if (in_index == read_chars) { 220 if (out_index) { 221 xwrite(STDOUT_FILENO, (char *)output, out_index); 222 out_index = 0; 223 } 224 read_chars = read(STDIN_FILENO, tr_buf, BUFSIZ); 225 if (read_chars <= 0) { 226 if (write(STDOUT_FILENO, (char *)output, out_index) != out_index) 227 bb_perror_msg(bb_msg_write_error); 228 exit(EXIT_SUCCESS); 229 } 230 in_index = 0; 231 } 232 c = tr_buf[in_index++]; 233 coded = vector[c]; 234 if ((flags & TR_OPT_delete) && invec[c]) 235 continue; 236 if ((flags & TR_OPT_squeeze_reps) && last == coded && 237 (invec[c] || outvec[coded])) 238 continue; 239 output[out_index++] = last = coded; 240 } 241 /* NOTREACHED */ 242 return EXIT_SUCCESS; 243 } -
branches/2.2.5/mindi-busybox/coreutils/true.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */ 25 12 26 #include <stdlib.h> 27 #include "busybox.h" 13 #include "libbb.h" 28 14 15 /* This is a NOFORK applet. Be very careful! */ 16 17 int true_main(int argc, char **argv); 29 18 int true_main(int argc, char **argv) 30 19 { -
branches/2.2.5/mindi-busybox/coreutils/tty.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 24 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/tty.html */ 25 12 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <unistd.h> 29 #include "busybox.h" 13 #include "libbb.h" 30 14 15 int tty_main(int argc, char **argv); 31 16 int tty_main(int argc, char **argv) 32 17 { 33 18 const char *s; 34 int silent;/* Note: No longer relevant in SUSv3. */19 USE_INCLUDE_SUSv2(int silent;) /* Note: No longer relevant in SUSv3. */ 35 20 int retval; 36 21 37 bb_default_error_retval = 2; /* SUSv3 requires > 1 for error. */22 xfunc_error_retval = 2; /* SUSv3 requires > 1 for error. */ 38 23 39 silent = bb_getopt_ulflags(argc, argv, "s");24 USE_INCLUDE_SUSv2(silent = getopt32(argv, "s");) 40 25 41 26 /* gnu tty outputs a warning that it is ignoring all args. */ … … 44 29 retval = 0; 45 30 46 if ((s = ttyname(0)) == NULL) { 31 s = ttyname(0); 32 if (s == NULL) { 47 33 /* According to SUSv3, ttyname can on fail with EBADF or ENOTTY. 48 34 * We know the file descriptor is good, so failure means not a tty. */ … … 50 36 retval = 1; 51 37 } 38 USE_INCLUDE_SUSv2(if (!silent) puts(s);) 39 SKIP_INCLUDE_SUSv2(puts(s);) 52 40 53 if (!silent) { 54 puts(s); 55 } 56 57 bb_fflush_stdout_and_exit(retval); 41 fflush_stdout_and_exit(retval); 58 42 } -
branches/2.2.5/mindi-busybox/coreutils/uname.c
r821 r1765 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* uname -- print system information 3 Copyright (C) 1989-1999 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2, or (at your option) 8 any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software Foundation, 17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 3 * Copyright (C) 1989-1999 Free Software Foundation, Inc. 4 * 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 6 */ 18 7 19 8 /* BB_AUDIT SUSv3 compliant */ … … 42 31 */ 43 32 44 #include <stdio.h>45 #include <stdlib.h>46 #include <stddef.h>47 #include <string.h>48 #include <unistd.h>49 #include <sys/types.h>50 33 #include <sys/utsname.h> 51 #include " busybox.h"34 #include "libbb.h" 52 35 53 36 typedef struct { … … 56 39 } uname_info_t; 57 40 58 static const char options[] = "snrvmpa";59 static const unsigned short int utsname_offset[]= {41 static const char options[] ALIGN1 = "snrvmpa"; 42 static const unsigned short utsname_offset[] ALIGN2 = { 60 43 offsetof(uname_info_t,name.sysname), 61 44 offsetof(uname_info_t,name.nodename), … … 66 49 }; 67 50 51 int uname_main(int argc, char **argv); 68 52 int uname_main(int argc, char **argv) 69 53 { … … 75 59 char toprint; 76 60 77 toprint = bb_getopt_ulflags(argc,argv, options);61 toprint = getopt32(argv, options); 78 62 79 63 if (argc != optind) { … … 103 87 strcpy(uname_info.processor, "unknown"); 104 88 105 delta =utsname_offset;89 delta = utsname_offset; 106 90 do { 107 91 if (toprint & 1) { 108 bb_printf(((char *)(&uname_info)) + *delta);92 printf(((char *)(&uname_info)) + *delta); 109 93 if (toprint > 1) { 110 94 putchar(' '); … … 115 99 putchar('\n'); 116 100 117 bb_fflush_stdout_and_exit(EXIT_SUCCESS);101 fflush_stdout_and_exit(EXIT_SUCCESS); 118 102 } -
branches/2.2.5/mindi-busybox/coreutils/uniq.c
r821 r1765 11 11 /* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */ 12 12 13 #include "busybox.h" 14 #include <string.h> 15 #include <ctype.h> 16 #include <unistd.h> 13 #include "libbb.h" 17 14 18 static const char uniq_opts[] ="f:s:" "cdu\0\1\2\4";15 static const char uniq_opts[] ALIGN1 = "cdu" "f:s:" "cdu\0\1\2\4"; 19 16 20 17 static FILE *xgetoptfile_uniq_s(char **argv, int read0write2) … … 22 19 const char *n; 23 20 24 if ((n = *argv) != NULL) { 21 n = *argv; 22 if (n != NULL) { 25 23 if ((*n != '-') || n[1]) { 26 return bb_xfopen(n, "r\0w" + read0write2);24 return xfopen(n, "r\0w" + read0write2); 27 25 } 28 26 } … … 30 28 } 31 29 30 int uniq_main(int argc, char **argv); 32 31 int uniq_main(int argc, char **argv) 33 32 { 34 33 FILE *in, *out; 35 unsigned long dups, skip_fields, skip_chars, i , uniq_flags;34 unsigned long dups, skip_fields, skip_chars, i; 36 35 const char *s0, *e0, *s1, *e1, *input_filename; 37 intopt;36 unsigned opt; 38 37 39 uniq_flags = skip_fields = skip_chars = 0; 38 enum { 39 OPT_c = 0x1, 40 OPT_d = 0x2, 41 OPT_u = 0x4, 42 OPT_f = 0x8, 43 OPT_s = 0x10, 44 }; 40 45 41 while ((opt = getopt(argc, argv, uniq_opts)) > 0) { 42 if ((opt == 'f') || (opt == 's')) { 43 int t = bb_xgetularg10(optarg); 44 if (opt == 'f') { 45 skip_fields = t; 46 } else { 47 skip_chars = t; 48 } 49 } else if ((s0 = strchr(uniq_opts, opt)) != NULL) { 50 uniq_flags |= s0[4]; 51 } else { 52 bb_show_usage(); 53 } 54 } 46 skip_fields = skip_chars = 0; 55 47 56 input_filename = *(argv += optind); 48 opt = getopt32(argv, "cduf:s:", &s0, &s1); 49 if (opt & OPT_f) 50 skip_fields = xatoul(s0); 51 if (opt & OPT_s) 52 skip_chars = xatoul(s1); 53 argv += optind; 54 55 input_filename = *argv; 57 56 58 57 in = xgetoptfile_uniq_s(argv, 0); … … 73 72 74 73 /* gnu uniq ignores newlines */ 75 while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) {74 while ((s1 = xmalloc_getline(in)) != NULL) { 76 75 e1 = s1; 77 for (i =skip_fields ; i; i--) {76 for (i = skip_fields; i; i--) { 78 77 e1 = skip_whitespace(e1); 79 while (*e1 && !isspace(*e1)) { 80 ++e1; 81 } 78 e1 = skip_non_whitespace(e1); 82 79 } 83 for (i = skip_chars ; *e1 && i; i--) {80 for (i = skip_chars; *e1 && i; i--) { 84 81 ++e1; 85 82 } … … 93 90 94 91 if (s0) { 95 if (!( uniq_flags & (2 << !!dups))) {96 bb_fprintf(out, "\0%d " + (uniq_flags& 1), dups + 1);97 bb_fprintf(out, "%s\n", s0);92 if (!(opt & (OPT_d << !!dups))) { /* (if dups, opt & OPT_e) */ 93 fprintf(out, "\0%d " + (opt & 1), dups + 1); 94 fprintf(out, "%s\n", s0); 98 95 } 99 96 free((void *)s0); … … 101 98 } while (s1); 102 99 103 bb_xferror(in, input_filename);100 die_if_ferror(in, input_filename); 104 101 105 bb_fflush_stdout_and_exit(EXIT_SUCCESS);102 fflush_stdout_and_exit(EXIT_SUCCESS); 106 103 } -
branches/2.2.5/mindi-busybox/coreutils/usleep.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 10 /* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */ 24 11 25 #include <stdlib.h> 26 #include <limits.h> 27 #include <unistd.h> 28 #include "busybox.h" 12 #include "libbb.h" 29 13 14 /* This is a NOFORK applet. Be very careful! */ 15 16 int usleep_main(int argc, char **argv); 30 17 int usleep_main(int argc, char **argv) 31 18 { … … 34 21 } 35 22 36 if (usleep( bb_xgetularg10_bnd(argv[1], 0, UINT_MAX))) {23 if (usleep(xatou(argv[1]))) { 37 24 bb_perror_nomsg_and_die(); 38 25 } -
branches/2.2.5/mindi-busybox/coreutils/uudecode.c
r821 r1765 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * Copyright 2003, Glenn McGrath <bug1@iinet.net.au> … … 12 13 13 14 14 #include <stdio.h> 15 #include <errno.h> 16 #include <getopt.h> /* optind */ 17 #include <string.h> 18 #include <stdlib.h> 19 #include "busybox.h" 20 21 static int read_stduu(FILE *src_stream, FILE *dst_stream) 15 #include "libbb.h" 16 17 static void read_stduu(FILE *src_stream, FILE *dst_stream) 22 18 { 23 19 char *line; 24 20 25 while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) {21 while ((line = xmalloc_getline(src_stream)) != NULL) { 26 22 int length; 27 23 char *line_ptr = line; 28 24 29 25 if (strcmp(line, "end") == 0) { 30 return (EXIT_SUCCESS);26 return; 31 27 } 32 28 length = ((*line_ptr - 0x20) & 0x3f)* 4 / 3; … … 37 33 } 38 34 if (length > 60) { 39 bb_error_msg_and_die(" Line too long");35 bb_error_msg_and_die("line too long"); 40 36 } 41 37 42 38 line_ptr++; 43 /* Tolerate an overly long line to ac omadate a possible exta '`' */39 /* Tolerate an overly long line to accomodate a possible exta '`' */ 44 40 if (strlen(line_ptr) < (size_t)length) { 45 bb_error_msg_and_die(" Short file");41 bb_error_msg_and_die("short file"); 46 42 } 47 43 … … 68 64 free(line); 69 65 } 70 bb_error_msg_and_die(" Short file");66 bb_error_msg_and_die("short file"); 71 67 } 72 68 73 static intread_base64(FILE *src_stream, FILE *dst_stream)69 static void read_base64(FILE *src_stream, FILE *dst_stream) 74 70 { 75 static const char base64_table[] = 76 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"; 77 char term_count = 0; 71 int term_count = 1; 78 72 79 73 while (1) { … … 85 79 int ch; 86 80 87 /* Get next _valid_ character */ 81 /* Get next _valid_ character. 82 * global vector bb_uuenc_tbl_base64[] contains this string: 83 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" 84 */ 88 85 do { 89 86 ch = fgetc(src_stream); 90 87 if (ch == EOF) { 91 bb_error_msg_and_die(" Short file");88 bb_error_msg_and_die("short file"); 92 89 } 93 } while ((table_ptr = strchr(base64_table, ch)) == NULL); 94 95 /* Convert encoded charcter to decimal */ 96 ch = table_ptr - base64_table; 90 table_ptr = strchr(bb_uuenc_tbl_base64, ch); 91 } while (table_ptr == NULL); 92 93 /* Convert encoded character to decimal */ 94 ch = table_ptr - bb_uuenc_tbl_base64; 97 95 98 96 if (*table_ptr == '=') { 99 97 if (term_count == 0) { 100 translated[count] = 0;98 translated[count] = '\0'; 101 99 break; 102 100 } 103 101 term_count++; 104 } 105 else if (*table_ptr == '\n') { 102 } else if (*table_ptr == '\n') { 106 103 /* Check for terminating line */ 107 104 if (term_count == 5) { 108 return (EXIT_SUCCESS);105 return; 109 106 } 110 107 term_count = 1; … … 118 115 119 116 /* Merge 6 bit chars to 8 bit */ 120 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream); 117 if (count > 1) { 118 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream); 119 } 121 120 if (count > 2) { 122 121 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream); … … 128 127 } 129 128 129 int uudecode_main(int argc, char **argv); 130 130 int uudecode_main(int argc, char **argv) 131 131 { 132 int (*decode_fn_ptr) (FILE * src, FILE * dst); 133 FILE *src_stream; 132 FILE *src_stream = stdin; 134 133 char *outname = NULL; 135 134 char *line; 136 int opt; 137 138 opt = bb_getopt_ulflags(argc, argv, "o:", &outname); 139 140 if (optind == argc) { 141 src_stream = stdin; 142 } else if (optind + 1 == argc) { 143 src_stream = bb_xfopen(argv[optind], "r"); 144 } else { 145 bb_show_usage(); 146 } 135 136 opt_complementary = "?1"; /* 1 argument max */ 137 getopt32(argv, "o:", &outname); 138 argv += optind; 139 140 if (argv[0]) 141 src_stream = xfopen(argv[0], "r"); 147 142 148 143 /* Search for the start of the encoding */ 149 while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) { 150 char *line_ptr = NULL; 151 152 if (line == NULL) { 153 break; 154 } else if (strncmp(line, "begin-base64 ", 13) == 0) { 144 while ((line = xmalloc_getline(src_stream)) != NULL) { 145 void (*decode_fn_ptr)(FILE * src, FILE * dst); 146 char *line_ptr; 147 FILE *dst_stream; 148 int mode; 149 150 if (strncmp(line, "begin-base64 ", 13) == 0) { 155 151 line_ptr = line + 13; 156 152 decode_fn_ptr = read_base64; … … 158 154 line_ptr = line + 6; 159 155 decode_fn_ptr = read_stduu; 160 } 161 162 if (line_ptr) { 163 FILE *dst_stream; 164 int mode; 165 int ret; 166 167 mode = strtoul(line_ptr, NULL, 8); 168 if (outname == NULL) { 169 outname = strchr(line_ptr, ' '); 170 if ((outname == NULL) || (*outname == '\0')) { 171 break; 172 } 173 outname++; 174 } 175 if (strcmp(outname, "-") == 0) { 176 dst_stream = stdout; 177 } else { 178 dst_stream = bb_xfopen(outname, "w"); 179 chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 180 } 156 } else { 181 157 free(line); 182 ret = decode_fn_ptr(src_stream, dst_stream); 183 bb_fclose_nonstdin(src_stream); 184 return(ret); 158 continue; 159 } 160 161 /* begin line found. decode and exit */ 162 mode = strtoul(line_ptr, NULL, 8); 163 if (outname == NULL) { 164 outname = strchr(line_ptr, ' '); 165 if ((outname == NULL) || (*outname == '\0')) { 166 break; 167 } 168 outname++; 169 } 170 dst_stream = stdout; 171 if (NOT_LONE_DASH(outname)) { 172 dst_stream = xfopen(outname, "w"); 173 chmod(outname, mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 185 174 } 186 175 free(line); 176 decode_fn_ptr(src_stream, dst_stream); 177 /* fclose_if_not_stdin(src_stream); - redundant */ 178 return EXIT_SUCCESS; 187 179 } 188 bb_error_msg_and_die(" No `begin' line");180 bb_error_msg_and_die("no 'begin' line"); 189 181 } 182 183 /* Test script. 184 Put this into an empty dir with busybox binary, an run. 185 186 #!/bin/sh 187 test -x busybox || { echo "No ./busybox?"; exit; } 188 ln -sf busybox uudecode 189 ln -sf busybox uuencode 190 >A_null 191 echo -n A >A 192 echo -n AB >AB 193 echo -n ABC >ABC 194 echo -n ABCD >ABCD 195 echo -n ABCDE >ABCDE 196 echo -n ABCDEF >ABCDEF 197 cat busybox >A_bbox 198 for f in A*; do 199 echo uuencode $f 200 ./uuencode $f <$f >u_$f 201 ./uuencode -m $f <$f >m_$f 202 done 203 mkdir unpk_u unpk_m 2>/dev/null 204 for f in u_*; do 205 ./uudecode <$f -o unpk_u/${f:2} 206 diff -a ${f:2} unpk_u/${f:2} >/dev/null 2>&1 207 echo uudecode $f: $? 208 done 209 for f in m_*; do 210 ./uudecode <$f -o unpk_m/${f:2} 211 diff -a ${f:2} unpk_m/${f:2} >/dev/null 2>&1 212 echo uudecode $f: $? 213 done 214 */ -
branches/2.2.5/mindi-busybox/coreutils/uuencode.c
r821 r1765 6 6 * Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. 7 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 9 */ 22 #include <stdio.h>23 #include <string.h>24 #include <stdlib.h>25 #include <sys/types.h>26 #include <sys/stat.h>27 #include <unistd.h>28 #include "busybox.h"29 10 30 /* Conversion table. for base 64 */ 31 static const char tbl_base64[65] = { 32 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 33 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 34 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 35 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 36 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 37 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 38 'w', 'x', 'y', 'z', '0', '1', '2', '3', 39 '4', '5', '6', '7', '8', '9', '+', '/', 40 '=' /* termination character */ 11 #include "libbb.h" 12 13 enum { 14 SRC_BUF_SIZE = 45, /* This *MUST* be a multiple of 3 */ 15 DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), 41 16 }; 42 17 43 static const char tbl_std[65] = { 44 '`', '!', '"', '#', '$', '%', '&', '\'', 45 '(', ')', '*', '+', ',', '-', '.', '/', 46 '0', '1', '2', '3', '4', '5', '6', '7', 47 '8', '9', ':', ';', '<', '=', '>', '?', 48 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 49 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 51 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', 52 '`' /* termination character */ 53 }; 54 55 /* 56 * Encode the string S of length LENGTH to base64 format and place it 57 * to STORE. STORE will be 0-terminated, and must point to a writable 58 * buffer of at least 1+BASE64_LENGTH(length) bytes. 59 * where BASE64_LENGTH(len) = (4 * ((LENGTH + 2) / 3)) 60 */ 61 static void uuencode (const unsigned char *s, char *store, const int length, const char *tbl) 62 { 63 int i; 64 char *p = store; 65 66 /* Transform the 3x8 bits to 4x6 bits, as required by base64. */ 67 for (i = 0; i < length; i += 3) { 68 *p++ = tbl[s[0] >> 2]; 69 *p++ = tbl[((s[0] & 3) << 4) + (s[1] >> 4)]; 70 *p++ = tbl[((s[1] & 0xf) << 2) + (s[2] >> 6)]; 71 *p++ = tbl[s[2] & 0x3f]; 72 s += 3; 73 } 74 /* Pad the result if necessary... */ 75 if (i == length + 1) { 76 *(p - 1) = tbl[64]; 77 } 78 else if (i == length + 2) { 79 *(p - 1) = *(p - 2) = tbl[64]; 80 } 81 /* ...and zero-terminate it. */ 82 *p = '\0'; 83 } 84 85 #define SRC_BUF_SIZE 45 // This *MUST* be a multiple of 3 86 #define DST_BUF_SIZE 4 * ((SRC_BUF_SIZE + 2) / 3) 18 int uuencode_main(int argc, char **argv); 87 19 int uuencode_main(int argc, char **argv) 88 20 { 89 const size_t src_buf_size = SRC_BUF_SIZE;90 const size_t dst_buf_size = DST_BUF_SIZE;91 size_t write_size = dst_buf_size;92 21 struct stat stat_buf; 93 FILE *src_stream = stdin;22 int src_fd = STDIN_FILENO; 94 23 const char *tbl; 95 size_t size;96 24 mode_t mode; 97 RESERVE_CONFIG_BUFFER(src_buf, SRC_BUF_SIZE + 1);98 RESERVE_CONFIG_BUFFER(dst_buf, DST_BUF_SIZE + 1);25 char src_buf[SRC_BUF_SIZE]; 26 char dst_buf[DST_BUF_SIZE + 1]; 99 27 100 tbl = tbl_std; 101 if (bb_getopt_ulflags(argc, argv, "m") & 1) { 102 tbl = tbl_base64; 28 tbl = bb_uuenc_tbl_std; 29 mode = 0666 & ~umask(0666); 30 opt_complementary = "-1:?2"; /* must have 1 or 2 args */ 31 if (getopt32(argv, "m")) { 32 tbl = bb_uuenc_tbl_base64; 33 } 34 argv += optind; 35 if (argc == optind + 2) { 36 src_fd = xopen(*argv, O_RDONLY); 37 fstat(src_fd, &stat_buf); 38 mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); 39 argv++; 103 40 } 104 41 105 switch (argc - optind) { 106 case 2: 107 src_stream = bb_xfopen(argv[optind], "r"); 108 xstat(argv[optind], &stat_buf); 109 mode = stat_buf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); 110 if (src_stream == stdout) { 111 puts("NULL"); 112 } 42 printf("begin%s %o %s", tbl == bb_uuenc_tbl_std ? "" : "-base64", mode, *argv); 43 while (1) { 44 size_t size = full_read(src_fd, src_buf, SRC_BUF_SIZE); 45 if (!size) 113 46 break; 114 case 1: 115 mode = 0666 & ~umask(0666); 116 break; 117 default: 118 bb_show_usage(); 119 } 120 121 bb_printf("begin%s %o %s", tbl == tbl_std ? "" : "-base64", mode, argv[argc - 1]); 122 123 while ((size = fread(src_buf, 1, src_buf_size, src_stream)) > 0) { 124 if (size != src_buf_size) { 125 /* write_size is always 60 until the last line */ 126 write_size=(4 * ((size + 2) / 3)); 127 /* pad with 0s so we can just encode extra bits */ 128 memset(&src_buf[size], 0, src_buf_size - size); 129 } 47 if ((ssize_t)size < 0) 48 bb_perror_msg_and_die(bb_msg_read_error); 130 49 /* Encode the buffer we just read in */ 131 uuencode((unsigned char*)src_buf, dst_buf, size, tbl); 132 50 bb_uuencode(dst_buf, src_buf, size, tbl); 133 51 putchar('\n'); 134 if (tbl == tbl_std) {52 if (tbl == bb_uuenc_tbl_std) { 135 53 putchar(tbl[size]); 136 54 } 137 if (fwrite(dst_buf, 1, write_size, stdout) != write_size) { 138 bb_perror_msg_and_die(bb_msg_write_error); 139 } 55 fflush(stdout); 56 xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3)); 140 57 } 141 bb_printf(tbl ==tbl_std ? "\n`\nend\n" : "\n====\n");58 printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n"); 142 59 143 bb_xferror(src_stream, "source"); /* TODO - Fix this! */ 144 145 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 60 fflush_stdout_and_exit(EXIT_SUCCESS); 146 61 } -
branches/2.2.5/mindi-busybox/coreutils/wc.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 50 37 * 51 38 * echo hello > /tmp/testfile && 52 * (dd ibs=1k skip=1 count=0 &> /dev/null 39 * (dd ibs=1k skip=1 count=0 &> /dev/null; wc -c) < /tmp/testfile 53 40 * 54 41 * for which 'wc -c' should output '0'. 55 42 */ 56 43 57 #include <stdio.h> 58 #include <stdlib.h> 59 #include <string.h> 60 #include <unistd.h> 61 #include "busybox.h" 62 63 #ifdef CONFIG_LOCALE_SUPPORT 64 #include <locale.h> 65 #include <ctype.h> 44 #include "libbb.h" 45 46 #if ENABLE_LOCALE_SUPPORT 66 47 #define isspace_given_isprint(c) isspace(c) 67 48 #else … … 73 54 #endif 74 55 56 #if ENABLE_FEATURE_WC_LARGE 57 #define COUNT_T unsigned long long 58 #define COUNT_FMT "llu" 59 #else 60 #define COUNT_T unsigned 61 #define COUNT_FMT "u" 62 #endif 63 75 64 enum { 76 65 WC_LINES = 0, … … 80 69 }; 81 70 82 /* Note: If this changes, remember to change the initialization of 83 * 'name' in wc_main. It needs to point to the terminating nul. */ 84 static const char wc_opts[] = "lwcL"; /* READ THE WARNING ABOVE! */ 85 86 enum { 87 OP_INC_LINE = 1, /* OP_INC_LINE must be 1. */ 88 OP_SPACE = 2, 89 OP_NEWLINE = 4, 90 OP_TAB = 8, 91 OP_NUL = 16, 92 }; 93 94 /* Note: If fmt_str changes, the offsets to 's' in the OUTPUT section 95 * will need to be updated. */ 96 static const char fmt_str[] = " %7u\0 %s\n"; 97 static const char total_str[] = "total"; 98 71 int wc_main(int argc, char **argv); 99 72 int wc_main(int argc, char **argv) 100 73 { 101 74 FILE *fp; 102 const char *s; 103 unsigned int *pcounts; 104 unsigned int counts[4]; 105 unsigned int totals[4]; 106 unsigned int linepos; 107 unsigned int u; 75 const char *s, *arg; 76 const char *start_fmt = "%9"COUNT_FMT; 77 const char *fname_fmt = " %s\n"; 78 COUNT_T *pcounts; 79 COUNT_T counts[4]; 80 COUNT_T totals[4]; 81 unsigned linepos; 82 unsigned u; 108 83 int num_files = 0; 109 84 int c; 110 charstatus = EXIT_SUCCESS;111 charin_word;112 charprint_type;113 114 print_type = bb_getopt_ulflags(argc, argv, wc_opts);85 smallint status = EXIT_SUCCESS; 86 smallint in_word; 87 unsigned print_type; 88 89 print_type = getopt32(argv, "lwcL"); 115 90 116 91 if (print_type == 0) { … … 119 94 120 95 argv += optind; 121 if (! *argv) {96 if (!argv[0]) { 122 97 *--argv = (char *) bb_msg_standard_input; 98 fname_fmt = "\n"; 99 if (!((print_type-1) & print_type)) /* exactly one option? */ 100 start_fmt = "%"COUNT_FMT; 123 101 } 124 102 … … 127 105 pcounts = counts; 128 106 129 do{107 while ((arg = *argv++) != 0) { 130 108 ++num_files; 131 if (!(fp = bb_wfopen_input(*argv))) { 109 fp = fopen_or_warn_stdin(arg); 110 if (!fp) { 132 111 status = EXIT_FAILURE; 133 112 continue; … … 139 118 140 119 do { 120 /* Our -w doesn't match GNU wc exactly... oh well */ 121 141 122 ++counts[WC_CHARS]; 142 123 c = getc(fp); … … 170 151 } else if (c == EOF) { 171 152 if (ferror(fp)) { 172 bb_perror_msg("%s", *argv);153 bb_perror_msg("%s", arg); 173 154 status = EXIT_FAILURE; 174 155 } … … 191 172 totals[WC_LENGTH] -= counts[WC_LENGTH]; 192 173 193 bb_fclose_nonstdin(fp);174 fclose_if_not_stdin(fp); 194 175 195 176 OUTPUT: 196 s = fmt_str + 1; /* Skip the leading space on 1st pass. */ 177 /* coreutils wc tries hard to print pretty columns 178 * (saves results for all files, find max col len etc...) 179 * we won't try that hard, it will bloat us too much */ 180 s = start_fmt; 197 181 u = 0; 198 182 do { 199 183 if (print_type & (1 << u)) { 200 bb_printf(s, pcounts[u]);201 s = fmt_str;/* Ok... restore the leading space. */184 printf(s, pcounts[u]); 185 s = " %9"COUNT_FMT; /* Ok... restore the leading space. */ 202 186 } 203 187 totals[u] += pcounts[u]; 204 188 } while (++u < 4); 205 206 s += 8; /* Set the format to the empty string. */ 207 208 if (*argv != bb_msg_standard_input) { 209 s -= 3; /* We have a name, so do %s conversion. */ 210 } 211 bb_printf(s, *argv); 212 213 } while (*++argv); 189 printf(fname_fmt, arg); 190 } 214 191 215 192 /* If more than one file was processed, we want the totals. To save some … … 219 196 if (num_files > 1) { 220 197 num_files = 0; /* Make sure we don't get here again. */ 221 *--argv = (char *) total_str;198 arg = "total"; 222 199 pcounts = totals; 200 --argv; 223 201 goto OUTPUT; 224 202 } 225 203 226 bb_fflush_stdout_and_exit(status);204 fflush_stdout_and_exit(status); 227 205 } -
branches/2.2.5/mindi-busybox/coreutils/who.c
r821 r1765 12 12 * 13 13 * Copyright (c) 2002 AYR Networks, Inc. 14 * 15 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 16 * 14 17 *---------------------------------------------------------------------- 15 18 */ 16 19 17 #include " busybox.h"20 #include "libbb.h" 18 21 #include <utmp.h> 19 22 #include <time.h> 20 23 21 static const char * idle_string (time_t t)24 static void idle_string(char *str6, time_t t) 22 25 { 23 static char str[6]; 24 25 time_t s = time(NULL) - t; 26 t = time(NULL) - t; 26 27 27 if (s < 60) 28 return "."; 29 if (s < (24 * 60 * 60)) { 30 sprintf (str, "%02d:%02d", 31 (int) (s / (60 * 60)), 32 (int) ((s % (60 * 60)) / 60)); 33 return str; 28 /*if (t < 60) { 29 str6[0] = '.'; 30 str6[1] = '\0'; 31 return; 32 }*/ 33 if (t >= 0 && t < (24 * 60 * 60)) { 34 sprintf(str6, "%02d:%02d", 35 (int) (t / (60 * 60)), 36 (int) ((t % (60 * 60)) / 60)); 37 return; 34 38 } 35 return "old";39 strcpy(str6, "old"); 36 40 } 37 41 42 int who_main(int argc, char **argv); 38 43 int who_main(int argc, char **argv) 39 44 { 45 char str6[6]; 40 46 struct utmp *ut; 41 47 struct stat st; 42 48 char *name; 43 49 44 50 if (argc > 1) { 45 51 bb_show_usage(); 46 52 } 47 53 48 54 setutent(); 49 55 printf("USER TTY IDLE TIME HOST\n"); … … 54 60 /* ut->ut_line is device name of tty - "/dev/" */ 55 61 name = concat_path_file("/dev", ut->ut_line); 56 printf("%-10s %-8s %-8s %-12.12s %s\n", ut->ut_user, ut->ut_line, 57 (stat(name, &st)) ? "?" : idle_string(st.st_atime), 58 ctime(&thyme) + 4, ut->ut_host); 59 if (ENABLE_FEATURE_CLEAN_UP) free(name); 62 str6[0] = '?'; 63 str6[1] = '\0'; 64 if (stat(name, &st) == 0) 65 idle_string(str6, st.st_atime); 66 printf("%-10s %-8s %-9s %-14.14s %s\n", 67 ut->ut_user, ut->ut_line, str6, 68 ctime(&thyme) + 4, ut->ut_host); 69 if (ENABLE_FEATURE_CLEAN_UP) 70 free(name); 60 71 } 61 72 } 62 if (ENABLE_FEATURE_CLEAN_UP) endutent(); 73 if (ENABLE_FEATURE_CLEAN_UP) 74 endutent(); 63 75 return 0; 64 76 } -
branches/2.2.5/mindi-busybox/coreutils/whoami.c
r821 r1765 5 5 * Copyright (C) 2000 Edward Betts <edward@debian.org>. 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 23 10 /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ 24 11 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <unistd.h> 28 #include "busybox.h" 12 #include "libbb.h" 29 13 14 /* This is a NOFORK applet. Be very careful! */ 15 16 int whoami_main(int argc, char **argv); 30 17 int whoami_main(int argc, char **argv) 31 18 { … … 33 20 bb_show_usage(); 34 21 35 puts(bb_getpwuid(NULL, geteuid(), -1)); 36 /* exits on error */ 37 bb_fflush_stdout_and_exit(EXIT_SUCCESS); 22 /* Will complain and die if username not found */ 23 puts(bb_getpwuid(NULL, -1, geteuid())); 24 25 return fflush(stdout); 38 26 } -
branches/2.2.5/mindi-busybox/coreutils/yes.c
r821 r1765 5 5 * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> 6 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 21 8 */ 22 9 … … 28 15 */ 29 16 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include "busybox.h" 17 #include "libbb.h" 33 18 19 /* This is a NOFORK applet. Be very careful! */ 20 21 int yes_main(int argc, char **argv); 34 22 int yes_main(int argc, char **argv) 35 23 { 36 static const char fmt_str[] = " %s";37 const char *fmt;38 24 char **first_arg; 39 25 40 *argv ="y";26 argv[0] = (char*)"y"; 41 27 if (argc != 1) { 42 28 ++argv; … … 45 31 first_arg = argv; 46 32 do { 47 fmt = fmt_str + 1; 48 do { 49 bb_printf(fmt, *argv); 50 fmt = fmt_str; 51 } while (*++argv); 33 while (1) { 34 fputs(*argv, stdout); 35 if (!*++argv) 36 break; 37 putchar(' '); 38 } 52 39 argv = first_arg; 53 40 } while (putchar('\n') != EOF);
Note:
See TracChangeset
for help on using the changeset viewer.