dc: fix "dc does_not_exist" SEGVing
[oweals/busybox.git] / miscutils / i2c_tools.c
index 52fc5ec6b1851a7568712e135dc76370005726d9..6a213406317ad5478b4b86049ae69f209203246b 100644 (file)
@@ -421,8 +421,7 @@ static void check_write_funcs(int fd, int mode, int pec)
 static void confirm_or_abort(void)
 {
        fprintf(stderr, "Continue? [y/N] ");
-       fflush_all();
-       if (!bb_ask_confirmation())
+       if (!bb_ask_y_confirmation())
                bb_error_msg_and_die("aborting");
 }
 
@@ -454,19 +453,20 @@ static void confirm_action(int bus_addr, int mode, int data_addr, int pec)
 
 #if ENABLE_I2CGET
 //usage:#define i2cget_trivial_usage
-//usage:       "[-f] [-y] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]"
+//usage:       "[-fy] BUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]"
 //usage:#define i2cget_full_usage "\n\n"
-//usage:       "Read from I2C/SMBus chip registers\n"
-//usage:     "\n       I2CBUS  i2c bus number"
-//usage:     "\n       ADDRESS 0x03 - 0x77"
+//usage:       "Read from I2C/SMBus chip registers"
+//usage:     "\n"
+//usage:     "\n       I2CBUS  I2C bus number"
+//usage:     "\n       ADDRESS 0x03-0x77"
 //usage:     "\nMODE is:"
-//usage:     "\n       b       read byte data (default)"
-//usage:     "\n       w       read word data"
-//usage:     "\n       c       write byte/read byte"
+//usage:     "\n       b       Read byte data (default)"
+//usage:     "\n       w       Read word data"
+//usage:     "\n       c       Write byte/read byte"
 //usage:     "\n       Append p for SMBus PEC"
 //usage:     "\n"
