aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/constants.h8
-rw-r--r--src/exec-cmd.c495
-rw-r--r--src/implementation.c8
-rw-r--r--src/main.c470
-rw-r--r--src/r-x11.c2
5 files changed, 519 insertions, 464 deletions
diff --git a/src/constants.h b/src/constants.h
index 46ac024..cc15a86 100644
--- a/src/constants.h
+++ b/src/constants.h
@@ -26,12 +26,18 @@
#define GPGKEY_FILE ".gpg-key"
#define STD_TEXT_EDITOR "vi"
-#define errprint(RET, ...) \
+#define errprint_r(RET, ...) \
do { \
fprintf(stderr, "Error: " __VA_ARGS__); \
return RET; \
} while(0)
+#define errprint_ptr(PTR, RETVAL, ...) \
+ do { \
+ fprintf(stderr, "Error: " __VA_ARGS__); \
+ *PTR = RETVAL; \
+ } while(0)
+
#define usageprint(...) \
do { \
fprintf(stdout, "Usage: lpass " __VA_ARGS__); \
diff --git a/src/exec-cmd.c b/src/exec-cmd.c
new file mode 100644
index 0000000..6aced93
--- /dev/null
+++ b/src/exec-cmd.c
@@ -0,0 +1,495 @@
+/***
+ This file is part of LockPassword
+ Copyright (C) 2020-2021 Aleksandr D. Goncharov (Joursoir) <chat@joursoir.net>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+***/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <getopt.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#include "exec-cmd.h"
+#include "constants.h"
+#include "easydir.h"
+#include "implementation.h"
+#include "exec-cmd.h"
+#include "tree.h"
+
+int cmd_init(int argc, char *argv[])
+{
+ const char description[] = "init gpg-key\n";
+ int retval = 0, result;
+ char *gpg_key = argv[2];
+ if(gpg_key == NULL)
+ usageprint("%s", description);
+
+ // create .gpg-key in storage
+ FILE *filekey = fopen(GPGKEY_FILE, "w");
+ if(!filekey)
+ errprint_r(1, "%s\n", strerror(errno));
+
+ result = fputs(gpg_key, filekey);
+ if(result == EOF)
+ errprint_ptr(&retval, 1, "%s\n", strerror(errno));
+ else
+ printf("LockPassword initialized for %s\n", gpg_key);
+
+ fclose(filekey);
+ return retval;
+}
+
+int cmd_insert(int argc, char *argv[])
+{
+ const char description[] = "insert [-ecf] passname\n";
+ int retval = 0, result;
+ int flag_echo = 0, flag_force = 0, flag_copy = 0;
+ const struct option long_options[] = {
+ {"echo", no_argument, NULL, 'e'},
+ {"force", no_argument, NULL, 'f'},
+ {"copy", no_argument, NULL, 'c'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while((result = getopt_long(argc, argv, "efc", long_options, NULL)) != -1) {
+ switch(result) {
+ case 'e': { flag_echo = 1; break; }
+ case 'f': { flag_force = 1; break; }
+ case 'c': { flag_copy = 1; break; }
+ default: usageprint("%s", description);
+ }
+ }
+
+ if(optind < argc) optind++; // for skip "insert"
+ dbgprint("passname: %s\n", argv[optind]);
+
+ char *path = argv[optind];
+ if(path == NULL)
+ usageprint("%s", description);
+
+ result = check_sneaky_paths(path);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+
+ if(file_exist(path) == F_ISFILE) {
+ if(!flag_force) {
+ if(overwrite_answer(path) != 'y')
+ return 1;
+ }
+ }
+
+ char *f_pass, *s_pass;
+ do { // START DO
+
+ if(!flag_echo) {
+ visible_enter(0);
+
+ printf("Type your password: ");
+ f_pass = get_input(minlen_pass, maxlen_pass);
+ printf("\n");
+ if(f_pass == NULL) {
+ errprint_ptr(&retval, 1, "Incorrect password\n");
+ break;
+ }
+
+ printf("Type your password again: ");
+ s_pass = get_input(minlen_pass, maxlen_pass);
+ printf("\n");
+ if(s_pass == NULL) {
+ errprint_ptr(&retval, 1, "Incorrect password\n");
+ break;
+ }
+
+ if(strcmp(f_pass, s_pass) != 0) {
+ errprint_ptr(&retval, 1, "Password do not match\n");
+ break;
+ }
+ }
+ else {
+ printf("Type your password: ");
+ f_pass = get_input(minlen_pass, maxlen_pass);
+ if(f_pass == NULL) {
+ errprint_ptr(&retval, 1, "Incorrect password\n");
+ break;
+ }
+ }
+
+ result = insert_pass(path, f_pass);
+ if(result) {
+ errprint_ptr(&retval, 1, "Can't add password to LockPassword\n");
+ break;
+ }
+ if(flag_copy)
+ copy_outside(f_pass);
+
+ printf("Password added successfully for %s\n", path);
+
+ } while(0); // END DO
+
+ visible_enter(1);
+ if(f_pass)
+ free(f_pass);
+ if(s_pass)
+ free(s_pass);
+ return retval;
+}
+
+int cmd_edit(int argc, char *argv[])
+{
+ const char description[] = "edit passname\n";
+ int result, fd, pid, len_pass, save_errno;
+ /* We expect tmpfs to be mounted at /dev/shm */
+ char path_tmpfile[] = "/dev/shm/lpass.XXXXXX";
+ char *editor, *password;
+ char *path = argv[2];
+ if(!path)
+ usageprint("%s", description);
+
+ result = check_sneaky_paths(path);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+
+ result = file_exist(path);
+ if(result == F_NOEXIST)
+ errprint_r(1, "No such file exists\n");
+ if(result == F_ISDIR)
+ errprint_r(1, "It's a directory\n");
+
+ editor = getenv("EDITOR");
+ if(!editor)
+ editor = STD_TEXT_EDITOR;
+
+ password = get_password(path);
+ if(password == NULL)
+ errprint_r(1, "Decrypt password failed\n");
+
+ fd = mkstemp(path_tmpfile);
+ if(fd == -1) {
+ free(password);
+ errprint_r(1, "Create temporary file failed: %s\n", strerror(errno));
+ }
+ dbgprint("tmp file: %s\n", path_tmpfile);
+
+ len_pass = strlen(password);
+ result = write(fd, password, len_pass);
+ free(password);
+ close(fd);
+ if(result != len_pass) {
+ unlink(path_tmpfile);
+ errprint_r(1, "Write password to temporary file failed\n");
+ }
+
+ // fork for text editor
+ char *editor_arg[] = {editor, path_tmpfile, NULL};
+ pid = fork();
+ if(pid == -1) {
+ unlink(path_tmpfile);
+ errprint_r(1, "Start %s failed: %s\n", editor, strerror(errno));
+ }
+ if(pid == 0) { /* new process */
+ execvp(editor, editor_arg);
+ perror(editor);
+ exit(1);
+ }
+ wait(&pid);
+
+ fd = open(path_tmpfile, O_RDONLY);
+ if(fd == -1) {
+ unlink(path_tmpfile);
+ errprint_r(1, "Open temporary file failed: %s\n", strerror(errno));
+ }
+
+ password = malloc(sizeof(char) * (maxlen_pass + 1));
+ len_pass = read(fd, password, maxlen_pass);
+ save_errno = errno;
+ close(fd);
+ unlink(path_tmpfile);
+ if(len_pass < minlen_pass) {
+ free(password);
+ if(len_pass == -1)
+ errprint_r(1, "Read temporary file failed: %s\n", strerror(save_errno));
+ else
+ errprint_r(1, "Min. password length is %d\n", minlen_pass);
+ }
+ password[len_pass-1] = '\0';
+ dbgprint("new pass: %s\n", password);
+
+ // encrypt
+ result = insert_pass(path, password);
+ free(password);
+ if(result)
+ errprint_r(1, "Can't add password to LockPassword\n");
+
+ return 0;
+}
+
+int cmd_generate(int argc, char *argv[])
+{
+ const char description[] = "generate [-l=pass-length] [-f] passname\n";
+ int pass_length = stdlen_pass;
+ int flag_force = 0, flag_copy = 0, result;
+ const struct option long_options[] = {
+ {"length", required_argument, NULL, 'l'},
+ {"force", no_argument, NULL, 'f'},
+ {"copy", no_argument, NULL, 'c'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while((result = getopt_long(argc, argv, "l:fc", long_options, NULL)) != -1) {
+ switch(result) {
+ // if optarg - incorrect number, atoi return 0
+ case 'l': { pass_length = atoi(optarg); break; }
+ case 'f': { flag_force = 1; break; }
+ case 'c': { flag_copy = 1; break; }
+ default: usageprint("%s", description);
+ }
+ }
+
+ if(optind < argc) optind++; // for skip "generate"
+ dbgprint("passname: %s\n", argv[optind]);
+
+ char *path = argv[optind];
+ if(path == NULL)
+ usageprint("%s", description);
+
+ if(pass_length < minlen_pass || pass_length > maxlen_pass)
+ errprint_r(1, "You typed an incorrect length\n");
+
+ result = check_sneaky_paths(path);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+
+ result = file_exist(path);
+ if(result == F_ISFILE) {
+ if(!flag_force) {
+ if(overwrite_answer(path) != 'y')
+ return 1;
+ }
+ }
+ else if(result == F_ISDIR)
+ errprint_r(1, "You can't generate password for directory\n");
+
+ // generate password
+ char *g_pass = gen_password(pass_length);
+
+ result = insert_pass(path, g_pass);
+ if(result) {
+ free(g_pass);
+ errprint_r(1, "Can't add password to LockPassword\n");
+ }
+
+ if(flag_copy)
+ copy_outside(g_pass);
+ else
+ printf("Generated password: %s\n", g_pass);
+ printf("Password added successfully for %s\n", path);
+ free(g_pass);
+ return 0;
+}
+
+int cmd_remove(int argc, char *argv[])
+{
+ const char description[] = "rm passname\n";
+ int result;
+ char *path = argv[2];
+ if(!path)
+ usageprint("%s", description);
+
+ result = check_sneaky_paths(path);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+
+ result = file_exist(path);
+ if(result == F_NOEXIST)
+ errprint_r(1, "No such file exists\n");
+ if(result == F_ISDIR) {
+ if(count_dir_entries(path) != 0)
+ errprint_r(1, "Directory not empty\n");
+ }
+
+ result = remove(path);
+ if(result)
+ errprint_r(1, "%s\n", strerror(errno));
+ return 0;
+}
+
+int cmd_move(int argc, char *argv[])
+{
+ /* we have a two situation:
+ 1) mv file file
+ 2) mv file directory */
+
+ const char description[] = "mv [-f] old-path new-path\n";
+ const struct option long_options[] = {
+ {"force", no_argument, NULL, 'f'},
+ {NULL, 0, NULL, 0}
+ };
+
+ int result, flag_force = 0;
+ while((result = getopt_long(argc, argv, "f", long_options, NULL)) != -1) {
+ switch(result) {
+ case 'f': { flag_force = 1; break; }
+ default: usageprint("%s", description);
+ }
+ }
+
+ if(optind < argc) optind++; // for skip "move"
+ if(!argv[optind] || !argv[optind+1])
+ usageprint("%s", description);
+
+ char *old_path = argv[optind];
+ char *new_path = argv[optind+1];
+ dbgprint("old-path = %s\n", old_path);
+ dbgprint("new-path = %s\n", new_path);
+
+ result = check_sneaky_paths(old_path);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+ result = file_exist(old_path);
+ if(result == F_NOEXIST)
+ errprint_r(1, "No such file exists\n");
+
+ result = check_sneaky_paths(new_path);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+ result = file_exist(new_path);
+ if(result != F_NOEXIST) {
+ if(!flag_force) {
+ if(overwrite_answer(new_path) != 'y')
+ return 1;
+ }
+ }
+
+ result = rename(old_path, new_path);
+ if(result)
+ errprint_r(1, "%s\n", strerror(errno));
+ return 0;
+}
+
+int cmd_help(int argc, char *argv[])
+{
+ printf("Synopsis:\n"
+ "\tlpass [command] [arguments] ...\n"
+
+ "Commands:\n"
+ "\tinit gpg-key\n"
+ "\t\tInitialize the password manager using the passed gpg-key.\n"
+ "\tinsert [-e, --echo] [-c, --copy] [-f, --force] passname\n"
+ "\t\tAdd the specified passname to the password manager.\n"
+ "\tedit [-t, --text-editor=text-editor] passname\n"
+ "\t\tOpen the specified passname in a text editor, waiting for changes.\n"
+ "\tgenerate [-l, --length=pass-length] [-c, --copy] [-f, --force] passname\n"
+ "\t\tGenerate a random password and write it in passname.\n"
+ "\tmv [-f, --force] old-path new-path\n"
+ "\t\tMove/rename old-path to new-path.\n"
+ "\trm passname\n"
+ "\t\tRemove the passname you specified from the password manager.\n"
+ "\thelp\n"
+ "\t\tPrint help information about commands and the application itself.\n"
+ "\tversion\n"
+ "\t\tPrint version information.\n"
+
+ "\nMore information may be found in the lpass(1) man page.\n");
+ return 0;
+}
+
+int cmd_version(int argc, char *argv[])
+{
+ printf("LockPassword v%s\n"
+ "Release date: %s\n\n"
+ "Copyright (C) 2020-2021 Aleksandr D. Goncharov (Joursoir)\n"
+ "License: GNU GPL version 3\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "This program comes with ABSOLUTELY NO WARRANTY.\n",
+ VERSION, DATE_RELEASE);
+ return 0;
+}
+
+int cmd_showtree(int argc, char *argv[])
+{
+ const char description[] = "[-c] [passname]\n";
+ int flag_copy = 0;
+ int retval = 0, result;
+ char *path;
+ const struct option long_options[] = {
+ {"copy", no_argument, NULL, 'c'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while((result = getopt_long(argc, argv, "c", long_options, NULL)) != -1) {
+ switch(result) {
+ case 'c': { flag_copy = 1; break; }
+ default: usageprint("%s", description);
+ }
+ }
+
+ if(argv[optind]) {
+ result = check_sneaky_paths(argv[optind]);
+ if(result)
+ errprint_r(1, "You have used forbidden paths\n");
+ path = malloc(sizeof(char) * (strlen(argv[optind]) + 1));
+ strcpy(path, argv[optind]);
+ }
+ else {
+ path = malloc(sizeof(char) * 2);
+ strcpy(path, ".");
+ }
+
+ do { // START_DO
+
+ result = file_exist(path);
+ if(result == F_ISDIR)
+ {
+ if(flag_copy) {
+ errprint_ptr(&retval, 1,
+ "You must type a passname, not a directory\n");
+ break;
+ }
+
+ if(strcmp(path, ".") == 0)
+ printf("Password Manager\n");
+ else
+ printf("Password Manager/%s\n", path);
+ tree(path, "");
+ }
+ else if(result == F_ISFILE)
+ {
+ char *pass = get_password(path);
+ if(!pass) {
+ errprint_ptr(&retval, 1, "Decrypt password failed\n");
+ break;
+ }
+
+ if(flag_copy)
+ copy_outside(pass);
+ else
+ printf("%s\n", pass);
+
+ free(pass);
+ }
+ else
+ errprint_ptr(&retval, 1,
+ "This path is not in the password storage\n");
+
+ } while(0); // END_DO
+
+ free(path);
+ return retval;
+}
diff --git a/src/implementation.c b/src/implementation.c
index 5fcd17e..af59b21 100644
--- a/src/implementation.c
+++ b/src/implementation.c
@@ -43,7 +43,7 @@ int copy_outside(char *password)
int pid;
pid = fork();
if(pid == -1)
- errprint(1, "X11 fork() failed\n");
+ errprint_r(1, "X11 fork() failed\n");
if(pid == 0) /* new process */
exit(run_clipboard(password));
return 0;
@@ -54,7 +54,7 @@ int copy_outside(char *password)
int pid;
pid = fork();
if(pid == -1)
- errprint(1, "Wayland fork() failed\n");
+ errprint_r(1, "Wayland fork() failed\n");
if(pid == 0) { /* new process */
execvp("wl-copy", wl_copy);
perror("wl-copy");
@@ -64,7 +64,7 @@ int copy_outside(char *password)
return 0;
}
- errprint(1, "You didn't have x11 or wayland when app builded\n");
+ errprint_r(1, "You didn't have x11 or wayland when app builded\n");
}
/* check two dot in path */
@@ -88,7 +88,7 @@ char *get_pubkey()
if(fileGPG == NULL) {
free(pubkey);
if(errno == ENOENT)
- errprint(NULL, "No GPG key exists. Use \"lpass init\".");
+ errprint_r(NULL, "No GPG key exists. Use \"lpass init\".");
perror(".gpg-key");
return NULL;
}
diff --git a/src/main.c b/src/main.c
index 1b33323..22e9eb8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,21 +20,12 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <getopt.h>
-#include <dirent.h>
-#include <libgen.h>
-#include <stdarg.h>
#include <errno.h>
#include <sys/stat.h>
-#include <sys/wait.h>
-#include <fcntl.h>
#include "constants.h"
-#include "easydir.h"
-#include "xstd.h"
-#include "implementation.h"
#include "exec-cmd.h"
-#include "tree.h"
+#include "xstd.h"
struct cmd_struct {
const char *cmd;
@@ -53,438 +44,6 @@ static struct cmd_struct commands[] = {
{ NULL, NULL }
};
-int cmd_init(int argc, char *argv[])
-{
- const char description[] = "init gpg-key\n";
- char *gpg_key = argv[2];
- if(gpg_key == NULL)
- usageprint("%s", description);
-
- // create .gpg-key in storage
- FILE *filekey = fopen(GPGKEY_FILE, "w");
- if(!filekey)
- errprint(1, "fopen() failed");
-
- fputs(gpg_key, filekey);
- fclose(filekey);
-
- printf("LockPassword initialized for %s\n", gpg_key);
- return 0;
-}
-
-int cmd_insert(int argc, char *argv[])
-{
- const char description[] = "insert [-ecf] passname\n";
- int flag_echo = 0, flag_force = 0, flag_copy = 0, result;
- const struct option long_options[] = {
- {"echo", no_argument, NULL, 'e'},
- {"force", no_argument, NULL, 'f'},
- {"copy", no_argument, NULL, 'c'},
- {NULL, 0, NULL, 0}
- };
-
- while((result = getopt_long(argc, argv, "efc", long_options, NULL)) != -1) {
- switch(result) {
- case 'e': { flag_echo = 1; break; }
- case 'f': { flag_force = 1; break; }
- case 'c': { flag_copy = 1; break; }
- default: usageprint("%s", description);
- }
- }
-
- if(optind < argc) optind++; // for skip "insert"
- dbgprint("passname: %s\n", argv[optind]);
-
- char *path = argv[optind];
- if(path == NULL)
- usageprint("%s", description);
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- if(file_exist(path) == F_ISFILE) {
- if(!flag_force) {
- if(overwrite_answer(path) != 'y')
- return 1;
- }
- }
-
- char *f_pass;
- if(!flag_echo) {
- char *s_pass;
- visible_enter(0);
-
- fputs("Type your password: ", stdout);
- f_pass = get_input(minlen_pass, maxlen_pass);
- fputs("\n", stdout);
- if(f_pass == NULL) {
- visible_enter(1);
- errprint(1, "Incorrect password");
- }
-
- fputs("Type your password again: ", stdout);
- s_pass = get_input(minlen_pass, maxlen_pass);
- fputs("\n", stdout);
- visible_enter(1);
- if(s_pass == NULL) {
- free(f_pass);
- errprint(1, "Incorrect password");
- }
-
- if(strcmp(f_pass, s_pass) != 0) {
- free(f_pass);
- free(s_pass);
- errprint(1, "Password do not match");
- }
- free(s_pass);
- }
- else {
- fputs("Type your password: ", stdout);
- f_pass = get_input(minlen_pass, maxlen_pass);
- if(f_pass == NULL)
- errprint(1, "Incorrect password");
- }
-
- result = insert_pass(path, f_pass);
- if(result) {
- free(f_pass);
- errprint(1, "Can't add password to LockPassword");
- }
- if(flag_copy)
- copy_outside(f_pass);
-
- printf("Password added successfully for %s\n", path);
- free(f_pass);
- return 0;
-}
-
-int cmd_edit(int argc, char *argv[])
-{
- const char description[] = "edit passname\n";
- int result, fd, pid, len_pass, save_errno;
- /* We expect tmpfs to be mounted at /dev/shm */
- char path_tmpfile[] = "/dev/shm/lpass.XXXXXX";
- char *editor, *password;
- char *path = argv[2];
- if(!path)
- usageprint("%s", description);
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- editor = getenv("EDITOR");
- if(!editor)
- editor = STD_TEXT_EDITOR;
-
- password = get_password(path);
- if(password == NULL)
- errprint(1, "Decrypt password failed\n");
-
- fd = mkstemp(path_tmpfile);
- if(fd == -1) {
- free(password);
- errprint(1, "mkstemp() failed\n");
- }
- dbgprint("tmp file: %s\n", path_tmpfile);
-
- len_pass = strlen(password);
- result = write(fd, password, len_pass);
- free(password);
- close(fd);
- if(result != len_pass) {
- unlink(path_tmpfile);
- errprint(1, "Write password to temporary file failed\n");
- }
-
- // fork for text editor
- char *editor_arg[] = {editor, path_tmpfile, NULL};
- pid = fork();
- if(pid == -1) {
- unlink(path_tmpfile);
- errprint(1, "%s fork() failed\n", editor);
- }
- if(pid == 0) { /* new process */
- execvp(editor, editor_arg);
- perror(editor);
- exit(1);
- }
- wait(&pid);
-
- fd = open(path_tmpfile, O_RDONLY);
- if(fd == -1) {
- unlink(path_tmpfile);
- perror("open");
- return 1;
- }
-
- password = malloc(sizeof(char) * (maxlen_pass + 1));
- len_pass = read(fd, password, maxlen_pass);
- save_errno = errno;
- close(fd);
- unlink(path_tmpfile);
- if(len_pass < minlen_pass) {
- free(password);
- if(len_pass == -1)
- errprint(1, "Read temporary file: %s\n", strerror(save_errno));
- else
- errprint(1, "Min. password length is %d\n", minlen_pass);
- }
- password[len_pass-1] = '\0';
- dbgprint("new pass: %s\n", password);
-
- // encrypt
- result = insert_pass(path, password);
- free(password);
- if(result)
- errprint(1, "Can't add password to LockPassword\n");
-
- return 0;
-}
-
-int cmd_generate(int argc, char *argv[])
-{
- const char description[] = "generate [-l=pass-length] [-f] passname\n";
- int pass_length = stdlen_pass;
- int flag_force = 0, flag_copy = 0, result;
- const struct option long_options[] = {
- {"length", required_argument, NULL, 'l'},
- {"force", no_argument, NULL, 'f'},
- {"copy", no_argument, NULL, 'c'},
- {NULL, 0, NULL, 0}
- };
-
- while((result = getopt_long(argc, argv, "l:fc", long_options, NULL)) != -1) {
- switch(result) {
- // if optarg - incorrect number, atoi return 0
- case 'l': { pass_length = atoi(optarg); break; }
- case 'f': { flag_force = 1; break; }
- case 'c': { flag_copy = 1; break; }
- default: usageprint("%s", description);
- }
- }
-
- if(optind < argc) optind++; // for skip "generate"
- dbgprint("passname: %s\n", argv[optind]);
-
- char *path = argv[optind];
- if(path == NULL)
- usageprint("%s", description);
-
- if(pass_length < minlen_pass || pass_length > maxlen_pass)
- errprint(1, "You typed an incorrect length\n");
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- result = file_exist(path);
- if(result == F_ISFILE) {
- if(!flag_force) {
- if(overwrite_answer(path) != 'y')
- return 1;
- }
- }
- else if(result == F_ISDIR)
- errprint(1, "You can't generate password for directory\n");
-
- // generate password
- char *g_pass;
- g_pass = gen_password(pass_length);
-
- result = insert_pass(path, g_pass);
- if(result) {
- free(g_pass);
- errprint(1, "Can't add password to LockPassword");
- }
-
- if(flag_copy)
- copy_outside(g_pass);
- else
- printf("Generated password: %s\n", g_pass);
- printf("Password added successfully for %s\n", path);
- free(g_pass);
- return 0;
-}
-
-int cmd_remove(int argc, char *argv[])
-{
- const char description[] = "rm passname\n";
- int result;
- char *path = argv[2];
- if(!path)
- usageprint("%s", description);
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- result = file_exist(path);
- if(result == F_NOEXIST)
- errprint(1, "No such file exists\n");
- if(result == F_ISDIR) {
- if(count_dir_entries(path) != 0)
- errprint(1, "Directory not empty\n");
- }
-
- remove(path);
- return 0;
-}
-
-int cmd_move(int argc, char *argv[])
-{
- /* we have a two situation:
- 1) mv file file
- 2) mv file directory */
-
- const char description[] = "mv [-f] old-path new-path\n";
- const struct option long_options[] = {
- {"force", no_argument, NULL, 'f'},
- {NULL, 0, NULL, 0}
- };
-
- int result, flag_force = 0;
- while((result = getopt_long(argc, argv, "f", long_options, NULL)) != -1) {
- switch(result) {
- case 'f': { flag_force = 1; break; }
- default: usageprint("%s", description);
- }
- }
-
- if(optind < argc) optind++; // for skip "move"
- if(!argv[optind] || !argv[optind+1])
- usageprint("%s", description);
-
- char *old_path = argv[optind];
- char *new_path = argv[optind+1];
- dbgprint("old-path = %s\n", old_path);
- dbgprint("new-path = %s\n", new_path);
-
- result = check_sneaky_paths(old_path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
- result = file_exist(old_path);
- if(result == F_NOEXIST)
- errprint(1, "No such file exists\n");
-
- result = check_sneaky_paths(new_path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
- result = file_exist(new_path);
- if(result != F_NOEXIST) {
- if(!flag_force) {
- if(overwrite_answer(new_path) != 'y')
- return 1;
- }
- }
-
- if(rename(old_path, new_path))
- perror("rename");
- return 0;
-}
-
-int cmd_help(int argc, char *argv[])
-{
- printf("Synopsis:\n"
- "\tlpass [command] [arguments] ...\n"
-
- "Commands:\n"
- "\tinit gpg-key\n"
- "\t\tInitialize the password manager using the passed gpg-key.\n"
- "\tinsert [-e, --echo] [-c, --copy] [-f, --force] passname\n"
- "\t\tAdd the specified passname to the password manager.\n"
- "\tedit [-t, --text-editor=text-editor] passname\n"
- "\t\tOpen the specified passname in a text editor, waiting for changes.\n"
- "\tgenerate [-l, --length=pass-length] [-c, --copy] [-f, --force] passname\n"
- "\t\tGenerate a random password and write it in passname.\n"
- "\tmv [-f, --force] old-path new-path\n"
- "\t\tMove/rename old-path to new-path.\n"
- "\trm passname\n"
- "\t\tRemove the passname you specified from the password manager.\n"
- "\thelp\n"
- "\t\tPrint help information about commands and the application itself.\n"
- "\tversion\n"
- "\t\tPrint version information.\n"
-
- "\nMore information may be found in the lpass(1) man page.\n");
- return 0;
-}
-
-int cmd_version(int argc, char *argv[])
-{
- printf("LockPassword v%s\n"
- "Release date: %s\n\n"
- "Copyright (C) 2020-2021 Aleksandr D. Goncharov (Joursoir)\n"
- "License: GNU GPL version 3\n"
- "This is free software: you are free to change and redistribute it.\n"
- "This program comes with ABSOLUTELY NO WARRANTY.\n",
- VERSION, DATE_RELEASE);
- return 0;
-}
-
-int cmd_showtree(int argc, char *argv[])
-{
- const char description[] = "[-c] [passname]\n";
- int flag_copy = 0, result;
- char *path;
- const struct option long_options[] = {
- {"copy", no_argument, NULL, 'c'},
- {NULL, 0, NULL, 0}
- };
-
- while((result = getopt_long(argc, argv, "c", long_options, NULL)) != -1) {
- switch(result) {
- case 'c': { flag_copy = 1; break; }
- default: usageprint("%s", description);
- }
- }
-
- if(argv[optind]) {
- result = check_sneaky_paths(argv[optind]);
- if(result)
- errprint(1, "You have used forbidden paths\n");
- path = malloc(sizeof(char) * (strlen(argv[optind]) + 1));
- strcpy(path, argv[optind]);
- }
- else {
- path = malloc(sizeof(char) * 2);
- strcpy(path, ".");
- }
-
- result = file_exist(path);
- if(result == F_ISDIR)
- {
- if(flag_copy)
- errprint(1, "You must type a passname, not a directory\n");
-
- if(strcmp(path, ".") == 0) printf("Password Manager\n");
- else printf("Password Manager/%s\n", path);
- tree(path, "");
- }
- else if(result == F_ISFILE)
- {
- char *pass = get_password(path);
- if(pass == NULL) {
- free(path);
- errprint(1, "Decrypt password failed\n");
- }
- if(flag_copy)
- copy_outside(pass);
- else
- printf("%s\n", pass);
-
- free(pass);
- }
- else {
- free(path);
- errprint(1, "This path is not in the password storage\n");
- }
-
- free(path);
- return 0;
-}
-
static struct cmd_struct *get_cmd(const char *name)
{
struct cmd_struct *ptr;
@@ -497,41 +56,36 @@ static struct cmd_struct *get_cmd(const char *name)
static int goto_maindir()
{
- int ret = 0;
+ int retval = 0, result;
char *rootdir = xstrcat(getenv("HOME"), LOCKPASS_DIR, "/");
if(chdir(rootdir)) // failed
{
// create main directory:
- int res = mkdir(rootdir, S_IRWXU);
- if(res) {
- if(errno != EEXIST) {
- perror("mkdir");
- ret = 1;
- }
+ result = mkdir(rootdir, S_IRWXU);
+ if(result) {
+ if(errno != EEXIST)
+ errprint_ptr(&retval, 1, "%s", strerror(errno));
}
else // try again:
- ret = chdir(rootdir);
+ retval = chdir(rootdir);
}
free(rootdir);
- return ret;
+ return retval;
}
int main(int argc, char *argv[])
{
if(!isatty(STDIN_FILENO))
- errprint(1, "Please, use a terminal to run this application\n");
+ errprint_r(1, "Please, use a terminal to run this application\n");
if(goto_maindir())
- perror("chdir");
+ errprint_r(1, "%s", strerror(errno));
- int ret = 0;
char *cmd = (argv[1] != NULL) ? argv[1] : "";
struct cmd_struct *ptr;
if((ptr = get_cmd(cmd)))
- ret = ptr->func(argc, argv);
- else
- ret = cmd_showtree(argc, argv);
+ return ptr->func(argc, argv);
- return ret;
+ return cmd_showtree(argc, argv);
} \ No newline at end of file
diff --git a/src/r-x11.c b/src/r-x11.c
index b42c852..e869d3b 100644
--- a/src/r-x11.c
+++ b/src/r-x11.c
@@ -76,7 +76,7 @@ int run_clipboard(const char *data)
dpy = XOpenDisplay(NULL); // means use env $DISPLAY
if(!dpy)
- errprint(1, "Open X display failed\n");
+ errprint_r(1, "Open X display failed\n");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);