[Client] Test numbers from the command line

Check the return value of most calls to strto*().
Force base 10 when reading integers from the command line.
This commit is contained in:
Matteo Cypriani 2013-09-27 14:29:21 -04:00
parent 2d6b4c11d4
commit ed690ad196
1 changed files with 115 additions and 33 deletions

View File

@ -225,6 +225,9 @@ void parse_command_line(int argc, char **argv)
void parse_main_options(int argc, char **argv) void parse_main_options(int argc, char **argv)
{ {
int opt ; int opt ;
long arg_long ; // Integer value of optarg
unsigned long arg_ulong ; // Unsigned integer value of optarg
char *endptr ; // Return value of strto*()
while ((opt = getopt(argc, argv, OPTIONS)) != -1) while ((opt = getopt(argc, argv, OPTIONS)) != -1)
{ {
@ -234,26 +237,44 @@ void parse_main_options(int argc, char **argv)
options.daemon = true ; options.daemon = true ;
break ; break ;
case 'F' : case 'F' :
/* If -F is present, first set the flood delay to its default
* value (this can appear suboptimal when the user supplies a
* value, but will simplify the operations).
*/
options.flood_delay = DEFAULT_FLOOD_DELAY ;
/* Facultative getopt options do not handle separated values /* Facultative getopt options do not handle separated values
* (like -F <delay>), so we have to test separately. * (like -F <delay>), so we have to test separately.
*/ */
if (optarg) // We got an option like -F<delay>, it's OK if (optarg) // We got an option like -F<delay>, it's OK
{ {
options.flood_delay = strtoul(optarg, NULL, 0) ; arg_long = strtol(optarg, &endptr, 10) ;
if (endptr != optarg)
options.flood_delay = arg_long ;
else
fprintf(stderr, "Warning! Bad flood_delay:"
" failing back to the default value.\n") ;
if (optarg[0] == '+') if (optarg[0] == '+')
options.add_flood_delay = true ; options.add_flood_delay = true ;
} }
else // We got -F alone or -F <delay> else // We got -F alone or -F <delay>
{ {
/* If we are at the end of the string, or the next optind /* If we are not at the end of the string and the next
* is an option, we have the option without argument */ * optind is not an option, we have the option with a
if (argv[optind] == NULL || argv[optind][0] == '-') * separate argument. Otherwise we got the option alone,
// Take the default value: * but we have nothing to do since we already set the
options.flood_delay = DEFAULT_FLOOD_DELAY ; * default value.
else */
if (argv[optind] != NULL && argv[optind][0] != '-')
{ {
// Take the optind value: // Take the optind value:
options.flood_delay = strtoul(argv[optind], NULL, 0) ; arg_long = strtol(argv[optind], &endptr, 10) ;
if (endptr != argv[optind])
options.flood_delay = arg_long ;
else
fprintf(stderr, "Warning! Bad flood_delay:"
" failing back to the default value.\n") ;
if (argv[optind][0] == '+') if (argv[optind][0] == '+')
options.add_flood_delay = true ; options.add_flood_delay = true ;
++optind ; ++optind ;
@ -271,23 +292,42 @@ void parse_main_options(int argc, char **argv)
break ; break ;
case 'l' : case 'l' :
#ifdef OWLPS_CLIENT_RECEIVES_POSITION #ifdef OWLPS_CLIENT_RECEIVES_POSITION
/* If -l is present, first set the listening port to its
* default value (this can appear suboptimal when the user
* supplies a port number, but will simplify the operations).
*/
options.listening_port = OWL_DEFAULT_RESULT_PORT ;
/* Facultative getopt options do not handle separated values /* Facultative getopt options do not handle separated values
* (like -l <port>), so we have to test separately. * (like -l <port>), so we have to test separately.
*/ */
if (optarg) // We got an option like -l<port>, it's OK if (optarg) // We got an option like -l<port>, it's OK
options.listening_port = strtoul(optarg, NULL, 0) ; {
arg_ulong = strtoul(optarg, &endptr, 10) ;
if (endptr != optarg)
options.listening_port = arg_ulong ;
else
fprintf(stderr, "Warning! Bad listening_port:"
" failing back to the default value.\n") ;
}
else // We got -l alone or -l <port> else // We got -l alone or -l <port>
{ {
/* If we are at the end of the string, or the next optind /* If we are not at the end of the string and the next
* is an option, we have -l without a port number */ * optind is not an option, we have the option with a
if (argv[optind] == NULL || argv[optind][0] == '-') * separate argument. Otherwise we got the option alone,
// Take the default value: * but we have nothing to do since we already set the
options.listening_port = OWL_DEFAULT_RESULT_PORT ; * default value.
else */
if (argv[optind] != NULL && argv[optind][0] != '-')
{ {
// Take the optind value: // Take the optind value:
options.listening_port = arg_ulong = strtoul(argv[optind], &endptr, 10) ;
strtoul(argv[optind], NULL, 0) ; if (endptr != argv[optind])
options.listening_port = arg_ulong ;
else
fprintf(stderr, "Warning! Bad listening_port:"
" failing back to the default value.\n") ;
++optind ; ++optind ;
} }
} }
@ -298,22 +338,27 @@ void parse_main_options(int argc, char **argv)
#endif // OWLPS_CLIENT_RECEIVES_POSITION #endif // OWLPS_CLIENT_RECEIVES_POSITION
break ; break ;
case 'n' : case 'n' :
options.nb_pkt = strtoul(optarg, NULL, 0) ; options.nb_pkt = strtoul(optarg, NULL, 10) ;
break ; break ;
case 'N' : case 'N' :
options.nb_requests = strtoul(optarg, NULL, 0) ; options.nb_requests = strtoul(optarg, NULL, 10) ;
break ; break ;
case 'p' : case 'p' :
options.dest_port = strtoul(optarg, NULL, 0) ; options.dest_port = strtoul(optarg, NULL, 10) ;
break ; break ;
case 'q' : case 'q' :
options.verbose = false ; options.verbose = false ;
break ; break ;
case 's' : case 's' :
options.pkt_size = strtoul(optarg, NULL, 0) ; options.pkt_size = strtoul(optarg, NULL, 10) ;
break ; break ;
case 't' : case 't' :
options.delay = strtol(optarg, NULL, 0) ; arg_long = strtol(optarg, &endptr, 10) ;
if (endptr != optarg)
options.delay = arg_long ;
else
fprintf(stderr, "Warning! Bad delay:"
" failing back to the default value.\n") ;
break ; break ;
case 'v' : case 'v' :
options.verbose = true ; options.verbose = true ;
@ -344,25 +389,62 @@ void check_destination_host()
/* Parses remaining arguments (possible calibration data) */
void parse_calibration_data(int argc, char **argv) void parse_calibration_data(int argc, char **argv)
{ {
/* Parse remaining arguments (possible calibration data) */ /* No more arguments to parse */
if (argc - optind != 0) if (argc - optind == 0)
return ;
/* Exactly 4 more arguments */
if (argc - optind == 4)
{ {
if (argc - optind == 4) char *endptr ;
is_calibration_request = true ;
options.direction = strtoul(argv[optind], &endptr, 10) ;
if (endptr == argv[optind])
{ {
is_calibration_request = true ; fprintf(stderr,
options.direction = strtoul(argv[optind++], NULL, 0) ; "Error in calibration data: wrong direction!\n") ;
options.x = strtod(argv[optind++], NULL) ; goto error ;
options.y = strtod(argv[optind++], NULL) ;
options.z = strtod(argv[optind], NULL) ;
} }
else // Bad number of arguments optind++ ;
options.x = strtod(argv[optind], &endptr) ;
if (endptr == argv[optind])
{ {
print_usage() ; fprintf(stderr,
exit(OWL_ERR_BAD_USAGE) ; "Error in calibration data: wrong X coordinate!\n") ;
goto error ;
} }
optind++ ;
options.y = strtod(argv[optind], &endptr) ;
if (endptr == argv[optind])
{
fprintf(stderr,
"Error in calibration data: wrong Y coordinate!\n") ;
goto error ;
}
optind++ ;
options.z = strtod(argv[optind], &endptr) ;
if (endptr == argv[optind])
{
fprintf(stderr,
"Error in calibration data: wrong Z coordinate!\n") ;
goto error ;
}
return ; // No error occurred
} }
/* Bad number of arguments or parse error */
error:
print_usage() ;
exit(OWL_ERR_BAD_USAGE) ;
} }