Recently Written · git

pass-simple

fork of zerous' minimal pass rewrite with bugfixes

git clone https://github.com/equwal/pass-simple

Log | Files | Refs


commit 08805fb06c71d0025a1f0fcf3443540cf52152ae
Spenser Truex <truex@equwal.com>
2025-09-02 13:59:28 -0700

Bugfix v2: pass ver and help

 Makefile |   1 +
 pass.c   | 550 ++++++++++++++++++++++++++++++---------------------------------
 2 files changed, 264 insertions(+), 287 deletions(-)
diff --git a/Makefile b/Makefile
index 0dff475..93e4882 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,4 @@
+# also bump the version in pass.c when bumping
 VERSION = 0.1
 
 include config.mk
diff --git a/pass.c b/pass.c
index bcad67f..2e7dc3a 100644
--- a/pass.c
+++ b/pass.c
@@ -1,15 +1,15 @@
-/* See LICENSE file for copyright and license details. */		
+/* See LICENSE file for copyright and license details. */
 #include <errno.h>
 #include <fcntl.h>
-#include <gpgme.h>
 #include <getopt.h>
-#include <limits.h>
+#include <gpgme.h>
 #include <libgen.h>
+#include <limits.h>
 #include <locale.h>
 #include <pwd.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
@@ -19,327 +19,303 @@
 #define MAX_BUFSIZ 512
 static char file[PATH_MAX];
 const char *home;
+const char *version = "0.1"; // also change makefile
 
-void
-initgpgme(void)
-{
-	const char *reqlibver = "1.6.0";
-	const char *reqgpgver = "2.1.0";
+void initgpgme(void) {
+    const char *reqlibver = "1.6.0";
+    const char *reqgpgver = "2.1.0";
 
-	setlocale(LC_ALL, "en_US.UTF-8");
-	gpgme_set_locale(NULL, LC_ALL, "en_US.UTF-8");
-	gpgme_set_global_flag("require-gnupg", reqgpgver);
-	gpgme_check_version(reqlibver);
+    setlocale(LC_ALL, "en_US.UTF-8");
+    gpgme_set_locale(NULL, LC_ALL, "en_US.UTF-8");
+    gpgme_set_global_flag("require-gnupg", reqgpgver);
+    gpgme_check_version(reqlibver);
 }
 
-void
-gethomedir(void)
-{
-	if (!(home = getenv("HOME")))
-		fatalx("$HOME not set, cannot determine password-store location");
+void gethomedir(void) {
+    if (!(home = getenv("HOME")))
+        fatalx("$HOME not set, cannot determine password-store location");
 }
 
+void delete(char *item) {
+    char *l;
+    int r;
 
-void
-delete(char *item)
-{ 
-	char *l;
-	int r;
-	
-	gethomedir();
-	snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item);
-	printf("Are you sure you would like to delete %s? [y/N] ", item);
-	if ((r = getchar()) == 'N' || r == 'n')
-		exit(0);
-	else if ((r == 'y' || r == 'Y') && !remove(file)) {
-		printf("removed '%s'\n", file);
-		if ((l = strrchr(file, '/')))
-			*l = '\0';
-		rmdir(file);
-	}
+    gethomedir();
+    snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item);
+    printf("Are you sure you would like to delete %s? [y/N] ", item);
+    if ((r = getchar()) == 'N' || r == 'n')
+        exit(0);
+    else if ((r == 'y' || r == 'Y') && !remove(file)) {
+        printf("removed '%s'\n", file);
+        if ((l = strrchr(file, '/')))
+            *l = '\0';
+        rmdir(file);
+    }
 }
 
-void
-usage(void)
-{
-	fprintf(stderr,
-		"usage:\tpass init gpg-id\n"
-		"\tpass insert pass-name\n"
-		"\tpass pass-name\n"
-		"\tpass rm pass-name\n"
-	       );
-	exit(1);
+void usage(void) {
+    fprintf(stderr, "usage:\tpass init gpg-id\n"
+                    "\tpass insert pass-name\n"
+                    "\tpass pass-name\n"
+                    "\tpass rm pass-name\n");
+    exit(1);
 }
 
-void
-decrypt(char *buf)
-{
-	gpgme_data_t in, out;
-	gpgme_error_t gpgerr;
-	gpgme_ctx_t ctx;
-	gpgme_protocol_t proto; 
-	int a, ret;
+void decrypt(char *buf) {
+    gpgme_data_t in, out;
+    gpgme_error_t gpgerr;
+    gpgme_ctx_t ctx;
+    gpgme_protocol_t proto;
+    int a, ret;
 
-	initgpgme(); 
-	proto = GPGME_PROTOCOL_OpenPGP;
+    initgpgme();
+    proto = GPGME_PROTOCOL_OpenPGP;
 
-	gpgerr = gpgme_new(&ctx);
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "Error: gpgme_new: %s");
-	gpgerr = gpgme_set_protocol(ctx, proto); 
-	if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE)
-		fatalgpg(gpgerr, "Error: gpgme_set_protocol");
-	gpgerr = gpgme_data_new_from_file(&in, file, 1); 
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "Error: gpgme_data_new_from_file");
-	gpgerr = gpgme_data_new(&out);
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "Error: gpgme_data_new");
-	gpgerr = gpgme_op_decrypt(ctx, in, out);
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "Error: gpgme_op_decrypt");
-	ret = gpgme_data_seek(out, 0, SEEK_SET);
-	if (ret)
-		fatalx("gpgme_data_seek");
-	if ((a = gpgme_data_read(out, buf, 100)) > 0) 
-		buf[a] = '\0';
-	gpgme_data_release(in);
-	gpgme_data_release(out);
-	gpgme_release(ctx);
+    gpgerr = gpgme_new(&ctx);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "Error: gpgme_new: %s");
+    gpgerr = gpgme_set_protocol(ctx, proto);
+    if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE)
+        fatalgpg(gpgerr, "Error: gpgme_set_protocol");
+    gpgerr = gpgme_data_new_from_file(&in, file, 1);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "Error: gpgme_data_new_from_file");
+    gpgerr = gpgme_data_new(&out);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "Error: gpgme_data_new");
+    gpgerr = gpgme_op_decrypt(ctx, in, out);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "Error: gpgme_op_decrypt");
+    ret = gpgme_data_seek(out, 0, SEEK_SET);
+    if (ret)
+        fatalx("gpgme_data_seek");
+    if ((a = gpgme_data_read(out, buf, 100)) > 0)
+        buf[a] = '\0';
+    gpgme_data_release(in);
+    gpgme_data_release(out);
+    gpgme_release(ctx);
 }
 
