diff cmd.c @ 16:a07665727c19

Add status command Add status command to redisplay an error message of the previous command and unsaved changes. Add pwm_err function to display and save error messages.
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Tue, 08 Aug 2017 10:47:04 +0200
parents 3380c8fd9776
children a08ef0674d8e
line wrap: on
line diff
--- a/cmd.c	Mon Aug 07 19:11:56 2017 +0200
+++ b/cmd.c	Tue Aug 08 10:47:04 2017 +0200
@@ -82,6 +82,7 @@
 	CHARCLASS_GRAPH
 };
 
+static enum cmd_return	cmd_status(struct pwm_ctx *, int, char *[]);
 static enum cmd_return	cmd_info(struct pwm_ctx *, int, char *[]);
 static enum cmd_return	cmd_list(struct pwm_ctx *, int, char *[]);
 static enum cmd_return	cmd_create(struct pwm_ctx *, int, char *[]);
@@ -151,6 +152,8 @@
 };
 
 static struct cmd cmds[] = {
+    { "t", "status", "status", "Redisplay an error message of the previous "
+    "command and unsaved changes", cmd_status },
     { "i", "info", "info", "Show metadata information about the current file",
     cmd_info },
     { "ls", "list", "list [field~regex ...]", "List entries", cmd_list },
@@ -214,6 +217,22 @@
 }
 
 static enum cmd_return