-//usage:     "\n       -f      force access"
-//usage:     "\n       -y      disable interactive mode"
+//usage:     "\n       -f      Force access"
+//usage:     "\n       -y      Disable interactive mode"
 int i2cget_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int i2cget_main(int argc UNUSED_PARAM, char **argv)
 {
@@ -536,23 +536,24 @@ int i2cget_main(int argc UNUSED_PARAM, char **argv)
 
 #if ENABLE_I2CSET
 //usage:#define i2cset_trivial_usage
-//usage:       "[-f] [-y] [-m MASK] BUS CHIP-ADDR DATA-ADDR [VALUE] ... [MODE]"
+//usage:       "[-fy] [-m MASK] BUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]"
 //usage:#define i2cset_full_usage "\n\n"
-//usage:       "Set I2C registers\n"
-//usage:     "\n       I2CBUS  i2c bus number"
-//usage:     "\n       ADDRESS 0x03 - 0x77"
+//usage:       "Set I2C registers"
+//usage:     "\n"
+//usage:     "\n       I2CBUS  I2C bus number"
+//usage:     "\n       ADDRESS 0x03-0x77"
 //usage:     "\nMODE is:"
-//usage:     "\n       c       byte, no value"
-//usage:     "\n       b       byte data (default)"
-//usage:     "\n       w       word data"
+//usage:     "\n       c       Byte, no value"
+//usage:     "\n       b       Byte data (default)"
+//usage:     "\n       w       Word data"
 //usage:     "\n       i       I2C block data"
 //usage:     "\n       s       SMBus block data"
 //usage:     "\n       Append p for SMBus PEC"
 //usage:     "\n"
-//usage:     "\n       -f      force access"
-//usage:     "\n       -y      disable interactive mode"
-//usage:     "\n       -r      read back and compare the result"
-//usage:     "\n       -m MASK mask specifying which bits to write"
+//usage:     "\n       -f      Force access"
+//usage:     "\n       -y      Disable interactive mode"
+//usage:     "\n       -r      Read back and compare the result"
+//usage:     "\n       -m MASK Mask specifying which bits to write"
 int i2cset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int i2cset_main(int argc, char **argv)
 {
@@ -560,14 +561,19 @@ int i2cset_main(int argc, char **argv)
                              opt_m = (1 << 2), opt_r = (1 << 3);
 
        int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0;
-       int val, blen = 0, mask = 0, fd, status;
+       int val, blen, mask, fd, status;
        unsigned char block[I2C_SMBUS_BLOCK_MAX];
        char *opt_m_arg = NULL;
        unsigned opts;
 
-       opts = getopt32(argv, "^" "fym:r" "\0" "-3"/*from 3 to ? args*/, &opt_m_arg);
+       opts = getopt32(argv, "^"
+               "fym:r"
+               "\0" "-3", /* minimum 3 args */
+               &opt_m_arg
+       );
        argv += optind;
        argc -= optind;
+       argc--; /* now argv[argc] is last arg */
 
        bus_num = i2c_bus_lookup(argv[0]);
        bus_addr = i2c_parse_bus_addr(argv[1]);
@@ -577,20 +583,26 @@ int i2cset_main(int argc, char **argv)
                if (!argv[4] && argv[3][0] != 'c') {
                        mode = I2C_SMBUS_BYTE_DATA; /* Implicit b */
                } else {
-                       switch (argv[argc-1][0]) {
-                       case 'c': /* Already set */                     break;
-                       case 'b': mode = I2C_SMBUS_BYTE_DATA;           break;
-                       case 'w': mode = I2C_SMBUS_WORD_DATA;           break;
-                       case 's': mode = I2C_SMBUS_BLOCK_DATA;          break;
-                       case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;      break;
+                       switch (argv[argc][0]) {
+                       case 'c': /* Already set */
+                               break;
+                       case 'b': mode = I2C_SMBUS_BYTE_DATA;
+                               break;
+                       case 'w': mode = I2C_SMBUS_WORD_DATA;
+                               break;
+                       case 's': mode = I2C_SMBUS_BLOCK_DATA;
+                               break;
+                       case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;
+                               break;
                        default:
                                bb_error_msg("invalid mode");
                                bb_show_usage();
                        }
 
-                       pec = argv[argc-1][1] == 'p';
-                       if (mode == I2C_SMBUS_BLOCK_DATA ||
-                                       mode == I2C_SMBUS_I2C_BLOCK_DATA) {
+                       pec = (argv[argc][1] == 'p');
+                       if (mode == I2C_SMBUS_BLOCK_DATA
+                        || mode == I2C_SMBUS_I2C_BLOCK_DATA
+                       ) {
                                if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA)
                                        bb_error_msg_and_die(
                                                "PEC not supported for I2C "
@@ -604,6 +616,8 @@ int i2cset_main(int argc, char **argv)
        }
 
        /* Prepare the value(s) to be written according to current mode. */
+       mask = 0;
+       blen = 0;
        switch (mode) {
        case I2C_SMBUS_BYTE_DATA:
                val = xstrtou_range(argv[3], 0, 0, 0xff);
@@ -613,8 +627,9 @@ int i2cset_main(int argc, char **argv)
                break;
        case I2C_SMBUS_BLOCK_DATA:
        case I2C_SMBUS_I2C_BLOCK_DATA:
-               for (blen = 3; blen < (argc - 1); blen++)
-                       block[blen] = xstrtou_range(argv[blen], 0, 0, 0xff);
+               for (blen = 3; blen < argc; blen++)
+                       block[blen - 3] = xstrtou_range(argv[blen], 0, 0, 0xff);
+               blen -= 3;
                val = -1;
                break;
        default:
@@ -895,23 +910,24 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last)
 }
 
 //usage:#define i2cdump_trivial_usage
-//usage:       "[-f] [-r FIRST-LAST] [-y] BUS ADDR [MODE]"
+//usage:       "[-fy] [-r FIRST-LAST] BUS ADDR [MODE]"
 //usage:#define i2cdump_full_usage "\n\n"
-//usage:       "Examine I2C registers\n"
-//usage:     "\n       I2CBUS  i2c bus number"
-//usage:     "\n       ADDRESS 0x03 - 0x77"
+//usage:       "Examine I2C registers"
+//usage:     "\n"
+//usage:     "\n       I2CBUS  I2C bus number"
+//usage:     "\n       ADDRESS 0x03-0x77"
 //usage:     "\nMODE is:"
-//usage:     "\n       b       byte (default)"
-//usage:     "\n       w       word"
-//usage:     "\n       W       word on even register addresses"
+//usage:     "\n       b       Byte (default)"
+//usage:     "\n       w       Word"
+//usage:     "\n       W       Word on even register addresses"
 //usage:     "\n       i       I2C block"
 //usage:     "\n       s       SMBus block"
-//usage:     "\n       c       consecutive byte"
+//usage:     "\n       c       Consecutive byte"
 //usage:     "\n       Append p for SMBus PEC"
 //usage:     "\n"
-//usage:     "\n       -f      force access"
-//usage:     "\n       -y      disable interactive mode"
-//usage:     "\n       -r      limit the number of registers being accessed"
+//usage:     "\n       -f      Force access"
+//usage:     "\n       -y      Disable interactive mode"
+//usage:     "\n       -r      Limit the number of registers being accessed"
 int i2cdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int i2cdump_main(int argc UNUSED_PARAM, char **argv)
 {
@@ -1208,8 +1224,8 @@ static void will_skip(const char *cmd)
 //usage:#define i2cdetect_full_usage "\n\n"
 //usage:       "Detect I2C chips"
 //usage:     "\n"
-//usage:     "\n       -l      Print list of installed buses"
-//usage:     "\n       -F BUS# Print list of functionalities on this bus"
+//usage:     "\n       -l      List installed buses"
+//usage:     "\n       -F BUS# List functionalities on this bus"
 //usage:     "\n       -y      Disable interactive mode"
 //usage:     "\n       -a      Force scanning of non-regular addresses"
 //usage:     "\n       -q      Use smbus quick write commands for probing (default)"