+void printpass(char *item) {
+    char buf[MAX_BUFSIZ];
+    int fin;
 
-void
-printpass(char *item)
-{
-	char buf[MAX_BUFSIZ];
-	int fin;
-
-	gethomedir();
-	snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item);
-	/* Check if file exists */
-	fin = open(file, O_RDONLY);
-	if (fin == -1)
-		fatal("%s is not in password store.", file);
-	decrypt(buf);
-	printf("%s\n", buf);
-	close(fin);
+    gethomedir();
+    snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item);
+    /* Check if file exists */
+    fin = open(file, O_RDONLY);
+    if (fin == -1)
+        fatal("%s is not in password store.", file);
+    decrypt(buf);
+    printf("%s\n", buf);
+    close(fin);
 }
 
-void
-getuserid(char *u, int usize)
-{
-	char file[PATH_MAX];
-	FILE *fp;
-	int i;
+void printversion(void) { printf("%s\n", version); }
+
+void getuserid(char *u, int usize) {
+    char file[PATH_MAX];
+    FILE *fp;
+    int i;
 
-	snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home);
-	fp = fopen(file, "r");
-	if (!fp)
-		fatal("fopen: %s", file);
-	while ((i = fgetc(fp)) != EOF && usize--)
-		*u++ = i;
-	*u = '\0';
+    snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home);
+    fp = fopen(file, "r");
+    if (!fp)
+        fatal("fopen: %s", file);
+    while ((i = fgetc(fp)) != EOF && usize--)
+        *u++ = i;
+    *u = '\0';
 }
 