+cmd_status(struct pwm_ctx *ctx, int argc, char *argv[])
+{
+	if (argc != 1) {
+		return (CMD_USAGE);
+	}
+
+	if (ctx->errmsg != NULL) {
+		printf("%s\n", ctx->errmsg);
+	}
+	printf("There are%sunsaved changes\n", ctx->unsaved_changes ? " " :
+	    " no ");
+
+	return (CMD_STATUS);
+}
+
+static enum cmd_return
 cmd_info(struct pwm_ctx *ctx, int argc, char *argv[])
 {
 	struct metadata	*metadata;
@@ -267,7 +286,7 @@
 	for (i = 1; i < argc; i++) {
 		type = parse_arg(argv[i], field_namev, '~', &value);
 		if (type == FIELD_UNKNOWN) {
-			fprintf(stderr, "bad field name \"%s\"\n", argv[i]);
+			pwm_err(ctx, "bad field name \"%s\"", argv[i]);
 			goto out;
 		}
 		if (value[0] == '\0') {
@@ -291,7 +310,7 @@
 			repp = &url_re;
 			break;
 		default:
-			fprintf(stderr, "bad field name \"%s\"\n", argv[i]);
+			pwm_err(ctx, "bad field name \"%s\"", argv[i]);
 			goto out;
 		}
 
@@ -305,8 +324,7 @@
 			errbuf_size = regerror(errcode, *repp, "", 0);
 			errbuf = xmalloc(errbuf_size);
 			regerror(errcode, *repp, errbuf, errbuf_size);
-			fprintf(stderr, "bad regular expression \"%s\"\n",
-			    errbuf);
+			pwm_err(ctx, "bad regular expression \"%s\"", errbuf);
 			free(errbuf);
 
 			free(*repp);
@@ -383,8 +401,7 @@
 	for (i = 1; i < argc; i++) {
 		type = parse_arg(argv[i], field_namev, '=', &value);
 		if (type == FIELD_UNKNOWN) {
-			fprintf(stderr, "bad field assignment \"%s\"\n",
-			    argv[i]);
+			pwm_err(ctx, "bad field assignment \"%s\"", argv[i]);
 		}
 		if (value[0] == '\0') {
 			/* skip empty assignments */
@@ -410,7 +427,7 @@
 			record.url = value;
 			break;
 		default:
-			fprintf(stderr, "bad field name \"%s\"\n", argv[i]);
+			pwm_err(ctx, "bad field name \"%s\"", argv[i]);
 			return (CMD_ERR);
 		}
 	}
@@ -434,15 +451,14 @@
 	}
 
 	if (parse_id(argv[1], &id) != 0) {
-		fprintf(stderr, "invalid id %s\n", argv[1]);
+		pwm_err(ctx, "invalid id %s", argv[1]);
 		return (CMD_ERR);
 	}
 
 	for (i = 2; i < argc; i++) {
 		type = parse_arg(argv[i], field_namev, '=', &value);
 		if (type == FIELD_UNKNOWN) {
-			fprintf(stderr, "bad field assignment \"%s\"\n",
-			    argv[i]);
+			pwm_err(ctx, "bad field assignment \"%s\"", argv[i]);
 			return (CMD_ERR);
 		}
 		if (value[0] == '\0') {
@@ -469,7 +485,7 @@
 			record.url = value;
 			break;
 		default:
-			fprintf(stderr, "bad field name \"%s\"\n", argv[i]);
+			pwm_err(ctx, "bad field name \"%s\"", argv[i]);
 			return (CMD_ERR);
 		}
 	}
@@ -510,8 +526,8 @@
 			x = strtol(value, &p, 10);
 			if ((errno != 0) || (*value == '\0') || (*p != '\0') ||
 			    (x > PWS3_MAX_PASSWORD_LEN) || (x <= 0)) {
-				fprintf(stderr, "invalid password length "
-				    "\"%s\"\n", argv[i]);
+				pwm_err(ctx, "invalid password length \"%s\"",
+				    argv[i]);
 				goto out;
 			}
 			password_len = x;
@@ -521,8 +537,8 @@
 			x = strtol(value, &p, 10);
 			if ((errno != 0) || (*value == '\0') || (*p != ':') ||
 			    (x < 0) || (x > PWS3_MAX_PASSWORD_LEN)) {
-				fprintf(stderr, "invalid minimum number of "
-				    "characters \"%s\"\n", argv[i]);
+				pwm_err(ctx, "invalid minimum number of "
+				    "characters \"%s\"", argv[i]);
 				goto out;
 			}
 			chars_min = x;
@@ -530,9 +546,8 @@
 			chars = ++p;
 			while (*p != '\0') {
 				if (!isascii(*p) || !isprint(*p)) {
-					fprintf(stderr, "invalid character in "
-					    "character group \"%s\"\n",
-					    argv[i]);
+					pwm_err(ctx, "invalid character in "
+					    "character group \"%s\"", argv[i]);
 					goto out;
 				}
 				p++;
@@ -550,16 +565,16 @@
 			x = strtol(value, &p, 10);
 			if ((errno != 0) || (*value == '\0') || (*p != ':') ||
 			    (x < 0) || (x > PWS3_MAX_PASSWORD_LEN)) {
-				fprintf(stderr, "invalid minimum number of "
-				    "characters \"%s\"\n", argv[i]);
+				pwm_err(ctx, "invalid minimum number of "
+				    "characters \"%s\"", argv[i]);
 				goto out;
 			}
 			chars_min = x;
 
 			charclass = parse_arg(++p, charclass_namev, '\0', NULL);
 			if (charclass < 0) {
-				fprintf(stderr, "unknown character class "
-				    "\"%s\"\n", argv[i]);
+				pwm_err(ctx, "unknown character class \"%s\"",
+				    argv[i]);
 				goto out;
 			}
 			chars = charclass_values[charclass];
@@ -571,7 +586,7 @@
 			char_groupv_len++;
 			break;
 		default:
-			fprintf(stderr, "invalid argument \"%s\"\n", argv[i]);
+			pwm_err(ctx, "invalid argument \"%s\"", argv[i]);
 			retval = CMD_USAGE;
 			goto out;
 		}
@@ -579,8 +594,8 @@
 
 	for (j = 0; j < char_groupv_len; j++) {
 		if (char_groupv[j].chars_min > password_len) {
-			fprintf(stderr, "invalid minimum number of "
-			    "characters \"%zu:%s\"\n", char_groupv[j].chars_min,
+			pwm_err(ctx, "invalid minimum number of characters "
+			    "\"%zu:%s\"", char_groupv[j].chars_min,
 			    char_groupv[j].chars);
 			goto out;
 		}
@@ -596,15 +611,15 @@
 
 	if (pw_genrandom(char_groupv, char_groupv_len, password,
 	    password_len) != 0) {
-		fprintf(stderr, "failed to generate password that meets the "
-		    "given constraints\n");
+		pwm_err(ctx, "failed to generate password that meets the given "
+		    "constraints");
 		goto out;
 	}
 
 	if (id != 0) {
 		if (pwfile_modify_record(ctx, id,
 		    &(struct record){ .password = password }) != 0) {
-			fprintf(stderr, "record %u does not exist\n", id);
+			pwm_err(ctx, "record %u does not exist", id);
 			goto out;
 		}
 	} else {
@@ -629,12 +644,12 @@
 	}
 
 	if (parse_id(argv[1], &id) != 0) {
-		fprintf(stderr, "invalid id %s\n", argv[1]);
+		pwm_err(ctx, "invalid id %s", argv[1]);
 		return (CMD_ERR);
 	}
 
 	if (pwfile_remove_record(ctx, id) != 0) {
-		fprintf(stderr, "failed to remove record %u\n", id);
+		pwm_err(ctx, "failed to remove record %u", id);
 		return (CMD_ERR);
 	}
 
@@ -736,7 +751,7 @@
 	}
 
 	if (parse_id(argv[1], &id) != 0) {
-		fprintf(stderr, "invalid id %s\n", argv[1]);
+		pwm_err(ctx, "invalid id %s", argv[1]);
 		return (CMD_ERR);
 	}
 
@@ -748,7 +763,7 @@
 	for (i = 2; i < argc; i++) {
 		type = parse_arg(argv[i], field_namev, '\0', NULL);
 		if (type < 0) {
-			fprintf(stderr, "bad field name \"%s\"\n", argv[i]);
+			pwm_err(ctx, "bad field name \"%s\"", argv[i]);
 			return (CMD_ERR);
 		}
 		fields[type] = 1;
@@ -756,7 +771,7 @@
 
 	record = pwfile_get_record(ctx, id);
 	if (record == NULL) {
-		fprintf(stderr, "record %u does not exist\n", id);
+		pwm_err(ctx, "record %u does not exist", id);
 		return (CMD_ERR);
 	}
 	print_record(record, fields, 1, stdout);
@@ -780,13 +795,13 @@
 	}
 
 	if (parse_id(argv[1], &id) != 0) {
-		fprintf(stderr, "invalid id %s\n", argv[1]);
+		pwm_err(ctx, "invalid id %s", argv[1]);
 		return (CMD_ERR);
 	}
 
 	type = parse_arg(argv[2], field_namev, '\0', NULL);
 	if (type < 0) {
-		fprintf(stderr, "bad field name \"%s\"\n", argv[2]);
+		pwm_err(ctx, "bad field name \"%s\"", argv[2]);
 		return (CMD_ERR);
 	}
 	fields[type] = 1;
@@ -799,7 +814,7 @@
 
 	record = pwfile_get_record(ctx, id);
 	if (record == NULL) {
-		fprintf(stderr, "record %u does not exist\n", id);
+		pwm_err(ctx, "record %u does not exist", id);
 		goto out;
 	}
 
@@ -824,7 +839,7 @@
 	}
 
 	if (pwfile_create_group(ctx, argv[1]) != 0) {
-		fprintf(stderr, "group \"%s\" already exists\n", argv[1]);
+		pwm_err(ctx, "group \"%s\" already exists", argv[1]);
 		return (CMD_ERR);
 	}
 
@@ -839,7 +854,7 @@
 	}
 
 	if (pwfile_remove_group(ctx, argv[1]) != 0) {
-		fprintf(stderr, "there is no empty group \"%s\"\n", argv[1]);
+		pwm_err(ctx, "empty group \"%s\" does not exist", argv[1]);
 		return (CMD_ERR);
 	}
 
@@ -858,10 +873,10 @@
 	} else if (argc == 2) {
 		password_len = strlen(argv[1]);
 		if (password_len == 0) {
-			fprintf(stderr, "password must not be empty\n");
+			pwm_err(ctx, "password must not be empty");
 			return (CMD_ERR);
 		} else if (password_len + 1 > sizeof (ctx->password)) {
-			fprintf(stderr, "password too long\n");
+			pwm_err(ctx, "password too long");
 			return (CMD_ERR);
 		}
 		memcpy(ctx->password, argv[1], password_len + 1);
@@ -873,7 +888,7 @@
 		}
 		password_len = strlen(password_buf);
 		if (password_len == 0) {
-			fprintf(stderr, "password must not be empty\n");
+			pwm_err(ctx, "password must not be empty");
 			return (CMD_ERR);
 		}
 		if (readpassphrase("Confirm password: ", confirm_buf,
@@ -882,7 +897,7 @@
 			err(1, "readpassphrase");
 		}
 		if (strcmp(password_buf, confirm_buf) != 0) {
-			fprintf(stderr, "passwords do not match\n");
+			pwm_err(ctx, "passwords do not match");
 			return (CMD_ERR);
 		}
 		memcpy(ctx->password, password_buf, password_len + 1);