diff pwfile.c @ 10:17fb30016e64

Enable access to record and file metadata Add info command to show file metadata. Enable display of creation and modification dates of records.
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Fri, 28 Jul 2017 15:53:57 +0200
parents 60c8ab006e55
children cf81eb0c2d5a
line wrap: on
line diff
--- a/pwfile.c	Fri Jul 28 09:53:46 2017 +0200
+++ b/pwfile.c	Fri Jul 28 15:53:57 2017 +0200
@@ -23,6 +23,7 @@
 
 #include "compat.h"
 
+#include <ctype.h>
 #ifdef	HAVE_ERR_H
 #include <err.h>
 #endif /* HAVE_ERR_H */
@@ -597,6 +598,94 @@
 	free(list);
 }
 
+static int
+parse_user_host(const char *user_host, char **userp, char **hostp)
+{
+	size_t		user_host_len;
+	size_t		i;
+	unsigned int	user_len;
+
+	user_host_len = strlen(user_host);
+	if (user_host_len < 4) {
+		return (-1);
+	}
+	for (i = 0; i < 4; i++) {
+		if (!isxdigit(user_host[i])) {
+			return (-1);
+		}
+	}
+	if (sscanf(user_host, "%04x", &user_len) != 1) {
+		return (-1);
+	}
+	if (4 + (size_t)user_len > user_host_len) {
+		return (-1);
+	}
+
+	xasprintf(userp, "%.*s", (int)user_len, user_host + 4);
+	xasprintf(hostp, "%s", user_host + 4 + user_len);
+
+	return (0);
+}
+
+struct metadata *
+pwfile_get_metadata(struct pwm_ctx *ctx)
+{
+	struct metadata	*metadata;
+	struct pws3_field *version_field;
+	struct pws3_field *save_app_field;
+	struct pws3_field *save_timestamp_field;
+	struct pws3_field *save_user_field;
+	struct pws3_field *save_host_field;
+	struct pws3_field *save_user_host_field;
+
+	metadata = xmalloc(sizeof (struct metadata));
+
+	version_field = pws3_file_get_header_field(ctx->file,
+	    PWS3_HEADER_FIELD_VERSION);
+	metadata->version = pws3_field_get_uint16(version_field);
+
+	save_app_field = pws3_file_get_header_field(ctx->file,
+	    PWS3_HEADER_FIELD_SAVE_APPLICATION);
+	metadata->application = (save_app_field != NULL) ?
+	    xstrdup(pws3_field_get_text(save_app_field)) : NULL;
+
+	save_timestamp_field = pws3_file_get_header_field(ctx->file,
+	    PWS3_HEADER_FIELD_SAVE_TIMESTAMP);
+	metadata->timestamp = (save_timestamp_field != NULL) ?
+	    pws3_field_get_time(save_timestamp_field) : 0;
+
+	save_user_field = pws3_file_get_header_field(ctx->file,
+	    PWS3_HEADER_FIELD_SAVE_USER);
+	save_host_field = pws3_file_get_header_field(ctx->file,
+	    PWS3_HEADER_FIELD_SAVE_HOST);
+	save_user_host_field = pws3_file_get_header_field(ctx->file,
+	    PWS3_HEADER_FIELD_SAVE_USER_HOST);
+	metadata->user = NULL;
+	metadata->host = NULL;
+	if ((save_user_field != NULL) && (save_host_field != NULL)) {
+		metadata->user = xstrdup(pws3_field_get_text(save_user_field));
+		metadata->host = xstrdup(pws3_field_get_text(save_host_field));
+	} else if (save_user_host_field != NULL) {
+		parse_user_host(pws3_field_get_text(save_user_host_field),
+		    &metadata->user, &metadata->host);
+	}
+
+	return (metadata);
+}
+
+void
+pwfile_destroy_metadata(struct metadata *metadata)
+{
+	if (metadata == NULL) {
+		return;
+	}
+
+	free(metadata->user);
+	free(metadata->host);
+	free(metadata->application);
+	free(metadata);
+}
+
 static void
 update_record(struct pws3_record *pws3_record, struct record *record)
 {
@@ -820,6 +909,8 @@
 	struct record	*record;
 	const unsigned char *uuid;
 	struct pws3_record *pws3_record;
+	struct pws3_field *ctime_field;
+	struct pws3_field *mtime_field;
 	struct pws3_field *title_field;
 	struct pws3_field *group_field;
 	struct pws3_field *username_field;
@@ -835,6 +926,16 @@
 
 	record = xmalloc(sizeof (struct record));
 
+	ctime_field = pws3_record_get_field(pws3_record,
+	    PWS3_RECORD_FIELD_CREATION_TIME);
+	record->ctime = (ctime_field != NULL) ?
+	    pws3_field_get_time(ctime_field) : (time_t)0;
+
+	mtime_field = pws3_record_get_field(pws3_record,
+	    PWS3_RECORD_FIELD_MODIFICATION_TIME);
+	record->mtime = (mtime_field != NULL) ?
+	    pws3_field_get_time(mtime_field) : (time_t)0;
+
 	title_field = pws3_record_get_field(pws3_record,
 	    PWS3_RECORD_FIELD_TITLE);
 	record->title = (title_field != NULL) ?