-void
-mkdirp(const char *tp)
-{
-	char *i, t[PATH_MAX];
-	int r;
-	mode_t mode = S_IRWXU;
+void mkdirp(const char *tp) {
+    char *i, t[PATH_MAX];
+    int r;
+    mode_t mode = S_IRWXU;
 
-	memcpy(t, file, strlen(file) + 1);
-	while ((i = strchr(tp, '/'))) {	
-		*i = '\0';
-		snprintf(file, sizeof(file), "%s/%s", t, tp);
-		printf("mkdir %s\n", file);
-		if ((r = mkdir(file, mode)) == -1) {
-			if (errno != EEXIST)
-				fatal("mkdir");
-		}
-		tp = i + 1;
-	}
+    memcpy(t, file, strlen(file) + 1);
+    while ((i = strchr(tp, '/'))) {
+        *i = '\0';
+        snprintf(file, sizeof(file), "%s/%s", t, tp);
+        printf("mkdir %s\n", file);
+        if ((r = mkdir(file, mode)) == -1) {
+            if (errno != EEXIST)
+                fatal("mkdir");
+        }
+        tp = i + 1;
+    }
 }
 
-void
-encrypt()
-{
-	gpgme_data_t in, out;
-	gpgme_error_t gpgerr;
-	gpgme_ctx_t ctx;
-	gpgme_key_t key;
-	gpgme_key_t keys[2];
-	gpgme_protocol_t proto; 
-	char uid[MAX_BUFSIZ], t[PATH_MAX];
-	FILE *fin, *fout;
+void encrypt() {
+    gpgme_data_t in, out;
+    gpgme_error_t gpgerr;
+    gpgme_ctx_t ctx;
+    gpgme_key_t key;
+    gpgme_key_t keys[2];
+    gpgme_protocol_t proto;
+    char uid[MAX_BUFSIZ], t[PATH_MAX];
+    FILE *fin, *fout;
 
-	proto = GPGME_PROTOCOL_OpenPGP;
-	key = NULL;
+    proto = GPGME_PROTOCOL_OpenPGP;
+    key = NULL;
 
-	initgpgme();
-	getuserid(uid, MAX_BUFSIZ);
-	gpgerr = gpgme_new(&ctx);
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "gpme_new");
-	gpgerr = gpgme_set_protocol(ctx, proto); 
-	if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE)
-		fatalgpg(gpgerr, "gpgme_set_protocol");
-	gpgme_set_armor(ctx, 1);
-	if (gpgme_op_keylist_start(ctx, uid, 0) != GPG_ERR_INV_VALUE)
-		while (!(gpgerr = gpgme_op_keylist_next(ctx, &key))) {
-			if (key->can_encrypt)
-				break;
-		}
-	if (gpgme_err_code(gpgerr) == GPG_ERR_EOF)
-		fatalgpg(gpgerr, "can not find key");
-	keys[0] = key;
-	keys[1] = NULL;
-	fin = fopen(file, "r");
-	memcpy(t, file, strlen(file) + 1);
-	snprintf(file, sizeof(file), "%s.gpg", t);
-	fout = fopen(file, "w");
-	gpgerr = gpgme_data_new_from_stream(&in, fin);
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "gpgme_data_new_from_stream");
-	gpgerr = gpgme_data_new_from_stream(&out, fout);
-	gpgme_data_set_encoding(out, GPGME_DATA_ENCODING_ARMOR);
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "gpgme_data_new_from_stream");
-	gpgerr = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);	
-	if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
-		fatalgpg(gpgerr, "gpgme_op_encrypt");
-	if (remove(t))
-		fprintf(stderr, "remove failed\n");
-	gpgme_key_release(key);
-	gpgme_data_release(in);
-	gpgme_data_release(out);
-	gpgme_release(ctx);
+    initgpgme();
+    getuserid(uid, MAX_BUFSIZ);
+    gpgerr = gpgme_new(&ctx);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "gpme_new");
+    gpgerr = gpgme_set_protocol(ctx, proto);
+    if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE)
+        fatalgpg(gpgerr, "gpgme_set_protocol");
+    gpgme_set_armor(ctx, 1);
+    if (gpgme_op_keylist_start(ctx, uid, 0) != GPG_ERR_INV_VALUE)
+        while (!(gpgerr = gpgme_op_keylist_next(ctx, &key))) {
+            if (key->can_encrypt)
+                break;
+        }
+    if (gpgme_err_code(gpgerr) == GPG_ERR_EOF)
+        fatalgpg(gpgerr, "can not find key");
+    keys[0] = key;
+    keys[1] = NULL;
+    fin = fopen(file, "r");
+    memcpy(t, file, strlen(file) + 1);
+    snprintf(file, sizeof(file), "%s.gpg", t);
+    fout = fopen(file, "w");
+    gpgerr = gpgme_data_new_from_stream(&in, fin);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "gpgme_data_new_from_stream");
+    gpgerr = gpgme_data_new_from_stream(&out, fout);
+    gpgme_data_set_encoding(out, GPGME_DATA_ENCODING_ARMOR);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "gpgme_data_new_from_stream");
+    gpgerr = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
+    if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR)
+        fatalgpg(gpgerr, "gpgme_op_encrypt");
+    if (remove(t))
+        fprintf(stderr, "remove failed\n");
+    gpgme_key_release(key);
+    gpgme_data_release(in);
+    gpgme_data_release(out);
+    gpgme_release(ctx);
 }
 
