From c89e18ec972f165650a453aa8bd8b30309e323e6 Mon Sep 17 00:00:00 2001 From: toni Date: Tue, 13 Oct 2015 09:01:50 +0200 Subject: added semaphore tests --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index b4c01e9..4b8fd3a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ /naskpass +/tests/producer +/tests/consumer +/tests/semtest *.swp -- cgit v1.2.3 From d7071577be3f49b964c4d234024bf62328d0209d Mon Sep 17 00:00:00 2001 From: toni Date: Tue, 13 Oct 2015 17:42:21 +0200 Subject: better ipc: using POSIX (semaphores && msg queues) --- .gitignore | 1 + Makefile | 2 +- config.h | 4 ++ main.c | 129 +++++++++++++++++++++++++++++++++++++-------------------- tests/Makefile | 2 +- tests/mqtest.c | 46 ++++++++++++++++++++ ui.c | 66 +++++++++++++++-------------- ui.h | 5 +-- 8 files changed, 174 insertions(+), 81 deletions(-) create mode 100644 tests/mqtest.c (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index 4b8fd3a..3e2ffcd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /tests/producer /tests/consumer /tests/semtest +/tests/mqtest *.swp diff --git a/Makefile b/Makefile index fe89038..1abb87a 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CFLAGS ?= $(shell ncurses5-config --cflags) -Wall -D_GNU_SOURCE=1 DBGFLAGS = -g -LDFLAGS ?= $(shell ncurses5-config --libs) -pthread +LDFLAGS ?= $(shell ncurses5-config --libs) -pthread -lrt CC ?= gcc INSTALL ?= install VERSION ?= $(shell if [ -d ./.git ]; then echo -n "git-"; git rev-parse --short HEAD; else echo "1.2a"; fi) diff --git a/config.h b/config.h index 26fdb3c..a559771 100644 --- a/config.h +++ b/config.h @@ -5,6 +5,10 @@ #define DEFAULT_FIFO "/lib/cryptsetup/passfifo" #define SHTDWN_CMD "echo 'o' >/proc/sysrq-trigger" +#define SEM_GUI "/naskpass-gui" +#define SEM_INP "/naskpass-input" +#define MSQ_PWD "/naskpass-passwd" + #ifdef _VERSION #define VERSION _VERSION #else diff --git a/main.c b/main.c index 670503e..c40265d 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include #include "ui_ani.h" #include "ui_input.h" @@ -16,7 +19,9 @@ #include "config.h" -static bool ui_active = true; +static sem_t *sp_ui, *sp_input; +static mqd_t mq_passwd; + static void usage(char *arg0) @@ -51,23 +56,6 @@ check_fifo(char *fifo_path) return (false); } -/* stolen from http://www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html */ -static int -input_timeout(int filedes, unsigned int seconds) -{ - fd_set set; - struct timeval timeout; - - /* Initialize the file descriptor set. */ - FD_ZERO (&set); - FD_SET (filedes, &set); - /* Initialize the timeout data structure. */ - timeout.tv_sec = seconds; - timeout.tv_usec = 0; - /* select returns 0 if timeout, 1 if input available, -1 if error. */ - return TEMP_FAILURE_RETRY(select(FD_SETSIZE, &set, NULL, NULL, &timeout)); -} - int run_cryptcreate(char *pass, char *crypt_cmd) { @@ -80,22 +68,65 @@ run_cryptcreate(char *pass, char *crypt_cmd) return (retval); } +void sigfunc(int signal) +{ + switch (signal) { + case SIGTERM: + case SIGKILL: + case SIGINT: + sem_trywait(sp_ui); + sem_trywait(sp_input); + break; + } +} + int main(int argc, char **argv) { - int ffd, c_status, opt; + int ret = EXIT_FAILURE, ffd = -1, c_status, opt, i_sval; pid_t child; char pbuf[MAX_PASSWD_LEN+1]; char *fifo_path = NULL; char *crypt_cmd = NULL; + struct timespec ts_sem_input; + struct mq_attr mq_attr; - memset(pbuf, '\0', MAX_PASSWD_LEN+1); + signal(SIGINT, sigfunc); + signal(SIGTERM, sigfunc); + signal(SIGKILL, sigfunc); + + if ( clock_gettime(CLOCK_REALTIME, &ts_sem_input) == -1 ) { + fprintf(stderr, "%s: clock get time error: %d (%s)\n", argv[0], errno, strerror(errno)); + goto error; + } + if ( (sp_ui = sem_open(SEM_GUI, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0)) == SEM_FAILED || + (sp_input = sem_open(SEM_INP, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0)) == SEM_FAILED || +(mq_passwd = mq_open(MSQ_PWD, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, NULL)) == (mqd_t) -1 ) { + if ( errno == EEXIST ) { + fprintf(stderr, "%s: already started?\n", argv[0]); + } else { + fprintf(stderr, "%s: can not create semaphore: %d (%s)\n", argv[0], errno, strerror(errno)); + } + goto error; + } + if ( mq_getattr(mq_passwd, &mq_attr) == 0 ) { + mq_attr.mq_maxmsg = 2; + mq_attr.mq_msgsize = MAX_PASSWD_LEN; + if ( mq_setattr(mq_passwd, &mq_attr, NULL) != 0 ) { + fprintf(stderr, "%s: can not SET message queue attributes: %d (%s)\n", argv[0], errno, strerror(errno)); + goto error; + } + } else { + fprintf(stderr, "%s: can not GET message queue attributes: %d (%s)\n", argv[0], errno, strerror(errno)); + goto error; + } + memset(pbuf, '\0', MAX_PASSWD_LEN+1); while ((opt = getopt(argc, argv, "hf:c:")) != -1) { switch (opt) { case 'h': usage(argv[0]); - exit(EXIT_SUCCESS); + goto error; case 'f': fifo_path = strdup(optarg); break; @@ -104,56 +135,66 @@ main(int argc, char **argv) break; default: usage(argv[0]); - exit(EXIT_FAILURE); + goto error; } } if (optind < argc) { fprintf(stderr, "%s: I dont understand you.\n\n", argv[0]); usage(argv[0]); - exit(EXIT_FAILURE); + goto error; } if (fifo_path == NULL) fifo_path = strdup(DEFAULT_FIFO); if (check_fifo(fifo_path) == false) { usage(argv[0]); - exit(EXIT_FAILURE); + goto error; } if ((ffd = open(fifo_path, O_NONBLOCK | O_RDWR)) < 0) { - fprintf(stderr, "fifo: %s\n", fifo_path); - perror("open"); - exit(EXIT_FAILURE); + fprintf(stderr, "%s: fifo '%s' error: %d (%s)\n", argv[0], fifo_path, errno, strerror(errno)); + goto error; } if ((child = fork()) == 0) { /* child */ - ui_active = true; - do_ui(ffd); - ui_active = false; + fclose(stderr); + /* Slave process: TUI */ + sem_post(sp_ui); + do_ui(); } else if (child > 0) { /* parent */ fclose(stdin); - while (input_timeout(ffd, 1) == 0) { - usleep(100000); - if (ui_active == true) { - // TODO: smthng + fclose(stdout); + /* Master process: mainloop (read passwd from message queue or fifo and exec cryptcreate */ + while ( sem_getvalue(sp_ui, &i_sval) == 0 && i_sval > 0 ) { + if ( sem_getvalue(sp_input, &i_sval) == 0 && i_sval > 0 ) { + if (read(ffd, pbuf, MAX_PASSWD_LEN) > 0) { + if (run_cryptcreate(pbuf, crypt_cmd) != 0) { + fprintf(stderr, "cryptcreate error\n"); + } + } + } else if ( mq_receive(mq_passwd, pbuf, MAX_PASSWD_LEN, NULL) > 0 ) { +exit(77); } + usleep(100000); } - stop_ui(); wait(&c_status); - if (read(ffd, pbuf, MAX_PASSWD_LEN) > 0) { - if (run_cryptcreate(pbuf, crypt_cmd) != 0) { - fprintf(stderr, "cryptcreate error\n"); - } - } memset(pbuf, '\0', MAX_PASSWD_LEN+1); } else { /* fork error */ perror("fork"); - exit(EXIT_FAILURE); + goto error; } - close(ffd); + ret = EXIT_SUCCESS; +error: + if (ffd >= 0) close(ffd); if (crypt_cmd != NULL) free(crypt_cmd); - free(fifo_path); - return (EXIT_SUCCESS); + if (fifo_path != NULL) free(fifo_path); + sem_close(sp_ui); + sem_close(sp_input); + mq_close(mq_passwd); + sem_unlink(SEM_GUI); + sem_unlink(SEM_INP); + mq_unlink(MSQ_PWD); + exit(ret); } diff --git a/tests/Makefile b/tests/Makefile index 22a5469..5a041e6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,5 @@ CFLAGS = -Wall -LDFLAGS = -lpthread +LDFLAGS = -lpthread -lrt CC = gcc SOURCES = $(wildcard *.c) BINARIES = $(patsubst %.c,%,$(SOURCES)) diff --git a/tests/mqtest.c b/tests/mqtest.c new file mode 100644 index 0000000..56c2d2b --- /dev/null +++ b/tests/mqtest.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include + +#include + + +static mqd_t mq_test; +static const size_t bufsiz = 256; + +int main(int argc, char **argv) +{ + struct mq_attr m_attr; + char buf[bufsiz], recv[bufsiz]; + + memset(buf, '\0', bufsiz); + memset(buf, '\0', bufsiz); + if (argc > 1) + strncpy(buf, argv[1], bufsiz-1); + + mq_unlink("/testmq"); + assert( (mq_test = mq_open( "/testmq", O_CREAT | O_EXCL | O_RDWR | O_NONBLOCK, S_IRUSR | S_IWUSR, NULL )) != (mqd_t)-1 ); + assert( mq_getattr(mq_test, &m_attr) == 0 ); + printf("flags.....: %ld\n" + "maxmsg....: %ld\n" + "msgsize...: %ld\n" + "curmsg....: %ld\n", + m_attr.mq_flags, m_attr.mq_maxmsg, m_attr.mq_msgsize, m_attr.mq_curmsgs); + + m_attr.mq_msgsize = bufsiz-1; + assert ( mq_setattr(mq_test, &m_attr, NULL) == 0 ); + assert ( mq_send(mq_test, buf, bufsiz-1, 0) == 0 ); + assert ( mq_getattr(mq_test, &m_attr) == 0 ); + printf("new msgsize...: %ld\n" + "new curmsg....: %ld\n", + m_attr.mq_msgsize, m_attr.mq_curmsgs); + assert ( mq_receive(mq_test, recv, bufsiz-1, 0) > 0 ); + + printf("RECV: %s\n", recv); + + return 0; +} + diff --git a/ui.c b/ui.c index 58cc226..9d0abae 100644 --- a/ui.c +++ b/ui.c @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include #include "ui.h" @@ -30,17 +33,18 @@ #define STRLEN(s) (sizeof(s)/sizeof(s[0])) -static int ffd; static unsigned int max_x, max_y; static WINDOW *wnd_main; static struct nask_ui *nui = NULL; static pthread_t thrd; -static bool active, passwd_from_ui; +static bool active; static unsigned int atmout = APP_TIMEOUT; static pthread_cond_t cnd_update = PTHREAD_COND_INITIALIZER; static pthread_mutex_t mtx_update = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mtx_busy = PTHREAD_MUTEX_INITIALIZER; static sem_t sem_rdy; +static sem_t *sp_ui, *sp_input; +static mqd_t mq_passwd; void @@ -183,7 +187,6 @@ static int run_ui_thrd(void) { pthread_mutex_lock(&mtx_busy); active = true; - passwd_from_ui = false; pthread_cond_signal(&cnd_update); pthread_mutex_unlock(&mtx_busy); return (pthread_create(&thrd, NULL, &ui_thrd, NULL)); @@ -205,15 +208,15 @@ stop_ui_thrd(void) } static int -send_passwd(int fifo_fd, char *passwd, size_t len) +mq_passwd_send(char *passwd, size_t len) { - if (write(fifo_fd, passwd, len) != len) { - memset(passwd, '\0', len); - return (errno); - } else { - memset(passwd, '\0', len); - return (0); + struct mq_attr m_attr; + + if (mq_send(mq_passwd, "hellomq", 7, 0) == 0 && mq_getattr(mq_passwd, &m_attr) == 0) { + return m_attr.mq_curmsgs; } + memset(passwd, '\0', len); + return -1; } static bool @@ -224,9 +227,9 @@ process_key(char key, struct input *a, WINDOW *win) atmout = APP_TIMEOUT; switch (key) { case UIKEY_ENTER: - send_passwd(ffd, a->input, a->input_len); - passwd_from_ui = true; - retval = false; + if ( mq_passwd_send(a->input, a->input_len) > 0 ) { + retval = false; + } else retval = true; break; case UIKEY_BACKSPACE: del_input(win, a); @@ -262,18 +265,21 @@ infownd_update(WINDOW *win, struct txtwindow *tw) } int -do_ui(int fifo_fd) +do_ui(void) { struct input *pw_input; struct anic *heartbeat; struct statusbar *higher, *lower; struct txtwindow *infownd; char key = '\0'; - char *title; + char *title = NULL; + int i_sval = -1, ret = DOUI_ERR; asprintf(&title, "/* %s-%s */", PKGNAME, VERSION); - ffd = fifo_fd; - if (sem_init(&sem_rdy, 0, 0) == -1) { + sp_ui = sem_open(SEM_GUI, 0, 0, 0); + sp_input = sem_open(SEM_INP, 0, 0, 0); + mq_passwd = mq_open(MSQ_PWD, O_WRONLY, S_IWUSR, NULL); + if ( sem_init(&sem_rdy, 0, 0) == -1 || !sp_ui || !sp_input || mq_passwd == (mqd_t)-1 ) { perror("init semaphore"); goto error; } @@ -295,7 +301,7 @@ do_ui(int fifo_fd) } sem_wait(&sem_rdy); wtimeout(wnd_main, 1000); - while (active == true) { + while ( active && sem_getvalue(sp_ui, &i_sval) == 0 && i_sval > 0 ) { if ((key = wgetch(wnd_main)) == '\0') { break; } @@ -308,6 +314,7 @@ do_ui(int fifo_fd) do_ui_update(false); pthread_mutex_unlock(&mtx_busy); } + ui_thrd_force_update(); stop_ui_thrd(); unregister_ui_elt(lower); unregister_ui_elt(higher); @@ -319,19 +326,16 @@ do_ui(int fifo_fd) free_statusbar(lower); free_txtwindow(infownd); free_ui(); - return (DOUI_OK); + ret = DOUI_OK; + sem_trywait(sp_ui); + mq_close(mq_passwd); error: - free(title); - return (DOUI_ERR); -} - -bool -is_passwd_from_ui(void) -{ - bool ret; - pthread_mutex_lock(&mtx_busy); - ret = passwd_from_ui; - pthread_mutex_unlock(&mtx_busy); - return (ret); + if (title) free(title); + if (sp_ui) sem_close(sp_ui); + if (sp_input) sem_close(sp_input); + title = NULL; + sp_ui = NULL; + sp_input = NULL; + return ret; } diff --git a/ui.h b/ui.h index 77a5bc9..a34ca10 100644 --- a/ui.h +++ b/ui.h @@ -52,12 +52,9 @@ void free_ui(void); int -do_ui(int fifo_fd); +do_ui(void); void stop_ui(void); -bool -is_passwd_from_ui(void); - #endif -- cgit v1.2.3 From 659f5274b607a1d8da3e3b30662442de764e9d7a Mon Sep 17 00:00:00 2001 From: toni Date: Thu, 22 Oct 2015 15:14:02 +0200 Subject: export ui elements to an extra module --- .gitignore | 1 + Makefile | 27 +++++++++++++------ ui.c | 75 +++++++++++++++++------------------------------------ ui.h | 12 ++++++++- ui_elements.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ui_elements.h | 20 ++++++++++++++ ui_nwindow.c | 11 ++++---- ui_nwindow.h | 12 ++++----- 8 files changed, 168 insertions(+), 73 deletions(-) create mode 100644 ui_elements.c create mode 100644 ui_elements.h (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index cc27b30..d965c57 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /tests/mqtest /tests/strsep *.swp +*.o diff --git a/Makefile b/Makefile index 1abb87a..2780c74 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,28 @@ -CFLAGS ?= $(shell ncurses5-config --cflags) -Wall -D_GNU_SOURCE=1 +CFLAGS = $(shell ncurses5-config --cflags) -Wall -D_GNU_SOURCE=1 -fPIC DBGFLAGS = -g -LDFLAGS ?= $(shell ncurses5-config --libs) -pthread -lrt -CC ?= gcc -INSTALL ?= install -VERSION ?= $(shell if [ -d ./.git ]; then echo -n "git-"; git rev-parse --short HEAD; else echo "1.2a"; fi) +LDFLAGS = $(shell ncurses5-config --libs) -pthread -lrt +CC = gcc +INSTALL = install +STRIP = strip +VERSION = $(shell if [ -d ./.git ]; then echo -n "git-"; git rev-parse --short HEAD; else echo "1.2a"; fi) BIN = naskpass -SOURCES = status.c ui_ani.c ui_input.c ui_statusbar.c ui_nwindow.c ui.c main.c +SOURCES = status.c ui_ani.c ui_input.c ui_statusbar.c ui_nwindow.c ui.c ui_elements.c main.c +OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) -all: $(BIN) +all: $(OBJECTS) $(BIN) + +%.o: %.c + $(CC) $(CFLAGS) -D_VERSION=\"$(VERSION)\" -c $< -o $@ $(BIN): $(SOURCES) - $(CC) $(SOURCES) -D_VERSION=\"$(VERSION)\" $(CFLAGS) $(LDFLAGS) -o $(BIN) + $(CC) $(LDFLAGS) $(OBJECTS) -o $(BIN) $(MAKE) -C tests CC='$(CC)' CFLAGS='$(CFLAGS)' all +strip: + $(STRIP) $(BIN) + +release: all strip + debug: $(MAKE) CFLAGS='$(CFLAGS) $(DBGFLAGS)' $(MAKE) -C tests CFLAGS='$(CFLAGS) $(DBGFLAGS)' @@ -31,6 +41,7 @@ uninstall: rmdir --ignore-fail-on-non-empty $(DESTDIR)/usr/share/naskpass clean: + rm -f $(OBJECTS) rm -f $(BIN) $(MAKE) -C tests clean diff --git a/ui.c b/ui.c index 55c7103..e5f4454 100644 --- a/ui.c +++ b/ui.c @@ -15,6 +15,7 @@ #include #include "ui.h" +#include "ui_elements.h" #include "ui_ani.h" #include "ui_input.h" #include "ui_statusbar.h" @@ -40,11 +41,11 @@ static unsigned int max_x, max_y; static WINDOW *wnd_main; static struct nask_ui *nui = NULL; +static struct nask_input *nin = NULL; static pthread_t thrd; static unsigned int atmout = APP_TIMEOUT; static pthread_cond_t cnd_update = PTHREAD_COND_INITIALIZER; static pthread_mutex_t mtx_update = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t mtx_busy = PTHREAD_MUTEX_INITIALIZER; static sem_t sem_rdy; static sem_t /* TUI active? */ *sp_ui, /* Textfield input available? */ *sp_input; static mqd_t mq_passwd, mq_info; @@ -74,6 +75,12 @@ register_ui_elt(ui_callback uicb, void *data, WINDOW *wnd) } } +void +register_input(ui_input_callback ipcb, void *data, WINDOW *wnd) +{ + +} + void unregister_ui_elt(void *data) { @@ -130,23 +137,21 @@ ui_thrd(void *arg) struct timeval now; struct timespec wait; - pthread_mutex_lock(&mtx_update); gettimeofday(&now, NULL); wait.tv_sec = now.tv_sec + UILOOP_TIMEOUT; wait.tv_nsec = now.tv_usec * 1000; do_ui_update(true); sem_post(&sem_rdy); while ( sem_getvalue(sp_ui, &i_sval) == 0 && i_sval > 0 ) { - pthread_mutex_unlock(&mtx_busy); + pthread_mutex_lock(&mtx_update); cnd_ret = pthread_cond_timedwait(&cnd_update, &mtx_update, &wait); + if (--atmout == 0) sem_trywait(sp_ui); + do_ui_update( (cnd_ret == ETIMEDOUT ? true : false) ); if (cnd_ret == ETIMEDOUT) { wait.tv_sec += UILOOP_TIMEOUT; } - pthread_mutex_lock(&mtx_busy); - if (--atmout == 0) sem_trywait(sp_ui); - do_ui_update( (cnd_ret == ETIMEDOUT ? true : false) ); + pthread_mutex_unlock(&mtx_update); } - pthread_mutex_unlock(&mtx_busy); pthread_mutex_unlock(&mtx_update); return (NULL); } @@ -154,7 +159,9 @@ ui_thrd(void *arg) void ui_thrd_force_update(void) { + pthread_mutex_lock(&mtx_update); pthread_cond_signal(&cnd_update); + pthread_mutex_unlock(&mtx_update); } WINDOW * @@ -225,7 +232,6 @@ process_key(char key, struct input *a, WINDOW *win) break; case UIKEY_ESC: retval = false; - ui_thrd_force_update(); break; case UIKEY_DOWN: case UIKEY_UP: @@ -238,28 +244,10 @@ process_key(char key, struct input *a, WINDOW *win) return (retval); } -static int -lower_statusbar_update(WINDOW *win, struct statusbar *bar) -{ - char *tmp = get_system_stat(); - set_statusbar_text(bar, tmp); - free(tmp); - return (0); -} - -static int -infownd_update(WINDOW *win, struct txtwindow *tw) -{ - return (0); -} - int do_ui(void) { - struct input *pw_input; struct anic *heartbeat; - struct statusbar *higher, *lower; - struct txtwindow *infownd; char key = '\0'; char *title = NULL, mq_msg[IPC_MQSIZ+1]; int i_sval = -1, ret = DOUI_ERR; @@ -273,22 +261,11 @@ do_ui(void) perror("init semaphore/messageq"); goto error; } + + /* init TUI and UI Elements (input field, status bar, etc) */ init_ui(); - pw_input = init_input((unsigned int)(max_x / 2)-PASSWD_XRELPOS, (unsigned int)(max_y / 2)-PASSWD_YRELPOS, PASSWD_WIDTH, "PASSWORD: ", IPC_MQSIZ, COLOR_PAIR(3), COLOR_PAIR(2)); - heartbeat = init_anic(0, 0, A_BOLD | COLOR_PAIR(1), "[%c]"); - higher = init_statusbar(0, max_x, A_BOLD | COLOR_PAIR(3), NULL); - lower = init_statusbar(max_y - 1, max_x, COLOR_PAIR(3), lower_statusbar_update); - infownd = init_txtwindow((unsigned int)(max_x / 2)-INFOWND_XRELPOS, (unsigned int)(max_y / 2)-INFOWND_YRELPOS, INFOWND_WIDTH, INFOWND_HEIGHT, COLOR_PAIR(4), COLOR_PAIR(4) | A_BOLD, infownd_update); + init_ui_elements(wnd_main, max_x, max_y); - register_input(NULL, pw_input); - register_statusbar(higher); - register_statusbar(lower); - register_anic(heartbeat); - register_txtwindow(infownd); - set_txtwindow_title(infownd, "WARNING"); - set_txtwindow_text(infownd, "String0---------------#\nString1--------------------#\nString2-----#"); - activate_input(wnd_main, pw_input); - set_statusbar_text(higher, title); if (run_ui_thrd() != 0) { goto error; } @@ -301,28 +278,22 @@ do_ui(void) if (key == -1) { continue; } - pthread_mutex_lock(&mtx_busy); if ( process_key(key, pw_input, wnd_main) == false ) { + curs_set(0); memset(mq_msg, '\0', IPC_MQSIZ+1); mq_receive(mq_info, mq_msg, IPC_MQSIZ+1, 0); + set_txtwindow_text(infownd, mq_msg); + set_txtwindow_active(infownd, true); + sleep(3); sem_trywait(sp_ui); } activate_input(wnd_main, pw_input); do_ui_update(false); - pthread_mutex_unlock(&mtx_busy); } ui_thrd_force_update(); stop_ui_thrd(); - unregister_ui_elt(lower); - unregister_ui_elt(higher); - unregister_ui_elt(heartbeat); - unregister_ui_elt(pw_input); - free_input(pw_input); - free_anic(heartbeat); - free_statusbar(higher); - free_statusbar(lower); - free_txtwindow(infownd); - free_ui(); + free_ui_elements(); + ret = DOUI_OK; mq_close(mq_passwd); mq_close(mq_info); diff --git a/ui.h b/ui.h index fcca2a2..dc19fab 100644 --- a/ui.h +++ b/ui.h @@ -26,9 +26,16 @@ typedef int (*ui_callback)(WINDOW *, void *, bool); +typedef int (*ui_input_callback)(WINDOW *, void *, int); + + +union ui_type { + ui_callback ui_element; + ui_input_callback ui_input; +}; struct nask_ui { - ui_callback ui_elt_cb; + union ui_type type; WINDOW *wnd; void *data; struct nask_ui *next; @@ -37,6 +44,9 @@ struct nask_ui { void register_ui_elt(ui_callback uicb, void *data, WINDOW *wnd); +void +register_ui_input(ui_input_callback ipcb, void *data, WINDOW *wnd); + void unregister_ui_elt(void *data); diff --git a/ui_elements.c b/ui_elements.c new file mode 100644 index 0000000..b5b56e2 --- /dev/null +++ b/ui_elements.c @@ -0,0 +1,83 @@ +#include +#include +#include + +#include "ui_elements.h" + + +#define PASSWD_WIDTH 35 +#define PASSWD_HEIGHT 5 +#define PASSWD_XRELPOS (unsigned int)(PASSWD_WIDTH / 2) - (PASSWD_WIDTH / 6) +#define PASSWD_YRELPOS (unsigned int)(PASSWD_HEIGHT / 2) + 1 +#define INFOWND_WIDTH 25 +#define INFOWND_HEIGHT 3 +#define INFOWND_XRELPOS (unsigned int)(INFOWND_WIDTH / 2) - (INFOWND_WIDTH / 6) +#define INFOWND_YRELPOS (unsigned int)(INFOWND_HEIGHT / 2) + 1 + +static struct input *pw_input; +static struct anic *heartbeat; +static struct statusbar *higher, *lower; +static struct txtwindow *infownd; +static char *title = NULL; + + +static int +lower_statusbar_update(WINDOW *win, struct statusbar *bar) +{ + char *tmp = get_system_stat(); + set_statusbar_text(bar, tmp); + free(tmp); + return (0); +} + +static int +infownd_update(WINDOW *win, struct txtwindow *tw) +{ + char *tmp = (char*)(tw->userptr); + size_t len = strlen(tmp); + + if (tw->active) { + if ( len == 3 ) { + memset(tmp+1, '\0', 2); + } else strcat(tmp, "."); + } else (*tmp) = '.'; + return (0); +} + +void +init_ui_elements(WINDOW *wnd_main, unsigned int max_x, unsigned int max_y) +{ + asprintf(&title, "/* %s-%s */", PKGNAME, VERSION); + pw_input = init_input((unsigned int)(max_x / 2)-PASSWD_XRELPOS, (unsigned int)(max_y / 2)-PASSWD_YRELPOS, PASSWD_WIDTH, "PASSWORD: ", IPC_MQSIZ, COLOR_PAIR(3), COLOR_PAIR(2)); + heartbeat = init_anic(0, 0, A_BOLD | COLOR_PAIR(1), "[%c]"); + higher = init_statusbar(0, max_x, A_BOLD | COLOR_PAIR(3), NULL); + lower = init_statusbar(max_y - 1, max_x, COLOR_PAIR(3), lower_statusbar_update); + infownd = init_txtwindow((unsigned int)(max_x / 2)-INFOWND_XRELPOS, (unsigned int)(max_y / 2)-INFOWND_YRELPOS, INFOWND_WIDTH, INFOWND_HEIGHT, COLOR_PAIR(4), COLOR_PAIR(4) | A_BOLD, infownd_update); + infownd->userptr = calloc(4, sizeof(char)); + (*(char*)(infownd->userptr)) = '.'; + + register_input(NULL, pw_input); + register_statusbar(higher); + register_statusbar(lower); + register_anic(heartbeat); + register_txtwindow(infownd); + set_txtwindow_title(infownd, "WARNING"); + activate_input(wnd_main, pw_input); + set_statusbar_text(higher, title); +} + +void +free_ui_elements(void) +{ + unregister_ui_elt(lower); + unregister_ui_elt(higher); + unregister_ui_elt(heartbeat); + unregister_ui_elt(pw_input); + free_input(pw_input); + free_anic(heartbeat); + free_statusbar(higher); + free_statusbar(lower); + free(infownd->userptr); + free_txtwindow(infownd); + free_ui(); +} diff --git a/ui_elements.h b/ui_elements.h new file mode 100644 index 0000000..591e18b --- /dev/null +++ b/ui_elements.h @@ -0,0 +1,20 @@ +#ifndef UI_ELEMENTS_H +#define UI_ELEMENTS_H 1 + +#include "ui.h" +#include "ui_ani.h" +#include "ui_input.h" +#include "ui_statusbar.h" +#include "ui_nwindow.h" + +#include "status.h" +#include "config.h" + + +void +init_ui_elements(WINDOW *wnd_main, unsigned int max_x, unsigned int max_y); + +void +free_ui_elements(void); + +#endif diff --git a/ui_nwindow.c b/ui_nwindow.c index b21bb29..1b88319 100644 --- a/ui_nwindow.c +++ b/ui_nwindow.c @@ -1,7 +1,6 @@ #include #include -#include "ui.h" #include "ui_nwindow.h" @@ -14,7 +13,7 @@ init_txtwindow(unsigned int x, unsigned int y, unsigned int width, unsigned int a->y = y; a->width = width; a->height = height; - a->scrollable = false; + a->active = false; a->title_len = INITIAL_TITLE_LEN; a->title = calloc(a->title_len+1, sizeof(char)); a->text = NULL; @@ -74,19 +73,21 @@ print_wnd(struct txtwindow *a) mvprintw(y-2, (float)x+(float)(w/2)-(float)(a->title_len*2/3), "[ %s ]", a->title); /* print windows text */ i = 0; - while ( a->text[i] ) { + while ( a->text && a->text[i] ) { mvprintw(y+i, x, a->text[i]); i++; } attroff(a->text_attrs); } -int +static int txtwindow_cb(WINDOW *win, void *data, bool timedout) { struct txtwindow *a = (struct txtwindow *) data; - print_wnd(a); + if (a->active == true) { + print_wnd(a); + } return (UICB_OK); } diff --git a/ui_nwindow.h b/ui_nwindow.h index ee2b810..198481b 100644 --- a/ui_nwindow.h +++ b/ui_nwindow.h @@ -3,21 +3,25 @@ #include +#include "ui.h" #define INITIAL_TITLE_LEN 32 +#define set_txtwindow_active(wnd, activate) wnd->active = activate; ui_thrd_force_update() + struct txtwindow { unsigned int y; unsigned int x; unsigned int width; unsigned int height; - bool scrollable; + bool active; char *title; size_t title_len; char **text; int (*window_func)(WINDOW *, struct txtwindow *); chtype attrs; chtype text_attrs; + void *userptr; }; typedef int (*window_func)(WINDOW *, struct txtwindow *); @@ -28,18 +32,12 @@ init_txtwindow(unsigned int, unsigned int y, unsigned int width, unsigned int he void free_txtwindow(struct txtwindow *a); -int -txtwindow_cb(WINDOW *win, void *data, bool timedout); - void register_txtwindow(struct txtwindow *a); void set_txtwindow_text(struct txtwindow *a, char *text); -void -set_txtwindow_scrollable(struct txtwindow *a, bool scrollable); - void set_txtwindow_title(struct txtwindow *a, const char *title); -- cgit v1.2.3 From 1c8d37efdba437ab42d3d14257b7eb6adf7f2e4f Mon Sep 17 00:00:00 2001 From: toni Date: Mon, 26 Oct 2015 00:30:52 +0100 Subject: exported UI IPC --- .gitignore | 3 + Makefile | 8 ++- config.h | 1 + main.c | 81 +++++++-------------- tests/Makefile | 5 ++ tests/semconfig.h | 1 + tests/semtest.c | 8 ++- tests/semtest2.c | 43 +++++++++++ ui.c | 209 ++++++++++++++++++++++++++++-------------------------- ui.h | 19 ++++- ui_elements.c | 62 +++++++++++++++- ui_elements.h | 7 -- ui_input.c | 13 +++- ui_input.h | 6 +- ui_ipc.c | 139 ++++++++++++++++++++++++++++++++++++ ui_ipc.h | 52 ++++++++++++++ 16 files changed, 482 insertions(+), 175 deletions(-) create mode 100644 tests/semtest2.c create mode 100644 ui_ipc.c create mode 100644 ui_ipc.h (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index d965c57..dc4c5e9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,10 @@ /tests/producer /tests/consumer /tests/semtest +/tests/semtest2 /tests/mqtest /tests/strsep *.swp *.o +*.d + diff --git a/Makefile b/Makefile index 2780c74..1e581c9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS = $(shell ncurses5-config --cflags) -Wall -D_GNU_SOURCE=1 -fPIC +CFLAGS = $(shell ncurses5-config --cflags) -Wall -Wundef -Wshadow -D_GNU_SOURCE=1 -fPIC -fomit-frame-pointer -fno-inline -fstrength-reduce -frerun-cse-after-loop -frerun-loop-opt -fexpensive-optimizations -fstrict-aliasing -Os -MD -MP DBGFLAGS = -g LDFLAGS = $(shell ncurses5-config --libs) -pthread -lrt CC = gcc @@ -6,8 +6,9 @@ INSTALL = install STRIP = strip VERSION = $(shell if [ -d ./.git ]; then echo -n "git-"; git rev-parse --short HEAD; else echo "1.2a"; fi) BIN = naskpass -SOURCES = status.c ui_ani.c ui_input.c ui_statusbar.c ui_nwindow.c ui.c ui_elements.c main.c +SOURCES = status.c ui_ani.c ui_input.c ui_statusbar.c ui_nwindow.c ui.c ui_elements.c ui_ipc.c main.c OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) +DEPS = $(patsubst %.c,%.d,$(SOURCES)) all: $(OBJECTS) $(BIN) @@ -18,7 +19,7 @@ $(BIN): $(SOURCES) $(CC) $(LDFLAGS) $(OBJECTS) -o $(BIN) $(MAKE) -C tests CC='$(CC)' CFLAGS='$(CFLAGS)' all -strip: +strip: $(OBJECTS) $(BIN) $(STRIP) $(BIN) release: all strip @@ -41,6 +42,7 @@ uninstall: rmdir --ignore-fail-on-non-empty $(DESTDIR)/usr/share/naskpass clean: + rm -f $(DEPS) rm -f $(OBJECTS) rm -f $(BIN) $(MAKE) -C tests clean diff --git a/config.h b/config.h index 4f39307..a7fddc0 100644 --- a/config.h +++ b/config.h @@ -8,6 +8,7 @@ #define SEM_GUI "/naskpass-gui" #define SEM_INP "/naskpass-input" #define SEM_BSY "/naskpass-busy" +#define SEM_RDY "/naskpass-initialized" #define MSQ_PWD "/naskpass-passwd" #define MSQ_INF "/naskpass-info" diff --git a/main.c b/main.c index 6bcfb00..58c4baf 100644 --- a/main.c +++ b/main.c @@ -12,29 +12,32 @@ #include #include +#include "config.h" + +#include "ui.h" +#include "ui_ipc.h" #include "ui_ani.h" #include "ui_input.h" #include "ui_statusbar.h" -#include "ui.h" -#include "config.h" #define MSG(msg_idx) msg_arr[msg_idx] -static sem_t *sp_ui, *sp_input, *sp_busy; -static mqd_t mq_passwd, mq_info; - enum msg_index { MSG_BUSY_FD = 0, - MSG_BUSY + MSG_BUSY, + MSG_NO_FIFO, + MSG_FIFO_ERR, + MSG_NUM }; -static const char *msg_arr[] = { "Please wait, got a piped password ..", "Please wait, busy .." }; +static const char *msg_arr[] = { "Please wait, got a piped password ..", "Please wait, busy ..", + "check_fifo: %s is not a FIFO\n", "check_fifo: %s error(%d): %s\n" }; static void usage(char *arg0) { - fprintf(stderr, "%s (%s)\n %s\n", PKGNAME, VERSION, PKGDESC); + fprintf(stderr, "\n%s (%s)\n %s\n", PKGNAME, VERSION, PKGDESC); fprintf(stderr, " Written by %s (%s).\n", AUTHOR, AUTHOR_EMAIL); fprintf(stderr, " License GPLv3+: GNU GPL version 3 or later .\n\n"); fprintf(stderr, " Command:\n\t%s [args]\n", arg0); @@ -54,13 +57,13 @@ check_fifo(char *fifo_path) if (S_ISFIFO(st.st_mode) == 1) { return (true); } else { - fprintf(stderr, "stat: %s is not a FIFO\n", fifo_path); + fprintf(stderr, MSG(MSG_NO_FIFO), fifo_path); return (false); } } } } - perror("check_fifo"); + fprintf(stderr, MSG(MSG_FIFO_ERR), fifo_path, errno, strerror(errno)); return (false); } @@ -81,11 +84,9 @@ void sigfunc(int signal) { switch (signal) { case SIGTERM: - case SIGKILL: case SIGINT: - sem_trywait(sp_ui); - sem_trywait(sp_input); - sem_trywait(sp_busy); + ui_ipc_semtrywait(SEM_UI); + ui_ipc_semtrywait(SEM_IN); break; } } @@ -93,42 +94,23 @@ void sigfunc(int signal) int main(int argc, char **argv) { - int ret = EXIT_FAILURE, ffd = -1, c_status, opt, i_sval; + int ret = EXIT_FAILURE, ffd = -1, c_status, opt; pid_t child; char pbuf[IPC_MQSIZ+1]; char *fifo_path = NULL; char *crypt_cmd = NULL; struct timespec ts_sem_input; - struct mq_attr mq_attr; signal(SIGINT, sigfunc); signal(SIGTERM, sigfunc); - signal(SIGKILL, sigfunc); - - mq_attr.mq_flags = 0; - mq_attr.mq_msgsize = IPC_MQSIZ; - mq_attr.mq_maxmsg = 3; - mq_attr.mq_curmsgs = 0; if ( clock_gettime(CLOCK_REALTIME, &ts_sem_input) == -1 ) { fprintf(stderr, "%s: clock get time error: %d (%s)\n", argv[0], errno, strerror(errno)); goto error; } - sp_ui = sem_open(SEM_GUI, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0); - sp_input = sem_open(SEM_INP, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0); - sp_busy = sem_open(SEM_BSY, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0); - mq_passwd = mq_open(MSQ_PWD, O_NONBLOCK | O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG, &mq_attr); - mq_info = mq_open(MSQ_INF, O_NONBLOCK | O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG, &mq_attr); - - if ( sp_ui == SEM_FAILED || sp_input == SEM_FAILED || sp_busy == SEM_FAILED || - mq_passwd == (mqd_t) -1 || mq_info == (mqd_t) -1 ) { - - if ( errno == EEXIST ) { - fprintf(stderr, "%s: already started?\n", argv[0]); - } else { - fprintf(stderr, "%s: can not create semaphore/message queue: %d (%s)\n", argv[0], errno, strerror(errno)); - } + if (ui_ipc_init(1) != 0) { + fprintf(stderr, "%s: can not create semaphore/message queue: %d (%s)\n", argv[0], errno, strerror(errno)); goto error; } @@ -165,7 +147,7 @@ main(int argc, char **argv) goto error; } - sem_post(sp_ui); + ui_ipc_sempost(SEM_UI); if ((child = fork()) == 0) { /* child */ fclose(stderr); @@ -176,20 +158,20 @@ main(int argc, char **argv) fclose(stdin); fclose(stdout); /* Master process: mainloop (read passwd from message queue or fifo and exec cryptcreate */ - while ( (sem_getvalue(sp_ui, &i_sval) == 0 && i_sval > 0) || (sem_getvalue(sp_input, &i_sval) == 0 && i_sval > 0) ) { + while ( ui_ipc_getvalue(SEM_UI) > 0 || ui_ipc_getvalue(SEM_IN) > 0 ) { if (read(ffd, pbuf, IPC_MQSIZ) >= 0) { - sem_post(sp_busy); - mq_send(mq_info, MSG(MSG_BUSY_FD), strlen(MSG(MSG_BUSY_FD)), 0); + ui_ipc_sempost(SEM_BS); + ui_ipc_msgsend(MQ_IF, MSG(MSG_BUSY_FD), strlen(MSG(MSG_BUSY_FD))); if (run_cryptcreate(pbuf, crypt_cmd) != 0) { fprintf(stderr, "cryptcreate error\n"); } - } else if ( mq_receive(mq_passwd, pbuf, IPC_MQSIZ, NULL) >= 0 ) { - sem_post(sp_busy); - mq_send(mq_info, MSG(MSG_BUSY), strlen(MSG(MSG_BUSY)), 0); + } else if ( ui_ipc_msgrecv(MQ_PW, pbuf, IPC_MQSIZ) > 0 ) { + ui_ipc_sempost(SEM_BS); + ui_ipc_msgsend(MQ_IF, MSG(MSG_BUSY), strlen(MSG(MSG_BUSY))); if (run_cryptcreate(pbuf, crypt_cmd) != 0) { fprintf(stderr, "cryptcreate error\n"); } - sem_wait(sp_input); + ui_ipc_semwait(SEM_IN); } usleep(100000); } @@ -206,15 +188,6 @@ error: if (ffd >= 0) close(ffd); if (crypt_cmd != NULL) free(crypt_cmd); if (fifo_path != NULL) free(fifo_path); - sem_close(sp_ui); - sem_close(sp_input); - sem_close(sp_busy); - mq_close(mq_passwd); - mq_close(mq_info); - sem_unlink(SEM_GUI); - sem_unlink(SEM_INP); - sem_unlink(SEM_BSY); - mq_unlink(MSQ_PWD); - mq_unlink(MSQ_INF); + ui_ipc_free(1); exit(ret); } diff --git a/tests/Makefile b/tests/Makefile index 5a041e6..436d00f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,13 +3,18 @@ LDFLAGS = -lpthread -lrt CC = gcc SOURCES = $(wildcard *.c) BINARIES = $(patsubst %.c,%,$(SOURCES)) +DEPS = $(patsubst %.c,%.d,$(SOURCES)) all: $(BINARIES) +semtest2: + $(CC) $(CFLAGS) $(LDFLAGS) ../ui_ipc.o semtest2.c -o semtest2 + %: %.c $(CC) $(CFLAGS) $(LDFLAGS) $< -o $(patsubst %.c,%,$<) clean: + rm -f $(DEPS) rm -f $(BINARIES) .PHONY: all install clean diff --git a/tests/semconfig.h b/tests/semconfig.h index e34984d..0ad08b3 100644 --- a/tests/semconfig.h +++ b/tests/semconfig.h @@ -2,6 +2,7 @@ #define CONFIG_H 1 #define LOG(text) fprintf(stderr, "%s\n", text); +#define CMD(cmd) LOG(cmd); cmd; #define TESTSEM "/testsem" #define CNTSEM "/testcnt" diff --git a/tests/semtest.c b/tests/semtest.c index 7968127..f462a6e 100644 --- a/tests/semtest.c +++ b/tests/semtest.c @@ -7,15 +7,16 @@ #include #include +#include "semconfig.h" + sem_t *mysem = NULL; pid_t child; -#define LOG(cmd) fprintf(stderr, "%s\n", cmd); int main(int argc, char **argv) { - sem_unlink("/mysem"); - if ( (mysem = sem_open("/mysem", O_CREAT, S_IRUSR | S_IWUSR, 1)) != NULL ) { + sem_unlink(TESTSEM); + if ( (mysem = sem_open(TESTSEM, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0)) != NULL ) { if ( (child = fork()) == 0 ) { /* child */ sleep(1); @@ -37,6 +38,7 @@ int main(int argc, char **argv) { sem_close(mysem); exit(1); } + sem_unlink(TESTSEM); exit(0); } diff --git a/tests/semtest2.c b/tests/semtest2.c new file mode 100644 index 0000000..c015df8 --- /dev/null +++ b/tests/semtest2.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ui_ipc.h" + +pid_t child; + +#define LOG(cmd) fprintf(stderr, "%s\n", cmd); + +int main(int argc, char **argv) { + if (ui_ipc_init(1) != 0) { + perror("ui_ipc_init"); + exit(1); + } + if ( (child = fork()) == 0 ) { + /* child */ + sleep(1); + LOG("child: sempost"); + ui_ipc_sempost(SEM_RD); + LOG("child: done"); + sleep(1); + exit(0); + } else if (child > 0) { + /* parent */ + LOG("parent: semwait"); + ui_ipc_semwait(SEM_RD); + LOG("parent: waitpid"); + waitpid(child, NULL, 0); + } else if (child < 0) { + perror("fork"); + exit(1); + } + ui_ipc_free(1); + + exit(0); +} + diff --git a/ui.c b/ui.c index e5f4454..dc16b96 100644 --- a/ui.c +++ b/ui.c @@ -15,6 +15,7 @@ #include #include "ui.h" +#include "ui_ipc.h" #include "ui_elements.h" #include "ui_ani.h" #include "ui_input.h" @@ -40,52 +41,83 @@ static unsigned int max_x, max_y; static WINDOW *wnd_main; -static struct nask_ui *nui = NULL; -static struct nask_input *nin = NULL; +static struct nask_ui /* simple linked list to all GUI objects */ *nui = NULL, + /* simple linked list to all INPUT objects */ *nin = NULL, /* current active input */ *active = NULL; static pthread_t thrd; static unsigned int atmout = APP_TIMEOUT; static pthread_cond_t cnd_update = PTHREAD_COND_INITIALIZER; static pthread_mutex_t mtx_update = PTHREAD_MUTEX_INITIALIZER; -static sem_t sem_rdy; -static sem_t /* TUI active? */ *sp_ui, /* Textfield input available? */ *sp_input; -static mqd_t mq_passwd, mq_info; -void -register_ui_elt(ui_callback uicb, void *data, WINDOW *wnd) +static void +register_basic(enum ui_type utype, union ui_data uicb, void *data, WINDOW *wnd) { - struct nask_ui *tmp, *new; + struct nask_ui *tmp, *new, *ui = NULL; - if (nui != NULL) { - tmp = nui; - while (tmp->next != NULL) { - tmp = tmp->next; - } + switch (utype) { + case UI_ELEMENT: + ui = nui; + break; + case UI_INPUT: + ui = nin; + break; } new = calloc(1, sizeof(struct nask_ui)); - new->ui_elt_cb = uicb; + new->type = utype; + new->callback = uicb; new->wnd = wnd; new->data = data; new->next = NULL; - if (nui == NULL) { - nui = new; - nui->next = NULL; + if (ui == NULL) { + ui = new; + ui->next = NULL; + switch (utype) { + case UI_ELEMENT: + nui = ui; + break; + case UI_INPUT: + nin = ui; + break; + } } else { + tmp = ui; + while (tmp->next != NULL) { + tmp = tmp->next; + } tmp->next = new; } } void -register_input(ui_input_callback ipcb, void *data, WINDOW *wnd) +register_ui_elt(ui_callback uicb, void *data, WINDOW *wnd) { - + union ui_data cb; + cb.ui_element = uicb; + register_basic(UI_ELEMENT, cb, data, wnd); } void -unregister_ui_elt(void *data) +register_ui_input(ui_input_callback ipcb, void *data, WINDOW *wnd) +{ + union ui_data cb; + cb.ui_input = ipcb; + register_basic(UI_INPUT, cb, data, wnd); +} + +static void +unregister_basic(enum ui_type utype, void *data) { - struct nask_ui *cur = nui, *next, *before = NULL; + struct nask_ui *cur, *next, *before = NULL, **ui = NULL; + switch (utype) { + case UI_ELEMENT: + ui = &nui; + break; + case UI_INPUT: + ui = &nin; + break; + } + cur = *ui; while (cur != NULL) { next = cur->next; if (cur->data != NULL && cur->data == data) { @@ -93,7 +125,7 @@ unregister_ui_elt(void *data) if (before != NULL) { before->next = next; } else { - nui = next; + *ui = next; } } before = cur; @@ -101,6 +133,46 @@ unregister_ui_elt(void *data) } } +void +unregister_ui_elt(void *data) +{ + unregister_basic(UI_ELEMENT, data); +} + +void +unregister_ui_input(void *data) +{ + unregister_basic(UI_INPUT, data); +} + +int +activate_ui_input(void *data) +{ + struct nask_ui *cur = nin; + + if (cur == NULL || data == NULL) return DOUI_NINIT; + while ( cur != NULL ) { + if ( cur == data && cur->type == UI_INPUT ) { + if ( cur->callback.ui_input(cur->wnd, data, UIKEY_ACTIVATE) == DOUI_OK ) { + active = cur; + return DOUI_OK; + } + } + cur = cur->next; + } + return DOUI_ERR; +} + +static bool +process_key(char key) +{ + atmout = APP_TIMEOUT; + if ( active != NULL ) { + return ( active->callback.ui_input(active->wnd, active->data, key) == DOUI_OK ? true : false ); + } + return false; +} + static int do_ui_update(bool timed_out) { @@ -112,8 +184,8 @@ do_ui_update(bool timed_out) /* call all draw callback's */ erase(); while (cur != NULL) { - if (cur->ui_elt_cb != NULL) { - cur->ui_elt_cb(cur->wnd, cur->data, timed_out); + if (cur->type == UI_ELEMENT && cur->callback.ui_element != NULL) { + cur->callback.ui_element(cur->wnd, cur->data, timed_out); doupdate(); } else { retval = UICB_ERR_CB; @@ -133,7 +205,7 @@ do_ui_update(bool timed_out) static void * ui_thrd(void *arg) { - int cnd_ret, i_sval; + int cnd_ret; struct timeval now; struct timespec wait; @@ -141,11 +213,11 @@ ui_thrd(void *arg) wait.tv_sec = now.tv_sec + UILOOP_TIMEOUT; wait.tv_nsec = now.tv_usec * 1000; do_ui_update(true); - sem_post(&sem_rdy); - while ( sem_getvalue(sp_ui, &i_sval) == 0 && i_sval > 0 ) { + ui_ipc_sempost(SEM_RD); + while ( ui_ipc_getvalue(SEM_UI) > 0 ) { pthread_mutex_lock(&mtx_update); cnd_ret = pthread_cond_timedwait(&cnd_update, &mtx_update, &wait); - if (--atmout == 0) sem_trywait(sp_ui); + if (--atmout == 0) ui_ipc_semtrywait(SEM_UI); do_ui_update( (cnd_ret == ETIMEDOUT ? true : false) ); if (cnd_ret == ETIMEDOUT) { wait.tv_sec += UILOOP_TIMEOUT; @@ -202,66 +274,14 @@ stop_ui_thrd(void) return (pthread_join(thrd, NULL)); } -static int -mq_passwd_send(char *passwd, size_t len) -{ - struct mq_attr m_attr; - - sem_post(sp_input); - if (mq_send(mq_passwd, passwd, len, 0) == 0 && mq_getattr(mq_passwd, &m_attr) == 0) { - return m_attr.mq_curmsgs; - } - memset(passwd, '\0', len); - return -1; -} - -static bool -process_key(char key, struct input *a, WINDOW *win) -{ - bool retval = true; - - atmout = APP_TIMEOUT; - switch (key) { - case UIKEY_ENTER: - if ( mq_passwd_send(a->input, a->input_len) > 0 ) { - retval = false; - } else retval = true; - break; - case UIKEY_BACKSPACE: - del_input(win, a); - break; - case UIKEY_ESC: - retval = false; - break; - case UIKEY_DOWN: - case UIKEY_UP: - case UIKEY_LEFT: - case UIKEY_RIGHT: - break; - default: - add_input(win, a, key); - } - return (retval); -} - int do_ui(void) { - struct anic *heartbeat; char key = '\0'; - char *title = NULL, mq_msg[IPC_MQSIZ+1]; - int i_sval = -1, ret = DOUI_ERR; + char *title = NULL; + int ret = DOUI_ERR; asprintf(&title, "/* %s-%s */", PKGNAME, VERSION); - sp_ui = sem_open(SEM_GUI, 0, 0, 0); - sp_input = sem_open(SEM_INP, 0, 0, 0); - mq_passwd = mq_open(MSQ_PWD, O_WRONLY, 0, NULL); - mq_info = mq_open(MSQ_INF, O_RDONLY, 0, NULL); - if ( sem_init(&sem_rdy, 0, 0) == -1 || !sp_ui || !sp_input || mq_passwd == (mqd_t)-1 || mq_info == (mqd_t)-1 ) { - perror("init semaphore/messageq"); - goto error; - } - /* init TUI and UI Elements (input field, status bar, etc) */ init_ui(); init_ui_elements(wnd_main, max_x, max_y); @@ -269,25 +289,20 @@ do_ui(void) if (run_ui_thrd() != 0) { goto error; } - sem_wait(&sem_rdy); - wtimeout(wnd_main, 1000); - while ( sem_getvalue(sp_ui, &i_sval) == 0 && i_sval > 0 ) { + ui_ipc_semwait(SEM_RD); + wtimeout(wnd_main, 10); + while ( ui_ipc_getvalue(SEM_UI) > 0 ) { if ((key = wgetch(wnd_main)) == '\0') { break; } if (key == -1) { continue; } - if ( process_key(key, pw_input, wnd_main) == false ) { - curs_set(0); - memset(mq_msg, '\0', IPC_MQSIZ+1); - mq_receive(mq_info, mq_msg, IPC_MQSIZ+1, 0); - set_txtwindow_text(infownd, mq_msg); - set_txtwindow_active(infownd, true); - sleep(3); - sem_trywait(sp_ui); + if ( process_key(key) != true ) { +printf("BLABL\n"); + break; } - activate_input(wnd_main, pw_input); +printf("BLUBB\n"); do_ui_update(false); } ui_thrd_force_update(); @@ -295,15 +310,9 @@ do_ui(void) free_ui_elements(); ret = DOUI_OK; - mq_close(mq_passwd); - mq_close(mq_info); error: if (title) free(title); - if (sp_ui) sem_close(sp_ui); - if (sp_input) sem_close(sp_input); title = NULL; - sp_ui = NULL; - sp_input = NULL; return ret; } diff --git a/ui.h b/ui.h index dc19fab..d5a9123 100644 --- a/ui.h +++ b/ui.h @@ -12,10 +12,11 @@ #define DOUI_OK 0 #define DOUI_ERR 1 #define DOUI_TMOUT 2 -#define DOUI_PASSWD 3 +#define DOUI_NINIT 3 #define UILOOP_TIMEOUT 1 +#define UIKEY_ACTIVATE 0 #define UIKEY_ENTER 10 #define UIKEY_BACKSPACE 7 #define UIKEY_ESC 27 @@ -29,13 +30,19 @@ typedef int (*ui_callback)(WINDOW *, void *, bool); typedef int (*ui_input_callback)(WINDOW *, void *, int); -union ui_type { +enum ui_type { + UI_ELEMENT, + UI_INPUT +}; + +union ui_data { ui_callback ui_element; ui_input_callback ui_input; }; struct nask_ui { - union ui_type type; + enum ui_type type; + union ui_data callback; WINDOW *wnd; void *data; struct nask_ui *next; @@ -50,6 +57,12 @@ register_ui_input(ui_input_callback ipcb, void *data, WINDOW *wnd); void unregister_ui_elt(void *data); +void +unregister_ui_input(void *data); + +int +activate_ui_input(void *data); + void ui_thrd_force_update(void); diff --git a/ui_elements.c b/ui_elements.c index b5b56e2..b9885a0 100644 --- a/ui_elements.c +++ b/ui_elements.c @@ -2,8 +2,15 @@ #include #include +#include "ui.h" +#include "ui_ipc.h" +#include "ui_ani.h" +#include "ui_input.h" +#include "ui_statusbar.h" +#include "ui_nwindow.h" #include "ui_elements.h" +#include "status.h" #define PASSWD_WIDTH 35 #define PASSWD_HEIGHT 5 @@ -44,6 +51,57 @@ infownd_update(WINDOW *win, struct txtwindow *tw) return (0); } +static int +mq_passwd_send(char *passwd, size_t len) +{ + int ret; + + ui_ipc_sempost(SEM_IN); + ret = ui_ipc_msgsend(MQ_PW, passwd, len); + memset(passwd, '\0', len); + return ret; +} + +static int +passwd_input_cb(WINDOW *wnd, void *data, int key) +{ + struct input *a = (struct input *) data; + +/* + * if ( process_key(key, pw_input, wnd_main) == false ) { + * curs_set(0); + * memset(mq_msg, '\0', IPC_MQSIZ+1); + * mq_receive(mq_info, mq_msg, IPC_MQSIZ+1, 0); + * set_txtwindow_text(infownd, mq_msg); + * set_txtwindow_active(infownd, true); + * sleep(3); + * sem_trywait(sp_ui); + * } + * activate_input(wnd_main, pw_input); + */ + switch (key) { + case UIKEY_ENTER: + if ( mq_passwd_send(a->input, a->input_len) > 0 ) { + return DOUI_OK; + } else return DOUI_ERR; + break; + case UIKEY_BACKSPACE: + del_input(wnd, a); + break; + case UIKEY_ESC: + return DOUI_ERR; + break; + case UIKEY_DOWN: + case UIKEY_UP: + case UIKEY_LEFT: + case UIKEY_RIGHT: + break; + default: + add_input(wnd, a, key); + } + return DOUI_OK; +} + void init_ui_elements(WINDOW *wnd_main, unsigned int max_x, unsigned int max_y) { @@ -56,7 +114,7 @@ init_ui_elements(WINDOW *wnd_main, unsigned int max_x, unsigned int max_y) infownd->userptr = calloc(4, sizeof(char)); (*(char*)(infownd->userptr)) = '.'; - register_input(NULL, pw_input); + register_input(NULL, pw_input, passwd_input_cb); register_statusbar(higher); register_statusbar(lower); register_anic(heartbeat); @@ -72,7 +130,7 @@ free_ui_elements(void) unregister_ui_elt(lower); unregister_ui_elt(higher); unregister_ui_elt(heartbeat); - unregister_ui_elt(pw_input); + unregister_input(pw_input); free_input(pw_input); free_anic(heartbeat); free_statusbar(higher); diff --git a/ui_elements.h b/ui_elements.h index 591e18b..0cf8826 100644 --- a/ui_elements.h +++ b/ui_elements.h @@ -1,13 +1,6 @@ #ifndef UI_ELEMENTS_H #define UI_ELEMENTS_H 1 -#include "ui.h" -#include "ui_ani.h" -#include "ui_input.h" -#include "ui_statusbar.h" -#include "ui_nwindow.h" - -#include "status.h" #include "config.h" diff --git a/ui_input.c b/ui_input.c index 63d8bee..43836f1 100644 --- a/ui_input.c +++ b/ui_input.c @@ -125,7 +125,7 @@ activate_input(WINDOW *win, struct input *a) } else { wmove(win, a->y, a->x + p_len + a->cur_pos); } - return (UICB_OK); + return (activate_ui_input( (void *) a )); } int @@ -174,7 +174,16 @@ input_cb(WINDOW *win, void *data, bool timed_out) } void -register_input(WINDOW *win, struct input *a) +register_input(WINDOW *win, struct input *a, ui_input_callback uin) { + a->cb_input = uin; register_ui_elt(input_cb, (void *) a, win); + register_ui_input(uin, (void *) a, win); +} + +void +unregister_input(struct input *a) +{ + unregister_ui_input( (void *) a ); + unregister_ui_elt( (void *) a ); } diff --git a/ui_input.h b/ui_input.h index e65d560..be93864 100644 --- a/ui_input.h +++ b/ui_input.h @@ -16,6 +16,7 @@ struct input { char *prompt; chtype attrs; chtype shadow; + ui_input_callback cb_input; }; struct input * @@ -37,6 +38,9 @@ int input_cb(WINDOW *win, void *data, bool timed_out); void -register_input(WINDOW *win, struct input *a); +register_input(WINDOW *win, struct input *a, ui_input_callback uin); + +void +unregister_input(struct input *a); #endif diff --git a/ui_ipc.c b/ui_ipc.c new file mode 100644 index 0000000..60da7cb --- /dev/null +++ b/ui_ipc.c @@ -0,0 +1,139 @@ +#include +#include +#include +#ifdef SEM_TIMEDWAIT +#include +#endif +#include +#include +#include +#include + +#include "ui_ipc.h" + +#define JMP_IF(cmd, retval, jmplabel) if ( (cmd) == retval ) { printf("(%s) == %p\n", #cmd, (void*)retval); goto jmplabel; } + + +static sem_t *sems[SEM_NUM]; +static mqd_t msqs[MSQ_NUM]; +static unsigned char initialized = 0; + + +int +ui_ipc_init(int is_master) +{ + volatile int sp_oflags, mq_oflags; + mode_t crt_flags; + struct mq_attr m_attr; + + if (initialized) { + return -1; + } + bzero(sems, sizeof(sem_t*)*SEM_NUM); + bzero(msqs, sizeof(mqd_t)*MSQ_NUM); + m_attr.mq_flags = 0; + m_attr.mq_msgsize = IPC_MQSIZ; + m_attr.mq_maxmsg = 3; + m_attr.mq_curmsgs = 0; + if (is_master) { + sp_oflags = O_CREAT | O_EXCL; + mq_oflags = O_NONBLOCK | O_CREAT | O_EXCL; + crt_flags = S_IRUSR | S_IWUSR; + JMP_IF( msqs[MQ_PW] = mq_open(MSQ_PWD, mq_oflags | O_RDONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + JMP_IF( msqs[MQ_IF] = mq_open(MSQ_INF, mq_oflags | O_WRONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + } else { + sp_oflags = 0; + mq_oflags = 0; + crt_flags = 0; + JMP_IF( msqs[MQ_PW] = mq_open(MSQ_PWD, mq_oflags | O_WRONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + JMP_IF( msqs[MQ_IF] = mq_open(MSQ_INF, mq_oflags | O_RDONLY, crt_flags, &m_attr), (mqd_t)-1, error ); + } + JMP_IF( sems[SEM_UI] = sem_open(SEM_GUI, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + JMP_IF( sems[SEM_IN] = sem_open(SEM_INP, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + JMP_IF( sems[SEM_BS] = sem_open(SEM_BSY, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + JMP_IF( sems[SEM_RD] = sem_open(SEM_RDY, sp_oflags, crt_flags, 0), SEM_FAILED, error ); + initialized = 1; + return 0; +error: + return errno; +} + +void +ui_ipc_free(int is_master) +{ + int i; + + if (!initialized) { + return; + } + for (i = 0; i < SEM_NUM; i++) { + if (sems[i]) sem_close(sems[i]); + } + for (i = 0; i < MSQ_NUM; i++) { + if (msqs[i]) mq_close(msqs[i]); + } + if (is_master > 0) { + sem_unlink(SEM_BSY); + sem_unlink(SEM_GUI); + sem_unlink(SEM_INP); + sem_unlink(SEM_RDY); + mq_unlink(MSQ_PWD); + mq_unlink(MSQ_INF); + } + initialized = 0; +} + +int +ui_ipc_sempost(enum UI_IPC_SEM e_sp) +{ + return ( sem_post(sems[e_sp]) ); +} + +int +ui_ipc_semwait(enum UI_IPC_SEM e_sp) +{ + return ( sem_wait(sems[e_sp]) ); +} + +int +ui_ipc_semtrywait(enum UI_IPC_SEM e_sp) +{ + return ( sem_trywait(sems[e_sp]) ); +} + +int +ui_ipc_getvalue(enum UI_IPC_SEM e_sp) +{ + int sp_val = 0; + + if (sem_getvalue(sems[e_sp], &sp_val) != 0) { + return -1; + } + return sp_val; +} + +#ifdef SEM_TIMEDWAIT +int +ui_ipc_semtimedwait(enum UI_IPC_SEM e_sp, int timeout) +{ + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + return -1; + } + ts.tc_sec += timeout; + return ( sem_timedwait(sems[q_mq], &ts) ); +} +#endif + +int +ui_ipc_msgsend(enum UI_IPC_MSQ e_mq, const char *msg_ptr, size_t msg_len) +{ + return ( mq_send(msqs[e_mq], msg_ptr, msg_len, 0) ); +} + +ssize_t +ui_ipc_msgrecv(enum UI_IPC_MSQ e_mq, char *msg_ptr, size_t msg_len) +{ + return ( mq_receive(msqs[e_mq], msg_ptr, msg_len, NULL) ); +} + diff --git a/ui_ipc.h b/ui_ipc.h new file mode 100644 index 0000000..2c5bcb5 --- /dev/null +++ b/ui_ipc.h @@ -0,0 +1,52 @@ +#ifndef UI_IPC_H +#define UI_IPC_H 1 + +#include "status.h" +#include "config.h" + + +enum UI_IPC_SEM { + SEM_RD = 0, /* UI Init done? */ + SEM_UI, /* TUI active? */ + SEM_IN, /* Textfield has input avail */ + SEM_BS, /* Master process busy */ + SEM_NUM +}; + +enum UI_IPC_MSQ { + MQ_PW = 0, + MQ_IF, + MSQ_NUM +}; + + +int +ui_ipc_init(int is_master); + +void +ui_ipc_free(int is_master); + +int +ui_ipc_sempost(enum UI_IPC_SEM e_sp); + +int +ui_ipc_semwait(enum UI_IPC_SEM e_sp); + +int +ui_ipc_semtrywait(enum UI_IPC_SEM e_sp); + +int +ui_ipc_getvalue(enum UI_IPC_SEM e_sp); + +#ifdef SEM_TIMEDWAIT +int +ui_ipc_semtimedwait(enum UI_IPC_MSQ e_sp, int timeout); +#endif + +int +ui_ipc_msgsend(enum UI_IPC_MSQ e_mq, const char *msg_ptr, size_t msg_len); + +ssize_t +ui_ipc_msgrecv(enum UI_IPC_MSQ e_mq, char *msg_ptr, size_t msg_len); + +#endif -- cgit v1.2.3 From 089551924a7c6bae2b03bee9999e5563f9267571 Mon Sep 17 00:00:00 2001 From: toni Date: Mon, 16 Nov 2015 23:18:45 +0100 Subject: (auto(conf|make)|dpkg) versioning fix (src/version.h shows the DEFINITIVE version of the pkg) --- .gitignore | 1 + Makefile.am | 5 +++++ Makefile.debug | 8 ++------ configure.ac | 6 +++++- debian/rules | 4 +++- src/Makefile.am | 2 +- src/config.h | 8 +++++--- 7 files changed, 22 insertions(+), 12 deletions(-) (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index dc4c5e9..e233e82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /naskpass +/src/version.h /tests/producer /tests/consumer /tests/semtest diff --git a/Makefile.am b/Makefile.am index 1d76541..5b9f08b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,10 @@ SUBDIRS = src +install-exec-local: + /bin/mkdir -p '$(prefix)/lib/cryptsetup' + /usr/bin/install -c src/naskpass '$(prefix)/lib/cryptsetup/naskpass' + rm '$(prefix)/bin/naskpass' + rmdir '$(prefix)/bin' clean-local: rm -f naskpass diff --git a/Makefile.debug b/Makefile.debug index 66bf8e0..2faf3b2 100644 --- a/Makefile.debug +++ b/Makefile.debug @@ -3,7 +3,6 @@ LDFLAGS = $(shell ncurses5-config --libs) -pthread -lrt CC = gcc INSTALL = install STRIP = strip -VERSION = $(shell if [ -d ./.git ]; then echo -n "git-"; git rev-parse --short HEAD; else echo "1.2a"; fi) BIN = naskpass SOURCES = $(wildcard src/*.c) OBJECTS = $(patsubst %.c,%.o,$(SOURCES)) @@ -12,7 +11,7 @@ DEPS = $(patsubst %.c,%.d,$(SOURCES)) all: $(OBJECTS) $(BIN) %.o: %.c - $(CC) $(CFLAGS) -D_VERSION=\"$(VERSION)\" -c $< -o $@ + $(CC) $(CFLAGS) -c $< -o $@ $(BIN): $(SOURCES) $(CC) $(LDFLAGS) $(OBJECTS) -o $(BIN) @@ -46,7 +45,4 @@ clean: rm -f $(BIN) $(MAKE) -C tests clean -source: - -dh_make --createorig -p naskpass_$(VERSION) -s -y - -.PHONY: all install clean +.PHONY: all debug release strip install uninstall clean diff --git a/configure.ac b/configure.ac index 943f5cf..dc50072 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ # AC_PREREQ([2.67]) -AC_INIT([naskpass], [0.01], [matzeton@googlemail.com]) +AC_INIT([naskpass], [0], [matzeton@googlemail.com]) AC_CONFIG_AUX_DIR([build]) AM_INIT_AUTOMAKE([1.11 foreign no-define -Wall -Werror]) AM_WITH_DMALLOC @@ -66,3 +66,7 @@ AC_SUBST([AM_LDFLAGS]) AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT +echo "Run 'make' to finish the process." +test -d .git && VERSION="git-$(git rev-parse --short HEAD)" +echo "#define VERSION \"${VERSION}\"" >src/version.h + diff --git a/debian/rules b/debian/rules index 048a2ae..5cdc77d 100755 --- a/debian/rules +++ b/debian/rules @@ -10,6 +10,7 @@ configure-stamp: dh_testdir ./autogen.sh ./configure + echo "#define VERSION \"$(DEBVERS)\"" >src/version.h touch configure-stamp build: configure-stamp build-stamp @@ -30,7 +31,8 @@ distclean: build install: build dh_testdir dh_testroot - dh_clean -k + dh_clean + dh_prep dh_installdirs $(MAKE) install prefix=$(CURDIR)/debian/naskpass mkdir -p $(CURDIR)/debian/naskpass/usr/share/naskpass diff --git a/src/Makefile.am b/src/Makefile.am index 07b4cfa..aab865c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,3 @@ bin_PROGRAMS=naskpass -naskpass_SOURCES=main.c opt.c status.c ui_ani.c ui.c ui_elements.c ui_input.c ui_ipc.c ui_nwindow.c ui_statusbar.c +naskpass_SOURCES=main.c opt.c status.c ui_ani.c ui.c ui_elements.c ui_input.c ui_ipc.c ui_txtwindow.c ui_statusbar.c diff --git a/src/config.h b/src/config.h index 9d72ef3..797376f 100644 --- a/src/config.h +++ b/src/config.h @@ -12,8 +12,10 @@ #define MSQ_PWD "/naskpass-passwd" #define MSQ_INF "/naskpass-info" -#ifdef _VERSION -#define VERSION _VERSION -#else +#ifdef HAVE_CONFIG_H +#include "version.h" +#endif + +#ifndef VERSION #define VERSION "unknown" #endif -- cgit v1.2.3 From cb8ac81c8c538f4a02edb5c2762cfbc5f5adef88 Mon Sep 17 00:00:00 2001 From: toni Date: Mon, 16 Nov 2015 23:56:07 +0100 Subject: better tests --- .gitignore | 2 +- debian/rules | 1 + tests/Makefile | 17 +++++++++++++---- tests/consumer.c | 38 -------------------------------------- tests/producer.c | 5 ++--- tests/producer_consumer.c | 39 +++++++++++++++++++++++++++++++++++++++ tests/semconfig.h | 2 +- tests/semtest.c | 10 ++++++++-- tests/semtest2.c | 43 ------------------------------------------- tests/strsep.c | 28 +++++++++++++++++++++++----- 10 files changed, 88 insertions(+), 97 deletions(-) delete mode 100644 tests/consumer.c create mode 100644 tests/producer_consumer.c delete mode 100644 tests/semtest2.c (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index e233e82..2aa84b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ /naskpass /src/version.h /tests/producer -/tests/consumer +/tests/producer_consumer /tests/semtest /tests/semtest2 /tests/mqtest diff --git a/debian/rules b/debian/rules index 5cdc77d..46395bb 100755 --- a/debian/rules +++ b/debian/rules @@ -17,6 +17,7 @@ build: configure-stamp build-stamp build-stamp: dh_testdir $(MAKE) + $(MAKE) -C tests -f Makefile run touch build-stamp clean: diff --git a/tests/Makefile b/tests/Makefile index 20b86ba..8afc274 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -CFLAGS = -Wall +CFLAGS = -Wall -g LDFLAGS = -lpthread -lrt CC = gcc SOURCES = $(wildcard *.c) @@ -7,9 +7,6 @@ DEPS = $(patsubst %.c,%.d,$(SOURCES)) all: $(BINARIES) -semtest2: - $(CC) $(CFLAGS) $(LDFLAGS) -I ../src ../src/ui_ipc.o semtest2.c -o semtest2 - %: %.c $(CC) $(CFLAGS) $(LDFLAGS) $< -o $(patsubst %.c,%,$<) @@ -17,4 +14,16 @@ clean: rm -f $(DEPS) rm -f $(BINARIES) +run: all + @echo "* running tests" + for test in $(patsubst %.c,%,$(SOURCES)); do \ + echo -n "* running $${test}"; \ + ./$${test} >/dev/null; \ + if [ $$? -ne 0 ]; then \ + echo " FAILED!"; \ + else \ + echo " OK!"; \ + fi; \ + done + .PHONY: all install clean diff --git a/tests/consumer.c b/tests/consumer.c deleted file mode 100644 index 3f93d1e..0000000 --- a/tests/consumer.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "semconfig.h" - -sem_t *mysem = NULL, *mycnt = NULL; -pid_t child; - - -int main(int argc, char **argv) { - int semval = 0; - - if ( (mysem = sem_open(TESTSEM, 0, S_IRUSR | S_IWUSR, 1)) != NULL && - (mycnt = sem_open(CNTSEM, 0, S_IRUSR | S_IWUSR, 1)) != NULL ) { - assert( sem_getvalue(mycnt, &semval) == 0 ); - printf("factory producing %d items\n", semval); - - while ( semval-- >= 0 ) { - usleep(250000); - LOG("consumer: -1"); - assert( sem_wait(mysem) == 0 ); - printf("remaining: %d\n", semval); - } - } else { - exit(1); - } - assert( sem_close(mysem) == 0 ); - - exit(0); -} - diff --git a/tests/producer.c b/tests/producer.c index 25af700..f1a568d 100644 --- a/tests/producer.c +++ b/tests/producer.c @@ -24,13 +24,12 @@ int main(int argc, char **argv) { if ( (mysem = sem_open(TESTSEM, O_CREAT, S_IRUSR | S_IWUSR, 0)) != NULL && (mycnt = sem_open(CNTSEM, O_CREAT, S_IRUSR | S_IWUSR, semval)) != NULL ) { while (semval-- >= 0) { - sleep(1); - LOG("producer: +1"); + usleep(250); + printf("producer: +1"); assert( sem_post(mysem) == 0 ); printf("remaining: %d\n", semval); } assert( sem_close(mysem) == 0 && sem_close(mycnt) == 0 ); - assert( sem_unlink(TESTSEM) == 0 && sem_unlink(CNTSEM) == 0 ); } else { exit(1); } diff --git a/tests/producer_consumer.c b/tests/producer_consumer.c new file mode 100644 index 0000000..104004a --- /dev/null +++ b/tests/producer_consumer.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "semconfig.h" + +sem_t *mysem = NULL, *mycnt = NULL; +pid_t child; + + +int main(int argc, char **argv) { + int semval = 0; + + if ( (mysem = sem_open(TESTSEM, 0, S_IRUSR | S_IWUSR, 1)) != NULL && + (mycnt = sem_open(CNTSEM, 0, S_IRUSR | S_IWUSR, 1)) != NULL ) { + assert( sem_getvalue(mycnt, &semval) == 0 ); + printf("factory producing %d items\n", semval); + + while ( semval-- >= 0 ) { + usleep(250); + LOG("consumer: -1"); + assert( sem_wait(mysem) == 0 ); + printf("remaining: %d\n", semval); + } + } else { + exit(1); + } + assert( sem_close(mysem) == 0 ); + assert( sem_unlink(TESTSEM) == 0 && sem_unlink(CNTSEM) == 0 ); + + exit(0); +} + diff --git a/tests/semconfig.h b/tests/semconfig.h index 0ad08b3..2878dbe 100644 --- a/tests/semconfig.h +++ b/tests/semconfig.h @@ -1,7 +1,7 @@ #ifndef CONFIG_H #define CONFIG_H 1 -#define LOG(text) fprintf(stderr, "%s\n", text); +#define LOG(text) printf("%s\n", text); #define CMD(cmd) LOG(cmd); cmd; #define TESTSEM "/testsem" #define CNTSEM "/testcnt" diff --git a/tests/semtest.c b/tests/semtest.c index f462a6e..fdecf2d 100644 --- a/tests/semtest.c +++ b/tests/semtest.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "semconfig.h" @@ -19,11 +20,11 @@ int main(int argc, char **argv) { if ( (mysem = sem_open(TESTSEM, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0)) != NULL ) { if ( (child = fork()) == 0 ) { /* child */ - sleep(1); + usleep(250); LOG("child: sempost"); sem_post(mysem); LOG("child: done"); - sleep(1); + usleep(250); exit(0); } else if (child > 0) { /* parent */ @@ -38,6 +39,11 @@ int main(int argc, char **argv) { sem_close(mysem); exit(1); } + + int sval; + assert ( sem_getvalue(mysem, &sval) == 0 ); + assert (sval == 0); + sem_unlink(TESTSEM); exit(0); } diff --git a/tests/semtest2.c b/tests/semtest2.c deleted file mode 100644 index 1724cf1..0000000 --- a/tests/semtest2.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ui_ipc.h" - -pid_t child; - -#define LOG(cmd) fprintf(stderr, "%s\n", cmd); - -int main(int argc, char **argv) { - if (ui_ipc_init(1) != 0) { - perror("ui_ipc_init"); - exit(1); - } - if ( (child = fork()) == 0 ) { - /* child */ - sleep(1); - LOG("child: sempost"); - ui_ipc_sempost(SEM_RD); - LOG("child: done"); - sleep(1); - exit(0); - } else if (child > 0) { - /* parent */ - LOG("parent: semwait"); - ui_ipc_semwait(SEM_RD); - LOG("parent: waitpid"); - waitpid(child, NULL, 0); - } else if (child < 0) { - perror("fork"); - exit(1); - } - ui_ipc_free(1); - - exit(0); -} - diff --git a/tests/strsep.c b/tests/strsep.c index aa8e1ad..24564af 100644 --- a/tests/strsep.c +++ b/tests/strsep.c @@ -8,16 +8,28 @@ int main(int argc, char **argv) { int i = 0; char *tok, *p_tok; - char **arr; + static char **arr; - if (argc != 4) { + int arrsiz = 1000; + static char *delim; + static char *str; + + if (argc == 1) { + printf("automatic test ..\n"); + delim = strdup(" "); + str = strdup("this is a simple string, which should be extracted to 12 strings"); + } else if (argc != 4) { fprintf(stderr, "usage: %s [ARR_SIZ] [DELIM] [STRING]\n", argv[0]); exit(1); + } else { + arrsiz = atoi(argv[1]); + delim = strdup(argv[2]); + str = strdup(argv[3]); } - arr = calloc(atoi(argv[1]), sizeof(char *)); - p_tok = argv[3]; - while ( (tok = strsep(&p_tok, argv[2])) != NULL ) { + arr = calloc(arrsiz, sizeof(char *)); + p_tok = str; + while ( (tok = strsep(&p_tok, delim)) != NULL ) { arr[i] = tok; i++; } @@ -27,5 +39,11 @@ int main(int argc, char **argv) printf("ARRAY[%d]: %s\n", i, arr[i]); i++; } + + if (argc == 1) { + if (i == 12) { + return 0; + } else return -1; + } return 0; } -- cgit v1.2.3 From e674872a17825b6a9e48464ff80ced9b3e44ec46 Mon Sep 17 00:00:00 2001 From: toni Date: Tue, 17 Nov 2015 16:35:01 +0100 Subject: - pthread test --- .gitignore | 1 + tests/pthread.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/pthread.c (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index 2aa84b5..8c51c44 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /tests/semtest2 /tests/mqtest /tests/strsep +/tests/pthread *.swp *.o *.d diff --git a/tests/pthread.c b/tests/pthread.c new file mode 100644 index 0000000..eed53a6 --- /dev/null +++ b/tests/pthread.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include + + +static pthread_mutex_t testMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t testCond = PTHREAD_COND_INITIALIZER; + +static void +mywait(int time_secs) +{ + struct timespec now; + int rt; + + clock_gettime(CLOCK_REALTIME, &now); + now.tv_sec += time_secs; + + assert( pthread_mutex_lock(&testMutex) == 0 ); + rt = pthread_cond_timedwait(&testCond, &testMutex, &now); + assert( rt == ETIMEDOUT || rt == 0 ); + assert( pthread_mutex_unlock(&testMutex) == 0 ); + printf("Done.\n"); +} + +static void * +fun(void *arg) +{ + printf("Thread wait ..\n"); + mywait(1); + mywait(1); + return NULL; +} + +int +main(void) +{ + pthread_t thread; + void *ret; + + assert( pthread_create(&thread, NULL, fun, NULL) == 0 ); + usleep(50000); + assert( pthread_cond_signal(&testCond) == 0 ); + printf("Mainthread: join\n"); + assert( pthread_join(thread, &ret) == 0 ); + return 0; +} -- cgit v1.2.3 From 52a0dc4e34889317f4fec73a0a2f4069efa69ace Mon Sep 17 00:00:00 2001 From: toni Date: Tue, 17 Nov 2015 17:12:55 +0100 Subject: ncurses test --- .gitignore | 1 + tests/Makefile | 2 +- tests/ncurses.c | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tests/ncurses.c (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index 8c51c44..61d8ae2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /tests/mqtest /tests/strsep /tests/pthread +/tests/ncurses *.swp *.o *.d diff --git a/tests/Makefile b/tests/Makefile index 8afc274..a8b0e29 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,5 +1,5 @@ CFLAGS = -Wall -g -LDFLAGS = -lpthread -lrt +LDFLAGS = -lpthread -lrt -lncurses CC = gcc SOURCES = $(wildcard *.c) BINARIES = $(patsubst %.c,%,$(SOURCES)) diff --git a/tests/ncurses.c b/tests/ncurses.c new file mode 100644 index 0000000..23ef28d --- /dev/null +++ b/tests/ncurses.c @@ -0,0 +1,25 @@ +#include +#include +#include +#include + + +static WINDOW *wnd; + +int +main(void) +{ + assert( (wnd = initscr()) != NULL ); + assert( start_color() == 0 ); + assert( init_pair(1, COLOR_BLACK, COLOR_WHITE) == 0 ); + assert( raw() == 0 ); + assert( keypad(wnd, TRUE) == 0 ); + assert( noecho() == 0 ); + assert( cbreak() == 0 ); + assert( printw("TESTEST") == 0 ); + assert( refresh() == 0 ); + assert( clear() == 0 ); + assert( delwin(wnd) == 0 ); + assert( endwin() == 0 ); + return 0; +} -- cgit v1.2.3 From ad31e73105e58079c2f4fe85b70b80cd7ae1c76a Mon Sep 17 00:00:00 2001 From: toni Date: Mon, 4 Jan 2016 13:29:11 +0100 Subject: blah --- .gitignore | 1 + scripts/naskpass.initscript | 2 +- src/check/check.c | 36 +++++++++++++++++++++++------------- src/log.c | 19 +++++++++++++++++++ src/log.h | 8 ++++++++ src/main.c | 14 +++++++++++--- src/opt.c | 3 +++ 7 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 src/log.c create mode 100644 src/log.h (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index 61d8ae2..de07cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /naskpass +/naskpass_check /src/version.h /tests/producer /tests/producer_consumer diff --git a/scripts/naskpass.initscript b/scripts/naskpass.initscript index 21ced37..fa22318 100755 --- a/scripts/naskpass.initscript +++ b/scripts/naskpass.initscript @@ -311,7 +311,7 @@ setup_mapping() fi else dmesg -n 1 - if ! $cryptkeyscript -c "cryptsetup -T 1 open $cryptsource $crypttarget"; then + if ! $cryptkeyscript -c "/sbin/cryptsetup -T 1 open $cryptsource $crypttarget"; then message "naskpass: failed" continue else diff --git a/src/check/check.c b/src/check/check.c index bbc22eb..9d28129 100644 --- a/src/check/check.c +++ b/src/check/check.c @@ -4,13 +4,16 @@ #include #include #include +#include #include -#define myassert(x) if ((x)) { ret &= 0xFF; } else { ret &= 0x00; } -static volatile unsigned char ret = 0xFF; +#define myassert(x, emask) if ((x)) { ret &= ret; } else { ret |= emask; } + +static volatile unsigned long long int ret = 0x0; static mqd_t mq_test; static mqd_t mq_recv; +static sem_t *sp_test; static const size_t bufsiz = 256; int main(int argc, char **argv) @@ -32,24 +35,31 @@ int main(int argc, char **argv) m_attr.mq_curmsgs = 0; mq_unlink("/testmq"); - myassert( (mq_test = mq_open( "/testmq", O_NONBLOCK | O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG, &m_attr )) != (mqd_t)-1 ); - myassert( mq_getattr(mq_test, &m_attr) == 0 ); + myassert( (mq_test = mq_open( "/testmq", O_NONBLOCK | O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG, &m_attr )) != (mqd_t)-1, 0x1 ); + myassert( mq_getattr(mq_test, &m_attr) == 0, 0x2 ); strcpy(buf, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ"); - myassert( mq_send(mq_test, buf, bufsiz, 0) == 0 ); - myassert( (sz_recv = mq_receive(mq_test, recv, bufsiz, &prio)) > 0 ); + myassert( mq_send(mq_test, buf, bufsiz, 0) == 0, 0x4 ); + myassert( (sz_recv = mq_receive(mq_test, recv, bufsiz, &prio)) > 0, 0x8 ); memset(recv, '\0', bufsiz); if (fork() > 0) { - myassert( (mq_recv = mq_open( "/testmq", O_RDONLY, S_IRWXU | S_IRWXG, &m_attr )) != (mqd_t)-1 ); - myassert( (sz_recv = mq_receive(mq_recv, recv, bufsiz, &prio)) > 0 ); + myassert( (mq_recv = mq_open( "/testmq", O_RDONLY, S_IRWXU | S_IRWXG, &m_attr )) != (mqd_t)-1, 0x10 ); + myassert( (sz_recv = mq_receive(mq_recv, recv, bufsiz, &prio)) > 0, 0x20 ); return ret; } - myassert( mq_send(mq_test, buf, bufsiz, 0) == 0 ); + myassert( mq_send(mq_test, buf, bufsiz, 0) == 0, 0x40 ); wait(&c_stat); - myassert( c_stat == 0xFF ); - myassert( mq_close(mq_test) == 0 ); - myassert( mq_unlink("/testmq") == 0 ); + myassert( c_stat == 0xFF, 0x80 ); + myassert( mq_close(mq_test) == 0, 0x100 ); + myassert( mq_unlink("/testmq") == 0, 0x200 ); + + myassert( sem_unlink("/testsem") == 0, 0x400 ); + myassert( (sp_test = sem_open("/testsem", O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, 0)), 0x800 ); + myassert( sem_post(sp_test) == 0, 0x1000 ); + myassert( sem_wait(sp_test) == 0, 0x1200 ); + myassert( sem_close(sp_test) == 0, 0x1400 ); + myassert( sem_unlink("/testsem") == 0, 0x1800 ); - return ~ret; + return ret; } diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..93d6532 --- /dev/null +++ b/src/log.c @@ -0,0 +1,19 @@ +#include +#include + +#include "log.h" + + +static int logfd; + +int log_init(char *file) +{ + logfd = fopen(file, "a+"); + return logfd; +} + +int logs(char *format, ...) +{ + +} + diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..7b4affc --- /dev/null +++ b/src/log.h @@ -0,0 +1,8 @@ +#ifndef LOG_H +#define LOG_H 1 + +int log_init(char *file); + +int logs(char *format, ...); + +#endif diff --git a/src/main.c b/src/main.c index 31afd29..1065371 100644 --- a/src/main.c +++ b/src/main.c @@ -73,7 +73,7 @@ run_cryptcreate(char *pass, char *crypt_cmd) char *cmd; if (crypt_cmd == NULL || pass == NULL) return (-1); - asprintf(&cmd, "echo '%s' | %s >/dev/null 2>/dev/null", pass, crypt_cmd); + asprintf(&cmd, "echo '%s' | %s", pass, crypt_cmd); retval = system(cmd); free(cmd); return (retval); @@ -112,7 +112,12 @@ main(int argc, char **argv) } memset(pbuf, '\0', IPC_MQSIZ+1); - parse_cmd(argc, argv); + if ( parse_cmd(argc, argv) != 0 ) + goto error; + if (OPT(CRYPT_CMD).found == 0) { + usage(argv[0]); + goto error; + } if (check_fifo(GETOPT(FIFO_PATH).str) == false) { usage(argv[0]); goto error; @@ -164,7 +169,10 @@ main(int argc, char **argv) break; } } - wait(&c_status); + waitpid(child, &c_status, WNOHANG); + if ( WIFEXITED(c_status) == 0 ) { + wait(&c_status); + } memset(pbuf, '\0', IPC_MQSIZ+1); } else { /* fork error */ diff --git a/src/opt.c b/src/opt.c index 7b6d083..19d8879 100644 --- a/src/opt.c +++ b/src/opt.c @@ -39,6 +39,9 @@ parse_cmd(int argc, char **argv) case 'c': s_OPT(CRYPT_CMD, strdup(optarg)); break; + default: + usage(argv[0]); + return 1; } } return 0; -- cgit v1.2.3 From a5026891c37cc19f27cc311252d7d5e8056bc337 Mon Sep 17 00:00:00 2001 From: toni Date: Mon, 4 Jul 2016 00:14:25 +0200 Subject: wait(...) fail fixed --- .gitignore | 12 ------------ src/main.c | 2 +- 2 files changed, 1 insertion(+), 13 deletions(-) (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index de07cbd..ab9c734 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,3 @@ -/naskpass -/naskpass_check -/src/version.h -/tests/producer -/tests/producer_consumer -/tests/semtest -/tests/semtest2 -/tests/mqtest -/tests/strsep -/tests/pthread -/tests/ncurses *.swp *.o *.d - diff --git a/src/main.c b/src/main.c index 6cd2eea..f2a435d 100644 --- a/src/main.c +++ b/src/main.c @@ -175,7 +175,7 @@ main(int argc, char **argv) } } logs("%s\n", "waiting for child"); - wait(&child); + wait(&c_status); memset(pbuf, '\0', IPC_MQSIZ+1); } else { /* fork error */ -- cgit v1.2.3