Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/coreutils


Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

Location:
branches/stable/mindi-busybox/coreutils
Files:
7 deleted
72 edited
6 copied

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/coreutils/Config.in

    r821 r1770  
    66menu "Coreutils"
    77
    8 config CONFIG_BASENAME
     8config BASENAME
    99    bool "basename"
    1010    default n
     
    1414      to enable the 'basename' utility.
    1515
    16 config CONFIG_CAL
     16config CAL
    1717    bool "cal"
    1818    default n
     
    2020      cal is used to display a monthly calender.
    2121
    22 config CONFIG_CAT
     22config CAT
    2323    bool "cat"
    2424    default n
     
    2727      output.  Enable this option if you wish to enable the 'cat' utility.
    2828
    29 config CONFIG_CATV
     29config CATV
    3030    bool "catv"
    3131    default n
     
    3434      implementations' cat -v option).
    3535
    36 config CONFIG_CHGRP
     36config CHGRP
    3737    bool "chgrp"
    3838    default n
     
    4040      chgrp is used to change the group ownership of files.
    4141
    42 config CONFIG_CHMOD
     42config CHMOD
    4343    bool "chmod"
    4444    default n
     
    4646      chmod is used to change the access permission of files.
    4747
    48 config CONFIG_CHOWN
     48config CHOWN
    4949    bool "chown"
    5050    default n
     
    5353      of files.
    5454
    55 config CONFIG_CHROOT
     55config CHROOT
    5656    bool "chroot"
    5757    default n
     
    6060      The default command is `/bin/sh'.
    6161
    62 config CONFIG_CKSUM
     62config CKSUM
    6363    bool "cksum"
    6464    default n
     
    6666      cksum is used to calculate the CRC32 checksum of a file.
    6767
    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
     68config COMM
    7669    bool "comm"
    7770    default n
     
    8073      a three-column output.
    8174
    82 config CONFIG_CP
     75config CP
    8376    bool "cp"
    8477    default n
     
    8679      cp is used to copy files and directories.
    8780
    88 config CONFIG_CUT
     81config CUT
    8982    bool "cut"
    9083    default n
     
    9386      each file to stdout.
    9487
    95 config CONFIG_DATE
     88config DATE
    9689    bool "date"
    9790    default n
     
    10093      current time in the given format.
    10194
    102 config CONFIG_FEATURE_DATE_ISOFMT
     95config FEATURE_DATE_ISOFMT
    10396    bool "Enable ISO date format output (-I)"
    10497    default y
    105     depends on CONFIG_DATE
     98    depends on DATE
    10699    help
    107100      Enable option (-I) to output an ISO-8601 compliant
    108101      date/time string.
    109102
    110 config CONFIG_DD
     103config DD
    111104    bool "dd"
    112105    default n
     
    116109      while optionally performing conversions on it.
    117110
    118 config CONFIG_FEATURE_DD_SIGNAL_HANDLING
     111config FEATURE_DD_SIGNAL_HANDLING
    119112    bool "Enable DD signal handling for status reporting"
    120113    default y
    121     depends on CONFIG_DD
    122     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
    125118      so far, then to resume copying.
    126119
    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
    128121      10899206+0 records in 10899206+0 records out
    129122
    130 config CONFIG_FEATURE_DD_IBS_OBS
     123config FEATURE_DD_IBS_OBS
    131124    bool "Enable ibs, obs and conv options"
    132125    default n
    133     depends on CONFIG_DD
     126    depends on DD
    134127    help
    135128      Enables support for writing a certain number of bytes in and out,
    136129      at a time, and performing conversions on the data stream.
    137130
    138 config CONFIG_DF
     131config DF
    139132    bool "df"
    140133    default n
     
    143136      on filesystems.
    144137
    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
     138config DIRNAME
    178139    bool "dirname"
    179140    default n
     
    182143      a file name.
    183144
    184 config CONFIG_DOS2UNIX
     145config DOS2UNIX
    185146    bool "dos2unix/unix2dos"
    186147    default n
     
    189150      UNIX format, and vice versa.
    190151
    191 config CONFIG_UNIX2DOS
     152config UNIX2DOS
    192153    bool
    193154    default y
    194     depends on CONFIG_DOS2UNIX
     155    depends on DOS2UNIX
    195156    help
    196157      unix2dos is used to convert a text file from UNIX format to
    197158      DOS format, and vice versa.
    198159
    199 config CONFIG_DU
     160config DU
    200161    bool "du (default blocksize of 512 bytes)"
    201162    default n
     
    204165      for specified files.
    205166
    206 config CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
     167config FEATURE_DU_DEFAULT_BLOCKSIZE_1K
    207168    bool "Use a default blocksize of 1024 bytes (1K)"
    208169    default y
    209     depends on CONFIG_DU
     170    depends on DU
    210171    help
    211172      Use a blocksize of (1K) instead of the default 512b.
    212173
    213 config CONFIG_ECHO
     174config ECHO
    214175    bool "echo (basic SuSv3 version taking no options)"
    215176    default n
     
    218179
    219180# this entry also appears in shell/Config.in, next to the echo builtin
    220 config CONFIG_FEATURE_FANCY_ECHO
     181config FEATURE_FANCY_ECHO
    221182    bool "Enable echo options (-n and -e)"
    222183    default y
    223     depends on CONFIG_ECHO
     184    depends on ECHO
    224185    help
    225186      This adds options (-n and -e) to echo.
    226187
    227 config CONFIG_ENV
     188config ENV
    228189    bool "env"
    229190    default n
     
    233194      environment.
    234195
    235 config CONFIG_FEATURE_ENV_LONG_OPTIONS
     196config FEATURE_ENV_LONG_OPTIONS
    236197    bool "Enable long options"
    237198    default n
    238     depends on CONFIG_ENV && CONFIG_GETOPT_LONG
     199    depends on ENV && GETOPT_LONG
    239200    help
    240201      Support long options for the env applet.
    241202
    242 config CONFIG_EXPR
     203config EXPAND
     204    bool "expand"
     205    default n
     206    help
     207      By default, convert all tabs to spaces.
     208
     209config 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
     216config EXPR
    243217    bool "expr"
    244218    default n
     
    247221      to standard output.
    248222
    249 config CONFIG_EXPR_MATH_SUPPORT_64
     223config EXPR_MATH_SUPPORT_64
    250224    bool "Extend Posix numbers support to 64 bit"
    251225    default n
    252     depends on CONFIG_EXPR
     226    depends on EXPR
    253227    help
    254228      Enable 64-bit math support in the expr applet.  This will make
     
    256230      large numbers.
    257231
    258 config CONFIG_FALSE
     232config FALSE
    259233    bool "false"
    260234    default n
     
    262236      false returns an exit code of FALSE (1).
    263237
    264 config CONFIG_FOLD
     238config FOLD
    265239    bool "fold"
    266240    default n
     
    268242      Wrap text to fit a specific width.
    269243
    270 config CONFIG_HEAD
     244config HEAD
    271245    bool "head"
    272246    default n
     
    275249      from files.
    276250
    277 config CONFIG_FEATURE_FANCY_HEAD
     251config FEATURE_FANCY_HEAD
    278252    bool "Enable head options (-c, -q, and -v)"
    279253    default n
    280     depends on CONFIG_HEAD
     254    depends on HEAD
    281255    help
    282256      This enables the head options (-c, -q, and -v).
    283257
    284 config CONFIG_HOSTID
     258config HOSTID
    285259    bool "hostid"
    286260    default n
     
    289263      the current host.
    290264
    291 config CONFIG_ID
     265config ID
    292266    bool "id"
    293267    default n
     
    295269      id displays the current user and group ID names.
    296270
    297 config CONFIG_INSTALL
     271config INSTALL
    298272    bool "install"
    299273    default n
     
    301275      Copy files and set attributes.
    302276
    303 config CONFIG_FEATURE_INSTALL_LONG_OPTIONS
     277config FEATURE_INSTALL_LONG_OPTIONS
    304278    bool "Enable long options"
    305279    default n
    306     depends on CONFIG_INSTALL && CONFIG_GETOPT_LONG
     280    depends on INSTALL && GETOPT_LONG
    307281    help
    308282      Support long options for the install applet.
    309283
    310 config CONFIG_LENGTH
     284config LENGTH
    311285    bool "length"
    312286    default n
     
    314288      length is used to print out the length of a specified string.
    315289
    316 config CONFIG_LN
     290config LN
    317291    bool "ln"
    318292    default n
     
    320294      ln is used to create hard or soft links between files.
    321295
    322 config CONFIG_LOGNAME
     296config LOGNAME
    323297    bool "logname"
    324298    default n
     
    326300      logname is used to print the current user's login name.
    327301
    328 config CONFIG_LS
     302config LS
    329303    bool "ls"
    330304    default n
     
    332306      ls is used to list the contents of directories.
    333307
    334 config CONFIG_FEATURE_LS_FILETYPES
     308config FEATURE_LS_FILETYPES
    335309    bool "Enable filetyping options (-p and -F)"
    336310    default y
    337     depends on CONFIG_LS
     311    depends on LS
    338312    help
    339313      Enable the ls options (-p and -F).
    340314
    341 config CONFIG_FEATURE_LS_FOLLOWLINKS
     315config FEATURE_LS_FOLLOWLINKS
    342316    bool "Enable symlinks dereferencing (-L)"
    343317    default y
    344     depends on CONFIG_LS
     318    depends on LS
    345319    help
    346320      Enable the ls option (-L).
    347321
    348 config CONFIG_FEATURE_LS_RECURSIVE
     322config FEATURE_LS_RECURSIVE
    349323    bool "Enable recursion (-R)"
    350324    default y
    351     depends on CONFIG_LS
     325    depends on LS
    352326    help
    353327      Enable the ls option (-R).
    354328
    355 config CONFIG_FEATURE_LS_SORTFILES
     329config FEATURE_LS_SORTFILES
    356330    bool "Sort the file names"
    357331    default y
    358     depends on CONFIG_LS
     332    depends on LS
    359333    help
    360334      Allow ls to sort file names alphabetically.
    361335
    362 config CONFIG_FEATURE_LS_TIMESTAMPS
     336config FEATURE_LS_TIMESTAMPS
    363337    bool "Show file timestamps"
    364338    default y
    365     depends on CONFIG_LS
     339    depends on LS
    366340    help
    367341      Allow ls to display timestamps for files.
    368342
    369 config CONFIG_FEATURE_LS_USERNAME
     343config FEATURE_LS_USERNAME
    370344    bool "Show username/groupnames"
    371345    default y
    372     depends on CONFIG_LS
     346    depends on LS
    373347    help
    374348      Allow ls to display username/groupname for files.
    375349
    376 config CONFIG_FEATURE_LS_COLOR
     350config FEATURE_LS_COLOR
    377351    bool "Allow use of color to identify file types"
    378352    default y
    379     depends on CONFIG_LS && CONFIG_GETOPT_LONG
     353    depends on LS && GETOPT_LONG
    380354    help
    381355      This enables the --color option to ls.
    382356
    383 config CONFIG_FEATURE_LS_COLOR_IS_DEFAULT
     357config FEATURE_LS_COLOR_IS_DEFAULT
    384358    bool "Produce colored ls output by default"
    385359    default n
    386     depends on CONFIG_FEATURE_LS_COLOR
     360    depends on FEATURE_LS_COLOR
    387361    help
    388362      Saying yes here will turn coloring on by default,
     
    392366      many output screens.
    393367
    394 config CONFIG_MD5SUM
     368config MD5SUM
    395369    bool "md5sum"
    396370    default n
     
    398372      md5sum is used to print or check MD5 checksums.
    399373
    400 config CONFIG_MKDIR
     374config MKDIR
    401375    bool "mkdir"
    402376    default n
     
    404378      mkdir is used to create directories with the specified names.
    405379
    406 config CONFIG_FEATURE_MKDIR_LONG_OPTIONS
     380config FEATURE_MKDIR_LONG_OPTIONS
    407381    bool "Enable long options"
    408382    default n
    409     depends on CONFIG_MKDIR && CONFIG_GETOPT_LONG
     383    depends on MKDIR && GETOPT_LONG
    410384    help
    411385      Support long options for the mkdir applet.
    412386
    413 config CONFIG_MKFIFO
     387config MKFIFO
    414388    bool "mkfifo"
    415389    default n
     
    418392      The `mknod' program can also create FIFOs.
    419393
    420 config CONFIG_MKNOD
     394config MKNOD
    421395    bool "mknod"
    422396    default n
     
    425399      files with the specified names.
    426400
    427 config CONFIG_MV
     401config MV
    428402    bool "mv"
    429403    default n
     
    431405      mv is used to move or rename files or directories.
    432406
    433 config CONFIG_FEATURE_MV_LONG_OPTIONS
     407config FEATURE_MV_LONG_OPTIONS
    434408    bool "Enable long options"
    435409    default n
    436     depends on CONFIG_MV && CONFIG_GETOPT_LONG
     410    depends on MV && GETOPT_LONG
    437411    help
    438412      Support long options for the mv applet.
    439413
    440 config CONFIG_NICE
     414config NICE
    441415    bool "nice"
    442416    default n
     
    444418      nice runs a program with modified scheduling priority.
    445419
    446 config CONFIG_NOHUP
     420config NOHUP
    447421    bool "nohup"
    448422    default n
     
    450424      run a command immune to hangups, with output to a non-tty.
    451425
    452 config CONFIG_OD
     426config OD
    453427    bool "od"
    454428    default n
     
    456430      od is used to dump binary files in octal and other formats.
    457431
    458 config CONFIG_PRINTENV
     432config PRINTENV
    459433    bool "printenv"
    460434    default n
     
    462436      printenv is used to print all or part of environment.
    463437
    464 config CONFIG_PRINTF
     438config PRINTF
    465439    bool "printf"
    466440    default n
     
    469443      It's similar to `echo' except it has more options.
    470444
    471 config CONFIG_PWD
     445config PWD
    472446    bool "pwd"
    473447    default n
     
    475449      pwd is used to print the current directory.
    476450
    477 config CONFIG_REALPATH
     451config 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
     458config 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
     465config REALPATH
    478466    bool "realpath"
    479467    default n
     
    482470      This isn't provided by GNU shellutils, but where else does it belong.
    483471
    484 config CONFIG_RM
     472config RM
    485473    bool "rm"
    486474    default n
     
    488476      rm is used to remove files or directories.
    489477
    490 config CONFIG_RMDIR
     478config RMDIR
    491479    bool "rmdir"
    492480    default n
     
    494482      rmdir is used to remove empty directories.
    495483
    496 config CONFIG_SEQ
     484config SEQ
    497485    bool "seq"
    498486    default n
     
    500488      print a sequence of numbers
    501489
    502 config CONFIG_SHA1SUM
     490config SHA1SUM
    503491    bool "sha1sum"
    504492    default n
     
    506494      Compute and check SHA1 message digest
    507495
    508 config CONFIG_SLEEP
     496config SLEEP
    509497    bool "sleep (single integer arg with no suffix)"
    510498    default n
     
    512500      sleep is used to pause for a specified number of seconds,
    513501
    514 config CONFIG_FEATURE_FANCY_SLEEP
     502config FEATURE_FANCY_SLEEP
    515503    bool "Enable multiple integer args and optional time suffixes"
    516504    default n
    517     depends on CONFIG_SLEEP
     505    depends on SLEEP
    518506    help
    519507      Allow sleep to pause for specified minutes, hours, and days.
    520508
    521 config CONFIG_SORT
     509config SORT
    522510    bool "sort"
    523511    default n
     
    525513      sort is used to sort lines of text in specified files.
    526514
    527 config CONFIG_FEATURE_SORT_BIG
     515config FEATURE_SORT_BIG
    528516    bool "full SuSv3 compliant sort (Support -ktcsbdfiozgM)"
    529517    default y
    530     depends on CONFIG_SORT
     518    depends on SORT
    531519    help
    532520      Without this, sort only supports  -r, -u, and an integer version
     
    537525      http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
    538526
    539 config CONFIG_STAT
     527config SPLIT
     528    bool "split"
     529    default n
     530    help
     531      split a file into pieces.
     532
     533config 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
     542config STAT
    540543    bool "stat"
    541544    default n
     
    543546      display file or filesystem status.
    544547
    545 config CONFIG_FEATURE_STAT_FORMAT
     548config FEATURE_STAT_FORMAT
    546549    bool "Enable custom formats (-c)"
    547550    default n
    548     depends on CONFIG_STAT
     551    depends on STAT
    549552    help
    550553      Without this, stat will not support the '-c format' option where
     
    552555      7k to a nonstatic build on amd64.
    553556
    554 config CONFIG_STTY
     557config STTY
    555558    bool "stty"
    556559    default n
     
    558561      stty is used to change and print terminal line settings.
    559562
    560 config CONFIG_SUM
     563config SUM
    561564    bool "sum"
    562565    default n
     
    564567      checksum and count the blocks in a file
    565568
    566 config CONFIG_SYNC
     569config SYNC
    567570    bool "sync"
    568571    default n
     
    570573      sync is used to flush filesystem buffers.
    571574
    572 config CONFIG_TAIL
     575config TAIL
    573576    bool "tail"
    574577    default n
     
    577580      from files.
    578581
    579 config CONFIG_FEATURE_FANCY_TAIL
     582config FEATURE_FANCY_TAIL
    580583    bool "Enable extra tail options (-q, -s, and -v)"
    581584    default y
    582     depends on CONFIG_TAIL
     585    depends on TAIL
    583586    help
    584587      The options (-q, -s, and -v) are provided by GNU tail, but
    585588      are not specific in the SUSv3 standard.
    586589
    587 config CONFIG_TEE
     590config TEE
    588591    bool "tee"
    589592    default n
     
    592595      to standard output and files.
    593596
    594 config CONFIG_FEATURE_TEE_USE_BLOCK_IO
     597config FEATURE_TEE_USE_BLOCK_IO
    595598    bool "Enable block i/o (larger/faster) instead of byte i/o."
    596599    default n
    597     depends on CONFIG_TEE
     600    depends on TEE
    598601    help
    599602      Enable this option for a faster tee, at expense of size.
    600603
    601 config CONFIG_TEST
     604config TEST
    602605    bool "test"
    603606    default n
     
    607610      has test built in, ash can build it in optionally.
    608611
    609 config CONFIG_FEATURE_TEST_64
     612config FEATURE_TEST_64
    610613    bool "Extend test to 64 bit"
    611614    default n
    612     depends on CONFIG_TEST
     615    depends on TEST
    613616    help
    614617      Enable 64-bit support in test.
    615618
    616 config CONFIG_TOUCH
     619config TOUCH
    617620    bool "touch"
    618621    default n
     
    621624      modification timestamp of specified files.
    622625
    623 config CONFIG_TR
     626config TR
    624627    bool "tr"
    625628    default n
     
    628631      input, writing to standard output.
    629632
    630 config CONFIG_FEATURE_TR_CLASSES
     633config FEATURE_TR_CLASSES
    631634    bool "Enable character classes (such as [:upper:])"
    632635    default n
    633     depends on CONFIG_TR
     636    depends on TR
    634637    help
    635638      Enable character classes, enabling commands such as:
    636639      tr [:upper:] [:lower:] to convert input into lowercase.
    637640
    638 config CONFIG_FEATURE_TR_EQUIV
     641config FEATURE_TR_EQUIV
    639642    bool "Enable equivalence classes"
    640643    default n
    641     depends on CONFIG_TR
     644    depends on TR
    642645    help
    643646      Enable equivalence classes, which essentially add the enclosed
     
    647650      is possible.
    648651
    649 config CONFIG_TRUE
     652config TRUE
    650653    bool "true"
    651654    default n
     
    653656      true returns an exit code of TRUE (0).
    654657
    655 config CONFIG_TTY
     658config TTY
    656659    bool "tty"
    657660    default n
     
    660663      standard output.
    661664
    662 config CONFIG_UNAME
     665config UNAME
    663666    bool "uname"
    664667    default n
     
    666669      uname is used to print system information.
    667670
    668 config CONFIG_UNIQ
     671config UNEXPAND
     672    bool "unexpand"
     673    default n
     674    help
     675      By default, convert only leading sequences of blanks to tabs.
     676
     677config 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
     684config UNIQ
    669685    bool "uniq"
    670686    default n
     
    672688      uniq is used to remove duplicate lines from a sorted file.
    673689
    674 config CONFIG_USLEEP
     690config USLEEP
    675691    bool "usleep"
    676692    default n
     
    678694      usleep is used to pause for a specified number of microseconds.
    679695
    680 config CONFIG_UUDECODE
     696config UUDECODE
    681697    bool "uudecode"
    682698    default n
     
    684700      uudecode is used to decode a uuencoded file.
    685701
    686 config CONFIG_UUENCODE
     702config UUENCODE
    687703    bool "uuencode"
    688704    default n
     
    690706      uuencode is used to uuencode a file.
    691707
    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
     708config WC
    701709    bool "wc"
    702710    default n
     
    705713      in specified files.
    706714
    707 config CONFIG_WHO
     715config 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
     722config WHO
    708723    bool "who"
    709724    default n
    710     select CONFIG_FEATURE_UTMP
     725    select FEATURE_UTMP
    711726    help
    712727      who is used to show who is logged on.
    713728
    714 config CONFIG_WHOAMI
     729config WHOAMI
    715730    bool "whoami"
    716731    default n
     
    719734      user id (same as id -un).
    720735
    721 config CONFIG_YES
     736config YES
    722737    bool "yes"
    723738    default n
     
    727742
    728743comment "Common options for cp and mv"
    729     depends on CONFIG_CP || CONFIG_MV
    730 
    731 config CONFIG_FEATURE_PRESERVE_HARDLINKS
     744    depends on CP || MV
     745
     746config FEATURE_PRESERVE_HARDLINKS
    732747    bool "Preserve hard links"
    733748    default n
    734     depends on CONFIG_CP || CONFIG_MV
     749    depends on CP || MV
    735750    help
    736751      Allow cp and mv to preserve hard links.
    737752
    738753comment "Common options for ls, more and telnet"
    739     depends on CONFIG_LS || CONFIG_MORE || CONFIG_TELNET
    740 
    741 config CONFIG_FEATURE_AUTOWIDTH
     754    depends on LS || MORE || TELNET
     755
     756config FEATURE_AUTOWIDTH
    742757    bool "Calculate terminal & column widths"
    743758    default y
    744     depends on CONFIG_LS || CONFIG_MORE || CONFIG_TELNET
     759    depends on LS || MORE || TELNET
    745760    help
    746761      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
    748763      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
    750765      primitive and will be unable to determine the current screen width.
    751766
    752767comment "Common options for df, du, ls"
    753     depends on CONFIG_DF || CONFIG_DU || CONFIG_LS
    754 
    755 config CONFIG_FEATURE_HUMAN_READABLE
     768    depends on DF || DU || LS
     769
     770config FEATURE_HUMAN_READABLE
    756771    bool "Support for human readable output (example 13k, 23M, 235G)"
    757772    default n
    758     depends on CONFIG_DF || CONFIG_DU || CONFIG_LS
     773    depends on DF || DU || LS
    759774    help
    760775      Allow df, du, and ls to have human readable output.
    761776
    762777comment "Common options for md5sum, sha1sum"
    763     depends on CONFIG_MD5SUM || CONFIG_SHA1SUM
    764 
    765 config CONFIG_FEATURE_MD5_SHA1_SUM_CHECK
     778    depends on MD5SUM || SHA1SUM
     779
     780config FEATURE_MD5_SHA1_SUM_CHECK
    766781    bool "Enable -c, -s and -w options"
    767782    default n
    768     depends on CONFIG_MD5SUM || CONFIG_SHA1SUM
     783    depends on MD5SUM || SHA1SUM
    769784    help
    770785      Enabling the -c options allows files to be checked
  • branches/stable/mindi-busybox/coreutils/basename.c

    r821 r1770  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    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.
    208 *
    219 */
     
    3321 */
    3422
    35 #include <stdlib.h>
    36 #include <stdio.h>
    37 #include <string.h>
    38 #include "busybox.h"
     23#include "libbb.h"
    3924
     25/* This is a NOFORK applet. Be very careful! */
     26
     27int basename_main(int argc, char **argv);
    4028int basename_main(int argc, char **argv)
    4129{
     
    5947    puts(s);
    6048
    61     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     49    return fflush(stdout);
    6250}
  • branches/stable/mindi-busybox/coreutils/cal.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * Calendar implementation for busybox
     
    45 * See original copyright at the end of this file
    56 *
    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 */
    219
    2210/* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */
     
    3018 */
    3119
    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 */
    4523
    4624#define THURSDAY        4       /* for reformation */
     
    5331#define SPACE           -1      /* used in day array */
    5432
    55 static const char days_in_month[] = {
     33static const unsigned char days_in_month[] ALIGN1 = {
    5634    0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    5735};
    5836
    59 static const char sep1752[] = {
    60             1, 2,  14, 15, 16,
     37static const unsigned char sep1752[] ALIGN1 = {
     38        1, 2,  14, 15, 16,
    6139    17, 18, 19, 20, 21, 22, 23,
    6240    24, 25, 26, 27, 28, 29, 30
    6341};
    6442
    65 static int julian;
     43static unsigned julian;
    6644
    6745/* 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)
     46static int leap_year(unsigned yr)
     47{
     48    if (yr <= 1752)
     49        return !(yr % 4);
     50    return (!(yr % 4) && (yr % 100)) || !(yr % 400);
     51}
    7852
    7953/* number of centuries since 1700, not inclusive */
     
    8963    ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))
    9064
    91 static void center (char *, int, int);
    92 static void day_array (int, int, int *);
    93 static void trim_trailing_spaces_and_print (char *);
     65static void center(char *, unsigned, unsigned);
     66static void day_array(unsigned, unsigned, unsigned *);
     67static void trim_trailing_spaces_and_print(char *);
    9468
    9569static void blank_string(char *buf, size_t buflen);
    96 static char *build_row(char *p, int *dp);
     70static char *build_row(char *p, unsigned *dp);
    9771
    9872#define DAY_LEN     3       /* 3 spaces per day */
     
    10276#define HEAD_SEP    2       /* spaces between day headings */
    10377
     78int cal_main(int argc, char **argv);
    10479int cal_main(int argc, char **argv)
    10580{
     
    10782    struct tm zero_tm;
    10883    time_t now;
    109     int month, year, flags, i;
     84    unsigned month, year, flags, i;
    11085    char *month_names[12];
    11186    char day_headings[28];  /* 28 for julian, 21 for nonjulian */
    11287    char buf[40];
    11388
    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");
    12090    julian = flags & 1;
    121 
     91    month = 0;
    12292    argv += optind;
    123 
    124     month = 0;
    125 
    126     if ((argc -= optind) > 2) {
     93    argc -= optind;
     94
     95    if (argc > 2) {
    12796        bb_show_usage();
    12897    }
     
    137106    } else {
    138107        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 +  7*julian);
     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);
    145114
    146115    i = 0;
     
    148117        zero_tm.tm_mon = i;
    149118        strftime(buf, sizeof(buf), "%B", &zero_tm);
    150         month_names[i] = bb_xstrdup(buf);
     119        month_names[i] = xstrdup(buf);
    151120
    152121        if (i < 7) {
     
    158127
    159128    if (month) {
    160         int row, len, days[MAXDAYS];
    161         int *dp = days;
     129        unsigned row, len, days[MAXDAYS];
     130        unsigned *dp = days;
    162131        char lineout[30];
    163132
    164133        day_array(month, year, dp);
    165134        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",
    167136               ((7*julian + WEEK_LEN) - len) / 2, "",
    168137               lineout, day_headings);
     
    173142        }
    174143    } else {
    175         int row, which_cal, week_len, days[12][MAXDAYS];
    176         int *dp;
     144        unsigned row, which_cal, week_len, days[12][MAXDAYS];
     145        unsigned *dp;
    177146        char lineout[80];
    178147
     
    195164            }
    196165            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);
    198167            if (!julian) {
    199                 bb_printf("%*s%s", HEAD_SEP, "", day_headings);
     168                printf("%*s%s", HEAD_SEP, "", day_headings);
    200169            }
    201170            putchar('\n');
     
    211180    }
    212181
    213     bb_fflush_stdout_and_exit(0);
     182    fflush_stdout_and_exit(0);
    214183}
    215184
     
    221190 *  builds that array for any month from Jan. 1 through Dec. 9999.
    222191 */
    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;
     192static void day_array(unsigned month, unsigned year, unsigned *days)
     193{
     194    unsigned long temp;
     195    unsigned i;
     196    unsigned day, dw, dm;
    229197
    230198    memset(days, SPACE, MAXDAYS * sizeof(int));
    231199
    232200    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;
    233205        size_t oday = 0;
    234        
    235         j_offset = julian * 244;
     206
    236207        do {
    237208            days[oday+2] = sep1752[oday] + j_offset;
     
    242213
    243214    /* day_in_year
    244      *  return the 1 based day number within the year
     215     * return the 1 based day number within the year
    245216     */
    246217    day = 1;
     
    255226
    256227    /* day_in_week
    257      *  return the 0 based day number for any date from 1 Jan. 1 to
    258      *  31 Dec. 9999.  Assumes the Gregorian reformation eliminates
    259      *  3 Sep. 1752 through 13 Sep. 1752.  Returns Thursday for all
    260      *  missing days.
     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.
    261232     */
    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;
    265234    if (temp < FIRST_MISSING_DAY) {
    266235        dw = ((temp - 1 + SATURDAY) % 7);
    267     } else if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) {
     236    } else {
    268237        dw = (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);
    269238    }
     
    278247    }
    279248
    280     while (dm) {
     249    do {
    281250        days[dw++] = day++;
    282         --dm;
    283     }
     251    } while (--dm);
    284252}
    285253
     
    291259        ++p;
    292260    }
    293     while (p > s) {
     261    while (p != s) {
    294262        --p;
    295263        if (!(isspace)(*p)) {   /* We want the function... not the inline. */
     
    302270}
    303271
    304 static void center(char *str, int len, int separate)
    305 {
    306     int n = strlen(str);
     272static void center(char *str, unsigned len, unsigned separate)
     273{
     274    unsigned n = strlen(str);
    307275    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, "");
    309277}
    310278
     
    315283}
    316284
    317 static char *build_row(char *p, int *dp)
    318 {
    319     int col, val, day;
     285static char *build_row(char *p, unsigned *dp)
     286{
     287    unsigned col, val, day;
    320288
    321289    memset(p, ' ', (julian + DAY_LEN) * 7);
     
    323291    col = 0;
    324292    do {
    325         if ((day = *dp++) != SPACE) {
     293        day = *dp++;
     294        if (day != SPACE) {
    326295            if (julian) {
    327296                ++p;
     
    332301                }
    333302            }
    334             if ((val = day / 10) > 0) {
     303            val = day / 10;
     304            if (val > 0) {
    335305                *p = val + '0';
    336306            }
     
    376346 * SUCH DAMAGE.
    377347 */
    378 
    379 
  • branches/stable/mindi-busybox/coreutils/cat.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    88 */
    99
     
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */
    1212
    13 #include "busybox.h"
    14 #include <unistd.h>
     13#include "libbb.h"
    1514
    16 int cat_main(int argc, char **argv)
     15/* This is a NOFORK applet. Be very careful! */
     16
     17
     18int bb_cat(char **argv)
    1719{
    18     FILE *f;
     20    static const char *const argv_dash[] = { "-", NULL };
     21
     22    int fd;
    1923    int retval = EXIT_SUCCESS;
    2024
    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;
    2727
    2828    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)
    3338                continue;
    34             }
    3539        }
    3640        retval = EXIT_FAILURE;
     
    3943    return retval;
    4044}
     45
     46int cat_main(int argc, char **argv);
     47int cat_main(int argc, char **argv)
     48{
     49    getopt32(argv, "u");
     50    argv += optind;
     51    return bb_cat(argv);
     52}
  • branches/stable/mindi-busybox/coreutils/catv.c

    r821 r1770  
    1111 * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz */
    1212
    13 #include "busybox.h"
    14 #include <unistd.h>
    15 #include <fcntl.h>
     13#include "libbb.h"
    1614
     15int catv_main(int argc, char **argv);
    1716int catv_main(int argc, char **argv)
    1817{
    19     int retval = EXIT_SUCCESS, fd, flags;
     18    int retval = EXIT_SUCCESS;
     19    int fd;
     20    unsigned flags;
    2021
    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;
    2328
    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    }
    2735    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 (;;) {
    3343            int i, res;
    3444
    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];
    4053
    41                 if (c > 126 && (flags & 4)) {
     54                if (c > 126 && (flags & CATV_OPT_v)) {
    4255                    if (c == 127) {
    4356                        printf("^?");
    4457                        continue;
    45                     } else {
    46                         printf("M-");
    47                         c -= 128;
    4858                    }
     59                    printf("M-");
     60                    c -= 128;
    4961                }
    5062                if (c < 32) {
    5163                    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)) {
    5467                        printf("^%c", c+'@');
    5568                        continue;
     
    5972            }
    6073        }
    61         if (ENABLE_FEATURE_CLEAN_UP && fd) close(fd);
     74        if (ENABLE_FEATURE_CLEAN_UP && fd)
     75            close(fd);
    6276    } while (*++argv);
    6377
    64     return retval;
     78    fflush_stdout_and_exit(retval);
    6579}
  • branches/stable/mindi-busybox/coreutils/chgrp.c

    r821 r1770  
    88 */
    99
    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. */
    1312/* http://www.opengroup.org/onlinepubs/007904975/utilities/chgrp.html */
    1413
    15 #include <stdlib.h>
    16 #include <unistd.h>
    17 #include "busybox.h"
     14#include "libbb.h"
    1815
    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! */
    2317
    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 }
    3218
     19int chgrp_main(int argc, char **argv);
    3320int chgrp_main(int argc, char **argv)
    3421{
    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        }
    4329    }
    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);
    6031}
  • branches/stable/mindi-busybox/coreutils/chmod.c

    r821 r1770  
    1212
    1313/* BB_AUDIT SUSv3 compliant */
    14 /* BB_AUDIT GNU defects - unsupported options -c, -f, -v, and long options. */
     14/* BB_AUDIT GNU defects - unsupported long options. */
    1515/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
    1616
    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"
    2318
    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
     37static int fileAction(const char *fileName, struct stat *statbuf, void* param, int depth)
    2538{
    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;
    3268}
    3369
    34 int chmod_main(int ATTRIBUTE_UNUSED argc, char **argv)
     70int chmod_main(int argc, char **argv);
     71int chmod_main(int argc, char **argv)
    3572{
    3673    int retval = EXIT_SUCCESS;
    37     int recursiveFlag = FALSE;
    38     int count;
     74    char *arg, **argp;
    3975    char *smode;
    40     char **p;
    41     char *p0;
    42     char opt = '-';
    4376
    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;
    6886        }
    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        }
    7192    }
    7293
    73     argv[count] = NULL;
     94    /* Parse options */
     95    opt_complementary = "-2";
     96    getopt32(argv, ("-"OPT_STR) + 1); /* Reuse string */
     97    argv += optind;
    7498
    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] = '-';
    81101
    82102    /* Ok, ready to do the deed now */
     103    smode = *argv++;
    83104    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        ) {
    86112            retval = EXIT_FAILURE;
    87113        }
     
    90116    return retval;
    91117}
     118
     119/*
     120Security: chmod is too important and too subtle.
     121This is a test script (busybox chmod versus coreutils).
     122Run it in empty directory.
     123
     124#!/bin/sh
     125t1="/tmp/busybox chmod"
     126t2="/usr/bin/chmod"
     127create() {
     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}
     140tst() {
     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}
     149echo "If script produced 'out.diff' file, then at least one testcase failed"
     150create test1; create test2
     151tst "a+w file"
     152tst "a-w dir"
     153tst "a+w linkfile"
     154tst "a-w linkdir"
     155tst "-R a+w file"
     156tst "-R a-w dir"
     157tst "-R a+w linkfile"
     158tst "-R a-w linkdir"
     159tst "a-r,a+x linkfile"
     160*/
  • branches/stable/mindi-busybox/coreutils/chown.c

    r821 r1770  
    88 */
    99
    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. */
    1312/* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */
    1413
    15 #include <stdlib.h>
    16 #include <unistd.h>
    17 #include <string.h>
    18 #include "busybox.h"
     14#include "libbb.h"
    1915
    20 static uid_t uid = -1;
    21 static gid_t gid = -1;
     16/* This is a NOEXEC applet. Be very careful! */
    2217
    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
     40typedef int (*chown_fptr)(const char *, uid_t, gid_t);
     41
     42static struct bb_uidgid_t ugid = { -1, -1 };
    2443
    2544static int fileAction(const char *fileName, struct stat *statbuf,
    26         void ATTRIBUTE_UNUSED *junk)
     45        void *cf, int depth)
    2746{
    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        }
    3157        return TRUE;
    3258    }
    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... */
    3461    return FALSE;
    3562}
    3663
    37 #define FLAG_R 1
    38 #define FLAG_h 2
    39 
     64int chown_main(int argc, char **argv);
    4065int chown_main(int argc, char **argv)
    4166{
     67    int retval = EXIT_SUCCESS;
    4268    int flags;
    43     int retval = EXIT_SUCCESS;
    44     char *groupName;
     69    chown_fptr chown_func;
    4570
    46     flags = bb_getopt_ulflags(argc, argv, "Rh");
     71    opt_complementary = "-2";
     72    getopt32(argv, OPT_STR);
     73    argv += optind;
    4774
    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;
    5282    }
    5383
    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 */
    5591
    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]);
    6893
    6994    /* Ok, ready to do the deed now */
     95    argv++;
    7096    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        ) {
    73104            retval = EXIT_FAILURE;
    74105        }
     
    77108    return retval;
    78109}
     110
     111/*
     112Testcase. Run in empty directory.
     113
     114#!/bin/sh
     115t1="/tmp/busybox chown"
     116t2="/usr/bin/chown"
     117create() {
     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}
     133tst() {
     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}
     146tst_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}
     152echo "If script produced 'out.diff' file, then at least one testcase failed"
     153>test1.out
     154>test2.out
     155# These match coreutils 6.8:
     156tst_for_each "-v"
     157tst_for_each "-vR"
     158tst_for_each "-vRP"
     159tst_for_each "-vRL"
     160tst_for_each "-vRH"
     161tst_for_each "-vh"
     162tst_for_each "-vhR"
     163tst_for_each "-vhRP"
     164tst_for_each "-vhRL"
     165tst_for_each "-vhRH"
     166# Fix `name' in coreutils output
     167sed 's/`/'"'"'/g' -i test2.out
     168# Compare us with coreutils output
     169diff -u test1.out test2.out
     170
     171*/
  • branches/stable/mindi-busybox/coreutils/chroot.c

    r821 r1770  
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
    1111
    12 #include <stdlib.h>
    13 #include <stdio.h>
    14 #include <unistd.h>
    15 #include <errno.h>
    16 #include "busybox.h"
     12#include "libbb.h"
    1713
     14int chroot_main(int argc, char **argv);
    1815int chroot_main(int argc, char **argv)
    1916{
     
    2623        bb_perror_msg_and_die("cannot change root directory to %s", *argv);
    2724    }
    28     bb_xchdir("/");
     25    xchdir("/");
    2926
    3027    ++argv;
    3128    if (argc == 2) {
    3229        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;
    3533        }
    3634        argv[1] = (char *) "-i";
    3735    }
    3836
    39     execvp(*argv, argv);
     37    BB_EXECVP(*argv, argv);
    4038    bb_perror_msg_and_die("cannot execute %s", *argv);
    4139}
  • branches/stable/mindi-busybox/coreutils/cksum.c

    r821 r1770  
    44 *
    55 * Copyright (C) 2006 by Rob Sullivan, with ideas from code by Walter Harms
    6  * 
     6 *
    77 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */
    88
    9 #include <stdio.h>
    10 #include <unistd.h>
    11 #include <fcntl.h>
    12 #include "busybox.h"
     9#include "libbb.h"
    1310
    14 int cksum_main(int argc, char **argv) {
    15    
    16     uint32_t *crc32_table = bb_crc32_filltable(1);
     11int cksum_main(int argc, char **argv);
     12int cksum_main(int argc, char **argv)
     13{
     14    uint32_t *crc32_table = crc32_filltable(NULL, 1);
    1715
    1816    FILE *fp;
     
    2119    int bytes_read;
    2220    char *cp;
    23     RESERVE_CONFIG_BUFFER(buf, BUFSIZ);
     21
    2422    int inp_stdin = (argc == optind) ? 1 : 0;
    25    
     23
    2624    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
    2927        crc = 0;
    3028        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;
    3433            length += bytes_read;
    3534            while (bytes_read--)
    3635                crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ (*cp++)) & 0xffL];
    3736        }
    38        
     37
    3938        filesize = length;
    40        
     39
    4140        for (; length; length >>= 8)
    4241            crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ length) & 0xffL];
     
    4443
    4544        if (inp_stdin) {
    46             printf("%"PRIu32" %li\n", crc, filesize);
     45            printf("%" PRIu32 " %li\n", crc, filesize);
    4746            break;
    4847        }
    49        
    50         printf("%"PRIu32" %li %s\n", crc, filesize, *argv);
     48
     49        printf("%" PRIu32 " %li %s\n", crc, filesize, *argv);
    5150        fclose(fp);
    52     } while (*(argv+1));
    53    
    54     return EXIT_SUCCESS;
     51    } while (*(argv + 1));
     52
     53    fflush_stdout_and_exit(EXIT_SUCCESS);
    5554}
  • branches/stable/mindi-busybox/coreutils/comm.c

    r821 r1770  
    88 */
    99
    10 #include <stdio.h>
    11 #include <stdlib.h>
    12 #include <string.h>
    13 #include <unistd.h>
    14 #include "busybox.h"
     10#include "libbb.h"
    1511
    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)
    2515
    2616/* writeline outputs the input given, appropriately aligned according to class */
    27 static void writeline(char *line, int class)
     17static void writeline(char *line, int class, int flags)
    2818{
    2919    if (class == 0) {
    30         if (!only_file_1)
     20        if (flags & COMM_OPT_1)
    3121            return;
    3222    } else if (class == 1) {
    33         if (!only_file_2)
     23        if (flags & COMM_OPT_2)
    3424            return;
    35         if (only_file_1)
     25        if (!(flags & COMM_OPT_1))
    3626            putchar('\t');
    37     }
    38     else /*if (class == 2)*/ {
    39         if (!both)
     27    } else /*if (class == 2)*/ {
     28        if (flags & COMM_OPT_3)
    4029            return;
    41         if (only_file_1)
     30        if (!(flags & COMM_OPT_1))
    4231            putchar('\t');
    43         if (only_file_2)
     32        if (!(flags & COMM_OPT_2))
    4433            putchar('\t');
    4534    }
     
    4736}
    4837
    49 /* This is the real core of the program - lines are compared here */
    50 static void cmp_files(char **infiles)
     38int comm_main(int argc, char **argv);
     39int comm_main(int argc, char **argv)
    5140{
    5241#define LINE_LEN 100
     
    5645    FILE *streams[2];
    5746    int i;
     47    unsigned flags;
     48
     49    opt_complementary = "=2";
     50    flags = getopt32(argv, "123");
     51    argv += optind;
    5852
    5953    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");
    6155        fgets(thisline[i], LINE_LEN, streams[i]);
    6256    }
     57
     58    /* This is the real core of the program - lines are compared here */
    6359
    6460    while (*thisline[0] || *thisline[1]) {
     
    8379
    8480        if (order == 0 && !i)
    85             writeline(thisline[1], 2);
     81            writeline(thisline[1], 2, flags);
    8682        else if (order > 0 && !(i & BB_EOF_1))
    87             writeline(thisline[1], 1);
     83            writeline(thisline[1], 1, flags);
    8884        else if (order < 0 && !(i & BB_EOF_0))
    89             writeline(thisline[0], 0);
     85            writeline(thisline[0], 0, flags);
    9086
    9187        if (i & BB_EOF_0 & BB_EOF_1) {
     
    9692            while (!feof(streams[i])) {
    9793                if ((order < 0 && i) || (order > 0 && !i))
    98                     writeline(thisline[i], i);
     94                    writeline(thisline[i], i, flags);
    9995                fgets(thisline[i], LINE_LEN, streams[i]);
    10096            }
     
    109105    }
    110106
    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;
    113113}
    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/stable/mindi-busybox/coreutils/cp.c

    r821 r1770  
    44 *
    55 * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
     6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
    67 *
    78 * Licensed under GPL v2 or later, see file LICENSE in this tarball for details.
    89 */
    910
    10 /* BB_AUDIT SUSv3 defects - unsupported options -H, -L, and -P. */
    11 /* BB_AUDIT GNU defects - only extension options supported are -a and -d.  */
    1211/* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */
    1312
     
    1716 */
    1817
    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"
    2919#include "libcoreutils/coreutils.h"
    3020
     21/* This is a NOEXEC applet. Be very careful! */
     22
     23
     24int cp_main(int argc, char **argv);
    3125int cp_main(int argc, char **argv)
    3226{
     
    3933    int flags;
    4034    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    };
    4142
    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");
    5949    /* Default behavior of cp is to dereference, so we don't have to do
    6050     * anything special when we are given -L.
    6151     * The behavior of -H is *almost* like -L, but not quite, so let's
    6252     * 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();
    6560    }
    66     */
     61#endif
    6762
    6863    flags ^= FILEUTILS_DEREFERENCE;     /* The sense of this flag was reversed. */
     
    7873    if (optind + 2 == argc) {
    7974        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
    8482        /* ...if neither is a directory or...  */
    8583        if ( !((s_flags | d_flags) & 2) ||
    8684            /* ...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)
    9086        ) {
    9187            /* ...do a simple copy.  */
    92             dest = last;
     88            dest = xstrdup(last);
    9389            goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */
    9490        }
     
    9793    do {
    9894        dest = concat_path_file(last, bb_get_last_path_component(*argv));
    99     DO_COPY:
     95 DO_COPY:
    10096        if (copy_file(*argv, dest, flags) < 0) {
    10197            status = 1;
    10298        }
    103         if (*++argv == last) {
    104             break;
    105         }
    106         free((void *) dest);
    107     } while (1);
     99        free((void*)dest);
     100    } while (*++argv != last);
    108101
    109     exit(status);
     102    return status;
    110103}
  • branches/stable/mindi-busybox/coreutils/cut.c

    r821 r1770  
    1 /* vi: set sw=8 ts=8: */
     1/* vi: set sw=4 ts=4: */
    22/*
    33 * cut.c - minimalist version of cut
     
    55 * Copyright (C) 1999,2000,2001 by Lineo, inc.
    66 * Written by Mark Whitley <markw@codepoet.org>
     7 * debloated by Bernhard Fischer
    78 *
    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.
    2210 */
    2311
    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! */
    3015
    3116
    3217/* 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 */
     18static 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
     25static char delim = '\t';   /* delimiter, default is tab */
    4226
    4327struct cut_list {
     
    5236};
    5337
    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 */
     39static struct cut_list *cut_lists;
     40static unsigned int nlists; /* number of elements in above list */
    5641
    5742
    5843static int cmpfunc(const void *a, const void *b)
    5944{
    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
    6848}
    6949
    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(&ltok, "-");
    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(&ltok, "-");
    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)
     50static void cut_file(FILE * file)
    26951{
    27052    char *line = NULL;
    271     unsigned int linenum = 0; /* keep these zero-based to be consistent */
     53    unsigned int linenum = 0;   /* keep these zero-based to be consistent */
    27254
    27355    /* 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;
    27563
    27664        /* 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:
    288160        linenum++;
    289         free(line);
     161        free(printed);
     162        free(orig_line);
    290163    }
    291164}
    292165
    293 
     166static const char _op_on_field[] ALIGN1 = " only when operating on fields";
     167
     168int cut_main(int argc, char **argv);
    294169int cut_main(int argc, char **argv)
    295170{
    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, &ltok);
     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) {
    309182            bb_error_msg_and_die("the delimiter must be a single character");
    310183        }
    311         delim = sdopt[0];
    312     }
    313     supress_non_delimited_lines = opt & OPT_SUPRESS_FLGS;
     184        delim = ltok[0];
     185    }
    314186
    315187    /*  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);
    320193        }
    321194        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(&ltok, "-");
     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(&ltok, "-");
     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
    327270     * files were specified or '-' was specified, take input from stdin.
    328271     * 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])) {
    330273        cut_file(stdin);
    331     }
    332     else {
    333         int i;
     274    } else {
    334275        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) {
    338280                cut_file(file);
    339281                fclose(file);
    340282            }
    341         }
    342     }
    343 
     283        } while (*++argv);
     284    }
     285    if (ENABLE_FEATURE_CLEAN_UP)
     286        free(cut_lists);
    344287    return EXIT_SUCCESS;
    345288}
  • branches/stable/mindi-busybox/coreutils/date.c

    r821 r1770  
    66 *
    77 * iso-format handling added by Robert Griebl <griebl@gmx.de>
     8 * bugfixes and cleanup by Bernhard Fischer
    89 *
    910 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    1011*/
    1112
    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"
    1914
    2015/* This 'date' command supports only 2 time setting formats,
    2116   all the GNU strftime stuff (its in libc, lets use it),
    22    setting time using UTC and displaying int, as well as
    23    an RFC 822 complient date output for shell scripting
     17   setting time using UTC and displaying it, as well as
     18   an RFC 2822 compliant date output for shell scripting
    2419   mail commands */
    2520
     
    2924/* Default input handling to save surprising some people */
    3025
    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 }
    10526
    10627#define DATE_OPT_RFC2822    0x01
     
    11233#define DATE_OPT_HINT       0x40
    11334
     35static void maybe_set_utc(int opt)
     36{
     37    if (opt & DATE_OPT_UTC)
     38        putenv((char*)"TZ=UTC0");
     39}
     40
     41int date_main(int argc, char **argv);
    11442int date_main(int argc, char **argv)
    11543{
     44    time_t tm;
     45    struct tm tm_time;
     46    unsigned opt;
     47    int ifmt = -1;
    11648    char *date_str = NULL;
    11749    char *date_fmt = NULL;
    118     int set_time;
    119     int utc;
    120     time_t tm;
    121     unsigned long opt;
    122     struct tm tm_time;
    12350    char *filename = NULL;
    124 
    125     int ifmt = 0;
    12651    char *isofmt_arg;
    12752    char *hintfmt_arg;
    12853
    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)) {
    14163        if (!isofmt_arg) {
    142             ifmt = 1;
     64            ifmt = 0; /* default is date */
    14365        } 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 */
    15074            bb_show_usage();
     75 found: ;
    15176        }
    15277    }
     
    15681        date_fmt = &argv[optind][1];    /* Skip over the '+' */
    15782    } else if (date_str == NULL) {
    158         set_time = 1;
     83        opt |= DATE_OPT_SET;
    15984        date_str = argv[optind];
    16085    }
     
    16388       which depends on whether the clock is being set or read */
    16489
    165     if(filename) {
     90    if (filename) {
    16691        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);
    17096    memcpy(&tm_time, localtime(&tm), sizeof(tm_time));
    17197    /* Zero out fields - take her back to midnight! */
     
    179105            strptime(date_str, hintfmt_arg, &tm_time);
    180106        } 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            }
    182139        } 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;
    184165        }
    185166
     
    190171            bb_error_msg_and_die(bb_msg_invalid_date, date_str);
    191172        }
    192         if (utc && putenv("TZ=UTC0") != 0) {
    193             bb_error_msg_and_die(bb_msg_memory_exhausted);
    194         }
     173        maybe_set_utc(opt);
    195174
    196175        /* if setting time, set it */
    197         if (set_time && stime(&tm) < 0) {
     176        if ((opt & DATE_OPT_SET) && stime(&tm) < 0) {
    198177            bb_perror_msg("cannot set date");
    199178        }
     
    203182
    204183    /* Deal with format string */
     184
    205185    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
    225221    if (*date_fmt == '\0') {
    226 
    227222        /* With no format string, just print a blank line */
    228        
    229         *bb_common_bufsiz1=0;
     223        date_buf[0] = '\0';
    230224    } else {
    231 
    232225        /* Handle special conversions */
    233226
    234227        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";
    236229        }
    237230
    238231        /* 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);
    242235
    243236    return EXIT_SUCCESS;
  • branches/stable/mindi-busybox/coreutils/dd.c

    r821 r1770  
    99 */
    1010
    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
    2016
    2117static const struct suffix_mult dd_suffixes[] = {
     
    2521    { "kD", 1000 },
    2622    { "k", 1024 },
     23    { "K", 1024 },  /* compat with coreutils dd */
    2724    { "MD", 1000000 },
    2825    { "M", 1048576 },
    2926    { "GD", 1000000000 },
    3027    { "G", 1073741824 },
    31     { NULL, 0 }
     28    { }
    3229};
    3330
    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)
     31struct 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
     39static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal)
    4040{
    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);
    4446}
    4547
     48static 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
     57static 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
     76int dd_main(int argc, char **argv);
    4677int dd_main(int argc, char **argv)
    4778{
    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;
    54110    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 ',' */
    100194                }
    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 */
    116233        infile = bb_msg_standard_input;
    117234    }
    118 
    119235    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))
    123239            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)) {
    129244            if (ftruncate(ofd, seek * obs) < 0) {
    130245                struct stat st;
    131246
    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;
    136250            }
    137251        }
     
    140254        outfile = bb_msg_standard_output;
    141255    }
    142 
    143256    if (skip) {
    144257        if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
     
    146259                n = safe_read(ifd, ibuf, ibs);
    147260                if (n < 0)
    148                     bb_perror_msg_and_die("%s", infile);
     261                    goto die_infile;
    149262                if (n == 0)
    150263                    break;
     
    152265        }
    153266    }
    154 
    155267    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);
    167275        n = safe_read(ifd, ibuf, ibs);
    168         if (n == 0) {
     276        if (n == 0)
    169277            break;
    170         }
    171278        if (n < 0) {
    172             if (noerror) {
     279            if (flags & FLAG_NOERROR) {
    173280                n = ibs;
    174281                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) {
    184290                memset(ibuf + n, '\0', ibs - n);
    185291                n = ibs;
    186292            }
    187293        }
    188         if (twobufs_flag) {
     294        if (flags & FLAG_TWOBUFS) {
    189295            char *tmp = ibuf;
    190296            while (n) {
    191297                size_t d = obs - oc;
    192298
    193                 if (d > n) d = n;
     299                if (d > n)
     300                    d = n;
    194301                memcpy(obuf + oc, tmp, d);
    195302                n -= d;
     
    197304                oc += d;
    198305                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;
    203308                    oc = 0;
    204309                }
    205310            }
    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
    215315    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:
    222323        bb_perror_msg_and_die("%s", infile);
    223324    }
    224325
    225     if (close (ofd) < 0) {
     326    if (close(ofd) < 0) {
     327 die_outfile:
    226328        bb_perror_msg_and_die("%s", outfile);
    227329    }
    228 
     330 out_status:
    229331    dd_output_status(0);
    230332
  • branches/stable/mindi-busybox/coreutils/df.c

    r821 r1770  
    1919 */
    2020
    21 #include <stdio.h>
    22 #include <stdlib.h>
    23 #include <string.h>
    24 #include <unistd.h>
    2521#include <mntent.h>
    2622#include <sys/vfs.h>
    27 #include "busybox.h"
     23#include "libbb.h"
    2824
    29 #ifndef CONFIG_FEATURE_HUMAN_READABLE
    30 static long kscale(long b, long bs)
     25#if !ENABLE_FEATURE_HUMAN_READABLE
     26static unsigned long kscale(unsigned long b, unsigned long bs)
    3127{
    32     return ( b * (long long) bs + KILOBYTE/2 ) / KILOBYTE;
     28    return (b * (unsigned long long) bs + 1024/2) / 1024;
    3329}
    3430#endif
    3531
     32int df_main(int argc, char **argv);
    3633int df_main(int argc, char **argv)
    3734{
    38     long blocks_used;
    39     long blocks_percent_used;
    40 #ifdef CONFIG_FEATURE_HUMAN_READABLE
    41     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;
    4239#endif
    4340    int status = EXIT_SUCCESS;
    44     unsigned long opt;
     41    unsigned opt;
    4542    FILE *mount_table;
    4643    struct mntent *mount_entry;
    4744    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";
    5047
    51 #ifdef CONFIG_FEATURE_HUMAN_READABLE
    52     bb_opt_complementally = "h-km:k-hm:m-hk";
    53     opt = bb_getopt_ulflags(argc, argv, "hmk");
    54     if(opt & 1) {
    55                 df_disp_hr = 0;
    56                 disp_units_hdr = "     Size";
     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";
    5754    }
    58     if(opt & 2) {
    59                 df_disp_hr = MEGABYTE;
    60                 disp_units_hdr = "1M-blocks";
     55    if (opt & 2) {
     56        df_disp_hr = 1024*1024;
     57        disp_units_hdr = "1M-blocks";
    6158    }
    6259#else
    63     opt = bb_getopt_ulflags(argc, argv, "k");
     60    opt = getopt32(argv, "k");
    6461#endif
    6562
    66     bb_printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n",
     63    printf("Filesystem%11s%-15sUsed Available Use%% Mounted on\n",
    6764              "", disp_units_hdr);
    6865
     
    7067    argv += optind;
    7168    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) {
    7371            bb_perror_msg_and_die(bb_path_mtab_file);
    7472        }
    7573    }
    7674
    77     do {
     75    while (1) {
    7876        const char *device;
    7977        const char *mount_point;
    8078
    8179        if (mount_table) {
    82             if (!(mount_entry = getmntent(mount_table))) {
     80            mount_entry = getmntent(mount_table);
     81            if (!mount_entry) {
    8382                endmntent(mount_table);
    8483                break;
    8584            }
    8685        } else {
    87             if (!(mount_point = *argv++)) {
     86            mount_point = *argv++;
     87            if (!mount_point) {
    8888                break;
    8989            }
    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:
    9394                status = EXIT_FAILURE;
    9495                continue;
     
    108109            blocks_percent_used = 0;
    109110            if (blocks_used + s.f_bavail) {
    110                 blocks_percent_used = (((long long) blocks_used) * 100
    111                                        + (blocks_used + s.f_bavail)/2
    112                                        ) / (blocks_used + s.f_bavail);
     111                blocks_percent_used = (blocks_used * 100ULL
     112                        + (blocks_used + s.f_bavail)/2
     113                        ) / (blocks_used + s.f_bavail);
    113114            }
    114115
     
    118119                /* Adjusts device to be the real root device,
    119120                * 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) {
    121123                    goto SET_ERROR;
    122124                }
    123125            }
    124126
    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));
    128132
    129             bb_printf("%9s ",
    130                       make_human_readable_str( (s.f_blocks - s.f_bfree),
    131                                               s.f_bsize, df_disp_hr));
     133            printf(" %9s " + 1,
     134                make_human_readable_str((s.f_blocks - s.f_bfree),
     135                        s.f_bsize, df_disp_hr));
    132136
    133             bb_printf("%9s %3ld%% %s\n",
    134                       make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr),
    135                       blocks_percent_used, mount_point);
     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);
    136140#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);
    143146#endif
    144147        }
     148    }
    145149
    146     } while (1);
    147 
    148     bb_fflush_stdout_and_exit(status);
     150    fflush_stdout_and_exit(status);
    149151}
  • branches/stable/mindi-busybox/coreutils/dirname.c

    r821 r1770  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2411/* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */
    2512
    26 #include <stdio.h>
    27 #include <stdlib.h>
    28 #include "busybox.h"
     13#include "libbb.h"
    2914
     15/* This is a NOFORK applet. Be very careful! */
     16
     17int dirname_main(int argc, char **argv);
    3018int dirname_main(int argc, char **argv)
    3119{
     
    3624    puts(dirname(argv[1]));
    3725
    38     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     26    return fflush(stdout);
    3927}
  • branches/stable/mindi-busybox/coreutils/dos2unix.c

    r821 r1770  
    1313*/
    1414
    15 #include <string.h>
    16 #include <unistd.h>
    17 #include <stdint.h>
    18 #include <fcntl.h>
    19 #include "busybox.h"
     15#include "libbb.h"
    2016
    21 enum ConvType {
     17enum {
    2218    CT_UNIX2DOS = 1,
    2319    CT_DOS2UNIX
    24 } ConvType;
     20};
    2521
    2622/* if fn is NULL then input is stdin and output is stdout */
    27 static int convert(char *fn)
     23static int convert(char *fn, int conv_type)
    2824{
    2925    FILE *in, *out;
    3026    int i;
     27#define name_buf bb_common_bufsiz1
    3128
     29    in = stdin;
     30    out = stdout;
    3231    if (fn != NULL) {
    33         in = bb_xfopen(fn, "rw");
     32        in = xfopen(fn, "rw");
    3433        /*
    3534           The file is then created with mode read/write and
    3635           permissions 0666 for glibc 2.0.6 and earlier or
    37            0600  for glibc  2.0.7 and later.
     36           0600 for glibc 2.0.7 and later.
    3837         */
    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) {
    4741            bb_perror_nomsg_and_die();
    4842        }
     
    5044        if (!out) {
    5145            close(i);
    52             remove(bb_common_bufsiz1);
     46            remove(name_buf);
     47            return -2;
    5348        }
    54     } else {
    55         in = stdin;
    56         out = stdout;
    5749    }
    5850
     
    6153            continue;
    6254        if (i == '\n') {
    63             if (ConvType == CT_UNIX2DOS)
     55            if (conv_type == CT_UNIX2DOS)
    6456                fputc('\r', out);
    6557            fputc('\n', out);
     
    7264        if (fclose(in) < 0 || fclose(out) < 0) {
    7365            bb_perror_nomsg();
    74             remove(bb_common_bufsiz1);
     66            remove(name_buf);
    7567            return -2;
    7668        }
     
    7870         * should be true since we put them into the same directory
    7971         * 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);
    8274            return -1;
    8375        }
     
    8779}
    8880
    89 int dos2unix_main(int argc, char *argv[])
     81int dos2unix_main(int argc, char **argv);
     82int dos2unix_main(int argc, char **argv)
    9083{
    91     int o;
     84    int o, conv_type;
    9285
    9386    /* 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 */
    9689    } else {
    97         ConvType = CT_UNIX2DOS; /*1 */
     90        conv_type = CT_UNIX2DOS;    /* 1 */
    9891    }
    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");
    10596
    10697    /* Do the conversion requested by an argument else do the default
    10798     * conversion depending on our name.  */
    10899    if (o)
    109         ConvType = o;
     100        conv_type = o;
    110101
    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);
    117109
    118110    return o;
  • branches/stable/mindi-busybox/coreutils/du.c

    r821 r1770  
    2424 */
    2525
    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
     30static unsigned long disp_hr = 1024;
    3631# else
    3732static unsigned long disp_hr = 512;
    3833# endif
    39 #elif defined CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
    40 static unsigned int disp_k = 1;
    41 #else
    42 static unsigned int disp_k; /* bss inits to 0 */
     34#elif ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
     35static unsigned disp_k = 1;
     36#else
     37static unsigned disp_k; /* bss inits to 0 */
    4338#endif
    4439
     
    4641static nlink_t count_hardlinks = 1;
    4742
    48 static int status
    49 #if EXIT_SUCCESS == 0
    50     = EXIT_SUCCESS
    51 #endif
    52     ;
     43static int status;
    5344static int print_files;
    5445static int slink_depth;
     
    5849
    5950
    60 static void print(long size, char *filename)
     51static void print(long size, const char *const filename)
    6152{
    6253    /* TODO - May not want to defer error checking here. */
    63 #ifdef CONFIG_FEATURE_HUMAN_READABLE
    64     bb_printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr),
    65            filename);
     54#if ENABLE_FEATURE_HUMAN_READABLE
     55    printf("%s\t%s\n", make_human_readable_str(size, 512, disp_hr),
     56            filename);
    6657#else
    6758    if (disp_k) {
     
    6960        size >>= 1;
    7061    }
    71     bb_printf("%ld\t%s\n", size, filename);
     62    printf("%ld\t%s\n", size, filename);
    7263#endif
    7364}
    7465
    7566/* tiny recursive du */
    76 static long du(char *filename)
     67static long du(const char *const filename)
    7768{
    7869    struct stat statbuf;
    7970    long sum;
    8071
    81     if ((lstat(filename, &statbuf)) != 0) {
     72    if (lstat(filename, &statbuf) != 0) {
    8273        bb_perror_msg("%s", filename);
    8374        status = EXIT_FAILURE;
     
    9788    if (S_ISLNK(statbuf.st_mode)) {
    9889        if (slink_depth > du_depth) {   /* -H or -L */
    99             if ((stat(filename, &statbuf)) != 0) {
     90            if (stat(filename, &statbuf) != 0) {
    10091                bb_perror_msg("%s", filename);
    10192                status = EXIT_FAILURE;
     
    111102    if (statbuf.st_nlink > count_hardlinks) {
    112103        /* Add files/directories with links only once */
    113         if (is_in_ino_dev_hashtable(&statbuf, NULL)) {
     104        if (is_in_ino_dev_hashtable(&statbuf)) {
    114105            return 0;
    115106        }
     
    122113        char *newfile;
    123114
    124         dir = bb_opendir(filename);
     115        dir = warn_opendir(filename);
    125116        if (!dir) {
    126117            status = EXIT_FAILURE;
     
    136127
    137128            newfile = concat_subpath_file(filename, name);
    138             if(newfile == NULL)
     129            if (newfile == NULL)
    139130                continue;
    140131            ++du_depth;
     
    153144}
    154145
     146int du_main(int argc, char **argv);
    155147int du_main(int argc, char **argv)
    156148{
     
    159151    int print_final_total;
    160152    char *smax_print_depth;
    161     unsigned long opt;
    162 
    163 #ifdef CONFIG_FEATURE_DU_DEFUALT_BLOCKSIZE_1K
     153    unsigned opt;
     154
     155#if ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
    164156    if (getenv("POSIXLY_CORRECT")) {    /* TODO - a new libbb function? */
    165 #ifdef CONFIG_FEATURE_HUMAN_READABLE
     157#if ENABLE_FEATURE_HUMAN_READABLE
    166158        disp_hr = 512;
    167159#else
     
    171163#endif
    172164
    173     /* Note: SUSv3 specifies that -a and -s options can not be used together
     165    /* Note: SUSv3 specifies that -a and -s options cannot be used together
    174166     * in strictly conforming applications.  However, it also says that some
    175167     * du implementations may produce output when -a and -s are used together.
     
    177169     * ignore -a.  This is consistent with -s being equivalent to -d 0.
    178170     */
    179 #ifdef CONFIG_FEATURE_HUMAN_READABLE
    180     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)) {
    183175        /* -h opt */
    184176        disp_hr = 0;
    185177    }
    186     if((opt & (1 << 10))) {
     178    if (opt & (1 << 10)) {
    187179        /* -m opt */
    188         disp_hr = MEGABYTE;
    189     }
    190     if((opt & (1 << 2))) {
     180        disp_hr = 1024*1024;
     181    }
     182    if (opt & (1 << 2)) {
    191183        /* -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_1K
    198     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)) {
    199191        /* -k opt */
    200             disp_k = 1;
    201     }
    202 #endif
    203 #endif
    204     if((opt & (1 << 0))) {
     192        disp_k = 1;
     193    }
     194#endif
     195#endif
     196    if (opt & (1 << 0)) {
    205197        /* -a opt */
    206198        print_files = INT_MAX;
    207199    }
    208     if((opt & (1 << 1))) {
     200    if (opt & (1 << 1)) {
    209201        /* -H opt */
    210202        slink_depth = 1;
    211203    }
    212     if((opt & (1 << 3))) {
     204    if (opt & (1 << 3)) {
    213205        /* -L opt */
    214             slink_depth = INT_MAX;
    215     }
    216     if((opt & (1 << 4))) {
     206        slink_depth = INT_MAX;
     207    }
     208    if (opt & (1 << 4)) {
    217209        /* -s opt */
    218             max_print_depth = 0;
    219         }
     210        max_print_depth = 0;
     211    }
    220212    one_file_system = opt & (1 << 5); /* -x opt */
    221     if((opt & (1 << 6))) {
     213    if (opt & (1 << 6)) {
    222214        /* -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)) {
    226218        /* -l opt */
    227         count_hardlinks = INT_MAX;
     219        count_hardlinks = MAXINT(nlink_t);
    228220    }
    229221    print_final_total = opt & (1 << 8); /* -c opt */
     
    232224    argv += optind;
    233225    if (optind >= argc) {
    234         *--argv = ".";
     226        *--argv = (char*)".";
    235227        if (slink_depth == 1) {
    236228            slink_depth = 0;
     
    244236        slink_depth = slink_depth_save;
    245237    } 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();
    250240    if (print_final_total) {
    251241        print(total, "total");
    252242    }
    253243
    254     bb_fflush_stdout_and_exit(status);
     244    fflush_stdout_and_exit(status);
    255245}
  • branches/stable/mindi-busybox/coreutils/echo.c

    r821 r1770  
    2121 *     trailing newline.  SUSv3 specifies _no_ output after '\c'.
    2222 * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}.
    23  *    The previous version version did not allow 4-digit octals.
     23 *    The previous version did not allow 4-digit octals.
    2424 */
    2525
     26#include "libbb.h"
    2627
    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)
     28int bb_echo(char **argv)
    3329{
    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;
    3739#else
    3840    const char *p;
    39     int nflag = 1;
    40     int eflag = 0;
     41    char nflag = 1;
     42    char eflag = 0;
    4143
    42     while (*++argv && (**argv == '-')) {
     44    while (1) {
     45        arg = *++argv;
     46        if (!arg)
     47            goto newline_ret;
     48        if (*arg != '-')
     49            break;
     50
    4351        /* If it appears that we are handling options, then make sure
    4452         * that all of the options specified are actually valid.
    4553         * Otherwise, the string should just be echoed.
    4654         */
    47 
    48         if (!*(p = *argv + 1)) {    /* A single '-', so echo it. */
     55        p = arg + 1;
     56        if (!*p)    /* A single '-', so echo it. */
    4957            goto just_echo;
    50         }
    5158
    5259        do {
    53             if (strrchr("neE", *p) == 0) {
     60            if (!strrchr("neE", *p))
    5461                goto just_echo;
    55             }
    5662        } while (*++p);
    5763
    5864        /* All of the options in this arg are valid, so handle them. */
    59         p = *argv + 1;
     65        p = arg + 1;
    6066        do {
    61             if (*p == 'n') {
     67            if (*p == 'n')
    6268                nflag = 0;
    63             } else if (*p == 'e') {
     69            if (*p == 'e')
    6470                eflag = '\\';
    65             } else {
    66                 eflag = 0;
    67             }
    6871        } while (*++p);
    6972    }
     73 just_echo:
     74#endif
     75    while (1) {
     76        /* arg is already == *argv and isn't NULL */
     77        int c;
    7078
    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++)) {
    7783            if (c == eflag) {   /* Check for escape seq. */
    78                 if (**argv == 'c') {
     84                if (*arg == 'c') {
    7985                    /* '\c' means cancel newline and
    8086                     * ignore all subsequent chars. */
    81                     return 0;
     87                    goto ret;
    8288                }
    83 #ifndef CONFIG_FEATURE_FANCY_ECHO
     89#if !ENABLE_FEATURE_FANCY_ECHO
    8490                /* SUSv3 specifies that octal escapes must begin with '0'. */
    85                 if (((unsigned int)(**argv - '1')) >= 7)
     91                if ( (((unsigned char)*arg) - '1') >= 7)
    8692#endif
    8793                {
    8894                    /* Since SUSv3 mandates a first digit of 0, 4-digit octals
    8995                    * 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++;
    9298                    }
    9399                    /* bb_process_escape_sequence can handle nul correctly */
    94                     c = bb_process_escape_sequence((const char **) argv);
     100                    c = bb_process_escape_sequence(&arg);
    95101                }
    96102            }
     
    98104        }
    99105
    100         if (*++argv) {
    101             putchar(' ');
    102         }
     106        arg = *++argv;
     107        if (!arg)
     108            break;
     109        putchar(' ');
    103110    }
    104111
    105 #ifdef CONFIG_FEATURE_FANCY_ECHO
     112 newline_ret:
    106113    if (nflag) {
    107114        putchar('\n');
    108115    }
    109 #else
    110     putchar('\n');
    111 #endif
    112     return 0;
     116 ret:
     117    return fflush(stdout);
    113118}
    114119
     120/* This is a NOFORK applet. Be very careful! */
     121
     122int echo_main(int argc, char** argv);
    115123int echo_main(int argc, char** argv)
    116124{
    117     (void)bb_echo(argc, argv);
    118     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     125    return bb_echo(argv);
    119126}
    120127
  • branches/stable/mindi-busybox/coreutils/env.c

    r821 r1770  
    66 *  The Regents of the University of California.  All rights reserved.
    77 *
    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.
    219 *
    2210 * Original copyright notice is retained at the end of this file.
     
    3927 * - multiple "-u unsetenv" support
    4028 * - GNU long option support
    41  * - use bb_default_error_retval
     29 * - use xfunc_error_retval
    4230 */
    4331
     32#include <getopt.h> /* struct option */
     33extern char **environ;
    4434
    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"
    5236
    5337#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 };
     38static const char env_longopts[] ALIGN1 =
     39    "ignore-environment\0" No_argument       "i"
     40    "unset\0"              Required_argument "u"
     41    ;
    5942#endif
    6043
     44int env_main(int argc, char** argv);
    6145int env_main(int argc, char** argv)
    6246{
    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;
    6452
    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::";
    7154#if ENABLE_FEATURE_ENV_LONG_OPTIONS
    72     bb_applet_long_options = env_long_options;
     55    applet_long_options = env_longopts;
    7356#endif
    74 
    75     opt = bb_getopt_ulflags(argc, argv, "+iu:", &unset_env);
    76 
     57    opt = getopt32(argv, "+iu:", &unset_env);
    7758    argv += optind;
    78     if (*argv && (argv[0][0] == '-') && !argv[0][1]) {
     59    if (*argv && LONE_DASH(argv[0])) {
    7960        opt |= 1;
    8061        ++argv;
    8162    }
    82 
    83     if(opt & 1)
     63    if (opt & 1) {
     64        cleanenv[0] = NULL;
    8465        environ = cleanenv;
    85     else if(opt & 2) {
    86         while(unset_env) {
     66    } else {
     67        while (unset_env) {
    8768            unsetenv(unset_env->data);
    8869            unset_env = unset_env->link;
     
    9071    }
    9172
    92     while (*argv && ((p = strchr(*argv, '=')) != NULL)) {
     73    while (*argv && (strchr(*argv, '=') != NULL)) {
    9374        if (putenv(*argv) < 0) {
    9475            bb_perror_msg_and_die("putenv");
     
    9879
    9980    if (*argv) {
    100         execvp(*argv, argv);
     81        BB_EXECVP(*argv, argv);
    10182        /* SUSv3-mandated exit codes. */
    102         bb_default_error_retval = (errno == ENOENT) ? 127 : 126;
     83        xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
    10384        bb_perror_msg_and_die("%s", *argv);
    10485    }
     
    10889    }
    10990
    110     bb_fflush_stdout_and_exit(0);
     91    fflush_stdout_and_exit(0);
    11192}
    11293
  • branches/stable/mindi-busybox/coreutils/expr.c

    r821 r1770  
    1212 *  - 64 math support
    1313 *
    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.
    2815 */
    2916
     
    3926/* no getopt needed */
    4027
    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"
    4930
    5031/* The kinds of value we can have.  */
     
    5738#if ENABLE_EXPR_MATH_SUPPORT_64
    5839typedef int64_t arith_t;
     40
    5941#define PF_REZ      "ll"
    6042#define PF_REZ_TYPE (long long)
     
    6244#else
    6345typedef long arith_t;
     46
    6447#define PF_REZ      "l"
    6548#define PF_REZ_TYPE (long)
     
    6750#endif
    6851
     52/* TODO: use bb_strtol[l]? It's easier to check for errors... */
     53
    6954/* A value is.... */
    7055struct valinfo {
    71     TYPE type;                      /* Which kind. */
    72     union {                         /* The value itself. */
     56    TYPE type;          /* Which kind. */
     57    union {             /* The value itself. */
    7358        arith_t i;
    7459        char *s;
     
    7863
    7964/* 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)
     65struct globals {
     66    char **args;
     67};
     68#define G (*(struct globals*)&bb_common_bufsiz1)
     69
     70/* forward declarations */
     71static VALUE *eval(void);
     72
     73
     74/* Return a VALUE for I.  */
     75
     76static VALUE *int_value(arith_t i)
    9377{
    9478    VALUE *v;
    9579
    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));
    12181    v->type = integer;
    12282    v->u.i = i;
     
    12686/* Return a VALUE for S.  */
    12787
    128 static VALUE *str_value (char *s)
     88static VALUE *str_value(const char *s)
    12989{
    13090    VALUE *v;
    13191
    132     v = xmalloc (sizeof(VALUE));
     92    v = xmalloc(sizeof(VALUE));
    13393    v->type = string;
    134     v->u.s = bb_xstrdup (s);
     94    v->u.s = xstrdup(s);
    13595    return v;
    13696}
     
    13898/* Free VALUE V, including structure components.  */
    13999
    140 static void freev (VALUE *v)
     100static void freev(VALUE * v)
    141101{
    142102    if (v->type == string)
    143         free (v->u.s);
    144     free (v);
     103        free(v->u.s);
     104    free(v);
    145105}
    146106
    147107/* Return nonzero if V is a null-string or zero-number.  */
    148108
    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     }
     109static 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');
    157115}
    158116
    159117/* Coerce V to a string value (can't fail).  */
    160118
    161 static void tostring (VALUE *v)
     119static void tostring(VALUE * v)
    162120{
    163121    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);
    165123        v->type = string;
    166124    }
     
    169127/* Coerce V to an integer value.  Return 1 on success, 0 on failure.  */
    170128
    171 static int toarith (VALUE *v)
    172 {
    173     if(v->type == string) {
     129static bool toarith(VALUE * v)
     130{
     131    if (v->type == string) {
    174132        arith_t i;
    175133        char *e;
     
    180138        if ((v->u.s == e) || *e)
    181139            return 0;
    182         free (v->u.s);
     140        free(v->u.s);
    183141        v->u.i = i;
    184142        v->type = integer;
     
    190148   STR must not be NULL.  */
    191149
    192 static int
    193 nextarg (char *str)
    194 {
    195     if (*args == NULL)
     150static bool nextarg(const char *str)
     151{
     152    if (*G.args == NULL)
    196153        return 0;
    197     return strcmp (*args, str) == 0;
     154    return strcmp(*G.args, str) == 0;
    198155}
    199156
    200157/* The comparison operator handling functions.  */
    201158
    202 static int cmp_common (VALUE *l, VALUE *r, int op)
     159static int cmp_common(VALUE * l, VALUE * r, int op)
    203160{
    204161    int cmpval;
    205162
    206163    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
     185static 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;
    211203    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:
    251204        return li % ri;
    252   }
    253205}
    254206
     
    257209   PV is the VALUE for the rhs (the pattern).  */
    258210
    259 static VALUE *docolon (VALUE *sv, VALUE *pv)
     211static VALUE *docolon(VALUE * sv, VALUE * pv)
    260212{
    261213    VALUE *v;
     
    264216    regmatch_t re_regs[NMATCH];
    265217
    266     tostring (sv);
    267     tostring (pv);
     218    tostring(sv);
     219    tostring(pv);
    268220
    269221    if (pv->u.s[0] == '^') {
    270         fprintf (stderr, "\
     222        bb_error_msg("\
    271223warning: 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");
     224of 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);
    280230
    281231    /* expr uses an anchored pattern match, so check that there was a
    282232     * match and that the match starts at offset 0. */
    283     if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
    284             re_regs[0].rm_so == 0) {
     233    if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
     234        re_regs[0].rm_so == 0) {
    285235        /* Were \(...\) used? */
    286236        if (re_buffer.re_nsub > 0) {
    287237            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 {
    294242        /* Match failed -- return the right kind of null.  */
    295243        if (re_buffer.re_nsub > 0)
    296             v = str_value ("");
     244            v = str_value("");
    297245        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);
    300249    return v;
    301250}
     
    303252/* Handle bare operands and ( expr ) syntax.  */
    304253
    305 static VALUE *eval7 (void)
     254static VALUE *eval7(void)
    306255{
    307256    VALUE *v;
    308257
    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
     278static 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);
    319332        }
    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
    391339}
    392340
     
    394342   Calls docolon to do the real work.  */
    395343
    396 static VALUE *eval5 (void)
     344static VALUE *eval5(void)
    397345{
    398346    VALUE *l, *r, *v;
    399347
    400     l = eval6 ();
    401     while (nextarg (":")) {
    402         args++;
    403         r = eval6 ();
    404         v = docolon (l, r);
    405         freev (l);
    406         freev (r);
     348    l = eval6();
     349    while (nextarg(":")) {
     350        G.args++;
     351        r = eval6();
     352        v = docolon(l, r);
     353        freev(l);
     354        freev(r);
    407355        l = v;
    408356    }
     
    412360/* Handle *, /, % operators.  */
    413361
    414 static VALUE *eval4 (void)
     362static VALUE *eval4(void)
    415363{
    416364    VALUE *l, *r;
     
    418366    arith_t val;
    419367
    420     l = eval5 ();
     368    l = eval5();
    421369    while (1) {
    422         if (nextarg ("*"))
     370        if (nextarg("*"))
    423371            op = '*';
    424         else if (nextarg ("/"))
     372        else if (nextarg("/"))
    425373            op = '/';
    426         else if (nextarg ("%"))
     374        else if (nextarg("%"))
    427375            op = '%';
    428376        else
    429377            return l;
    430         args++;
    431         r = eval5 ();
    432         val = arithmetic_common (l, r, op);
    433         freev (l);
    434         freev (r);
    435         l = int_value (val);
     378        G.args++;
     379        r = eval5();
     380        val = arithmetic_common(l, r, op);
     381        freev(l);
     382        freev(r);
     383        l = int_value(val);
    436384    }
    437385}
     
    439387/* Handle +, - operators.  */
    440388
    441 static VALUE *eval3 (void)
     389static VALUE *eval3(void)
    442390{
    443391    VALUE *l, *r;
     
    445393    arith_t val;
    446394
    447     l = eval4 ();
     395    l = eval4();
    448396    while (1) {
    449         if (nextarg ("+"))
     397        if (nextarg("+"))
    450398            op = '+';
    451         else if (nextarg ("-"))
     399        else if (nextarg("-"))
    452400            op = '-';
    453401        else
    454402            return l;
    455         args++;
    456         r = eval4 ();
    457         val = arithmetic_common (l, r, op);
    458         freev (l);
    459         freev (r);
    460         l = int_value (val);
     403        G.args++;
     404        r = eval4();
     405        val = arithmetic_common(l, r, op);
     406        freev(l);
     407        freev(r);
     408        l = int_value(val);
    461409    }
    462410}
     
    464412/* Handle comparisons.  */
    465413
    466 static VALUE *eval2 (void)
     414static VALUE *eval2(void)
    467415{
    468416    VALUE *l, *r;
     
    470418    arith_t val;
    471419
    472     l = eval3 ();
     420    l = eval3();
    473421    while (1) {
    474         if (nextarg ("<"))
     422        if (nextarg("<"))
    475423            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("=="))
    479427            op = '=';
    480         else if (nextarg ("!="))
     428        else if (nextarg("!="))
    481429            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(">"))
    485433            op = '>';
    486434        else
    487435            return l;
    488         args++;
    489         r = eval3 ();
    490         toarith (l);
    491         toarith (r);
    492         val = cmp_common (l, r, op);
    493         freev (l);
    494         freev (r);
    495         l = int_value (val);
     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);
    496444    }
    497445}
     
    499447/* Handle &.  */
    500448
    501 static VALUE *eval1 (void)
     449static VALUE *eval1(void)
    502450{
    503451    VALUE *l, *r;
    504452
    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);
    516463    }
    517464    return l;
     
    520467/* Handle |.  */
    521468
    522 static VALUE *eval (void)
     469static VALUE *eval(void)
    523470{
    524471    VALUE *l, *r;
    525472
    526     l = eval1 ();
    527     while (nextarg ("|")) {
    528         args++;
    529         r = eval1 ();
    530         if (null (l)) {
    531             freev (l);
     473    l = eval1();
     474    while (nextarg("|")) {
     475        G.args++;
     476        r = eval1();
     477        if (null(l)) {
     478            freev(l);
    532479            l = r;
    533         }
    534         else
    535             freev (r);
     480        } else
     481            freev(r);
    536482    }
    537483    return l;
    538484}
     485
     486int expr_main(int argc, char **argv);
     487int 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/stable/mindi-busybox/coreutils/false.c

    r821 r1770  
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/false.html */
    1212
    13 #include <stdlib.h>
    14 #include "busybox.h"
     13#include "libbb.h"
    1514
     15/* This is a NOFORK applet. Be very careful! */
     16
     17int false_main(int ATTRIBUTE_UNUSED argc, char ATTRIBUTE_UNUSED **argv);
    1618int false_main(int ATTRIBUTE_UNUSED argc, char ATTRIBUTE_UNUSED **argv)
    1719{
  • branches/stable/mindi-busybox/coreutils/fold.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/* fold -- wrap each input line to fit in specified width.
    23
     
    1011*/
    1112
    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"
    2014
    2115static unsigned long flags;
     
    4539}
    4640
     41int fold_main(int argc, char **argv);
    4742int fold_main(int argc, char **argv)
    4843{
     44    char *line_out = NULL;
     45    int allocated_out = 0;
    4946    char *w_opt;
    5047    int width = 80;
     
    5249    int errs = 0;
    5350
    54     if(!ENABLE_DEBUG_YANK_SUSv2) {
     51    if (ENABLE_INCLUDE_SUSv2) {
    5552        /* Turn any numeric options into -w options.  */
    5653        for (i = 1; i < argc; i++) {
     
    6158                    break;
    6259                if (isdigit(*a)) {
    63                     argv[i] = bb_xasprintf("-w%s", a);
     60                    argv[i] = xasprintf("-w%s", a);
    6461                }
    6562            }
     
    6764    }
    6865
    69     flags = bb_getopt_ulflags(argc, argv, "bsw:", &w_opt);
     66    flags = getopt32(argv, "bsw:", &w_opt);
    7067    if (flags & FLAG_WIDTH)
    71         width = bb_xgetlarg(w_opt, 10, 1, 10000);
     68        width = xatoul_range(w_opt, 1, 10000);
    7269
    7370    argv += optind;
    7471    if (!*argv) {
    75         *--argv = "-";
     72        *--argv = (char*)"-";
    7673    }
    7774
    7875    do {
    79         FILE *istream = bb_wfopen_input(*argv);
     76        FILE *istream = fopen_or_warn_stdin(*argv);
    8077        int c;
    8178        int column = 0;     /* Screen column where next char will go. */
    8279        int offset_out = 0; /* Index in `line_out' for next char. */
    83         static char *line_out = NULL;
    84         static int allocated_out = 0;
    8580
    8681        if (istream == NULL) {
     
    10196                continue;
    10297            }
    103 
    104 rescan:
     98 rescan:
    10599            column = adjust_column(column, c);
    106100
     
    151145        }
    152146
    153         if (ferror(istream) || bb_fclose_nonstdin(istream)) {
     147        if (ferror(istream) || fclose_if_not_stdin(istream)) {
    154148            bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */
    155149            errs |= EXIT_FAILURE;
     
    157151    } while (*++argv);
    158152
    159     bb_fflush_stdout_and_exit(errs);
     153    fflush_stdout_and_exit(errs);
    160154}
    161 /* vi: set sw=4 ts=4: */
  • branches/stable/mindi-busybox/coreutils/head.c

    r821 r1770  
    1212/* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */
    1313
    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"
    2015
    21 static const char head_opts[] =
     16static const char head_opts[] ALIGN1 =
    2217    "n:"
    2318#if ENABLE_FEATURE_FANCY_HEAD
     
    3126    { "k", 1024 },
    3227    { "m", 1024*1024 },
    33     { NULL, 0 }
     28    { }
    3429};
    3530#endif
    36                                        
    37 static const char header_fmt_str[] = "\n==> %s <==\n";
    3831
     32static const char header_fmt_str[] ALIGN1 = "\n==> %s <==\n";
     33
     34int head_main(int argc, char **argv);
    3935int head_main(int argc, char **argv)
    4036{
     
    5349    int retval = EXIT_SUCCESS;
    5450
    55 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
     51#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
    5652    /* 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])
    6055    ) {
    6156        --argc;
     
    6661#endif
    6762
    68     /* No size benefit in converting this to bb_getopt_ulflags */
     63    /* No size benefit in converting this to getopt32 */
    6964    while ((opt = getopt(argc, argv, head_opts)) > 0) {
    70         switch(opt) {
     65        switch (opt) {
    7166#if ENABLE_FEATURE_FANCY_HEAD
    72             case 'q':
    73                 header_threshhold = INT_MAX;
    74                 break;
    75             case 'v':
    76                 header_threshhold = -1;
    77                 break;
    78             case 'c':
    79                 count_bytes = 1;
    80                 /* fall through */
     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 */
    8176#endif
    82             case 'n':
    83                 p = optarg;
    84 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
    85             GET_COUNT:
     77        case 'n':
     78            p = optarg;
     79#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_HEAD
     80 GET_COUNT:
    8681#endif
    8782
    8883#if !ENABLE_FEATURE_FANCY_HEAD
    89                 count = bb_xgetularg10(p);
     84            count = xatoul(p);
    9085#else
    91                 count = bb_xgetularg_bnd_sfx(p, 10,
    92                                 0, ULONG_MAX,
    93                                 head_suffixes);
     86            count = xatoul_sfx(p, head_suffixes);
    9487#endif
    95                 break;
    96             default:
    97                 bb_show_usage();
     88            break;
     89        default:
     90            bb_show_usage();
    9891        }
    9992    }
     
    10194    argv += optind;
    10295    if (!*argv) {
    103         *--argv = "-";
     96        *--argv = (char*)"-";
    10497    }
    10598
     
    120113
    121114    do {
    122         if ((fp = bb_wfopen_input(*argv)) != NULL) {
     115        fp = fopen_or_warn_stdin(*argv);
     116        if (fp) {
    123117            if (fp == stdin) {
    124118                *argv = (char *) bb_msg_standard_input;
    125119            }
    126120            if (header_threshhold) {
    127                 bb_printf(fmt, *argv);
     121                printf(fmt, *argv);
    128122            }
    129123            i = count;
     
    134128                putchar(c);
    135129            }
    136             if (bb_fclose_nonstdin(fp)) {
     130            if (fclose_if_not_stdin(fp)) {
    137131                bb_perror_msg("%s", *argv); /* Avoid multibyte problems. */
    138132                retval = EXIT_FAILURE;
    139133            }
    140             bb_xferror_stdout();
     134            die_if_ferror_stdout();
    141135        }
    142136        fmt = header_fmt_str;
    143137    } while (*++argv);
    144138
    145     bb_fflush_stdout_and_exit(retval);
     139    fflush_stdout_and_exit(retval);
    146140}
  • branches/stable/mindi-busybox/coreutils/hostid.c

    r821 r1770  
    1010/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
    1111
    12 #include <stdlib.h>
    13 #include <unistd.h>
    14 #include "busybox.h"
     12#include "libbb.h"
    1513
     14/* This is a NOFORK applet. Be very careful! */
     15
     16int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv);
    1617int hostid_main(int argc, char ATTRIBUTE_UNUSED **argv)
    1718{
     
    2021    }
    2122
    22     bb_printf("%lx\n", gethostid());
     23    printf("%lx\n", gethostid());
    2324
    24     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     25    return fflush(stdout);
    2526}
  • branches/stable/mindi-busybox/coreutils/id.c

    r821 r1770  
    1111/* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
    1212 * be more similar to GNU id.
     13 * -Z option support: by Yuichi Nakamura <ynakam@hitachisoft.jp>
    1314 */
    1415
    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"
    2417
    2518#define PRINT_REAL        1
     
    2720#define JUST_USER         4
    2821#define JUST_GROUP        8
     22#if ENABLE_SELINUX
     23#define JUST_CONTEXT     16
     24#endif
    2925
    30 static short printf_full(unsigned int id, const char *arg, const char prefix)
     26static int printf_full(unsigned int id, const char *arg, const char prefix)
    3127{
    3228    const char *fmt = "%cid=%u";
    33     short status=EXIT_FAILURE;
     29    int status = EXIT_FAILURE;
    3430
    35     if(arg) {
     31    if (arg) {
    3632        fmt = "%cid=%u(%s)";
    37         status=EXIT_SUCCESS;
     33        status = EXIT_SUCCESS;
    3834    }
    39     bb_printf(fmt, prefix, id, arg);
     35    printf(fmt, prefix, id, arg);
    4036    return status;
    4137}
    4238
     39int id_main(int argc, char **argv);
    4340int id_main(int argc, char **argv)
    4441{
     
    4845    unsigned long flags;
    4946    short status;
    50 
     47#if ENABLE_SELINUX
     48    security_context_t scontext;
     49#endif
    5150    /* Don't allow -n -r -nr -ug -rug -nug -rnug */
    5251    /* 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"));
    5554
    5655    /* This values could be overwritten later */
     
    6261    }
    6362
    64     if(argv[optind]) {
    65         p=getpwnam(argv[optind]);
    66         /* bb_xgetpwnam is 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]);
    6867        gid = p->pw_gid;
    6968        /* in this case PRINT_REAL is the same */
    7069    }
    7170
    72     if(flags & (JUST_GROUP | JUST_USER)) {
     71    if (flags & (JUST_GROUP | JUST_USER USE_SELINUX(| JUST_CONTEXT))) {
    7372        /* JUST_GROUP and JUST_USER are mutually exclusive */
    74         if(flags & NAME_NOT_NUMBER) {
    75             /* bb_getpwuid and bb_getgrgid exit on failure so puts 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));
    7776        } 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            }
    7983        }
     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
    8098        /* exit */
    81         bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     99        fflush_stdout_and_exit(EXIT_SUCCESS);
    82100    }
    83101
    84102    /* 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');
    87105    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');
    90107
    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;
    96112
    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);
    107121    }
    108122#endif
    109123
    110124    putchar('\n');
    111     bb_fflush_stdout_and_exit(status);
     125    fflush_stdout_and_exit(status);
    112126}
  • branches/stable/mindi-busybox/coreutils/install.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    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>
    35 *
    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.
    187 *
    198 * TODO: -d option, need a way of recursively making directories and changing
     
    2110 */
    2211
    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>
    2913#include <getopt.h> /* struct option */
    3014
    31 #include "busybox.h"
     15#include "libbb.h"
    3216#include "libcoreutils/coreutils.h"
    3317
    34 #define INSTALL_OPT_CMD 1
    35 #define INSTALL_OPT_DIRECTORY   2
    36 #define INSTALL_OPT_PRESERVE_TIME   4
    37 #define INSTALL_OPT_STRIP   8
    38 #define INSTALL_OPT_GROUP  16
    39 #define INSTALL_OPT_MODE  32
    40 #define INSTALL_OPT_OWNER  64
    41 
    4218#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 
     19static 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
     38static 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
     69int install_main(int argc, char **argv);
    5470int install_main(int argc, char **argv)
    5571{
     72    struct stat statbuf;
    5673    mode_t mode;
    5774    uid_t uid;
    5875    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;
    6280    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    };
    64103
    65104#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
    71129
    72130    /* 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) {
    74132        copy_flags |= FILEUTILS_PRESERVE_STATUS;
    75133    }
    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);
    80141
    81142    /* Create directories
    82      * dont use bb_make_directory() as it cant change uid or gid
     143     * don't use bb_make_directory() as it can't change uid or gid
    83144     * perhaps bb_make_directory() should be improved.
    84145     */
    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) {
    97154                    if (errno != EEXIST) {
    98                         bb_perror_msg("coulnt create %s", *argv);
     155                        bb_perror_msg("cannot create %s", arg);
    99156                        ret = EXIT_FAILURE;
    100157                        break;
    101158                    }
    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);
    105164                    ret = EXIT_FAILURE;
    106165                    break;
    107166                }
    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        }
    127192
    128193        /* Set the file mode */
    129         if (chmod(dest, mode) == -1) {
     194        if ((flags & OPT_MODE) && chmod(dest, mode) == -1) {
    130195            bb_perror_msg("cannot change permissions of %s", dest);
    131196            ret = EXIT_FAILURE;
    132197        }
    133 
     198#if ENABLE_SELINUX
     199        if (use_default_selinux_context)
     200            setdefaultfilecon(dest);
     201#endif
    134202        /* 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        ) {
    136206            bb_perror_msg("cannot change ownership of %s", dest);
    137207            ret = EXIT_FAILURE;
    138208        }
    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");
    142216                ret = EXIT_FAILURE;
    143217            }
    144218        }
    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;
    149225}
  • branches/stable/mindi-busybox/coreutils/length.c

    r821 r1770  
    33/* BB_AUDIT SUSv3 N/A -- Apparently a busybox (obsolete?) extension. */
    44
    5 #include <stdlib.h>
    6 #include <string.h>
    7 #include <stdio.h>
    8 #include "busybox.h"
     5#include "libbb.h"
    96
     7/* This is a NOFORK applet. Be very careful! */
     8
     9int length_main(int argc, char **argv);
    1010int length_main(int argc, char **argv)
    1111{
    12     if ((argc != 2) ||  (**(++argv) == '-')) {
    13         bb_show_usage();
     12    if ((argc != 2) || (**(++argv) == '-')) {
     13        bb_show_usage();
    1414    }
    1515
    16     bb_printf("%lu\n", (unsigned long)strlen(*argv));
     16    printf("%u\n", (unsigned)strlen(*argv));
    1717
    18     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     18    return fflush(stdout);
    1919}
  • branches/stable/mindi-busybox/coreutils/libcoreutils/coreutils.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     
    89typedef int (*stat_func)(const char *fn, struct stat *ps);
    910
    10 extern int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf);
    11 extern int cp_mv_stat(const char *fn, struct stat *fn_stat);
     11int cp_mv_stat2(const char *fn, struct stat *fn_stat, stat_func sf);
     12int cp_mv_stat(const char *fn, struct stat *fn_stat);
    1213
    13 extern mode_t getopt_mk_fifo_nod(int argc, char **argv);
     14mode_t getopt_mk_fifo_nod(int argc, char **argv);
    1415
    1516#endif
  • branches/stable/mindi-busybox/coreutils/libcoreutils/cp_mv_stat.c

    r821 r1770  
    2121 */
    2222
    23 #include <errno.h>
    24 #include <sys/stat.h>
    2523#include "libbb.h"
    2624#include "coreutils.h"
     
    3028    if (sf(fn, fn_stat) < 0) {
    3129        if (errno != ENOENT) {
    32             bb_perror_msg("unable to stat `%s'", fn);
     30            bb_perror_msg("cannot stat '%s'", fn);
    3331            return -1;
    3432        }
  • branches/stable/mindi-busybox/coreutils/libcoreutils/getopt_mk_fifo_nod.c

    r821 r1770  
    2121 */
    2222
    23 #include <sys/types.h>
    24 #include <sys/stat.h>
    25 #include <unistd.h>
    2623#include "libbb.h"
    2724#include "coreutils.h"
     
    3128    mode_t mode = 0666;
    3229    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) {
    3636        if (bb_parse_mode(smode, &mode))
    3737            umask(0);
    3838    }
     39
     40#if ENABLE_SELINUX
     41    if (opt & 2) {
     42        selinux_or_die();
     43        setfscreatecon_or_die(scontext);
     44    }
     45#endif
     46
    3947    return mode;
    4048}
  • branches/stable/mindi-busybox/coreutils/ln.c

    r821 r1770  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2512/* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
    2613
    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
    3218
    3319#define LN_SYMLINK          1
     
    3723#define LN_SUFFIX           16
    3824
     25int ln_main(int argc, char **argv);
    3926int ln_main(int argc, char **argv)
    4027{
     
    4431    char *src_name;
    4532    char *src;
    46     char *suffix = "~";
     33    char *suffix = (char*)"~";
    4734    struct stat statbuf;
    4835    int (*link_func)(const char *, const char *);
    4936
    50     flag = bb_getopt_ulflags(argc, argv, "sfnbS:", &suffix);
     37    flag = getopt32(argv, "sfnbS:", &suffix);
    5138
    5239    if (argc == optind) {
     
    5946    if (argc == optind + 1) {
    6047        *--argv = last;
    61         last = bb_get_last_path_component(bb_xstrdup(last));
     48        last = bb_get_last_path_component(xstrdup(last));
    6249    }
    6350
     
    6754
    6855        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);
    7260            src = concat_path_file(src, bb_get_last_path_component(src_name));
    7361            free(src_name);
     
    7563        }
    7664        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            }
    8172        }
    8273
    8374        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;
    9280                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);
    9990        } else if (flag & LN_FORCE) {
    10091            unlink(src);
  • branches/stable/mindi-busybox/coreutils/logname.c

    r821 r1770  
    2121 */
    2222
    23 #include <stdio.h>
    24 #include <stdlib.h>
    25 #include <unistd.h>
    26 #include "busybox.h"
     23#include "libbb.h"
    2724
     25/* This is a NOFORK applet. Be very careful! */
     26
     27int logname_main(int argc, char ATTRIBUTE_UNUSED **argv);
    2828int logname_main(int argc, char ATTRIBUTE_UNUSED **argv)
    2929{
    30     const char *p;
     30    char buf[128];
    3131
    3232    if (argc > 1) {
     
    3434    }
    3535
    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);
    3940    }
    4041
  • branches/stable/mindi-busybox/coreutils/ls.c

    r821 r1770  
    3030 */
    3131
     32#include <getopt.h>
     33#include "libbb.h"
     34
     35/* This is a NOEXEC applet. Be very careful! */
     36
     37
    3238enum {
    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
     40TERMINAL_WIDTH  = 80,           /* use 79 if terminal has linefold bug */
     41COLUMN_GAP      = 2,            /* includes the file type char */
    4942
    5043/* 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
     44STYLE_COLUMNS   = 1 << 21,      /* fill columns */
     45STYLE_LONG      = 2 << 21,      /* one record per line, extended info */
     46STYLE_SINGLE    = 3 << 21,      /* one record per line */
     47STYLE_MASK      = STYLE_SINGLE,
    5748
    5849/* 51306 lrwxrwxrwx  1 root     root         2 May 11 01:43 /bin/view -> vi* */
    5950/* 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)
     51LIST_INO        = 1 << 0,
     52LIST_BLOCKS     = 1 << 1,
     53LIST_MODEBITS   = 1 << 2,
     54LIST_NLINKS     = 1 << 3,
     55LIST_ID_NAME    = 1 << 4,
     56LIST_ID_NUMERIC = 1 << 5,
     57LIST_CONTEXT    = 1 << 6,
     58LIST_SIZE       = 1 << 7,
     59LIST_DEV        = 1 << 8,
     60LIST_DATE_TIME  = 1 << 9,
     61LIST_FULLTIME   = 1 << 10,
     62LIST_FILENAME   = 1 << 11,
     63LIST_SYMLINK    = 1 << 12,
     64LIST_FILETYPE   = 1 << 13,
     65LIST_EXEC       = 1 << 14,
     66LIST_MASK       = (LIST_EXEC << 1) - 1,
    7767
    7868/* 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)
     69DISP_DIRNAME    = 1 << 15,      /* 2 or more items? label directories */
     70DISP_HIDDEN     = 1 << 16,      /* show filenames starting with . */
     71DISP_DOT        = 1 << 17,      /* show . and .. */
     72DISP_NOLIST     = 1 << 18,      /* show directory as itself, not contents */
     73DISP_RECURSIVE  = 1 << 19,      /* show directory and everything below it */
     74DISP_ROWS       = 1 << 20,      /* print across rows */
     75DISP_MASK       = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1),
     76
     77/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */
     78SORT_FORWARD    = 0,            /* sort in reverse order */
     79SORT_REVERSE    = 1 << 27,      /* sort in reverse order */
     80
     81SORT_NAME       = 0,            /* sort by file name */
     82SORT_SIZE       = 1 << 28,      /* sort by file size */
     83SORT_ATIME      = 2 << 28,      /* sort by last access time */
     84SORT_CTIME      = 3 << 28,      /* sort by last change time */
     85SORT_MTIME      = 4 << 28,      /* sort by last modification time */
     86SORT_VERSION    = 5 << 28,      /* sort by version */
     87SORT_EXT        = 6 << 28,      /* sort by file name extension */
     88SORT_DIR        = 7 << 28,      /* sort by file or directory */
     89SORT_MASK       = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES,
    10390
    10491/* 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
     92TIME_CHANGE     = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
     93TIME_ACCESS     = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS,
     94TIME_MASK       = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
     95
     96FOLLOW_LINKS    = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS,
     97
     98LS_DISP_HR      = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE,
     99
     100LIST_SHORT      = LIST_FILENAME,
     101LIST_LONG       = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
     102                  LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK,
     103
     104SPLIT_DIR       = 1,
     105SPLIT_FILE      = 0,
     106SPLIT_SUBDIR    = 2,
     107
     108};
    125109
    126110#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
    127111#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)])
    146113#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
    147114             "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
    148115#define ATTR(mode)  ("\00\00\01\00\01\00\01\00"\
    149116             "\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
     120static smallint show_color;
     121/* long option entry used only for --color, which has no short option
     122 * equivalent */
     123static const char ls_color_opt[] ALIGN1 =
     124    "color\0" Optional_argument "\xff" /* no short equivalent */
     125    ;
     126#else
     127enum { show_color = 0 };
    150128#endif
    151129
     
    153131 * a directory entry and its stat info are stored here
    154132 */
    155 struct dnode {          /* the basic node */
    156     char *name;     /* the dir entry name */
    157     char *fullname;     /* the dir entry name */
     133struct dnode {                  /* the basic node */
     134    const char *name;             /* the dir entry name */
     135    const char *fullname;         /* the dir entry name */
    158136    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 */
    164140};
    165141typedef struct dnode dnode_t;
     
    169145static int list_single(struct dnode *);
    170146
    171 static unsigned int all_fmt;
    172 
    173 #ifdef CONFIG_FEATURE_AUTOWIDTH
    174 static int terminal_width = TERMINAL_WIDTH;
    175 static unsigned short tabstops = COLUMN_GAP;
     147static unsigned all_fmt;
     148
     149#if ENABLE_FEATURE_AUTOWIDTH
     150static unsigned tabstops = COLUMN_GAP;
     151static unsigned terminal_width = TERMINAL_WIDTH;
    176152#else
    177 #define tabstops COLUMN_GAP
    178 #define terminal_width TERMINAL_WIDTH
     153enum {
     154    tabstops = COLUMN_GAP,
     155    terminal_width = TERMINAL_WIDTH,
     156};
    179157#endif
    180158
    181159static int status = EXIT_SUCCESS;
    182160
    183 static struct dnode *my_stat(char *fullname, char *name)
     161static struct dnode *my_stat(const char *fullname, const char *name, int force_follow)
    184162{
    185163    struct stat dstat;
    186164    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
    194169        if (is_selinux_enabled())  {
    195              getfilecon(fullname,&sid);
     170             getfilecon(fullname, &sid);
    196171        }
    197172#endif
     
    201176            return 0;
    202177        }
    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);
    209182        }
    210183#endif
     
    216189    }
    217190
    218     cur = (struct dnode *) xmalloc(sizeof(struct dnode));
     191    cur = xmalloc(sizeof(struct dnode));
    219192    cur->fullname = fullname;
    220193    cur->name = name;
    221194    cur->dstat = dstat;
    222 #ifdef CONFIG_SELINUX
    223     cur->sid = sid;
    224 #endif
     195    USE_SELINUX(cur->sid = sid;)
    225196    return cur;
    226197}
    227198
    228 /*----------------------------------------------------------------------*/
    229 #ifdef CONFIG_FEATURE_LS_COLOR
     199#if ENABLE_FEATURE_LS_COLOR
    230200static char fgcolor(mode_t mode)
    231201{
    232202    /* Check wheter the file is existing (if so, color it red!) */
    233     if (errno == ENOENT) {
     203    if (errno == ENOENT)
    234204        return '\037';
    235     }
    236205    if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
    237206        return COLOR(0xF000);   /* File is executable ... */
     
    239208}
    240209
    241 /*----------------------------------------------------------------------*/
    242210static char bgcolor(mode_t mode)
    243211{
     
    248216#endif
    249217
    250 /*----------------------------------------------------------------------*/
    251 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR)
     218#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
    252219static char append_char(mode_t mode)
    253220{
     
    264231#endif
    265232
    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)
    271235static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs)
    272236{
    273237    int i, dirs;
    274238
    275     if (dn == NULL || nfiles < 1)
    276         return (0);
     239    if (!dn)
     240        return 0;
    277241    dirs = 0;
    278242    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        ) {
    284250            dirs++;
    285     }
    286     return (dirs);
     251        }
     252    }
     253    return dirs;
    287254}
    288255
     
    293260
    294261    if (dnp == NULL)
    295         return (0);
     262        return 0;
    296263    nfiles = 0;
    297     for (cur = dnp[0]; cur->next != NULL; cur = cur->next)
     264    for (cur = dnp[0]; cur->next; cur = cur->next)
    298265        nfiles++;
    299266    nfiles++;
    300     return (nfiles);
     267    return nfiles;
    301268}
    302269
     
    304271static struct dnode **dnalloc(int num)
    305272{
    306     struct dnode **p;
    307 
    308273    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
    316280static void dfree(struct dnode **dnp, int nfiles)
    317281{
     
    323287    for (i = 0; i < nfiles; i++) {
    324288        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 */
    327291        free(cur);      /* free the dnode */
    328292    }
     
    330294}
    331295#else
    332 #define dfree(...)
     296#define dfree(...) ((void)0)
    333297#endif
    334298
     
    339303
    340304    if (dn == NULL || nfiles < 1)
    341         return (NULL);
     305        return NULL;
    342306
    343307    /* count how many dirs and regular files there are */
     
    356320    for (d = i = 0; i < nfiles; i++) {
    357321        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];
    366330            }
    367331        } else if (!(which & (SPLIT_DIR|SPLIT_SUBDIR))) {
     
    369333        }
    370334    }
    371     return (dnp);
    372 }
    373 
    374 /*----------------------------------------------------------------------*/
    375 #ifdef CONFIG_FEATURE_LS_SORTFILES
     335    return dnp;
     336}
     337
     338#if ENABLE_FEATURE_LS_SORTFILES
    376339static int sortcmp(const void *a, const void *b)
    377340{
    378341    struct dnode *d1 = *(struct dnode **)a;
    379342    struct dnode *d2 = *(struct dnode **)b;
    380     unsigned int sort_opts = all_fmt & SORT_MASK;
     343    unsigned sort_opts = all_fmt & SORT_MASK;
    381344    int dif;
    382345
    383     dif = 0;            /* assume SORT_NAME */
     346    dif = 0; /* assume SORT_NAME */
     347    // TODO: use pre-initialized function pointer
     348    // instead of branch forest
    384349    if (sort_opts == SORT_SIZE) {
    385350        dif = (int) (d2->dstat.st_size - d1->dstat.st_size);
     
    397362
    398363    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 */
    400365        if (ENABLE_LOCALE_SUPPORT) dif = strcoll(d1->name, d2->name);
    401366        else dif = strcmp(d1->name, d2->name);
    402367    }
    403368
    404     if (all_fmt & SORT_ORDER_REVERSE) {
     369    if (all_fmt & SORT_REVERSE) {
    405370        dif = -dif;
    406371    }
    407     return (dif);
    408 }
    409 
    410 /*----------------------------------------------------------------------*/
     372    return dif;
     373}
     374
    411375static void dnsort(struct dnode **dn, int size)
    412376{
    413     qsort(dn, size, sizeof *dn, sortcmp);
     377    qsort(dn, size, sizeof(*dn), sortcmp);
    414378}
    415379#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
    422384static void showfiles(struct dnode **dn, int nfiles)
    423385{
     
    430392        return;
    431393
    432     if (all_fmt & STYLE_ONE_RECORD_FLAG) {
     394    if (all_fmt & STYLE_LONG) {
    433395        ncols = 1;
    434396    } 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 */
    436398        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);
    443400            if (column_width < len)
    444401                column_width = len;
    445402        }
    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);
    447407        ncols = (int) (terminal_width / column_width);
    448408    }
     
    450410    if (ncols > 1) {
    451411        nrows = nfiles / ncols;
    452         if ((nrows * ncols) < nfiles)
     412        if (nrows * ncols < nfiles)
    453413            nrows++;                /* round up fractionals */
    454414    } else {
     
    466426                if (column > 0) {
    467427                    nexttab -= column;
    468                     while (nexttab--) {
    469                         putchar(' ');
    470                         column++;
    471                     }
    472             }
     428                    printf("%*s", nexttab, "");
     429                    column += nexttab;
     430                }
    473431                nexttab = column + column_width;
    474432                column += list_single(dn[i]);
    475         }
     433            }
    476434        }
    477435        putchar('\n');
     
    480438}
    481439
    482 /*----------------------------------------------------------------------*/
     440
    483441static void showdirs(struct dnode **dn, int ndirs, int first)
    484442{
     
    494452        if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) {
    495453            if (!first)
    496                 printf("\n");
     454                puts("");
    497455            first = 0;
    498456            printf("%s:\n", dn[i]->fullname);
     
    502460        if (nfiles > 0) {
    503461            /* list all files at this level */
    504             if (ENABLE_FEATURE_LS_SORTFILES) dnsort(subdnp, nfiles);
     462            dnsort(subdnp, nfiles);
    505463            showfiles(subdnp, nfiles);
    506464            if (ENABLE_FEATURE_LS_RECURSIVE) {
     
    510468                    dndirs = countsubdirs(subdnp, nfiles);
    511469                    if (dndirs > 0) {
    512                         if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnd, dndirs);
     470                        dnsort(dnd, dndirs);
    513471                        showdirs(dnd, dndirs, 0);
    514472                        /* free the array of dnode pointers to the dirs */
     
    523481}
    524482
    525 /*----------------------------------------------------------------------*/
     483
    526484static struct dnode **list_dir(const char *path)
    527485{
     
    532490
    533491    if (path == NULL)
    534         return (NULL);
     492        return NULL;
    535493
    536494    dn = NULL;
    537495    nfiles = 0;
    538     dir = bb_opendir(path);
     496    dir = warn_opendir(path);
    539497    if (dir == NULL) {
    540498        status = EXIT_FAILURE;
    541         return (NULL);  /* could not open the dir */
     499        return NULL;    /* could not open the dir */
    542500    }
    543501    while ((entry = readdir(dir)) != NULL) {
     
    546504        /* are we going to list the file- it may be . or .. or a hidden file */
    547505        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);
    552518            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        }
    560520        cur->allocated = 1;
    561521        cur->next = dn;
     
    566526
    567527    /* now that we know how many files there are
    568        ** allocate memory for an array to hold dnode pointers
     528     * allocate memory for an array to hold dnode pointers
    569529     */
    570530    if (dn == NULL)
    571         return (NULL);
     531        return NULL;
    572532    dnp = dnalloc(nfiles);
    573533    for (i = 0, cur = dn; i < nfiles; i++) {
     
    576536    }
    577537
    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() */
     545static time_t current_time_t;
     546#endif
     547
    582548static int list_single(struct dnode *dn)
    583549{
    584550    int i, column = 0;
    585551
    586 #ifdef CONFIG_FEATURE_LS_USERNAME
    587     char scratch[16];
    588 #endif
    589 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
     552#if ENABLE_FEATURE_LS_TIMESTAMPS
    590553    char *filetime;
    591554    time_t ttime, age;
    592555#endif
    593 #if defined(CONFIG_FEATURE_LS_FILETYPES) || defined (CONFIG_FEATURE_LS_COLOR)
     556#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
    594557    struct stat info;
    595558    char append;
     
    597560
    598561    if (dn->fullname == NULL)
    599         return (0);
    600 
    601 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
     562        return 0;
     563
     564#if ENABLE_FEATURE_LS_TIMESTAMPS
    602565    ttime = dn->dstat.st_mtime; /* the default time */
    603566    if (all_fmt & TIME_ACCESS)
     
    607570    filetime = ctime(&ttime);
    608571#endif
    609 #ifdef CONFIG_FEATURE_LS_FILETYPES
     572#if ENABLE_FEATURE_LS_FILETYPES
    610573    append = append_char(dn->dstat.st_mode);
    611574#endif
     
    614577        switch (all_fmt & (1 << i)) {
    615578        case LIST_INO:
    616             column += printf("%7ld ", (long int) dn->dstat.st_ino);
     579            column += printf("%7ld ", (long) dn->dstat.st_ino);
    617580            break;
    618581        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);
    624583            break;
    625584        case LIST_MODEBITS:
     
    630589            break;
    631590        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));
    637595            column += 17;
    638596            break;
     
    647605                       (int) minor(dn->dstat.st_rdev));
    648606            } else {
    649 #ifdef CONFIG_FEATURE_HUMAN_READABLE
    650607                if (all_fmt & LS_DISP_HR) {
    651608                    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);
    661612                }
    662613            }
    663614            break;
    664 #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
     615#if ENABLE_FEATURE_LS_TIMESTAMPS
    665616        case LIST_FULLTIME:
    666617            printf("%24.24s ", filetime);
     
    669620        case LIST_DATE_TIME:
    670621            if ((all_fmt & LIST_FULLTIME) == 0) {
    671                 age = time(NULL) - ttime;
     622                /* current_time_t ~== time(NULL) */
     623                age = current_time_t - ttime;
    672624                printf("%6.6s ", filetime + 4);
    673625                if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) {
     
    681633            break;
    682634#endif
    683 #ifdef CONFIG_SELINUX
     635#if ENABLE_SELINUX
    684636        case LIST_CONTEXT:
    685637            {
     
    688640
    689641                if (dn->sid) {
    690                   /*  I assume sid initilized with NULL */
    691                   len = strlen(dn->sid)+1;
    692                   safe_strncpy(context, dn->sid, len);
    693                   freecon(dn->sid);
    694                 }else {
    695                   safe_strncpy(context, "unknown", 8);
     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);
    696648                }
    697649                printf("%-32s ", context);
     
    701653#endif
    702654        case LIST_FILENAME:
    703 #ifdef CONFIG_FEATURE_LS_COLOR
    704655            errno = 0;
     656#if ENABLE_FEATURE_LS_COLOR
    705657            if (show_color && !lstat(dn->fullname, &info)) {
    706658                printf("\033[%d;%dm", bgcolor(info.st_mode),
    707                        fgcolor(info.st_mode));
     659                        fgcolor(info.st_mode));
    708660            }
    709661#endif
    710662            column += printf("%s", dn->name);
    711 #ifdef CONFIG_FEATURE_LS_COLOR
    712663            if (show_color) {
    713664                printf("\033[0m");
    714665            }
    715 #endif
    716666            break;
    717667        case LIST_SYMLINK:
    718668            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);
    742675                }
    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
    746692        case LIST_FILETYPE:
    747             if (append != '\0') {
    748                 printf("%1c", append);
     693            if (append) {
     694                putchar(append);
    749695                column++;
    750696            }
     
    756702    return column;
    757703}
    758 
    759 /*----------------------------------------------------------------------*/
    760704
    761705/* "[-]Cadil1", POSIX mandated options, busybox always supports */
     
    767711/* "[-]K", SELinux mandated options, busybox optionally supports */
    768712/* "[-]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
     713static 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
     725enum {
     726    LIST_MASK_TRIGGER   = 0,
     727    STYLE_MASK_TRIGGER  = STYLE_MASK,
     728    DISP_MASK_TRIGGER   = DISP_ROWS,
     729    SORT_MASK_TRIGGER   = SORT_MASK,
     730};
    826731
    827732static 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
    870771    LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */
    871772#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 */
    874778#endif
    875779    (1U<<31)
     
    877781
    878782
    879 /*----------------------------------------------------------------------*/
    880 
     783/* THIS IS A "SAFE" APPLET, main() MAY BE CALLED INTERNALLY FROM SHELL */
     784/* BE CAREFUL! */
     785
     786int ls_main(int argc, char **argv);
    881787int ls_main(int argc, char **argv)
    882788{
     
    886792    struct dnode *dn;
    887793    struct dnode *cur;
    888     long opt;
     794    unsigned opt;
    889795    int nfiles = 0;
    890796    int dnfiles;
     
    894800    int i;
    895801    char **av;
    896 #ifdef CONFIG_FEATURE_AUTOWIDTH
    897     char *tabstops_str = NULL;
    898     char *terminal_width_str = NULL;
    899 #endif
    900 #ifdef CONFIG_FEATURE_LS_COLOR
    901     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(&current_time_t);
    902808#endif
    903809
    904810    all_fmt = LIST_SHORT |
    905         (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_ORDER_FORWARD));
    906 
    907 #ifdef CONFIG_FEATURE_AUTOWIDTH
    908     /* Obtain the terminal width. */
    909     get_terminal_width_height(STDOUT_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);
    910816    /* Go one less... */
    911817    terminal_width--;
    912818#endif
    913819
    914 #ifdef CONFIG_FEATURE_LS_COLOR
    915     bb_applet_long_options = ls_color_opt;
    916 #endif
    917 
    918820    /* 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);
    931829#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));
    937831#endif
    938832    for (i = 0; opt_flags[i] != (1U<<31); i++) {
    939833        if (opt & (1 << i)) {
    940             unsigned int flags = opt_flags[i];
    941 
    942             if (flags & LIST_MASK_TRIGGER) {
     834            unsigned flags = opt_flags[i];
     835
     836            if (flags & LIST_MASK_TRIGGER)
    943837                all_fmt &= ~LIST_MASK;
    944             }
    945             if (flags & STYLE_MASK_TRIGGER) {
     838            if (flags & STYLE_MASK_TRIGGER)
    946839                all_fmt &= ~STYLE_MASK;
    947             }
    948             if (ENABLE_FEATURE_LS_SORTFILES && (flags & SORT_MASK_TRIGGER)) {
     840            if (flags & SORT_MASK_TRIGGER)
    949841                all_fmt &= ~SORT_MASK;
    950             }
    951             if (flags & DISP_MASK_TRIGGER) {
     842            if (flags & DISP_MASK_TRIGGER)
    952843                all_fmt &= ~DISP_MASK;
    953             }
    954             if (flags & TIME_MASK) {
     844            if (flags & TIME_MASK)
    955845                all_fmt &= ~TIME_MASK;
    956             }
    957             if (flags & LIST_CONTEXT) {
     846            if (flags & LIST_CONTEXT)
    958847                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;
    965851            all_fmt |= flags;
    966852        }
    967853    }
    968854
    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")))
    980861            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;
    992870    }
    993871#endif
    994872
    995873    /* 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))
    998875        all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */
    999 #endif
    1000876    if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) {
    1001877        if (all_fmt & TIME_CHANGE)
     
    1006882    if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */
    1007883        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 */
    1012887
    1013888    /* choose a display format */
     
    1024899    ac = argc - optind; /* how many cmd line args are left */
    1025900    if (ac < 1) {
    1026         static const char * const dotdir[] = { "." };
     901        static const char *const dotdir[] = { "." };
    1027902
    1028903        av = (char **) dotdir;
     
    1036911        all_fmt |= DISP_DIRNAME;    /* 2 or more items? label directories */
    1037912
    1038     /* stuff the command line file names into an dnode array */
     913    /* stuff the command line file names into a dnode array */
    1039914    dn = NULL;
    1040915    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));
    1042918        if (!cur)
    1043919            continue;
     
    1049925
    1050926    /* now that we know how many files there are
    1051        ** allocate memory for an array to hold dnode pointers
     927     * allocate memory for an array to hold dnode pointers
    1052928     */
    1053929    dnp = dnalloc(nfiles);
     
    1058934
    1059935    if (all_fmt & DISP_NOLIST) {
    1060         if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnp, nfiles);
     936        dnsort(dnp, nfiles);
    1061937        if (nfiles > 0)
    1062938            showfiles(dnp, nfiles);
     
    1067943        dnfiles = nfiles - dndirs;
    1068944        if (dnfiles > 0) {
    1069             if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnf, dnfiles);
     945            dnsort(dnf, dnfiles);
    1070946            showfiles(dnf, dnfiles);
    1071947            if (ENABLE_FEATURE_CLEAN_UP)
     
    1073949        }
    1074950        if (dndirs > 0) {
    1075             if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnd, dndirs);
     951            dnsort(dnd, dndirs);
    1076952            showdirs(dnd, dndirs, dnfiles == 0);
    1077953            if (ENABLE_FEATURE_CLEAN_UP)
     
    1081957    if (ENABLE_FEATURE_CLEAN_UP)
    1082958        dfree(dnp, nfiles);
    1083     return (status);
    1084 }
     959    return status;
     960}
  • branches/stable/mindi-busybox/coreutils/md5_sha1_sum.c

    r902 r1770  
    77 */
    88
    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"
    1810
    1911typedef enum { HASH_SHA1, HASH_MD5 } hash_algo_t;
     
    2517/* This might be useful elsewhere */
    2618static unsigned char *hash_bin_to_hex(unsigned char *hash_value,
    27                                       unsigned char hash_length)
     19                unsigned hash_length)
    2820{
    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;
    3825}
    3926
     
    5037    void (*final)(void*, void*);
    5138
    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        }
    5745    }
    5846
     
    7260    }
    7361
    74     while (0 < (count = read(src_fd, in_buf, 4096))) {
     62    while (0 < (count = safe_read(src_fd, in_buf, 4096))) {
    7563        update(in_buf, count, &context);
    7664    }
     
    9078}
    9179
    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)
     80int md5_sha1_sum_main(int argc, char **argv);
     81int md5_sha1_sum_main(int argc, char **argv)
    9482{
    9583    int return_value = EXIT_SUCCESS;
    9684    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;
    9889
    9990    if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK)
    100         flags = bb_getopt_ulflags(argc, argv, "scw");
     91        flags = getopt32(argv, "scw");
    10192    else optind = 1;
    10293
     
    10495        if (flags & FLAG_SILENT) {
    10596            bb_error_msg_and_die
    106                 ("the -s option is meaningful only when verifying checksums");
     97                ("-%c is meaningful only when verifying checksums", 's');
    10798        } else if (flags & FLAG_WARN) {
    10899            bb_error_msg_and_die
    109                 ("the -w option is meaningful only when verifying checksums");
     100                ("-%c is meaningful only when verifying checksums", 'w');
    110101        }
    111102    }
    112103
    113104    if (argc == optind) {
    114         argv[argc++] = "-";
     105        argv[argc++] = (char*)"-";
    115106    }
    116107
    117     if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && flags & FLAG_CHECK) {
     108    if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) {
    118109        FILE *pre_computed_stream;
    119110        int count_total = 0;
     
    127118        }
    128119
    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");
    133123        }
    134124
    135         while ((line = bb_get_chomped_line_from_file(pre_computed_stream)) != NULL) {
     125        while ((line = xmalloc_getline(pre_computed_stream)) != NULL) {
    136126            char *filename_ptr;
    137127
    138128            count_total++;
    139129            filename_ptr = strstr(line, "  ");
     130            /* handle format for binary checksums */
     131            if (filename_ptr == NULL) {
     132                filename_ptr = strstr(line, " *");
     133            }
    140134            if (filename_ptr == NULL) {
    141135                if (flags & FLAG_WARN) {
    142                     bb_error_msg("Invalid format");
     136                    bb_error_msg("invalid format");
    143137                }
    144138                count_failed++;
     
    169163                         count_failed, count_total);
    170164        }
    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);
    173168        }
     169        */
    174170    } else {
    175171        while (optind < argc) {
     
    185181        }
    186182    }
    187     return (return_value);
     183    return return_value;
    188184}
    189 
    190 #ifdef CONFIG_MD5SUM
    191 int md5sum_main(int argc, char **argv)
    192 {
    193     return (hash_files(argc, argv, HASH_MD5));
    194 }
    195 #endif
    196 
    197 #ifdef CONFIG_SHA1SUM
    198 int sha1sum_main(int argc, char **argv)
    199 {
    200     return (hash_files(argc, argv, HASH_SHA1));
    201 }
    202 #endif
  • branches/stable/mindi-busybox/coreutils/mkdir.c

    r821 r1770  
    55 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
    66 *
    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.
    218 */
    229
     
    3017 */
    3118
    32 #include <stdlib.h>
    33 #include <unistd.h>
     19/* Nov 28, 2006      Yoshinori Sato <ysato@users.sourceforge.jp>: Add SELinux Support.
     20 */
     21
    3422#include <getopt.h> /* struct option */
    35 #include "busybox.h"
     23#include "libbb.h"
     24
     25/* This is a NOFORK applet. Be very careful! */
    3626
    3727#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 };
     28static 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    ;
    4335#endif
    4436
    45 int mkdir_main (int argc, char **argv)
     37int mkdir_main(int argc, char **argv);
     38int mkdir_main(int argc, char **argv)
    4639{
    4740    mode_t mode = (mode_t)(-1);
    4841    int status = EXIT_SUCCESS;
    4942    int flags = 0;
    50     unsigned long opt;
     43    unsigned opt;
    5144    char *smode;
     45#if ENABLE_SELINUX
     46    security_context_t scontext;
     47#endif
    5248
    5349#if ENABLE_FEATURE_MKDIR_LONG_OPTIONS
    54     bb_applet_long_options = mkdir_long_options;
     50    applet_long_options = mkdir_longopts;
    5551#endif
    56     opt = bb_getopt_ulflags(argc, argv, "m:p", &smode);
    57     if(opt & 1) {
    58             mode = 0777;
    59         if (!bb_parse_mode (smode, &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);
    6157        }
    6258    }
    63     if(opt & 2)
     59    if (opt & 2)
    6460        flags |= FILEUTILS_RECUR;
     61#if ENABLE_SELINUX
     62    if (opt & 4) {
     63        selinux_or_die();
     64        setfscreatecon_or_die(scontext);
     65    }
     66#endif
    6567
    6668    if (optind == argc) {
  • branches/stable/mindi-busybox/coreutils/mkfifo.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2411/* http://www.opengroup.org/onlinepubs/007904975/utilities/mkfifo.html */
    2512
    26 #include <stdlib.h>
    27 #include <unistd.h>
    28 #include <sys/types.h>
    29 #include "busybox.h"
     13#include "libbb.h"
    3014#include "libcoreutils/coreutils.h"
    3115
     16int mkfifo_main(int argc, char **argv);
    3217int mkfifo_main(int argc, char **argv)
    3318{
     
    3722    mode = getopt_mk_fifo_nod(argc, argv);
    3823
    39     if (!*(argv += optind)) {
     24    argv += optind;
     25    if (!*argv) {
    4026        bb_show_usage();
    4127    }
  • branches/stable/mindi-busybox/coreutils/mknod.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
    2310/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
    2411
    25 #include <stdlib.h>
    26 #include <string.h>
    27 #include <sys/stat.h>
    2812#include <sys/sysmacros.h>  // For makedev
    29 #include <unistd.h>
    30 #include "busybox.h"
     13
     14#include "libbb.h"
    3115#include "libcoreutils/coreutils.h"
    3216
    33 static const char modes_chars[] = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };
     17static const char modes_chars[] ALIGN1 = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };
    3418static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK };
    3519
     20int mknod_main(int argc, char **argv);
    3621int mknod_main(int argc, char **argv)
    3722{
     
    4934        dev = 0;
    5035        if ((*name != 'p') && ((argc -= 2) == 2)) {
    51             /* Autodetect what the system supports; thexe macros should
     36            /* Autodetect what the system supports; these macros should
    5237             * 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)));
    5540        }
    5641
  • branches/stable/mindi-busybox/coreutils/mv.c

    r821 r1770  
    44 *
    55 * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
     6 * SELinux support by Yuichi Nakamura <ynakam@hitachisoft.jp>
    67 *
    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.
    219 */
    2210
     
    2816#include <sys/types.h>
    2917#include <sys/stat.h>
    30 #include <unistd.h>
    3118#include <dirent.h>
    32 #include <errno.h>
    33 #include <stdlib.h>
    3419#include <getopt.h> /* struct option */
    35 #include "busybox.h"
     20#include "libbb.h"
    3621#include "libcoreutils/coreutils.h"
    3722
    3823#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 };
     24static const char mv_longopts[] ALIGN1 =
     25    "interactive\0" No_argument "i"
     26    "force\0"       No_argument "f"
     27    ;
    4428#endif
    4529
     
    4731#define OPT_FILEUTILS_INTERACTIVE 2
    4832
    49 static const char fmt[] = "cannot overwrite %sdirectory with %sdirectory";
     33static const char fmt[] ALIGN1 =
     34    "cannot overwrite %sdirectory with %sdirectory";
    5035
     36int mv_main(int argc, char **argv);
    5137int mv_main(int argc, char **argv)
    5238{
     
    5743    int dest_exists;
    5844    int status = 0;
     45    int copy_flag = 0;
    5946
    6047#if ENABLE_FEATURE_MV_LONG_OPTIONS
    61     bb_applet_long_options = mv_long_options;
     48    applet_long_options = mv_longopts;
    6249#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");
    6552    if (optind + 2 > argc) {
    6653        bb_show_usage();
     
    7158
    7259    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) {
    7462            return 1;
    7563        }
     
    8371    do {
    8472        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) {
    8775            goto RET_1;
    8876        }
     
    9381            ((access(dest, W_OK) < 0 && isatty(0)) ||
    9482            (flags & OPT_FILEUTILS_INTERACTIVE))) {
    95             if (fprintf(stderr, "mv: overwrite `%s'? ", dest) < 0) {
     83            if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) {
    9684                goto RET_1; /* Ouch! fprintf failed! */
    9785            }
     
    10694            if (errno != EXDEV ||
    10795                (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);
    10997            } else {
    11098                if (dest_exists) {
     
    121109                    }
    122110                    if (unlink(dest) < 0) {
    123                         bb_perror_msg("cannot remove `%s'", dest);
     111                        bb_perror_msg("cannot remove '%s'", dest);
    124112                        goto RET_1;
    125113                    }
    126114                }
    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) &&
    129120                    (remove_file(*argv, FILEUTILS_RECUR | FILEUTILS_FORCE) >= 0)) {
    130121                    goto RET_0;
     
    140131    } while (*++argv != last);
    141132
    142     return (status);
     133    return status;
    143134}
  • branches/stable/mindi-busybox/coreutils/nice.c

    r821 r1770  
    55 * Copyright (C) 2005  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
    23 #include <stdio.h>
    24 #include <stdlib.h>
    25 #include <string.h>
    26 #include <limits.h>
    27 #include <errno.h>
    28 #include <unistd.h>
    2910#include <sys/resource.h>
    30 #include "busybox.h"
     11#include "libbb.h"
    3112
    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 
     13int nice_main(int argc, char **argv);
    4514int nice_main(int argc, char **argv)
    4615{
    47     static const char Xetpriority_msg[] = "cannot %cet priority";
    48 
    4916    int old_priority, adjustment;
    5017
    51     errno = 0;           /* Needed for getpriority error detection. */
    5218    old_priority = getpriority(PRIO_PROCESS, 0);
    53     if (errno) {
    54         bb_perror_msg_and_die(Xetpriority_msg, 'g');
    55     }
    5619
    5720    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);
    6023    }
    6124
    6225    adjustment = 10;            /* Set default adjustment. */
    6326
    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        }
    6535        if (argc < 4) {         /* Missing priority and/or utility! */
    6636            bb_show_usage();
    6737        }
    68         adjustment = bb_xgetlarg(argv[1], 10, INT_MIN, INT_MAX);
     38        adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2);
    6939        argv += 2;
    7040    }
    7141
    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;
    7444
    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);
    7747        }
    7848    }
    7949
    80     execvp(*argv, argv);        /* Now exec the desired program. */
     50    BB_EXECVP(*argv, argv);     /* Now exec the desired program. */
    8151
    8252    /* The exec failed... */
    83     bb_default_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */
     53    xfunc_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */
    8454    bb_perror_msg_and_die("%s", *argv);
    8555}
  • branches/stable/mindi-busybox/coreutils/nohup.c

    r821 r1770  
    1 /* vi:set ts=4: */
     1/* vi: set sw=4 ts=4: */
    22/* nohup - invoke a utility immune to hangups.
    3  * 
     3 *
    44 * Busybox version based on nohup specification at
    55 * http://www.opengroup.org/onlinepubs/007904975/utilities/nohup.html
    6  * 
     6 *
    77 * Copyright 2006 Rob Landley <rob@landley.net>
    8  *
     8 * Copyright 2006 Bernhard Fischer
     9 *
    910 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    1011 */
    1112
    12 #include <fcntl.h>
    13 #include <signal.h>
    14 #include <unistd.h>
    15 #include "busybox.h"
     13#include "libbb.h"
    1614
    17 int nohup_main(int argc, char *argv[])
     15int nohup_main(int argc, char **argv);
     16int nohup_main(int argc, char **argv)
    1817{
    19     int temp, nullfd;
    20     char *nohupout = "nohup.out", *home = NULL;
     18    int nullfd;
     19    const char *nohupout;
     20    char *home = NULL;
    2121
    22     // I have no idea why the standard cares about this.
     22    xfunc_error_retval = 127;
    2323
    24     bb_default_error_retval = 127;
     24    if (argc < 2) bb_show_usage();
    2525
    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);
    2730
    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);
    3735        if (open(nohupout, O_CREAT|O_WRONLY|O_APPEND, S_IRUSR|S_IWUSR) < 0) {
    3836            home = getenv("HOME");
    3937            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);
    4240            }
    4341        }
    44     } else dup2(nullfd, 1);
     42    } else dup2(nullfd, STDOUT_FILENO);
    4543
    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);
    4851
    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);
    5455
    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]);
    6060}
  • branches/stable/mindi-busybox/coreutils/od.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * od implementation for busybox
     
    67 *  The Regents of the University of California.  All rights reserved.
    78 *
    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.
    2110 *
    2211 * Original copyright notice is retained at the end of this file.
    2312 */
    2413
    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
    2720#include <getopt.h>
    28 #include <stdlib.h>
    29 #include "busybox.h"
     21
    3022#include "dump.h"
    3123
    32 #define isdecdigit(c) (isdigit)(c)
     24#define isdecdigit(c) isdigit(c)
    3325#define ishexdigit(c) (isxdigit)(c)
    3426
     
    3628odoffset(int argc, char ***argvp)
    3729{
    38     register char *num, *p;
     30    char *num, *p;
    3931    int base;
    4032    char *end;
     
    140132}
    141133
    142 static const char * const add_strings[] = {
     134static const char *const add_strings[] = {
    143135    "16/1 \"%3_u \" \"\\n\"",               /* a */
    144136    "8/2 \" %06o \" \"\\n\"",               /* B, o */
     
    156148};
    157149
    158 static const char od_opts[] = "aBbcDdeFfHhIiLlOoXxv";
    159 
    160 static const char od_o2si[] = {
     150static const char od_opts[] ALIGN1 = "aBbcDdeFfHhIiLlOoXxv";
     151
     152static const char od_o2si[] ALIGN1 = {
    161153    0, 1, 2, 3, 5,
    162154    4, 6, 6, 7, 8,
     
    165157};
    166158
     159int od_main(int argc, char **argv);
    167160int od_main(int argc, char **argv)
    168161{
     
    199192    odoffset(argc, &argv);
    200193
    201     return(bb_dump_dump(argv));
     194    return bb_dump_dump(argv);
    202195}
     196#endif /* ENABLE_DESKTOP */
    203197
    204198/*-
  • branches/stable/mindi-busybox/coreutils/printenv.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * printenv implementation for busybox
     
    56 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
    67 *
    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.
    219 */
    2210
    23 #include <stdio.h>
    24 #include <string.h>
    25 #include <stdlib.h>
    26 #include "busybox.h"
     11#include "libbb.h"
     12extern char **environ;
    2713
     14int printenv_main(int argc, char **argv);
    2815int printenv_main(int argc, char **argv)
    2916{
    30     extern char **environ;
    31     int e = 0;
    32 
    3317    /* no variables specified, show whole env */
    34     if (argc == 1)
     18    if (argc == 1) {
     19        int e = 0;
    3520        while (environ[e])
    3621            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 */
    4224        char *arg, *env;
    4325
    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        }
    5031    }
    5132
    52     bb_fflush_stdout_and_exit(0);
     33    fflush_stdout_and_exit(0);
    5334}
  • branches/stable/mindi-busybox/coreutils/printf.c

    r821 r1770  
    3131   %b = print an argument string, interpreting backslash escapes
    3232
    33    The `format' argument is re-used as many times as necessary
     33   The 'format' argument is re-used as many times as necessary
    3434   to convert all of the given arguments.
    3535
     
    3939//   19990508 Busy Boxed! Dave Cinege
    4040
    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
     43typedef void (*converter)(const char *arg, void *result);
     44
     45static void multiconvert(const char *arg, void *result, converter convert)
     46{
     47    char s[sizeof(int)*3 + 2];
     48
    6049    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
     59static void conv_strtoul(const char *arg, void *result)
     60{
     61    *(unsigned long*)result = bb_strtoul(arg, NULL, 0);
     62}
     63static void conv_strtol(const char *arg, void *result)
     64{
     65    *(long*)result = bb_strtol(arg, NULL, 0);
     66}
     67static 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
     76static unsigned long my_xstrtoul(const char *arg)
    6877{
    6978    unsigned long result;
    70 
    71     multiconvert(arg,&result, (converter)safe_strtoul);
     79    multiconvert(arg, &result, conv_strtoul);
    7280    return result;
    7381}
    7482
    75 static long xstrtol(char *arg)
     83static long my_xstrtol(const char *arg)
    7684{
    7785    long result;
    78     multiconvert(arg, &result, (converter)safe_strtol);
     86    multiconvert(arg, &result, conv_strtol);
    7987    return result;
    8088}
    8189
    82 static double xstrtod(char *arg)
     90static double my_xstrtod(const char *arg)
    8391{
    8492    double result;
    85     multiconvert(arg, &result, (converter)safe_strtod);
     93    multiconvert(arg, &result, conv_strtod);
    8694    return result;
    8795}
     
    100108}
    101109
    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;
     110static 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);
    128186}
    129187
    130188/* Print the text in FORMAT, using ARGV (with ARGC elements) for
    131    arguments to any `%' directives.
     189   arguments to any '%' directives.
    132190   Return the number of elements of ARGV used.  */
    133191
    134192static int print_formatted(char *format, int argc, char **argv)
    135193{
    136     int save_argc = argc;       /* Preserve original value.  */
    137     char *f;                    /* Pointer into `format'.  */
    138     char *direc_start;          /* Start of % directive.  */
    139     size_t direc_length;        /* Length of % directive.  */
    140     int field_width;            /* Arg to first '*', or -1 if none.  */
    141     int precision;              /* Arg to second '*', or -1 if none.  */
     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.  */
    142200
    143201    for (f = format; *f; ++f) {
     
    167225                ++direc_length;
    168226                if (argc > 0) {
    169                     field_width = xstrtoul(*argv);
     227                    field_width = my_xstrtoul(*argv);
    170228                    ++argv;
    171229                    --argc;
    172230                } else
    173231                    field_width = 0;
    174             } else
     232            } else {
    175233                while (isdigit(*f)) {
    176234                    ++f;
    177235                    ++direc_length;
    178236                }
     237            }
    179238            if (*f == '.') {
    180239                ++f;
     
    184243                    ++direc_length;
    185244                    if (argc > 0) {
    186                         precision = xstrtoul(*argv);
     245                        precision = my_xstrtoul(*argv);
    187246                        ++argv;
    188247                        --argc;
     
    200259            }
    201260            /*
    202                if (!strchr ("diouxXfeEgGcs", *f))
    203                fprintf(stderr, "%%%c: invalid directive", *f);
    204              */
     261            if (!strchr ("diouxXfeEgGcs", *f))
     262            fprintf(stderr, "%%%c: invalid directive", *f);
     263            */
    205264            ++direc_length;
    206265            if (argc > 0) {
     
    213272                            precision, "");
    214273            break;
    215 
    216274        case '\\':
    217275            if (*++f == 'c')
     
    220278            f--;
    221279            break;
    222 
    223280        default:
    224281            putchar(*f);
     
    229286}
    230287
    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 }
     288int printf_main(int argc, char **argv);
     289int 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/stable/mindi-busybox/coreutils/pwd.c

    r821 r1770  
    55 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
    66 *
    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.
    218 */
    229
    23 #include <stdio.h>
    24 #include <stdlib.h>
    25 #include "busybox.h"
     10#include "libbb.h"
    2611
     12/* This is a NOFORK applet. Be very careful! */
     13
     14int pwd_main(int argc, char **argv);
    2715int pwd_main(int argc, char **argv)
    2816{
    2917    char *buf;
    3018
    31     if ((buf = xgetcwd(NULL)) != NULL) {
     19    buf = xrealloc_getcwd_or_warn(NULL);
     20    if (buf != NULL) {
    3221        puts(buf);
    33         bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     22        free(buf);
     23        return fflush(stdout);
    3424    }
    3525
  • branches/stable/mindi-busybox/coreutils/realpath.c

    r821 r1770  
    66 *
    77 * Now does proper error checking on output and returns a failure exit code
    8  * if one or more paths can not be resolved.
     8 * if one or more paths cannot be resolved.
    99 *
    1010 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    1111 */
    1212
    13 #include <limits.h>
    14 #include <stdlib.h>
    15 #include "busybox.h"
     13#include "libbb.h"
    1614
     15int realpath_main(int argc, char **argv);
    1716int realpath_main(int argc, char **argv)
    1817{
     
    4544#endif
    4645
    47     bb_fflush_stdout_and_exit(retval);
     46    fflush_stdout_and_exit(retval);
    4847}
  • branches/stable/mindi-busybox/coreutils/rm.c

    r821 r1770  
    55 * Copyright (C) 2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
    66 *
    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.
    228 */
    239
     
    3016 */
    3117
    32 #include <unistd.h>
    33 #include "busybox.h"
     18#include "libbb.h"
    3419
     20/* This is a NOFORK applet. Be very careful! */
     21
     22int rm_main(int argc, char **argv);
    3523int rm_main(int argc, char **argv)
    3624{
    3725    int status = 0;
    3826    int flags = 0;
    39     unsigned long opt;
     27    unsigned opt;
    4028
    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)
    4635        flags |= FILEUTILS_INTERACTIVE;
    47     if(opt & 12)
     36    if (opt & 12)
    4837        flags |= FILEUTILS_RECUR;
    4938
    50     if (*(argv += optind) != NULL) {
     39    if (*argv != NULL) {
    5140        do {
    5241            const char *base = bb_get_last_path_component(*argv);
    5342
    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 '..'");
    5645            } else if (remove_file(*argv, flags) >= 0) {
    5746                continue;
  • branches/stable/mindi-busybox/coreutils/rmdir.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2411/* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */
    2512
    26 #include <stdlib.h>
    27 #include <unistd.h>
    2813#include <libgen.h>
    29 #include "busybox.h"
     14#include "libbb.h"
    3015
     16/* This is a NOFORK applet. Be very careful! */
     17
     18
     19int rmdir_main(int argc, char **argv);
    3120int rmdir_main(int argc, char **argv)
    3221{
     
    3625    char *path;
    3726
    38     flags = bb_getopt_ulflags(argc, argv, "p");
    39 
     27    flags = getopt32(argv, "p");
    4028    argv += optind;
    4129
     
    5038        do_dot = (*path == '.');
    5139
    52         do {
     40        while (1) {
    5341            if (rmdir(path) < 0) {
    54                 bb_perror_msg("`%s'", path);    /* Match gnu rmdir msg. */
     42                bb_perror_msg("'%s'", path);    /* Match gnu rmdir msg. */
    5543                status = EXIT_FAILURE;
    5644            } else if (flags) {
     
    6048                 * returns "." if there are no parents.  We must distinguish
    6149                 * this from the case of the original path starting with '.'.
    62         */
     50                */
    6351                if (do_dot || (*path != '.') || path[1]) {
    6452                    continue;
     
    6654            }
    6755            break;
    68         } while (1);
     56        }
    6957
    7058    } while (*++argv);
  • branches/stable/mindi-busybox/coreutils/seq.c

    r821 r1770  
    88 */
    99
    10 #include <stdio.h>
    11 #include <stdlib.h>
    12 #include "busybox.h"
     10#include "libbb.h"
    1311
     12/* This is a NOFORK applet. Be very careful! */
     13
     14
     15int seq_main(int argc, char **argv);
    1416int seq_main(int argc, char **argv)
    1517{
    16     double last, first, increment, i;
    17    
    18     first = increment = 1;
     18    double last, increment, i;
     19
     20    i = increment = 1;
    1921    switch (argc) {
    2022        case 4:
    21             increment=atof(argv[2]);
     23            increment = atof(argv[2]);
    2224        case 3:
    23             first=atof(argv[1]);
     25            i = atof(argv[1]);
    2426        case 2:
    25             last=atof(argv[argc -1]);
     27            last = atof(argv[argc-1]);
    2628            break;
    2729        default:
     
    3032
    3133    /* 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)) {
    3635        printf("%g\n", i);
     36        i += increment;
    3737    }
    3838
    39     return EXIT_SUCCESS;
     39    return fflush(stdout);
    4040}
  • branches/stable/mindi-busybox/coreutils/sleep.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    3219 */
    3320
    34 #include <stdlib.h>
    35 #include <limits.h>
    36 #include <unistd.h>
    37 #include "busybox.h"
     21#include "libbb.h"
    3822
    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
     27static const struct suffix_mult sfx[] = {
    4128    { "s", 1 },
    4229    { "m", 60 },
    4330    { "h", 60*60 },
    4431    { "d", 24*60*60 },
    45     { NULL, 0 }
     32    { }
    4633};
    4734#endif
    4835
     36int sleep_main(int argc, char **argv);
    4937int sleep_main(int argc, char **argv)
    5038{
    51     unsigned int duration;
     39    unsigned duration;
    5240
    53 #ifdef CONFIG_FEATURE_FANCY_SLEEP
     41#if ENABLE_FEATURE_FANCY_SLEEP
    5442
    5543    if (argc < 2) {
     
    6048    duration = 0;
    6149    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);
    6551    } while (*++argv);
    6652
    67 #else  /* CONFIG_FEATURE_FANCY_SLEEP */
     53#else  /* FEATURE_FANCY_SLEEP */
    6854
    6955    if (argc != 2) {
     
    7157    }
    7258
    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]);
    7860
    79 #endif /* CONFIG_FEATURE_FANCY_SLEEP */
     61#endif /* FEATURE_FANCY_SLEEP */
    8062
    8163    if (sleep(duration)) {
  • branches/stable/mindi-busybox/coreutils/sort.c

    r821 r1770  
    66 *
    77 * MAINTAINER: Rob Landley <rob@landley.net>
    8  * 
     8 *
    99 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    1010 *
     
    1313 */
    1414
    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
    2519
    2620/*
     
    3024
    3125/* 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 */
     26static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:t:";
     27enum {
     28    FLAG_n  = 1,            /* Numeric sort */
     29    FLAG_g  = 2,            /* Sort using strtod() */
     30    FLAG_M  = 4,            /* Sort date */
    3531/* 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 */
    4036/* 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
    5052static char key_separator;
    5153
    52 static struct sort_key
    53 {
     54static struct sort_key {
    5455    struct sort_key *next_key;  /* linked list */
    55     unsigned short range[4];    /* start word, start char, end word, end char */
    56     int flags;
     56    unsigned range[4];  /* start word, start char, end word, end char */
     57    unsigned flags;
    5758} *key_list;
    5859
    5960static char *get_key(char *str, struct sort_key *key, int flags)
    6061{
    61     int start=0,end,len,i,j;
     62    int start = 0, end = 0, len, i, j;
    6263
    6364    /* 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;
    7176        /* Loop through fields */
    7277        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                    }
    8596                }
    8697            }
    8798        }
    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    }
    92101    /* 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++;
    94105    /* 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--;
    96108    /* 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;
    104116    }
    105117    /* 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);
    108120    /* 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';
    113126    }
    114127    /* 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';
    119133    }
    120134    /* 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]);
    122138
    123139    return str;
     
    126142static struct sort_key *add_key(void)
    127143{
    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));
    131148}
    132149
    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))
    135154#else
    136 #define GET_LINE(fp)        bb_get_chomped_line_from_file(fp)
     155#define GET_LINE(fp) xmalloc_getline(fp)
    137156#endif
    138157
     
    140159static int compare_keys(const void *xarg, const void *yarg)
    141160{
    142     int flags=global_flags,retval=0;
    143     char *x,*y;
    144 
    145 #ifdef CONFIG_FEATURE_SORT_BIG
     161    int flags = option_mask32, retval = 0;
     162    char *x, *y;
     163
     164#if ENABLE_FEATURE_SORT_BIG
    146165    struct sort_key *key;
    147166
    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;
    150169        /* 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);
    153172#else
    154173    /* 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 */
    156175    {
    157         x=*(char **)xarg;
    158         y=*(char **)yarg;
     176        x = *(char **)xarg;
     177        y = *(char **)yarg;
    159178#endif
    160179        /* 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 */
    210243        /* 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 */
    214247#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
    222256    /* 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;
    227262}
    228263
     264#if ENABLE_FEATURE_SORT_BIG
     265static 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
     277int sort_main(int argc, char **argv);
    229278int sort_main(int argc, char **argv)
    230279{
    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
    237289    /* 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);
    280327            }
    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
    289353    /* 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;
    299364        }
    300365        fclose(fp);
    301366    }
    302 #ifdef CONFIG_FEATURE_SORT_BIG
     367#if ENABLE_FEATURE_SORT_BIG
    303368    /* 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;
    305371    /* 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);
    311377                return 1;
    312378            }
     
    315381#endif
    316382    /* Perform the actual sort */
    317     qsort(lines,linecount,sizeof(char *),compare_keys);
     383    qsort(lines, linecount, sizeof(char *), compare_keys);
    318384    /* 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;
    325397    }
    326398    /* 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);
    330403}
  • branches/stable/mindi-busybox/coreutils/stat.c

    r821 r1770  
    1 /* vi:set ts=4:*/
     1/* vi: set sw=4 ts=4: */
    22/*
    33 * stat -- display file or file system status
     
    66 * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
    77 * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
     8 * Copyright (C) 2006 by Yoshinori Sato <ysato@users.sourceforge.jp>
    89 *
    910 * Written by Michael Meskes
     
    1314 */
    1415
    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"
    2817
    2918/* 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
     24static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;
     25
     26static char const * file_type(struct stat const *st)
    3527{
    3628    /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107
     
    5749static char const *human_time(time_t t)
    5850{
     51    /* Old
    5952    static char *str;
    6053    str = ctime(&t);
    6154    str[strlen(str)-1] = '\0';
    6255    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;
    6361}
    6462
     
    7371    static const struct types {
    7472        long type;
    75         const char *fs;
     73        const char *const fs;
    7674    } humantypes[] = {
    7775        { 0xADFF,     "affs" },
     
    112110        { 0, "UNKNOWN" }
    113111    };
    114     for (i=0; humantypes[i].type; ++i)
     112    for (i = 0; humantypes[i].type; ++i)
    115113        if (humantypes[i].type == f_type)
    116114            break;
     
    118116}
    119117
    120 #ifdef CONFIG_FEATURE_STAT_FORMAT
     118#if ENABLE_FEATURE_STAT_FORMAT
    121119/* print statfs info */
    122 static void print_statfs(char *pformat, size_t buf_len, char m,
    123              char const *filename, void const *data)
     120static 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))
    124123{
    125124    struct statfs const *statfsbuf = data;
    126 
    127     switch (m) {
    128     case 'n':
     125    if (m == 'n') {
    129126        strncat(pformat, "s", buf_len);
    130127        printf(pformat, filename);
    131         break;
    132     case 'i':
     128    } else if (m == 'i') {
    133129        strncat(pformat, "Lx", buf_len);
    134130        printf(pformat, statfsbuf->f_fsid);
    135         break;
    136     case 'l':
     131    } else if (m == 'l') {
    137132        strncat(pformat, "lu", buf_len);
    138133        printf(pformat, statfsbuf->f_namelen);
    139         break;
    140     case 't':
     134    } else if (m == 't') {
    141135        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') {
    145138        strncat(pformat, "s", buf_len);
    146139        printf(pformat, human_fstype(statfsbuf->f_type));
    147         break;
    148     case 'b':
     140    } else if (m == 'b') {
    149141        strncat(pformat, "jd", buf_len);
    150142        printf(pformat, (intmax_t) (statfsbuf->f_blocks));
    151         break;
    152     case 'f':
     143    } else if (m == 'f') {
    153144        strncat(pformat, "jd", buf_len);
    154145        printf(pformat, (intmax_t) (statfsbuf->f_bfree));
    155         break;
    156     case 'a':
     146    } else if (m == 'a') {
    157147        strncat(pformat, "jd", buf_len);
    158148        printf(pformat, (intmax_t) (statfsbuf->f_bavail));
    159         break;
    160     case 'S':
    161     case 's':
     149    } else if (m == 's' || m == 'S') {
    162150        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') {
    166153        strncat(pformat, "jd", buf_len);
    167154        printf(pformat, (intmax_t) (statfsbuf->f_files));
    168         break;
    169     case 'd':
     155    } else if (m == 'd') {
    170156        strncat(pformat, "jd", buf_len);
    171157        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 {
    174164        strncat(pformat, "c", buf_len);
    175165        printf(pformat, m);
    176         break;
    177166    }
    178167}
    179168
    180169/* print stat info */
    181 static void print_stat(char *pformat, size_t buf_len, char m,
    182                char const *filename, void const *data)
     170static 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))
    183173{
    184174#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
     
    187177    struct group *gw_ent;
    188178
    189     switch (m) {
    190     case 'n':
     179    if (m == 'n') {
    191180        strncat(pformat, "s", buf_len);
    192181        printf(pformat, filename);
    193         break;
    194     case 'N':
     182    } else if (m == 'N') {
    195183        strncat(pformat, "s", buf_len);
    196184        if (S_ISLNK(statbuf->st_mode)) {
    197             char *linkname = xreadlink(filename);
     185            char *linkname = xmalloc_readlink_or_warn(filename);
    198186            if (linkname == NULL) {
    199187                bb_perror_msg("cannot read symbolic link '%s'", filename);
     
    207195            printf(pformat, filename);
    208196        }
    209         break;
    210     case 'd':
     197    } else if (m == 'd') {
    211198        strncat(pformat, "ju", buf_len);
    212199        printf(pformat, (uintmax_t) statbuf->st_dev);
    213         break;
    214     case 'D':
     200    } else if (m == 'D') {
    215201        strncat(pformat, "jx", buf_len);
    216202        printf(pformat, (uintmax_t) statbuf->st_dev);
    217         break;
    218     case 'i':
     203    } else if (m == 'i') {
    219204        strncat(pformat, "ju", buf_len);
    220205        printf(pformat, (uintmax_t) statbuf->st_ino);
    221         break;
    222     case 'a':
     206    } else if (m == 'a') {
    223207        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') {
    227210        strncat(pformat, "s", buf_len);
    228211        printf(pformat, bb_mode_string(statbuf->st_mode));
    229         break;
    230     case 'f':
     212    } else if (m == 'f') {
    231213        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') {
    235216        strncat(pformat, "s", buf_len);
    236217        printf(pformat, file_type(statbuf));
    237         break;
    238     case 'h':
     218    } else if (m == 'h') {
    239219        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') {
    243222        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') {
    247225        strncat(pformat, "s", buf_len);
    248226        setpwent();
    249227        pw_ent = getpwuid(statbuf->st_uid);
    250228        printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
    251         break;
    252     case 'g':
     229    } else if (m == 'g') {
    253230        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') {
    257233        strncat(pformat, "s", buf_len);
    258234        setgrent();
    259235        gw_ent = getgrgid(statbuf->st_gid);
    260236        printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
    261         break;
    262     case 't':
     237    } else if (m == 't') {
    263238        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') {
    267241        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') {
    271244        strncat(pformat, "ju", buf_len);
    272245        printf(pformat, (uintmax_t) (statbuf->st_size));
    273         break;
    274     case 'B':
     246    } else if (m == 'B') {
    275247        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') {
    279250        strncat(pformat, "ju", buf_len);
    280251        printf(pformat, (uintmax_t) statbuf->st_blocks);
    281         break;
    282     case 'o':
     252    } else if (m == 'o') {
    283253        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') {
    287256        strncat(pformat, "s", buf_len);
    288257        printf(pformat, human_time(statbuf->st_atime));
    289         break;
    290     case 'X':
     258    } else if (m == 'X') {
    291259        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') {
    295262        strncat(pformat, "s", buf_len);
    296263        printf(pformat, human_time(statbuf->st_mtime));
    297         break;
    298     case 'Y':
     264    } else if (m == 'Y') {
    299265        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') {
    303268        strncat(pformat, "s", buf_len);
    304269        printf(pformat, human_time(statbuf->st_ctime));
    305         break;
    306     case 'Z':
     270    } else if (m == 'Z') {
    307271        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 {
    311279        strncat(pformat, "c", buf_len);
    312280        printf(pformat, m);
    313         break;
    314281    }
    315282}
    316283
    317284static 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) )
    320288{
    321289    char *b;
    322290
    323291    /* create a working copy of the format string */
    324     char *format = bb_xstrdup(masterformat);
    325 
    326     /* Add 2 to accommodate our conversion of the stat `%s' format string
    327      * 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.  */
    328296    size_t n_alloc = strlen(format) + 2 + 1;
    329297    char *dest = xmalloc(n_alloc);
     
    331299    b = format;
    332300    while (b) {
     301        size_t len;
    333302        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':
    360321            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;
    361329        }
    362330    }
     
    368336
    369337/* Stat the file system and print what we find.  */
    370 static int do_statfs(char const *filename, char const *format)
     338static bool do_statfs(char const *filename, char const *format)
    371339{
    372340    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
    374355    if (statfs(filename, &statfsbuf) != 0) {
    375356        bb_perror_msg("cannot read file system information for '%s'", filename);
     
    377358    }
    378359
    379 #ifdef CONFIG_FEATURE_STAT_FORMAT
     360#if ENABLE_FEATURE_STAT_FORMAT
    380361    if (format == NULL)
    381         format = (flags & OPT_TERSE
     362#if !ENABLE_SELINUX
     363        format = (option_mask32 & OPT_TERSE
    382364            ? "%n %i %l %t %s %b %f %a %c %d\n"
    383365            : "  File: \"%n\"\n"
     
    385367              "Block size: %-10s\n"
    386368              "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));
    389371#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
    392392        ? "%s %llx %lu "
    393393        : "  File: \"%s\"\n"
     
    398398           statfsbuf.f_namelen);
    399399
    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));
    402402    else
    403403        printf("Type: %s\n", human_fstype(statfsbuf.f_type));
    404404
    405     format = (flags & OPT_TERSE
     405#if !ENABLE_SELINUX
     406    format = (option_mask32 & OPT_TERSE
    406407        ? "%lu %ld %ld %ld %ld %ld\n"
    407408        : "Block size: %-10lu\n"
     
    409410          "Inodes: Total: %-10jd Free: %jd\n");
    410411    printf(format,
    411            (unsigned long int) (statfsbuf.f_bsize),
     412           (unsigned long) (statfsbuf.f_bsize),
    412413           (intmax_t) (statfsbuf.f_blocks),
    413414           (intmax_t) (statfsbuf.f_bfree),
     
    415416           (intmax_t) (statfsbuf.f_files),
    416417           (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 */
    419443    return 1;
    420444}
    421445
    422446/* stat the file and print what we find */
    423 static int do_stat(char const *filename, char const *format)
     447static bool do_stat(char const *filename, char const *format)
    424448{
    425449    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) {
    428465        bb_perror_msg("cannot stat '%s'", filename);
    429466        return 0;
    430467    }
    431468
    432 #ifdef CONFIG_FEATURE_STAT_FORMAT
     469#if ENABLE_FEATURE_STAT_FORMAT
    433470    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";
    436474        } else {
    437475            if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
     
    452490            }
    453491        }
    454     }
    455     print_it(format, filename, print_stat, &statbuf);
    456492#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"),
    459535               filename,
    460536               (uintmax_t) (statbuf.st_size),
    461537               (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,
    465541               (uintmax_t) statbuf.st_dev,
    466542               (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_blksize
     543               (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
    474550        );
     551#if ENABLE_SELINUX
     552        if (option_mask32 & OPT_SELINUX)
     553            printf(" %lc\n", *scontext);
     554        else
     555            putchar('\n');
     556#endif
    475557    } else {
    476558        char *linkname = NULL;
     
    484566
    485567        if (S_ISLNK(statbuf.st_mode))
    486             linkname = xreadlink(filename);
     568            linkname = xmalloc_readlink_or_warn(filename);
    487569        if (linkname)
    488570            printf("  File: \"%s\" -> \"%s\"\n", filename, linkname);
     
    494576               (uintmax_t) (statbuf.st_size),
    495577               (uintmax_t) statbuf.st_blocks,
    496                (unsigned long int) statbuf.st_blksize,
     578               (unsigned long) statbuf.st_blksize,
    497579               file_type(&statbuf),
    498580               (uintmax_t) statbuf.st_dev,
    499581               (uintmax_t) statbuf.st_dev,
    500582               (uintmax_t) statbuf.st_ino,
    501                (unsigned long int) statbuf.st_nlink);
     583               (unsigned long) statbuf.st_nlink);
    502584        if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode))
    503585            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));
    506588        else
    507589            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)),
    511592               bb_mode_string(statbuf.st_mode),
    512                (unsigned long int) statbuf.st_uid,
     593               (unsigned long) statbuf.st_uid,
    513594               (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",
    516601               human_time(statbuf.st_atime),
    517602               human_time(statbuf.st_mtime),
    518603               human_time(statbuf.st_ctime));
    519604    }
    520 #endif
     605#endif  /* FEATURE_STAT_FORMAT */
    521606    return 1;
    522607}
    523608
     609int stat_main(int argc, char **argv);
    524610int stat_main(int argc, char **argv)
    525611{
     612    char *format = NULL;
    526613    int i;
    527     char *format = NULL;
    528614    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)
    533620    );
    534621
    535     if (flags & 1)                /* -f */
     622    if (option_mask32 & OPT_FILESYS) /* -f */
    536623        statfunc = do_statfs;
    537624    if (argc == optind)           /* files */
    538625        bb_show_usage();
    539626
     627#if ENABLE_SELINUX
     628    if (option_mask32 & OPT_SELINUX) {
     629        selinux_or_die();
     630    }
     631#endif  /* ENABLE_SELINUX */
    540632    for (i = optind; i < argc; ++i)
    541633        ok &= statfunc(argv[i], format);
  • branches/stable/mindi-busybox/coreutils/stty.c

    r821 r1770  
    2222   */
    2323
    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"
    5225
    5326#ifndef _POSIX_VDISABLE
     
    5629
    5730#define Control(c) ((c) & 0x1f)
    58 /* Canonical values for control characters. */
     31/* Canonical values for control characters */
    5932#ifndef CINTR
    60 # define CINTR Control ('c')
     33# define CINTR Control('c')
    6134#endif
    6235#ifndef CQUIT
     
    6740#endif
    6841#ifndef CKILL
    69 # define CKILL Control ('u')
     42# define CKILL Control('u')
    7043#endif
    7144#ifndef CEOF
    72 # define CEOF Control ('d')
     45# define CEOF Control('d')
    7346#endif
    7447#ifndef CEOL
     
    7649#endif
    7750#ifndef CSTART
    78 # define CSTART Control ('q')
     51# define CSTART Control('q')
    7952#endif
    8053#ifndef CSTOP
    81 # define CSTOP Control ('s')
     54# define CSTOP Control('s')
    8255#endif
    8356#ifndef CSUSP
    84 # define CSUSP Control ('z')
     57# define CSUSP Control('z')
    8558#endif
    8659#if defined(VEOL2) && !defined(CEOL2)
    8760# define CEOL2 _POSIX_VDISABLE
    8861#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 */
    9063#if defined(VSUSP) && !defined(VSWTCH)
    9164# define VSWTCH VSUSP
     
    9669#endif
    9770
    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__)
    10174# undef CSWTCH
    10275# define CSWTCH _POSIX_VDISABLE
    10376#endif
    10477
    105 #if defined(VWERSE) && !defined (VWERASE)       /* AIX-3.2.5 */
     78#if defined(VWERSE) && !defined(VWERASE)       /* AIX-3.2.5 */
    10679# define VWERASE VWERSE
    10780#endif
    108 #if defined(VDSUSP) && !defined (CDSUSP)
    109 # define CDSUSP Control ('y')
     81#if defined(VDSUSP) && !defined(CDSUSP)
     82# define CDSUSP Control('y')
    11083#endif
    11184#if !defined(VREPRINT) && defined(VRPRNT)       /* Irix 4.0.5 */
     
    11386#endif
    11487#if defined(VREPRINT) && !defined(CRPRNT)
    115 # define CRPRNT Control ('r')
     88# define CRPRNT Control('r')
    11689#endif
    11790#if defined(VWERASE) && !defined(CWERASE)
    118 # define CWERASE Control ('w')
     91# define CWERASE Control('w')
    11992#endif
    12093#if defined(VLNEXT) && !defined(CLNEXT)
    121 # define CLNEXT Control ('v')
     94# define CLNEXT Control('v')
    12295#endif
    12396#if defined(VDISCARD) && !defined(VFLUSHO)
     
    137110#endif
    138111#if defined(VFLUSHO) && !defined(CFLUSHO)
    139 # define CFLUSHO Control ('o')
     112# define CFLUSHO Control('o')
    140113#endif
    141114#if defined(VSTATUS) && !defined(CSTATUS)
    142 # define CSTATUS Control ('t')
    143 #endif
    144 
    145 /* Which speeds to set. */
     115# define CSTATUS Control('t')
     116#endif
     117
     118/* Which speeds to set */
    146119enum speed_setting {
    147120    input_speed, output_speed, both_speeds
    148121};
    149122
    150 /* Which member(s) of `struct termios' a mode uses. */
    151 enum mode_type {
     123/* Which member(s) of 'struct termios' a mode uses */
     124enum {
    152125    /* Do NOT change the order or values, as mode_type_flag()
    153      * depends on them. */
     126     * depends on them */
    154127    control, input, output, local, combination
    155128};
    156129
    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.  */
     130static const char evenp     [] ALIGN1 = "evenp";
     131static const char raw       [] ALIGN1 = "raw";
     132static const char stty_min  [] ALIGN1 = "min";
     133static const char stty_time [] ALIGN1 = "time";
     134static const char stty_swtch[] ALIGN1 = "swtch";
     135static const char stty_eol  [] ALIGN1 = "eol";
     136static const char stty_eof  [] ALIGN1 = "eof";
     137static const char parity    [] ALIGN1 = "parity";
     138static const char stty_oddp [] ALIGN1 = "oddp";
     139static const char stty_nl   [] ALIGN1 = "nl";
     140static const char stty_ek   [] ALIGN1 = "ek";
     141static const char stty_sane [] ALIGN1 = "sane";
     142static const char cbreak    [] ALIGN1 = "cbreak";
     143static const char stty_pass8[] ALIGN1 = "pass8";
     144static const char litout    [] ALIGN1 = "litout";
     145static const char cooked    [] ALIGN1 = "cooked";
     146static const char decctlq   [] ALIGN1 = "decctlq";
     147static const char stty_tabs [] ALIGN1 = "tabs";
     148static const char stty_lcase[] ALIGN1 = "lcase";
     149static const char stty_LCASE[] ALIGN1 = "LCASE";
     150static const char stty_crt  [] ALIGN1 = "crt";
     151static 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 */
    189160struct mode_info {
    190     const char *name;       /* Name given on command line.           */
    191     /* enum mode_type type; */
    192     char 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            */
    196167};
    197168
     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
    198173#define MI_ENTRY(N,T,F,B,M) { N, T, F, M, B }
    199174
    200 static const struct  mode_info mode_info[] = {
     175static const struct mode_info mode_info[] = {
    201176    MI_ENTRY("parenb",   control,     REV,               PARENB,     0 ),
    202177    MI_ENTRY("parodd",   control,     REV,               PARODD,     0 ),
     
    333308    MI_ENTRY(decctlq,    combination, REV        | OMIT, 0,          0 ),
    334309#endif
    335 #if defined (TABDLY) || defined (OXTABS)
     310#if defined(TABDLY) || defined(OXTABS)
    336311    MI_ENTRY(stty_tabs,  combination, REV        | OMIT, 0,          0 ),
    337312#endif
     
    345320
    346321enum {
    347     NUM_mode_info =
    348     (sizeof(mode_info) / sizeof(struct mode_info))
     322    NUM_mode_info = ARRAY_SIZE(mode_info)
    349323};
    350324
    351 /* Control character settings. */
     325/* Control character settings */
    352326struct 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 */
    356330};
    357331
    358 /* Control characters. */
    359 
    360 static const struct  control_info control_info[] = {
     332/* Control characters */
     333
     334static const struct control_info control_info[] = {
    361335    {"intr",     CINTR,   VINTR},
    362336    {"quit",     CQUIT,   VQUIT},
     
    392366    {"status",   CSTATUS, VSTATUS},
    393367#endif
    394     /* These must be last because of the display routines. */
     368    /* These must be last because of the display routines */
    395369    {stty_min,   1,       VMIN},
    396370    {stty_time,  0,       VTIME},
     
    398372
    399373enum {
    400     NUM_control_info =
    401     (sizeof(control_info) / sizeof(struct control_info))
     374    NUM_control_info = ARRAY_SIZE(control_info)
    402375};
    403376
    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 */
     378unsigned max_col = 80; /* default */
     379
     380struct 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
     387static 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 */
     391static 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
     418static 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
     433static 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
     448static ATTRIBUTE_NORETURN void perror_on_device_and_die(const char *fmt)
    428449{
    429450    bb_perror_msg_and_die(fmt, device_name);
    430451}
    431452
    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;
     453static void perror_on_device(const char *fmt)
     454{
     455    bb_perror_msg(fmt, device_name);
     456}
    438457
    439458/* Print format string MESSAGE and optional args.
    440459   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 */
    443461static void wrapf(const char *message, ...)
    444462{
     463    char buf[128];
    445464    va_list args;
    446     char buf[1024];                 /* Plenty long for our needs. */
    447465    int buflen;
    448466
    449467    va_start(args, message);
    450     vsprintf(buf, message, args);
     468    buflen = vsnprintf(buf, sizeof(buf), message, args);
    451469    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        }
    460483    }
    461484    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
     490static 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        }
    950498        memset(&win, 0, sizeof(win));
    951499    }
     
    956504        win.ws_col = cols;
    957505
    958 # ifdef TIOCSSIZE
    959     /* 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 better
    962        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 # endif
    980 
    981506    if (ioctl(STDIN_FILENO, TIOCSWINSZ, (char *) &win))
     507bail:
    982508        perror_on_device("%s");
    983509}
    984510
    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)) {
     511static 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)) {
    991517        if ((errno != EINVAL) || ((fmt_str += 2), !fancy)) {
    992518            perror_on_device(fmt_str);
     
    994520    } else {
    995521        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
     526static const struct suffix_mult stty_suffixes[] = {
     527    { "b",  512 },
     528    { "k", 1024 },
     529    { "B", 1024 },
     530    { }
     531};
     532
     533static const struct mode_info *find_mode(const char *name)
    1044534{
    1045535    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
     542static const struct control_info *find_control(const char *name)
    1119543{
    1120544    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
     551enum {
     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
     563static 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
     582static int recover_mode(const char *arg, struct termios *mode)
    1211583{
    1212584    int i, n;
    1213     unsigned int chr;
     585    unsigned chr;
    1214586    unsigned long iflag, oflag, cflag, lflag;
    1215587
    1216588    /* 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' */
    1218590    if (sscanf(arg, "%lx:%lx:%lx:%lx%n",
    1219591               &iflag, &oflag, &cflag, &lflag, &n) != 4)
     
    1231603    }
    1232604
    1233     /* Fail if there are too many fields. */
     605    /* Fail if there are too many fields */
    1234606    if (*arg != '\0')
    1235607        return 0;
     
    1238610}
    1239611
    1240 static speed_t string_to_baud(const char *arg)
    1241 {
    1242     return tty_value_to_baud(bb_xparse_number(arg, 0));
     612static 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
     624static 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
     640static 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");
    1243699}
    1244700
     
    1258714    for (i = 0; i < NUM_mode_info; ++i) {
    1259715        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);
    1261717            *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask))
    1262718                | mode_info[i].bits;
    1263719        } 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);
    1265721            *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask)
    1266722                & ~mode_info[i].bits;
     
    1269725}
    1270726
    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
     762static 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
     889static 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)
     914int stty_main(int argc, char **argv);
     915int 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/stable/mindi-busybox/coreutils/sum.c

    r821 r1770  
    1111 * Taken from coreutils and turned into a busybox applet by Mike Frysinger
    1212 *
    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.
    1414 */
    1515
    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"
    2117
    22 #include "busybox.h"
     18enum { SUM_BSD, PRINT_NAME, SUM_SYSV };
    2319
    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.  */
     24static unsigned sum_file(const char *file, const unsigned type)
    3625{
    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
    8727    uintmax_t total_bytes = 0;
     28    int fd = 0, r;
    8829
    8930    /* The sum of all the input bytes, modulo (UINT_MAX + 1).  */
    90     unsigned int s = 0;
     31    unsigned s = 0;
    9132
    92     if (IS_STDIN(file)) {
    93         fd = 0;
    94         have_read_stdin = 1;
    95     } else {
     33    if (NOT_LONE_DASH(file)) {
    9634        fd = open(file, O_RDONLY);
    9735        if (fd == -1)
    98             goto release_and_ret;
     36            goto ret_bad;
    9937    }
    10038
    10139    while (1) {
    102         size_t bytes_read = safe_read(fd, buf, MY_BUF_SIZE);
     40        size_t bytes_read = safe_read(fd, buf, BUFSIZ);
    10341
    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:
    10948            bb_perror_msg(file);
    110             RELEASE_CONFIG_BUFFER(buf);
    111             if (!IS_STDIN(file))
    112                 close(fd);
    11349            return 0;
    11450        }
    11551
    11652        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        }
    11963    }
    12064
    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);
    12869        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);
    13473    return 1;
     74#undef buf
    13575}
    13676
     77int sum_main(int argc, char **argv);
    13778int sum_main(int argc, char **argv)
    13879{
    139     int flags;
    140     int ok;
    141     int (*sum_func)(const char *, int) = bsd_sum_file;
     80    unsigned n;
     81    unsigned type = SUM_BSD;
    14282
    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;
    14987
    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;
    161100}
  • branches/stable/mindi-busybox/coreutils/sync.c

    r821 r1770  
    55 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
    66 *
    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.
    218 */
    229
    2310/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
    2411
    25 #include <stdlib.h>
    26 #include <unistd.h>
    27 #include "busybox.h"
     12#include "libbb.h"
    2813
     14/* This is a NOFORK applet. Be very careful! */
     15
     16int sync_main(int argc, char **argv);
    2917int sync_main(int argc, char **argv)
    3018{
     
    3321    sync();
    3422
    35     return(EXIT_SUCCESS);
     23    return EXIT_SUCCESS;
    3624}
  • branches/stable/mindi-busybox/coreutils/tail.c

    r821 r1770  
    2525 */
    2626
    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"
    3528
    3629static const struct suffix_mult tail_suffixes[] = {
    3730    { "b", 512 },
    3831    { "k", 1024 },
    39     { "m", 1048576 },
    40     { NULL, 0 }
     32    { "m", 1024*1024 },
     33    { }
    4134};
    4235
    43 static int status;
     36struct globals {
     37    bool status;
     38};
     39#define G (*(struct globals*)&bb_common_bufsiz1)
    4440
    4541static void tail_xprint_header(const char *fmt, const char *filename)
    4642{
    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)
    4944        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     }
    6045}
    6146
     
    6348{
    6449    ssize_t r;
    65     off_t current,end;
     50    off_t current, end;
    6651    struct stat sbuf;
    6752
     
    7055        end = sbuf.st_size;
    7156    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) {
    7359        bb_perror_msg(bb_msg_read_error);
    74         status = EXIT_FAILURE;
     60        G.status = EXIT_FAILURE;
    7561    }
    7662
     
    7864}
    7965
    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 
     66static const char header_fmt[] ALIGN1 = "\n==> %s <==\n";
     67
     68static 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
     75int tail_main(int argc, char **argv);
    8976int tail_main(int argc, char **argv)
    9077{
    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;
    9581    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;)
    9784
    9885    char *tailbuf;
     
    10087    int taillen = 0;
    10188    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;
    10492    char *s, *buf;
    10593    const char *fmt;
    10694
    107 #if !ENABLE_DEBUG_YANK_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
     95#if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL
    10896    /* 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;
    117106#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    }
    130108#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
    142117#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
    152121#endif
    153             default:
    154                 bb_show_usage();
    155         }
    156     }
     122    argc -= optind;
     123    argv += optind;
     124    from_top = G.status;
    157125
    158126    /* open all the files */
    159     fds = (int *)xmalloc(sizeof(int) * (argc - optind + 1));
    160 
    161     argv += optind;
     127    fds = xmalloc(sizeof(int) * (argc + 1));
    162128    nfiles = i = 0;
    163 
    164     if ((argc -= optind) == 0) {
     129    G.status = EXIT_SUCCESS;
     130    if (argc == 0) {
    165131        struct stat statbuf;
    166132
    167133        if (!fstat(STDIN_FILENO, &statbuf) && S_ISFIFO(statbuf.st_mode)) {
    168             follow = 0;
    169         }
    170         /* --argv; */
     134            opt &= ~1; /* clear FOLLOW */
     135        }
    171136        *argv = (char *) bb_msg_standard_input;
    172         goto DO_STDIN;
    173     }
    174 
     137    }
    175138    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;
    182142            continue;
    183143        }
    184         argv[nfiles] = argv[i];
    185         ++nfiles;
     144        fds[nfiles] = fileno(fil);
     145        argv[nfiles++] = argv[i];
    186146    } while (++i < argc);
    187147
    188     if (!nfiles) {
     148    if (!nfiles)
    189149        bb_error_msg_and_die("no files");
    190     }
    191150
    192151    tailbufsize = BUFSIZ;
    193152
    194153    /* 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) {
    197155        if (tailbufsize < count) {
    198156            tailbufsize = count + BUFSIZ;
     
    210168         * Beware of backing up too far.  See example in wc.c.
    211169         */
    212         if ((!(count|from_top)) && (lseek(fds[i], 0, SEEK_END) >= 0)) {
     170        if (!(count | from_top) && lseek(fds[i], 0, SEEK_END) >= 0) {
    213171            continue;
    214172        }
     
    228186                nwrite = nread;
    229187                if (seen < count) {
    230                     if (count_bytes) {
     188                    if (COUNT_BYTES) {
    231189                        nwrite -= (count - seen);
    232190                        seen = count;
     
    235193                        do {
    236194                            --nwrite;
    237                             if ((*s++ == '\n') && (++seen == count)) {
     195                            if (*s++ == '\n' && ++seen == count) {
    238196                                break;
    239197                            }
     
    241199                    }
    242200                }
    243                 tail_xbb_full_write(buf + nread - nwrite, nwrite);
     201                xwrite(STDOUT_FILENO, buf + nread - nwrite, nwrite);
    244202            } else if (count) {
    245                 if (count_bytes) {
     203                if (COUNT_BYTES) {
    246204                    taillen += nread;
    247205                    if (taillen > count) {
     
    263221                        newline += nbuf;
    264222                        taillen += nread;
    265 
    266223                    } else {
    267224                        int extra = 0;
    268                         if (buf[nread-1] != '\n') {
     225
     226                        if (buf[nread-1] != '\n')
    269227                            extra = 1;
    270                         }
    271 
    272228                        k = newline + nbuf + extra - count;
    273229                        s = tailbuf;
     
    278234                            ++s;
    279235                        }
    280 
    281236                        taillen += nread - (s - tailbuf);
    282237                        memmove(tailbuf, s, taillen);
     
    293248
    294249        if (!from_top) {
    295             tail_xbb_full_write(tailbuf, taillen);
     250            xwrite(STDOUT_FILENO, tailbuf, taillen);
    296251        }
    297252
     
    303258    fmt = NULL;
    304259
    305     while (follow) {
     260    if (FOLLOW) while (1) {
    306261        sleep(sleep_period);
    307262        i = 0;
     
    315270                    fmt = NULL;
    316271                }
    317                 tail_xbb_full_write(buf, nread);
     272                xwrite(STDOUT_FILENO, buf, nread);
    318273            }
    319274        } while (++i < nfiles);
    320275    }
    321 
    322     return status;
    323 }
     276    if (ENABLE_FEATURE_CLEAN_UP) {
     277        free(fds);
     278    }
     279    return G.status;
     280}
  • branches/stable/mindi-busybox/coreutils/tee.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2411/* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */
    2512
    26 #include <stdio.h>
    27 #include <stdlib.h>
     13#include "libbb.h"
    2814#include <signal.h>
    29 #include <unistd.h>
    30 #include "busybox.h"
    3115
     16int tee_main(int argc, char **argv);
    3217int tee_main(int argc, char **argv)
    3318{
    3419    const char *mode = "w\0a";
    3520    FILE **files;
    36     FILE **p;
    37     char **filenames;
    38     int flags;
    39     int retval = EXIT_SUCCESS;
    40 #ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO
     21    FILE **fp;
     22    char **names;
     23    char **np;
     24    char retval;
     25#if ENABLE_FEATURE_TEE_USE_BLOCK_IO
    4126    ssize_t c;
    4227# define buf bb_common_bufsiz1
     
    4429    int c;
    4530#endif
     31    retval = getopt32(argv, "ia");  /* 'a' must be 2nd */
     32    argc -= optind;
     33    argv += optind;
    4634
    47     flags = bb_getopt_ulflags(argc, argv, "ia");    /* 'a' must be 2nd */
     35    mode += (retval & 2);   /* Since 'a' is the 2nd option... */
    4836
    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. */
    5339    }
    54 
     40    retval = EXIT_SUCCESS;
    5541    /* gnu tee ignores SIGPIPE in case one of the output files is a pipe
    5642     * 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. */
    5844
    5945    /* 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;
    6550    goto GOT_NEW_FILE;
    66 
    6751    do {
    68         if ((*p = bb_wfopen(*argv, mode)) == NULL) {
     52        *fp = fopen_or_warn(*argv, mode);
     53        if (*fp == NULL) {
    6954            retval = EXIT_FAILURE;
    7055            continue;
    7156        }
    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 */
    7763
    78     *p = NULL;              /* Store the sentinal value. */
    79 
    80 #ifdef CONFIG_FEATURE_TEE_USE_BLOCK_IO
     64#if ENABLE_FEATURE_TEE_USE_BLOCK_IO
    8165    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);
    8570    }
    86 
    87     if (c < 0) {            /* Make sure read errors are signaled. */
     71    if (c < 0) {        /* Make sure read errors are signaled. */
    8872        retval = EXIT_FAILURE;
    8973    }
    90 
    9174#else
    9275    setvbuf(stdout, NULL, _IONBF, 0);
    9376    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);
    9781    }
    9882#endif
     
    10286     * file table is stdout, we can save one "if ferror" test by
    10387     * setting the first entry to stdin and checking stdout error
    104      * status with bb_fflush_stdout_and_exit()... although fflush()ing
     88     * status with fflush_stdout_and_exit()... although fflush()ing
    10589     * 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. */
    11095        /* Checking ferror should be sufficient, but we may want to fclose.
    11196         * 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);
    11499
    115     bb_fflush_stdout_and_exit(retval);
     100    fflush_stdout_and_exit(retval);
    116101}
  • branches/stable/mindi-busybox/coreutils/test.c

    r902 r1770  
    1313 *     modified by Erik Andersen <andersen@codepoet.org> to be used
    1414 *     in busybox.
     15 *     modified by Bernhard Fischer to be useable (i.e. a bit less bloaty).
    1516 *
    1617 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     
    2021 */
    2122
    22 #include "busybox.h"
    23 #include <unistd.h>
    24 #include <ctype.h>
    25 #include <errno.h>
    26 #include <string.h>
     23#include "libbb.h"
    2724#include <setjmp.h>
     25
     26/* This is a NOEXEC applet. Be very careful! */
     27
    2828
    2929/* test(1) accepts the following grammar:
     
    8686    OPERAND
    8787};
    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)
    8994enum token_types {
    9095    UNOP,
     
    96101
    97102static const struct t_op {
    98     const char *op_text;
    99     short op_num, op_type;
     103    char op_text[4];
     104    unsigned char op_num, op_type;
    100105} 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  },
    144147};
    145148
    146 #ifdef CONFIG_FEATURE_TEST_64
     149
     150#if ENABLE_FEATURE_TEST_64
    147151typedef int64_t arith_t;
    148152#else
     
    150154#endif
    151155
     156/* Cannot eliminate these static data (do the G trick)
     157 * because of test_main usage from other applets */
    152158static char **t_wp;
    153159static struct t_op const *t_wp_op;
    154160static gid_t *group_array;
    155161static int ngroups;
     162static jmp_buf leaving;
    156163
    157164static enum token t_lex(char *s);
     
    163170static int filstat(char *nm, enum token mode);
    164171static arith_t getn(const char *s);
     172/* UNUSED
    165173static int newerf(const char *f1, const char *f2);
    166174static int olderf(const char *f1, const char *f2);
    167175static int equalf(const char *f1, const char *f2);
     176*/
    168177static int test_eaccess(char *path, int mode);
    169178static int is_a_group_member(gid_t gid);
    170179static void initialize_group_array(void);
    171180
    172 static jmp_buf leaving;
    173 
    174 int bb_test(int argc, char **argv)
     181int test_main(int argc, char **argv)
    175182{
    176183    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            }
    188200        }
    189201        argv[argc] = NULL;
     
    202214     * prevails...
    203215     */
    204      ngroups = 0;
     216    ngroups = 0;
    205217
    206218    /* Implement special cases from POSIX.2, section 4.62.4 */
    207     switch (argc) {
    208     case 1:
     219    if (argc == 1)
    209220        return 1;
    210     case 2:
     221    if (argc == 2)
    211222        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)
    214231            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;
    215237        }
    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    }
    235239    t_wp = &argv[1];
    236240    res = !oexpr(t_lex(*t_wp));
     
    243247}
    244248
     249static void syntax(const char *op, const char *msg) ATTRIBUTE_NORETURN;
    245250static void syntax(const char *op, const char *msg)
    246251{
     
    248253        bb_error_msg("%s: %s", op, msg);
    249254    } else {
    250         bb_error_msg("%s", msg);
     255        bb_error_msg("%s: %s"+4, msg);
    251256    }
    252257    longjmp(leaving, 2);
     
    300305        if (*++t_wp == NULL)
    301306            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)
    308312            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) {
    315318        return binop();
    316319    }
    317320
    318     return strlen(*t_wp) > 0;
     321    return t_wp[0][0] != '\0';
    319322}
    320323
     
    323326    const char *opnd1, *opnd2;
    324327    struct t_op const *op;
     328    arith_t val1, val2;
    325329
    326330    opnd1 = *t_wp;
     
    328332    op = t_wp_op;
    329333
    330     if ((opnd2 = *++t_wp) == (char *) 0)
     334    opnd2 = *++t_wp;
     335    if (opnd2 == NULL)
    331336        syntax(op->op_text, "argument expected");
    332337
    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 */
    363382}
    364383
     
    366385{
    367386    struct stat s;
    368     unsigned int i;
     387    int i = i; /* gcc 3.x thinks it can be used uninitialized */
    369388
    370389    if (mode == FILSYM) {
     
    380399    if (stat(nm, &s) != 0)
    381400        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)
    391402        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) {
    405422#ifdef S_IFIFO
    406         i = S_IFIFO;
    407         goto filetype;
     423            i = S_IFIFO;
    408424#else
    409         return 0;
     425            return 0;
    410426#endif
    411     case FILSOCK:
     427        }
     428        if (mode == FILSOCK) {
    412429#ifdef S_IFSOCK
    413         i = S_IFSOCK;
    414         goto filetype;
     430            i = S_IFSOCK;
    415431#else
    416         return 0;
     432            return 0;
    417433#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)
    428448        return s.st_size > 0L;
    429     case FILUID:
     449    if (mode == FILUID)
    430450        return s.st_uid == geteuid();
    431     case FILGID:
     451    if (mode == FILGID)
    432452        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 */
    442454}
    443455
    444456static enum token t_lex(char *s)
    445457{
    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) {
    450462        return EOI;
    451463    }
    452     while (op->op_text) {
     464
     465    op = ops;
     466    do {
    453467        if (strcmp(s, op->op_text) == 0) {
    454468            t_wp_op = op;
     
    456470        }
    457471        op++;
    458     }
    459     t_wp_op = (struct t_op *) 0;
     472    } while (op < ops + ARRAY_SIZE(ops));
     473
    460474    return OPERAND;
    461475}
    462476
    463477/* atoi with error detection */
     478//XXX: FIXME: duplicate of existing libbb function?
    464479static arith_t getn(const char *s)
    465480{
    466481    char *p;
    467 #ifdef CONFIG_FEATURE_TEST_64
     482#if ENABLE_FEATURE_TEST_64
    468483    long long r;
    469484#else
     
    472487
    473488    errno = 0;
    474 #ifdef CONFIG_FEATURE_TEST_64
     489#if ENABLE_FEATURE_TEST_64
    475490    r = strtoll(s, &p, 10);
    476491#else
     
    487502}
    488503
     504/* UNUSED
    489505static int newerf(const char *f1, const char *f2)
    490506{
     
    511527            b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino);
    512528}
     529*/
    513530
    514531/* Do the same thing access(2) does, but use the effective uid and gid,
     
    521538
    522539    if (stat(path, &st) < 0)
    523         return (-1);
     540        return -1;
    524541
    525542    if (euid == 0) {
    526543        /* Root can read or write any file. */
    527544        if (mode != X_OK)
    528             return (0);
     545            return 0;
    529546
    530547        /* Root can execute any file that has any one of the execute
    531548           bits set. */
    532549        if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
    533             return (0);
     550            return 0;
    534551    }
    535552
     
    540557
    541558    if (st.st_mode & mode)
    542         return (0);
    543 
    544     return (-1);
     559        return 0;
     560
     561    return -1;
    545562}
    546563
     
    549566    ngroups = getgroups(0, NULL);
    550567    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));
    552574        getgroups(ngroups, group_array);
    553575    }
     
    555577
    556578/* 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()
    557582static int is_a_group_member(gid_t gid)
    558583{
    559     register int i;
     584    int i;
    560585
    561586    /* Short-circuit if possible, maybe saving a call to getgroups(). */
    562587    if (gid == getgid() || gid == getegid())
    563         return (1);
     588        return 1;
    564589
    565590    if (ngroups == 0)
     
    569594    for (i = 0; i < ngroups; i++)
    570595        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/stable/mindi-busybox/coreutils/touch.c

    r821 r1770  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    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.
    218 */
    229
     
    3118 */
    3219
    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"
    4121
     22/* This is a NOFORK applet. Be very careful! */
     23
     24int touch_main(int argc, char **argv);
    4225int touch_main(int argc, char **argv)
    4326{
    4427    int fd;
    45     int flags;
    4628    int status = EXIT_SUCCESS;
    47 
    48     flags = bb_getopt_ulflags(argc, argv, "c");
     29    int flags = getopt32(argv, "c");
    4930
    5031    argv += optind;
     
    5637    do {
    5738        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. */
    6041                    continue;
    6142                }
  • branches/stable/mindi-busybox/coreutils/tr.c

    r821 r1770  
    1616 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    1717 */
    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"
    2422
    2523#define ASCII 0377
    2624
    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
     29static void map(char *pvector,
     30        unsigned char *string1, unsigned int string1_len,
     31        unsigned char *string2, unsigned int string2_len)
    6732{
    6833    char last = '0';
     
    7136    for (j = 0, i = 0; i < string1_len; i++) {
    7237        if (string2_len <= j)
    73             pvector[(GCC4_IS_STUPID)string1[i]] = last;
     38            pvector[string1[i]] = last;
    7439        else
    75             pvector[(GCC4_IS_STUPID)string1[i]] = last = string2[j++];
     40            pvector[string1[i]] = last = string2[j++];
    7641    }
    7742}
     
    8550{
    8651    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
    8971    while (*arg) {
    9072        if (*arg == '\\') {
     
    9375        } else if (*(arg+1) == '-') {
    9476            ac = *(arg+2);
    95             if(ac == 0) {
     77            if (ac == 0) {
    9678                *buffer++ = *arg++;
    9779                continue;
     
    10587            i = *arg++;
    10688            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) {
    108100                    for (i = 'A'; i <= 'Z'; i++)
    109101                        *buffer++ = i;
     102                }
     103                if (j == CLASS_alpha || j == CLASS_alnum || j == CLASS_lower) {
    110104                    for (i = 'a'; i <= 'z'; i++)
    111105                        *buffer++ = i;
    112106                }
    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) {
    136108                    *buffer++ = '\t';
     109                    if (j == CLASS_space) {
     110                        *buffer++ = '\n';
     111                        *buffer++ = '\v';
     112                        *buffer++ = '\f';
     113                        *buffer++ = '\r';
     114                    }
    137115                    *buffer++ = ' ';
    138116                }
    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) {
    141118                    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)))
    143122                            *buffer++ = i;
    144123                }
    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) {
    151125                    *buffer++ = '[';
    152126                    *buffer++ = ':';
     
    157131            if (ENABLE_FEATURE_TR_EQUIV && i == '=') {
    158132                *buffer++ = *arg;
    159                 /* skip the closing =] */
    160                 arg += 3;
     133                arg += 3;   /* Skip the closing =] */
    161134                continue;
    162135            }
     
    169142            while (i <= ac)
    170143                *buffer++ = i++;
    171             arg++;              /* Skip the assumed ']' */
     144            arg++;  /* Skip the assumed ']' */
    172145        } else
    173146            *buffer++ = *arg++;
    174147    }
    175 
    176148    return (buffer - buffer_start);
    177149}
     
    179151static int complement(char *buffer, int buffer_len)
    180152{
    181     register short i, j, ix;
     153    int i, j, ix;
    182154    char conv[ASCII + 2];
    183155
     
    194166}
    195167
     168int tr_main(int argc, char **argv);
    196169int tr_main(int argc, char **argv)
    197170{
    198     register unsigned char *ptr;
    199     int output_length=0, input_length;
     171    unsigned char *ptr;
     172    int output_length = 0, input_length;
    200173    int idx = 1;
    201174    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);
    203178    RESERVE_CONFIG_BUFFER(vector, ASCII+1);
    204179    RESERVE_CONFIG_BUFFER(invec,  ASCII+1);
    205180    RESERVE_CONFIG_BUFFER(outvec, ASCII+1);
    206181
    207     /* ... but make them available globally */
    208     poutput = output;
    209     pvector = vector;
    210     pinvec  = invec;
    211     poutvec = outvec;
    212 
    213182    if (argc > 1 && argv[idx][0] == '-') {
    214183        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
    226191                bb_show_usage();
    227             }
    228192        }
    229193        idx++;
     
    234198    }
    235199
     200#define tr_buf bb_common_bufsiz1
    236201    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);
    240205        if (argv[idx] != NULL) {
    241206            if (*argv[idx] == '\0')
    242207                bb_error_msg_and_die("STRING2 cannot be empty");
    243208            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);
    245210        }
    246211        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;
    248213        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/stable/mindi-busybox/coreutils/true.c

    r821 r1770  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2411/* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */
    2512
    26 #include <stdlib.h>
    27 #include "busybox.h"
     13#include "libbb.h"
    2814
     15/* This is a NOFORK applet. Be very careful! */
     16
     17int true_main(int argc, char **argv);
    2918int true_main(int argc, char **argv)
    3019{
  • branches/stable/mindi-busybox/coreutils/tty.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2411/* http://www.opengroup.org/onlinepubs/007904975/utilities/tty.html */
    2512
    26 #include <stdio.h>
    27 #include <stdlib.h>
    28 #include <unistd.h>
    29 #include "busybox.h"
     13#include "libbb.h"
    3014
     15int tty_main(int argc, char **argv);
    3116int tty_main(int argc, char **argv)
    3217{
    3318    const char *s;
    34     int silent;     /* Note: No longer relevant in SUSv3. */
     19    USE_INCLUDE_SUSv2(int silent;)  /* Note: No longer relevant in SUSv3. */
    3520    int retval;
    3621
    37     bb_default_error_retval = 2;    /* SUSv3 requires > 1 for error. */
     22    xfunc_error_retval = 2; /* SUSv3 requires > 1 for error. */
    3823
    39     silent = bb_getopt_ulflags(argc, argv, "s");
     24    USE_INCLUDE_SUSv2(silent = getopt32(argv, "s");)
    4025
    4126    /* gnu tty outputs a warning that it is ignoring all args. */
     
    4429    retval = 0;
    4530
    46     if ((s = ttyname(0)) == NULL) {
     31    s = ttyname(0);
     32    if (s == NULL) {
    4733    /* According to SUSv3, ttyname can on fail with EBADF or ENOTTY.
    4834     * We know the file descriptor is good, so failure means not a tty. */
     
    5036        retval = 1;
    5137    }
     38    USE_INCLUDE_SUSv2(if (!silent) puts(s);)
     39    SKIP_INCLUDE_SUSv2(puts(s);)
    5240
    53     if (!silent) {
    54         puts(s);
    55     }
    56 
    57     bb_fflush_stdout_and_exit(retval);
     41    fflush_stdout_and_exit(retval);
    5842}
  • branches/stable/mindi-busybox/coreutils/uname.c

    r821 r1770  
    11/* vi: set sw=4 ts=4: */
    22/* 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 */
    187
    198/* BB_AUDIT SUSv3 compliant */
     
    4231 */
    4332
    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>
    5033#include <sys/utsname.h>
    51 #include "busybox.h"
     34#include "libbb.h"
    5235
    5336typedef struct {
     
    5639} uname_info_t;
    5740
    58 static const char options[] = "snrvmpa";
    59 static const unsigned short int utsname_offset[] = {
     41static const char options[] ALIGN1 = "snrvmpa";
     42static const unsigned short utsname_offset[] ALIGN2 = {
    6043    offsetof(uname_info_t,name.sysname),
    6144    offsetof(uname_info_t,name.nodename),
     
    6649};
    6750
     51int uname_main(int argc, char **argv);
    6852int uname_main(int argc, char **argv)
    6953{
     
    7559    char toprint;
    7660
    77     toprint = bb_getopt_ulflags(argc, argv, options);
     61    toprint = getopt32(argv, options);
    7862
    7963    if (argc != optind) {
     
    10387    strcpy(uname_info.processor, "unknown");
    10488
    105     delta=utsname_offset;
     89    delta = utsname_offset;
    10690    do {
    10791        if (toprint & 1) {
    108             bb_printf(((char *)(&uname_info)) + *delta);
     92            printf(((char *)(&uname_info)) + *delta);
    10993            if (toprint > 1) {
    11094                putchar(' ');
     
    11599    putchar('\n');
    116100
    117     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     101    fflush_stdout_and_exit(EXIT_SUCCESS);
    118102}
  • branches/stable/mindi-busybox/coreutils/uniq.c

    r821 r1770  
    1111/* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */
    1212
    13 #include "busybox.h"
    14 #include <string.h>
    15 #include <ctype.h>
    16 #include <unistd.h>
     13#include "libbb.h"
    1714
    18 static const char uniq_opts[] = "f:s:" "cdu\0\1\2\4";
     15static const char uniq_opts[] ALIGN1 = "cdu" "f:s:" "cdu\0\1\2\4";
    1916
    2017static FILE *xgetoptfile_uniq_s(char **argv, int read0write2)
     
    2219    const char *n;
    2320
    24     if ((n = *argv) != NULL) {
     21    n = *argv;
     22    if (n != NULL) {
    2523        if ((*n != '-') || n[1]) {
    26             return bb_xfopen(n, "r\0w" + read0write2);
     24            return xfopen(n, "r\0w" + read0write2);
    2725        }
    2826    }
     
    3028}
    3129
     30int uniq_main(int argc, char **argv);
    3231int uniq_main(int argc, char **argv)
    3332{
    3433    FILE *in, *out;
    35     unsigned long dups, skip_fields, skip_chars, i, uniq_flags;
     34    unsigned long dups, skip_fields, skip_chars, i;
    3635    const char *s0, *e0, *s1, *e1, *input_filename;
    37     int opt;
     36    unsigned opt;
    3837
    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    };
    4045
    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;
    5547
    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;
    5756
    5857    in = xgetoptfile_uniq_s(argv, 0);
     
    7372
    7473        /* gnu uniq ignores newlines */
    75         while ((s1 = bb_get_chomped_line_from_file(in)) != NULL) {
     74        while ((s1 = xmalloc_getline(in)) != NULL) {
    7675            e1 = s1;
    77             for (i=skip_fields ; i ; i--) {
     76            for (i = skip_fields; i; i--) {
    7877                e1 = skip_whitespace(e1);
    79                 while (*e1 && !isspace(*e1)) {
    80                     ++e1;
    81                 }
     78                e1 = skip_non_whitespace(e1);
    8279            }
    83             for (i = skip_chars ; *e1 && i ; i--) {
     80            for (i = skip_chars; *e1 && i; i--) {
    8481                ++e1;
    8582            }
     
    9390
    9491        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);
    9895            }
    9996            free((void *)s0);
     
    10198    } while (s1);
    10299
    103     bb_xferror(in, input_filename);
     100    die_if_ferror(in, input_filename);
    104101
    105     bb_fflush_stdout_and_exit(EXIT_SUCCESS);
     102    fflush_stdout_and_exit(EXIT_SUCCESS);
    106103}
  • branches/stable/mindi-busybox/coreutils/usleep.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
    2310/* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */
    2411
    25 #include <stdlib.h>
    26 #include <limits.h>
    27 #include <unistd.h>
    28 #include "busybox.h"
     12#include "libbb.h"
    2913
     14/* This is a NOFORK applet. Be very careful! */
     15
     16int usleep_main(int argc, char **argv);
    3017int usleep_main(int argc, char **argv)
    3118{
     
    3421    }
    3522
    36     if (usleep(bb_xgetularg10_bnd(argv[1], 0, UINT_MAX))) {
     23    if (usleep(xatou(argv[1]))) {
    3724        bb_perror_nomsg_and_die();
    3825    }
  • branches/stable/mindi-busybox/coreutils/uudecode.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 *  Copyright 2003, Glenn McGrath <bug1@iinet.net.au>
     
    1213
    1314
    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
     17static void read_stduu(FILE *src_stream, FILE *dst_stream)
    2218{
    2319    char *line;
    2420
    25     while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) {
     21    while ((line = xmalloc_getline(src_stream)) != NULL) {
    2622        int length;
    2723        char *line_ptr = line;
    2824
    2925        if (strcmp(line, "end") == 0) {
    30             return(EXIT_SUCCESS);
     26            return;
    3127        }
    3228        length = ((*line_ptr - 0x20) & 0x3f)* 4 / 3;
     
    3733        }
    3834        if (length > 60) {
    39             bb_error_msg_and_die("Line too long");
     35            bb_error_msg_and_die("line too long");
    4036        }
    4137
    4238        line_ptr++;
    43         /* Tolerate an overly long line to acomadate a possible exta '`' */
     39        /* Tolerate an overly long line to accomodate a possible exta '`' */
    4440        if (strlen(line_ptr) < (size_t)length) {
    45             bb_error_msg_and_die("Short file");
     41            bb_error_msg_and_die("short file");
    4642        }
    4743
     
    6864        free(line);
    6965    }
    70     bb_error_msg_and_die("Short file");
     66    bb_error_msg_and_die("short file");
    7167}
    7268
    73 static int read_base64(FILE *src_stream, FILE *dst_stream)
     69static void read_base64(FILE *src_stream, FILE *dst_stream)
    7470{
    75     static const char base64_table[] =
    76         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
    77     char term_count = 0;
     71    int term_count = 1;
    7872
    7973    while (1) {
     
    8579            int ch;
    8680
    87             /* Get next _valid_ character */
     81            /* Get next _valid_ character.
     82             * global vector bb_uuenc_tbl_base64[] contains this string:
     83             * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
     84             */
    8885            do {
    8986                ch = fgetc(src_stream);
    9087                if (ch == EOF) {
    91                     bb_error_msg_and_die("Short file");
     88                    bb_error_msg_and_die("short file");
    9289                }
    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;
    9795
    9896            if (*table_ptr == '=') {
    9997                if (term_count == 0) {
    100                     translated[count] = 0;
     98                    translated[count] = '\0';
    10199                    break;
    102100                }
    103101                term_count++;
    104             }
    105             else if (*table_ptr == '\n') {
     102            } else if (*table_ptr == '\n') {
    106103                /* Check for terminating line */
    107104                if (term_count == 5) {
    108                     return(EXIT_SUCCESS);
     105                    return;
    109106                }
    110107                term_count = 1;
     
    118115
    119116        /* 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        }
    121120        if (count > 2) {
    122121            fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
     
    128127}
    129128
     129int uudecode_main(int argc, char **argv);
    130130int uudecode_main(int argc, char **argv)
    131131{
    132     int (*decode_fn_ptr) (FILE * src, FILE * dst);
    133     FILE *src_stream;
     132    FILE *src_stream = stdin;
    134133    char *outname = NULL;
    135134    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");
    147142
    148143    /* 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) {
    155151            line_ptr = line + 13;
    156152            decode_fn_ptr = read_base64;
     
    158154            line_ptr = line + 6;
    159155            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 {
    181157            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));
    185174        }
    186175        free(line);
     176        decode_fn_ptr(src_stream, dst_stream);
     177        /* fclose_if_not_stdin(src_stream); - redundant */
     178        return EXIT_SUCCESS;
    187179    }
    188     bb_error_msg_and_die("No `begin' line");
     180    bb_error_msg_and_die("no 'begin' line");
    189181}
     182
     183/* Test script.
     184Put this into an empty dir with busybox binary, an run.
     185
     186#!/bin/sh
     187test -x busybox || { echo "No ./busybox?"; exit; }
     188ln -sf busybox uudecode
     189ln -sf busybox uuencode
     190>A_null
     191echo -n A >A
     192echo -n AB >AB
     193echo -n ABC >ABC
     194echo -n ABCD >ABCD
     195echo -n ABCDE >ABCDE
     196echo -n ABCDEF >ABCDEF
     197cat busybox >A_bbox
     198for f in A*; do
     199    echo uuencode $f
     200    ./uuencode    $f <$f >u_$f
     201    ./uuencode -m $f <$f >m_$f
     202done
     203mkdir unpk_u unpk_m 2>/dev/null
     204for 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: $?
     208done
     209for 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: $?
     213done
     214*/
  • branches/stable/mindi-busybox/coreutils/uuencode.c

    r821 r1770  
    66 *  Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    77 *
    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.
    219 */
    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"
    2910
    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
     13enum {
     14    SRC_BUF_SIZE = 45,  /* This *MUST* be a multiple of 3 */
     15    DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3),
    4116};
    4217
    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)
     18int uuencode_main(int argc, char **argv);
    8719int uuencode_main(int argc, char **argv)
    8820{
    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;
    9221    struct stat stat_buf;
    93     FILE *src_stream = stdin;
     22    int src_fd = STDIN_FILENO;
    9423    const char *tbl;
    95     size_t size;
    9624    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];
    9927
    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++;
    10340    }
    10441
    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)
    11346            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);
    13049        /* 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);
    13351        putchar('\n');
    134         if (tbl == tbl_std) {
     52        if (tbl == bb_uuenc_tbl_std) {
    13553            putchar(tbl[size]);
    13654        }
    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));
    14057    }
    141     bb_printf(tbl == tbl_std ? "\n`\nend\n" : "\n====\n");
     58    printf(tbl == bb_uuenc_tbl_std ? "\n`\nend\n" : "\n====\n");
    14259
    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);
    14661}
  • branches/stable/mindi-busybox/coreutils/wc.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    5037 *
    5138 *      echo hello > /tmp/testfile &&
    52  *      (dd ibs=1k skip=1 count=0 &> /dev/null ; wc -c) < /tmp/testfile
     39 *      (dd ibs=1k skip=1 count=0 &> /dev/null; wc -c) < /tmp/testfile
    5340 *
    5441 * for which 'wc -c' should output '0'.
    5542 */
    5643
    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
    6647#define isspace_given_isprint(c) isspace(c)
    6748#else
     
    7354#endif
    7455
     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
    7564enum {
    7665    WC_LINES    = 0,
     
    8069};
    8170
    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 
     71int wc_main(int argc, char **argv);
    9972int wc_main(int argc, char **argv)
    10073{
    10174    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;
    10883    int num_files = 0;
    10984    int c;
    110     char status = EXIT_SUCCESS;
    111     char in_word;
    112     char print_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");
    11590
    11691    if (print_type == 0) {
     
    11994
    12095    argv += optind;
    121     if (!*argv) {
     96    if (!argv[0]) {
    12297        *--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;
    123101    }
    124102
     
    127105    pcounts = counts;
    128106
    129     do {
     107    while ((arg = *argv++) != 0) {
    130108        ++num_files;
    131         if (!(fp = bb_wfopen_input(*argv))) {
     109        fp = fopen_or_warn_stdin(arg);
     110        if (!fp) {
    132111            status = EXIT_FAILURE;
    133112            continue;
     
    139118
    140119        do {
     120            /* Our -w doesn't match GNU wc exactly... oh well */
     121
    141122            ++counts[WC_CHARS];
    142123            c = getc(fp);
     
    170151            } else if (c == EOF) {
    171152                if (ferror(fp)) {
    172                     bb_perror_msg("%s", *argv);
     153                    bb_perror_msg("%s", arg);
    173154                    status = EXIT_FAILURE;
    174155                }
     
    191172        totals[WC_LENGTH] -= counts[WC_LENGTH];
    192173
    193         bb_fclose_nonstdin(fp);
     174        fclose_if_not_stdin(fp);
    194175
    195176    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;
    197181        u = 0;
    198182        do {
    199183            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. */
    202186            }
    203187            totals[u] += pcounts[u];
    204188        } 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    }
    214191
    215192    /* If more than one file was processed, we want the totals.  To save some
     
    219196    if (num_files > 1) {
    220197        num_files = 0;              /* Make sure we don't get here again. */
    221         *--argv = (char *) total_str;
     198        arg = "total";
    222199        pcounts = totals;
     200        --argv;
    223201        goto OUTPUT;
    224202    }
    225203
    226     bb_fflush_stdout_and_exit(status);
     204    fflush_stdout_and_exit(status);
    227205}
  • branches/stable/mindi-busybox/coreutils/who.c

    r821 r1770  
    1212 *
    1313 * Copyright (c) 2002 AYR Networks, Inc.
     14 *
     15 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     16 *
    1417 *----------------------------------------------------------------------
    1518 */
    1619
    17 #include "busybox.h"
     20#include "libbb.h"
    1821#include <utmp.h>
    1922#include <time.h>
    2023
    21 static const char * idle_string (time_t t)
     24static void idle_string(char *str6, time_t t)
    2225{
    23     static char str[6];
    24    
    25     time_t s = time(NULL) - t;
     26    t = time(NULL) - t;
    2627
    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;
    3438    }
    35     return "old";
     39    strcpy(str6, "old");
    3640}
    3741
     42int who_main(int argc, char **argv);
    3843int who_main(int argc, char **argv)
    3944{
     45    char str6[6];
    4046    struct utmp *ut;
    4147    struct stat st;
    4248    char *name;
    43    
     49
    4450    if (argc > 1) {
    4551        bb_show_usage();
    4652    }
    47    
     53
    4854    setutent();
    4955    printf("USER       TTY      IDLE      TIME           HOST\n");
     
    5460            /* ut->ut_line is device name of tty - "/dev/" */
    5561            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);
    6071        }
    6172    }
    62     if (ENABLE_FEATURE_CLEAN_UP) endutent();
     73    if (ENABLE_FEATURE_CLEAN_UP)
     74        endutent();
    6375    return 0;
    6476}
  • branches/stable/mindi-busybox/coreutils/whoami.c

    r821 r1770  
    55 * Copyright (C) 2000  Edward Betts <edward@debian.org>.
    66 *
    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.
    218 */
    229
    2310/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
    2411
    25 #include <stdio.h>
    26 #include <stdlib.h>
    27 #include <unistd.h>
    28 #include "busybox.h"
     12#include "libbb.h"
    2913
     14/* This is a NOFORK applet. Be very careful! */
     15
     16int whoami_main(int argc, char **argv);
    3017int whoami_main(int argc, char **argv)
    3118{
     
    3320        bb_show_usage();
    3421
    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);
    3826}
  • branches/stable/mindi-busybox/coreutils/yes.c

    r821 r1770  
    55 * Copyright (C) 2003  Manuel Novoa III  <mjn3@codepoet.org>
    66 *
    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.
    218 */
    229
     
    2815 */
    2916
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include "busybox.h"
     17#include "libbb.h"
    3318
     19/* This is a NOFORK applet. Be very careful! */
     20
     21int yes_main(int argc, char **argv);
    3422int yes_main(int argc, char **argv)
    3523{
    36     static const char fmt_str[] = " %s";
    37     const char *fmt;
    3824    char **first_arg;
    3925
    40     *argv = "y";
     26    argv[0] = (char*)"y";
    4127    if (argc != 1) {
    4228        ++argv;
     
    4531    first_arg = argv;
    4632    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        }
    5239        argv = first_arg;
    5340    } while (putchar('\n') != EOF);
Note: See TracChangeset for help on using the changeset viewer.