Mercurial > projects > pwm
diff cmd.c @ 22:ec01c579024a
Add fully interactive mode
author | Guido Berhoerster <guido+pwm@berhoerster.name> |
---|---|
date | Thu, 07 Sep 2017 12:40:50 +0200 |
parents | 5c6155c8e9b6 |
children | 1b89066d992c |
line wrap: on
line diff
--- a/cmd.c Wed Sep 06 16:41:58 2017 +0200 +++ b/cmd.c Thu Sep 07 12:40:50 2017 +0200 @@ -402,18 +402,101 @@ return (retval); } +static int +read_record_fields(struct pwm_ctx *ctx, struct record *record) +{ + char group_buf[PWM_LINE_MAX] = { '\0' }; + char title_buf[PWM_LINE_MAX] = { '\0' }; + char username_buf[PWM_LINE_MAX] = { '\0' }; + char password_buf[PWM_LINE_MAX] = { '\0' }; + char notes_buf[PWM_LINE_MAX] = { '\0' }; + char url_buf[PWM_LINE_MAX] = { '\0' }; + + if (io_get_line(NULL, "Group: ", 0, record->group, -1, + sizeof (group_buf), group_buf) == IO_SIGNAL) { + return (CMD_SIGNAL); + } + io_trim_nl(group_buf); + + if (io_get_line(NULL, "Title: ", 0, record->title, -1, + sizeof (title_buf), title_buf) == IO_SIGNAL) { + return (CMD_SIGNAL); + } + io_trim_nl(title_buf); + + if (io_get_line(NULL, "Username: ", 0, record->username, -1, + sizeof (username_buf), username_buf) == IO_SIGNAL) { + return (CMD_SIGNAL); + } + io_trim_nl(username_buf); + + for (;;) { + switch (io_get_password("Password: ", "Confirm Password: ", + sizeof (password_buf), password_buf)) { + case IO_OK: /* FALLTHROUGH */ + case IO_PASSWORD_EMPTY: + goto password_done; + case IO_SIGNAL: + return (CMD_SIGNAL); + case IO_PASSWORD_MISMATCH: + pwm_err(ctx, "passwords do not match"); + continue; + } + } + +password_done: + if (io_get_line(NULL, "Notes: ", 0, record->notes, -1, + sizeof (notes_buf), notes_buf) == IO_SIGNAL) { + return (CMD_SIGNAL); + } + io_trim_nl(notes_buf); + + if (io_get_line(NULL, "URL: ", 0, record->url, -1, sizeof (url_buf), + url_buf) == IO_SIGNAL) { + return (CMD_SIGNAL); + } + io_trim_nl(url_buf); + + free(record->group); + record->group = (group_buf[0] != '\0') ? xstrdup(group_buf) : NULL; + free(record->title); + record->title = (title_buf[0] != '\0') ? xstrdup(title_buf) : NULL; + free(record->username); + record->username = (username_buf[0] != '\0') ? xstrdup(username_buf) : + NULL; + /* + * the current password cannot be edited, keep the current password if + * the user pressed return or ^D instead of deleting it like other + * fields + */ + if (password_buf[0] != '\0') { + free(record->password); + record->password = xstrdup(password_buf); + } + free(record->notes); + record->notes = (notes_buf[0] != '\0') ? xstrdup(notes_buf) : NULL; + free(record->url); + record->url = (url_buf[0] != '\0') ? xstrdup(url_buf) : NULL; + + return (CMD_OK); +} + static enum cmd_return cmd_create(struct pwm_ctx *ctx, int argc, char *argv[]) { + enum cmd_return retval = CMD_ERR; int i; - struct record record = { 0 }; + struct record *record = NULL; enum field_type type; char *value; - if (argc < 2) { - return (CMD_USAGE); + if (!ctx->is_interactive && (argc < 2)) { + retval = CMD_USAGE; + goto out; } + record = pwfile_create_record(); + for (i = 1; i < argc; i++) { type = parse_arg(argv[i], field_namev, '=', &value); if (type == FIELD_UNKNOWN) { @@ -425,57 +508,76 @@ } switch (type) { case FIELD_GROUP: - record.group = value; + free(record->group); + record->group = xstrdup(value); break; case FIELD_TITLE: - record.title = value; + free(record->title); + record->title = xstrdup(value); break; case FIELD_USERNAME: - record.username = value; + free(record->username); + record->username = xstrdup(value); break; case FIELD_PASSWORD: - record.password = value; + free(record->password); + record->password = xstrdup(value); break; case FIELD_NOTES: - record.notes = value; + free(record->notes); + record->notes = xstrdup(value); break; case FIELD_URL: - record.url = value; + free(record->url); + record->url = xstrdup(value); break; default: pwm_err(ctx, "bad field name \"%s\"", argv[i]); - return (CMD_ERR); + goto out; } } - pwfile_create_record(ctx, &record); + if (ctx->is_interactive && (argc < 2)) { + if (read_record_fields(ctx, record) != 0) { + goto out; + } + } - return (CMD_OK); + pwfile_create_pws_record(ctx, record); + retval = CMD_OK; + +out: + pwfile_destroy_record(record); + + return (retval); } static enum cmd_return cmd_modify(struct pwm_ctx *ctx, int argc, char *argv[]) { + int retval = CMD_ERR; unsigned int id; int i; - struct record record = { 0 }; + struct record *record = NULL; enum field_type type; char *value; - if (argc < 2) { - return (CMD_USAGE); + if (!ctx->is_interactive && (argc < 2)) { + retval = CMD_USAGE; + goto out; } if (parse_id(argv[1], &id) != 0) { pwm_err(ctx, "invalid id %s", argv[1]); - return (CMD_ERR); + goto out; } + record = pwfile_get_record(ctx, id); for (i = 2; i < argc; i++) { type = parse_arg(argv[i], field_namev, '=', &value); if (type == FIELD_UNKNOWN) { pwm_err(ctx, "bad field assignment \"%s\"", argv[i]); - return (CMD_ERR); + goto out; } if (value[0] == '\0') { /* skip empty assignments */ @@ -483,32 +585,48 @@ } switch (type) { case FIELD_GROUP: - record.group = value; + free(record->group); + record->group = xstrdup(value); break; case FIELD_TITLE: - record.title = value; + free(record->title); + record->title = xstrdup(value); break; case FIELD_USERNAME: - record.username = value; + free(record->username); + record->username = xstrdup(value); break; case FIELD_PASSWORD: - record.password = value; + free(record->password); + record->password = xstrdup(value); break; case FIELD_NOTES: - record.notes = value; + free(record->notes); + record->notes = xstrdup(value); break; case FIELD_URL: - record.url = value; + free(record->url); + record->url = xstrdup(value); break; default: pwm_err(ctx, "bad field name \"%s\"", argv[i]); - return (CMD_ERR); + goto out; } } - pwfile_modify_record(ctx, id, &record); + if (ctx->is_interactive && (argc < 3)) { + if (read_record_fields(ctx, record) != 0) { + goto out; + } + } - return (CMD_OK); + pwfile_modify_pws_record(ctx, id, record); + retval = CMD_OK; + +out: + pwfile_destroy_record(record); + + return (retval); } static enum cmd_return @@ -633,7 +751,7 @@ } if (id != 0) { - if (pwfile_modify_record(ctx, id, + if (pwfile_modify_pws_record(ctx, id, &(struct record){ .password = password }) != 0) { pwm_err(ctx, "record %u does not exist", id); goto out; @@ -663,7 +781,7 @@ return (CMD_ERR); } - if (pwfile_remove_record(ctx, id) != 0) { + if (pwfile_remove_pws_record(ctx, id) != 0) { pwm_err(ctx, "failed to remove record %u", id); return (CMD_ERR); } @@ -835,13 +953,27 @@ static enum cmd_return cmd_creategroup(struct pwm_ctx *ctx, int argc, char *argv[]) { - if (argc != 2) { + char group_buf[PWM_LINE_MAX] = { '\0' }; + + if (!ctx->is_interactive && (argc != 2)) { return (CMD_USAGE); } - if (pwfile_create_group(ctx, argv[1]) != 0) { - pwm_err(ctx, "group \"%s\" already exists", argv[1]); - return (CMD_ERR); + if (ctx->is_interactive && (argc != 2)) { + if (io_get_line(NULL, "Group: ", 0, NULL, 0, + sizeof (group_buf), group_buf) == IO_SIGNAL) { + return (CMD_SIGNAL); + } + io_trim_nl(group_buf); + } else { + strcpy(group_buf, argv[1]); + } + + if (group_buf[0] != '\0') { + if (pwfile_create_group(ctx, group_buf) != 0) { + pwm_err(ctx, "group \"%s\" already exists", group_buf); + return (CMD_ERR); + } } return (CMD_OK);