diff options
-rw-r--r-- | src/constants.h | 8 | ||||
-rw-r--r-- | src/exec-cmd.c | 495 | ||||
-rw-r--r-- | src/implementation.c | 8 | ||||
-rw-r--r-- | src/main.c | 470 | ||||
-rw-r--r-- | src/r-x11.c | 2 |
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; } @@ -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); |