Changeset 5926

Show
Ignore:
Timestamp:
02/15/11 17:11:45 (15 months ago)
Author:
groeck
Message:

i2cset: Get command/mode before reading data

Get and validate the command/mode parameter for all commands
before reading and evaluating actual data.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • i2c-tools/trunk/tools/i2cset.c

    r5924 r5926  
    208208        } 
    209209 
    210         /* check for block data */ 
    211         len = 0; 
    212         if (argc > flags + 5) { 
     210        /* check for command/mode */ 
     211        if (argc == flags + 4) { 
     212                /* Implicit "c" */ 
     213                size = I2C_SMBUS_BYTE; 
     214        } else if (argc == flags + 5) { 
     215                /* "c", "cp",  or implicit "b" */ 
     216                if (!strcmp(argv[flags+4], "c") 
     217                 || !strcmp(argv[flags+4], "cp")) { 
     218                        size = I2C_SMBUS_BYTE; 
     219                        pec = argv[flags+4][1] == 'p'; 
     220                } else { 
     221                        size = I2C_SMBUS_BYTE_DATA; 
     222                } 
     223        } else { 
     224                /* All other commands */ 
     225                if (strlen(argv[argc-1]) > 2 
     226                    || (strlen(argv[argc-1]) == 2 && argv[argc-1][1] != 'p')) { 
     227                        fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]); 
     228                        help(); 
     229                } 
    213230                switch (argv[argc-1][0]) { 
     231                case 'b': size = I2C_SMBUS_BYTE_DATA; break; 
     232                case 'w': size = I2C_SMBUS_WORD_DATA; break; 
    214233                case 's': size = I2C_SMBUS_BLOCK_DATA; break; 
    215234                case 'i': size = I2C_SMBUS_I2C_BLOCK_DATA; break; 
    216235                default: 
    217                         size = 0; 
    218                         break; 
    219                 } 
     236                        fprintf(stderr, "Error: Invalid mode '%s'!\n", argv[argc-1]); 
     237                        help(); 
     238                } 
     239                pec = argv[argc-1][1] == 'p'; 
    220240                if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA) { 
    221                         pec = argv[argc-1][1] == 'p'; 
    222241                        if (pec && size == I2C_SMBUS_I2C_BLOCK_DATA) { 
    223242                                fprintf(stderr, "Error: PEC not supported for I2C block writes!\n"); 
     
    232251                                help(); 
    233252                        } 
    234                         for (len = 0; len + flags + 5 < argc; len++) { 
    235                                 value = strtol(argv[flags + len + 4], &end, 0); 
    236                                 if (*end || value < 0 || value > 0xff) { 
    237                                         fprintf(stderr, "Error: Block data value invalid!\n"); 
    238                                         help(); 
    239                                 } 
    240                                 block[len] = value; 
    241                         } 
    242                         goto dofile; 
    243253                } else if (argc != flags + 6) { 
    244254                        fprintf(stderr, "Error: Too many arguments!\n"); 
     
    247257        } 
    248258 
    249         if (argc > flags + 4) { 
    250                 if (!strcmp(argv[flags+4], "c") 
    251                  || !strcmp(argv[flags+4], "cp")) { 
    252                         size = I2C_SMBUS_BYTE; 
    253                         value = -1; 
    254                         pec = argv[flags+4][1] == 'p'; 
    255                 } else { 
    256                         size = I2C_SMBUS_BYTE_DATA; 
    257                         value = strtol(argv[flags+4], &end, 0); 
     259        len = 0; /* Must always initialize len since it is passed to confirm() */ 
     260 
     261        /* read values from command line */ 
     262        switch (size) { 
     263        case I2C_SMBUS_BYTE_DATA: 
     264        case I2C_SMBUS_WORD_DATA: 
     265                value = strtol(argv[flags+4], &end, 0); 
     266                if (*end || value < 0) { 
     267                        fprintf(stderr, "Error: Data value invalid!\n"); 
     268                        help(); 
     269                } 
     270                if ((size == I2C_SMBUS_BYTE_DATA && value > 0xff) 
     271                    || (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) { 
     272                        fprintf(stderr, "Error: Data value out of range!\n"); 
     273                        help(); 
     274                } 
     275                break; 
     276        case I2C_SMBUS_BLOCK_DATA: 
     277        case I2C_SMBUS_I2C_BLOCK_DATA: 
     278                for (len = 0; len + flags + 5 < argc; len++) { 
     279                        value = strtol(argv[flags + len + 4], &end, 0); 
    258280                        if (*end || value < 0) { 
    259281                                fprintf(stderr, "Error: Data value invalid!\n"); 
    260282                                help(); 
    261283                        } 
    262                 } 
    263         } else { 
    264                 size = I2C_SMBUS_BYTE; 
     284                        if (value > 0xff) { 
     285                                fprintf(stderr, "Error: Data value out of range!\n"); 
     286                                help(); 
     287                        } 
     288                        block[len] = value; 
     289                } 
    265290                value = -1; 
    266         } 
    267  
    268         if (argc > flags + 5) { 
    269                 switch (argv[flags+5][0]) { 
    270                 case 'b': size = I2C_SMBUS_BYTE_DATA; break; 
    271                 case 'w': size = I2C_SMBUS_WORD_DATA; break; 
    272                 default: 
    273                         fprintf(stderr, "Error: Invalid mode!\n"); 
    274                         help(); 
    275                 } 
    276                 pec = argv[flags+5][1] == 'p'; 
     291                break; 
     292        default: 
     293                value = -1; 
     294                break; 
    277295        } 
    278296 
     
    285303        } 
    286304 
    287         if ((size == I2C_SMBUS_BYTE_DATA && value > 0xff) 
    288          || (size == I2C_SMBUS_WORD_DATA && value > 0xffff)) { 
    289                 fprintf(stderr, "Error: Data value out of range!\n"); 
    290                 help(); 
    291         } 
    292  
    293 dofile: 
    294305        file = open_i2c_dev(i2cbus, filename, sizeof(filename), 0); 
    295306        if (file < 0