-void
-insert(char *item)
-{
-	char *filename, t[PATH_MAX];
-	FILE *fp;
-	char pass[MAX_BUFSIZ];
-	int c, fd;
+void insert(char *item) {
+    char *filename, t[PATH_MAX];
+    FILE *fp;
+    char pass[MAX_BUFSIZ];
+    int c, fd;
 
-	c = 'y';
-	fd = fileno(stdin);
+    c = 'y';
+    fd = fileno(stdin);
 
-	gethomedir();
-	snprintf(file, sizeof(file), "%s/.password-store", home);
-	filename = basename(item);
-	mkdirp(item);	
-	memcpy(t, file, strlen(file) + 1);
-	snprintf(file, sizeof(file), "%s/%s", t, filename);
-	snprintf(t, sizeof(t), "%s.gpg", file);
-	if ((fp = fopen(t, "r"))) {
-		if (isatty(fd)) {
-			printf("An entry already exists for %s. Overwrite it? [y/N] ", filename);
-			if ((c = getchar()) == 'N' || c == 'n') {
-				fclose(fp);
-				logdbgx("Don't overwrite");
-				exit(1);
-			}
-		} else
-			/* Assuming user knows what he/she is doing */
-			printf("Overwriting %s\n", filename);
-	}
-	if (c != 'Y' && c != 'y')
-		exit(1);
-	if (!(fp = fopen(file, "w+b")))
-		fatal("fopen: %s", file);
-	if (isatty(fd)) {
-		readpassphrase("Enter password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF);
-		memcpy(t, pass, strlen(pass) + 1);
-		readpassphrase("Retype password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF);
-		if (!strcmp(pass, t))
-		{
-			int i = 0;
-			while(t[i] != '\0') {
-				if (fputc(t[i], fp) == EOF)
-					fatal("fputc: %s", file);
-				i++;
-			}
-		} else 
-			fatalx("Passwords don't match.");
-	} else {
-		int c;
-		while ((c = getchar()) != EOF && c != '\n')
-			fputc(c, fp);
-	}
-	fclose(fp);
-	encrypt();
+    gethomedir();
+    snprintf(file, sizeof(file), "%s/.password-store", home);
+    filename = basename(item);
+    mkdirp(item);
+    memcpy(t, file, strlen(file) + 1);
+    snprintf(file, sizeof(file), "%s/%s", t, filename);
+    snprintf(t, sizeof(t), "%s.gpg", file);
+    if ((fp = fopen(t, "r"))) {
+        if (isatty(fd)) {
+            printf("An entry already exists for %s. Overwrite it? [y/N] ", filename);
+            if ((c = getchar()) == 'N' || c == 'n') {
+                fclose(fp);
+                logdbgx("Don't overwrite");
+                exit(1);
+            }
+        } else
+            /* Assuming user knows what he/she is doing */
+            printf("Overwriting %s\n", filename);
+    }
+    if (c != 'Y' && c != 'y')
+        exit(1);
+    if (!(fp = fopen(file, "w+b")))
+        fatal("fopen: %s", file);
+    if (isatty(fd)) {
+        readpassphrase("Enter password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF);
+        memcpy(t, pass, strlen(pass) + 1);
+        readpassphrase("Retype password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF);
+        if (!strcmp(pass, t)) {
+            int i = 0;
+            while (t[i] != '\0') {
+                if (fputc(t[i], fp) == EOF)
+                    fatal("fputc: %s", file);
+                i++;
+            }
+        } else
+            fatalx("Passwords don't match.");
+    } else {
+        int c;
+        while ((c = getchar()) != EOF && c != '\n')
+            fputc(c, fp);
+    }
+    fclose(fp);
+    encrypt();
 }
 
-int
-isinit(void)
-{
-	int fp;
-	struct stat sb;
+int isinit(void) {
+    int fp;
+    struct stat sb;
 
-	gethomedir();
-	snprintf(file, sizeof(file), "%s/.password-store", home);
-	if ((fp = open(file, O_RDONLY)) != -1 &&
-	    (!fstat(fp, &sb)) &&
-	    (S_ISDIR(sb.st_mode))) {
-		close(fp);
-		return 1;
-	}
-	return 0;
+    gethomedir();
+    snprintf(file, sizeof(file), "%s/.password-store", home);
+    if ((fp = open(file, O_RDONLY)) != -1 && (!fstat(fp, &sb)) && (S_ISDIR(sb.st_mode))) {
+        close(fp);
+        return 1;
+    }
+    return 0;
 }
 
-void
-initpass(char *pgpid)
-{
-	FILE *gpg;
-	mode_t mode = S_IRWXU;
+void initpass(char *pgpid) {
+    FILE *gpg;
+    mode_t mode = S_IRWXU;
 
-	if (!pgpid) {
-		usage();
-	}
-	if (!isinit())
-	{
-		if (mkdir(file, mode))
-			fatal("mkdir");
-		snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home);
-		if (!(gpg = fopen(file, "a"))) 
-			fatal("fopen");
-		if (fputs(pgpid, gpg) == EOF)
-			fatal("fputs");
-		printf("Password store initialized for %s\n", pgpid);
-		fclose(gpg);
-	} else
-		printf("Password store initialized for %s\n", pgpid);
+    if (!pgpid) {
+        usage();
+    }
+    if (!isinit()) {
+        if (mkdir(file, mode))
+            fatal("mkdir");
+        snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home);
+        if (!(gpg = fopen(file, "a")))
+            fatal("fopen");
+        if (fputs(pgpid, gpg) == EOF)
+            fatal("fputs");
+        printf("Password store initialized for %s\n", pgpid);
+        fclose(gpg);
+    } else
+        printf("Password store initialized for %s\n", pgpid);
 }
 
-int
-main(int argc, char** argv)
-{
-	char **s;
-	int i;
+int main(int argc, char **argv) {
+    char **s;
+    int i;
 
-	debug = 0;
+    debug = 0;
 
-	for (s = argv, i = 0; i < argc; i++) {
-		if (!strcmp("-d", *s++))
-			debug = 1;
-	}
-	if (argc > 1)
-	{
-		argv++;
-		loginit("pass");
-		if 	(!strcmp("init", *argv))
-			initpass(*(argv + 1));
-		else if (!strcmp("insert", *argv))
-			insert(*(argv + 1));
-		else if (!strcmp("rm", *argv))
-			delete(*(argv + 1));
-		else
-			printpass(*argv);
-	} else 
-		usage();
-	return 0;
+    for (s = argv, i = 0; i < argc - 1; i++) {
+        if (!strcmp("-d", *s++)) {
+            debug = 1;
+            argv++;
+        }
+    }
+    if (argc > 1) {
+        argv++;
+        loginit("pass");
+        if (!strcmp("init", *argv))
+            initpass(*(argv + 1));
+        else if (!strcmp("insert", *argv))
+            insert(*(argv + 1));
+        else if (!strcmp("rm", *argv))
+            delete(*(argv + 1));
+        else if (!strcmp("show", *argv))
+            printpass(*(argv + 1));
+        else if (!strcmp("help", *argv))
+            usage();
+        else if (!strcmp("ver", *argv))
+            printversion();
+        else
+            printpass(*argv);
+    } else
+        usage();
+    return 0;
 }