diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | config.h | 1 | ||||
-rw-r--r-- | main.c | 81 | ||||
-rw-r--r-- | tests/Makefile | 5 | ||||
-rw-r--r-- | tests/semconfig.h | 1 | ||||
-rw-r--r-- | tests/semtest.c | 8 | ||||
-rw-r--r-- | tests/semtest2.c | 43 | ||||
-rw-r--r-- | ui.c | 209 | ||||
-rw-r--r-- | ui.h | 19 | ||||
-rw-r--r-- | ui_elements.c | 62 | ||||
-rw-r--r-- | ui_elements.h | 7 | ||||
-rw-r--r-- | ui_input.c | 13 | ||||
-rw-r--r-- | ui_input.h | 6 | ||||
-rw-r--r-- | ui_ipc.c | 139 | ||||
-rw-r--r-- | ui_ipc.h | 52 |
16 files changed, 482 insertions, 175 deletions
@@ -2,7 +2,10 @@ /tests/producer /tests/consumer /tests/semtest +/tests/semtest2 /tests/mqtest /tests/strsep *.swp *.o +*.d + @@ -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 @@ -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" @@ -12,29 +12,32 @@ #include <time.h> #include <mqueue.h> +#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 <http://gnu.org/licenses/gpl.html>.\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 <sys/wait.h> #include <fcntl.h> +#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 <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <semaphore.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> + +#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); +} + @@ -15,6 +15,7 @@ #include <signal.h> #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; } @@ -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; @@ -51,6 +58,12 @@ void unregister_ui_elt(void *data); void +unregister_ui_input(void *data); + +int +activate_ui_input(void *data); + +void ui_thrd_force_update(void); WINDOW * 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 <stdlib.h> #include <string.h> +#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" @@ -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 ); } @@ -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 <stdio.h> +#include <stdlib.h> +#include <strings.h> +#ifdef SEM_TIMEDWAIT +#include <time.h> +#endif +#include <semaphore.h> +#include <mqueue.h> +#include <sys/stat.h> +#include <errno.h> + +#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 |