comparison cmd.c @ 31:9be355e742e5

Distinguish between unknown argument and missing value
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Tue, 28 Nov 2017 16:48:45 +0100
parents 2552eec9b913
children b5ebed168e59
comparison
equal deleted inserted replaced
30:2552eec9b913 31:9be355e742e5
199 }; 199 };
200 200
201 static int 201 static int
202 parse_arg(char *arg, const char *namev[], int sep, char **valuep) 202 parse_arg(char *arg, const char *namev[], int sep, char **valuep)
203 { 203 {
204 char *p;
204 size_t i; 205 size_t i;
205 size_t name_len; 206
207 if ((sep != '\0') && ((p = strchr(arg, sep)) != NULL)) {
208 *p++ = '\0';
209 }
210 if (valuep != NULL) {
211 *valuep = p;
212 }
206 213
207 for (i = 0; namev[i] != NULL; i++) { 214 for (i = 0; namev[i] != NULL; i++) {
208 name_len = strlen(namev[i]); 215 if (strcmp(namev[i], arg) == 0) {
209 if ((strncmp(namev[i], arg, name_len) == 0) &&
210 (arg[name_len] == sep)) {
211 if (valuep != NULL) {
212 *valuep = arg + name_len + 1;
213 }
214 return (i); 216 return (i);
215 } 217 }
216 } 218 }
217 219
218 return (-1); 220 return (-1);
254 } else if (argc != 2) { 256 } else if (argc != 2) {
255 return (CMD_USAGE); 257 return (CMD_USAGE);
256 } 258 }
257 259
258 type = parse_arg(argv[1], optionv, '=', &value); 260 type = parse_arg(argv[1], optionv, '=', &value);
261 if ((type >= 0) && (value == NULL)) {
262 pwm_err(ctx, "missing value for \"%s\"", argv[1]);
263 return (CMD_ERR);
264 }
259 switch (type) { 265 switch (type) {
260 case OPTION_FILENAME: 266 case OPTION_FILENAME:
261 free(ctx->filename); 267 free(ctx->filename);
262 ctx->filename = (value[0] != '\0') ? xstrdup(value) : 268 ctx->filename = (value[0] != '\0') ? xstrdup(value) :
263 xasprintf(&ctx->filename, "%s/pwm.psafe3", ctx->dirname); 269 xasprintf(&ctx->filename, "%s/pwm.psafe3", ctx->dirname);
265 case OPTION_PIPECOMMAND: 271 case OPTION_PIPECOMMAND:
266 free(ctx->pipecmd); 272 free(ctx->pipecmd);
267 ctx->pipecmd = (value[0] != '\0') ? xstrdup(value) : NULL; 273 ctx->pipecmd = (value[0] != '\0') ? xstrdup(value) : NULL;
268 break; 274 break;
269 default: 275 default:
270 pwm_err(ctx, "bad option name \"%s\"", argv[1]); 276 pwm_err(ctx, "unknown option \"%s\"", argv[1]);
271 return (CMD_ERR); 277 return (CMD_ERR);
272 } 278 }
273 279
274 return (CMD_OK); 280 return (CMD_OK);
275 } 281 }
422 size_t j; 428 size_t j;
423 struct record *record; 429 struct record *record;
424 430
425 for (i = 1; i < argc; i++) { 431 for (i = 1; i < argc; i++) {
426 type = parse_arg(argv[i], field_namev, '~', &value); 432 type = parse_arg(argv[i], field_namev, '~', &value);
427 if (type == FIELD_UNKNOWN) { 433 if ((type >= 0) && ((value == NULL) || (value[0] == '\0'))) {
428 pwm_err(ctx, "bad field name \"%s\"", argv[i]);
429 goto out;
430 }
431 if (value[0] == '\0') {
432 /* skip empty expressions */ 434 /* skip empty expressions */
433 continue; 435 continue;
434 } 436 }
435 switch (type) { 437 switch (type) {
436 case FIELD_GROUP: 438 case FIELD_GROUP:
447 break; 449 break;
448 case FIELD_URL: 450 case FIELD_URL:
449 repp = &url_re; 451 repp = &url_re;
450 break; 452 break;
451 default: 453 default:
452 pwm_err(ctx, "bad field name \"%s\"", argv[i]); 454 pwm_err(ctx, "unknown field name \"%s\"", argv[i]);
453 goto out; 455 goto out;
454 } 456 }
455 457
456 if (*repp == NULL) { 458 if (*repp == NULL) {
457 *repp = xmalloc(sizeof (regex_t)); 459 *repp = xmalloc(sizeof (regex_t));
632 634
633 record = pwfile_create_record(); 635 record = pwfile_create_record();
634 636
635 for (i = 1; i < argc; i++) { 637 for (i = 1; i < argc; i++) {
636 type = parse_arg(argv[i], field_namev, '=', &value); 638 type = parse_arg(argv[i], field_namev, '=', &value);
637 if (type == FIELD_UNKNOWN) { 639 if ((type >= 0) && ((value == NULL) || (value[0] == '\0'))) {
638 pwm_err(ctx, "bad field assignment \"%s\"", argv[i]);
639 }
640 if (value[0] == '\0') {
641 /* skip empty assignments */ 640 /* skip empty assignments */
642 continue; 641 continue;
643 } 642 }
644 switch (type) { 643 switch (type) {
645 case FIELD_GROUP: 644 case FIELD_GROUP:
665 case FIELD_URL: 664 case FIELD_URL:
666 free(record->url); 665 free(record->url);
667 record->url = xstrdup(value); 666 record->url = xstrdup(value);
668 break; 667 break;
669 default: 668 default:
670 pwm_err(ctx, "bad field name \"%s\"", argv[i]); 669 pwm_err(ctx, "unknown field name \"%s\"", argv[i]);
671 goto out; 670 goto out;
672 } 671 }
673 } 672 }
674 673
675 if (ctx->is_interactive && (argc < 2)) { 674 if (ctx->is_interactive && (argc < 2)) {
714 713
715 record = pwfile_get_record(ctx, id); 714 record = pwfile_get_record(ctx, id);
716 715
717 for (i = 2; i < argc; i++) { 716 for (i = 2; i < argc; i++) {
718 type = parse_arg(argv[i], field_namev, '=', &value); 717 type = parse_arg(argv[i], field_namev, '=', &value);
719 if (type == FIELD_UNKNOWN) { 718 if ((type >= 0) && ((value == NULL) || (value[0] == '\0'))) {
720 pwm_err(ctx, "bad field assignment \"%s\"", argv[i]);
721 goto out;
722 }
723 if (value[0] == '\0') {
724 /* skip empty assignments */ 719 /* skip empty assignments */
725 continue; 720 continue;
726 } 721 }
727 switch (type) { 722 switch (type) {
728 case FIELD_GROUP: 723 case FIELD_GROUP:
748 case FIELD_URL: 743 case FIELD_URL:
749 free(record->url); 744 free(record->url);
750 record->url = xstrdup(value); 745 record->url = xstrdup(value);
751 break; 746 break;
752 default: 747 default:
753 pwm_err(ctx, "bad field name \"%s\"", argv[i]); 748 pwm_err(ctx, "unknown field name \"%s\"", argv[i]);
754 goto out; 749 goto out;
755 } 750 }
756 } 751 }
757 752
758 if (ctx->is_interactive && (argc < 3)) { 753 if (ctx->is_interactive && (argc < 3)) {
774 cmd_generatepassword(struct pwm_ctx *ctx, int argc, char *argv[]) 769 cmd_generatepassword(struct pwm_ctx *ctx, int argc, char *argv[])
775 { 770 {
776 enum cmd_return retval = CMD_ERR; 771 enum cmd_return retval = CMD_ERR;
777 unsigned int id = 0; 772 unsigned int id = 0;
778 int i = 1; 773 int i = 1;
774 enum cmd_generatepassword_arg_type type;
779 char *value = NULL; 775 char *value = NULL;
780 long x; 776 long x;
781 char *p; 777 char *p;
782 size_t password_len = 16; 778 size_t password_len = 16;
783 size_t chars_min; 779 size_t chars_min;
796 goto out; 792 goto out;
797 } 793 }
798 } 794 }
799 795
800 for (; i < argc; i++) { 796 for (; i < argc; i++) {
801 switch (parse_arg(argv[i], cmd_generatepassword_argv, '=', 797 type = parse_arg(argv[i], cmd_generatepassword_argv, '=',
802 &value)) { 798 &value);
799 if ((type >= 0) && ((value == NULL) || (value[0] == '\0'))) {
800 pwm_err(ctx, "invalid value for \"%s\"", argv[i]);
801 retval = CMD_USAGE;
802 goto out;
803 }
804 switch (type) {
803 case CMD_GP_ARG_LEN: 805 case CMD_GP_ARG_LEN:
804 errno = 0; 806 errno = 0;
805 x = strtol(value, &p, 10); 807 x = strtol(value, &p, 10);
806 if ((errno != 0) || (*value == '\0') || (*p != '\0') || 808 if ((errno != 0) || (*value == '\0') || (*p != '\0') ||
807 (x > PWS3_MAX_PASSWORD_LEN) || (x <= 0)) { 809 (x > PWS3_MAX_PASSWORD_LEN) || (x <= 0)) {
1030 } 1032 }
1031 1033
1032 for (i = 2; i < argc; i++) { 1034 for (i = 2; i < argc; i++) {
1033 type = parse_arg(argv[i], field_namev, '\0', NULL); 1035 type = parse_arg(argv[i], field_namev, '\0', NULL);
1034 if (type < 0) { 1036 if (type < 0) {
1035 pwm_err(ctx, "bad field name \"%s\"", argv[i]); 1037 pwm_err(ctx, "unknown field name \"%s\"", argv[i]);
1036 return (CMD_ERR); 1038 return (CMD_ERR);
1037 } 1039 }
1038 fields[type] = 1; 1040 fields[type] = 1;
1039 } 1041 }
1040 1042
1072 return (CMD_ERR); 1074 return (CMD_ERR);
1073 } 1075 }
1074 1076
1075 type = parse_arg(argv[2], field_namev, '\0', NULL); 1077 type = parse_arg(argv[2], field_namev, '\0', NULL);
1076 if (type < 0) { 1078 if (type < 0) {
1077 pwm_err(ctx, "bad field name \"%s\"", argv[2]); 1079 pwm_err(ctx, "unknown field name \"%s\"", argv[2]);
1078 return (CMD_ERR); 1080 return (CMD_ERR);
1079 } 1081 }
1080 fields[type] = 1; 1082 fields[type] = 1;
1081 1083
1082 cmd = (argc == 4) ? argv[3] : ctx->pipecmd; 1084 cmd = (argc == 4) ? argv[3] : ctx->pipecmd;