aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile8
-rw-r--r--config.h1
-rw-r--r--main.c81
-rw-r--r--tests/Makefile5
-rw-r--r--tests/semconfig.h1
-rw-r--r--tests/semtest.c8
-rw-r--r--tests/semtest2.c43
-rw-r--r--ui.c209
-rw-r--r--ui.h19
-rw-r--r--ui_elements.c62
-rw-r--r--ui_elements.h7
-rw-r--r--ui_input.c13
-rw-r--r--ui_input.h6
-rw-r--r--ui_ipc.c139
-rw-r--r--ui_ipc.h52
16 files changed, 482 insertions, 175 deletions
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 <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);
+}
+
diff --git a/ui.c b/ui.c
index e5f4454..dc16b96 100644
--- a/ui.c
+++ b/ui.c
@@ -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;
}
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;
@@ -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"
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 <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