diff --git a/.gitignore b/.gitignore index 7a580c71..d9efcd26 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ profanity curses_example *.o *.log +*.swp diff --git a/Makefile b/Makefile index a5b950af..9451b991 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,16 @@ CC = gcc WARNS = -Werror -Wall -Wextra -Wno-unused-parameter -Wno-unused-but-set-variable LIBS = -lxml2 -lssl -lresolv -lncurses -lstrophe CFLAGS = -O3 $(WARNS) $(LIBS) -OBJS = log.o windows.o jabber.o profanity.o +OBJS = log.o windows.o jabber.o app.o profanity.o profanity: $(OBJS) $(CC) -o profanity $(OBJS) $(LIBS) log.o: log.h windows.o: windows.h -jabber.o: log.h windows.h -profanity.o: log.h +jabber.o: jabber.h log.h windows.h +app.o: log.h windows.h jabber.h +profanity.o: log.h windows.h app.h .PHONY: clean clean: diff --git a/app.c b/app.c new file mode 100644 index 00000000..714f4403 --- /dev/null +++ b/app.c @@ -0,0 +1,116 @@ +#include +#include + +#include +#include + +#include "log.h" +#include "windows.h" +#include "jabber.h" + +// window references +extern WINDOW *title_bar; +extern WINDOW *cmd_bar; +extern WINDOW *cmd_win; +extern WINDOW *main_win; + +static void main_event_loop(void); + +void start_profanity(void) +{ + char cmd[50]; + while (TRUE) { + cmd_get_command_str(cmd); + + if (strcmp(cmd, "/quit") == 0) { + break; + } else if (strncmp(cmd, "/connect ", 9) == 0) { + char *user; + char passwd[20]; + + user = strndup(cmd+9, strlen(cmd)-9); + + bar_print_message("Enter password:"); + cmd_get_password(passwd); + bar_print_message(user); + + jabber_connect(user, passwd); + + main_event_loop(); + + break; + } else { + // echo ignore + wclear(cmd_win); + wmove(cmd_win, 0, 0); + } + } +} + +static void main_event_loop(void) +{ + int cmd_y = 0; + int cmd_x = 0; + + wtimeout(cmd_win, 0); + + while(TRUE) { + int ch = ERR; + char command[100]; + int size = 0; + + // while not enter + while(ch != '\n') { + usleep(1); + // handle incoming messages + jabber_process_events(); + + // move cursor back to cmd_win + getyx(cmd_win, cmd_y, cmd_x); + wmove(cmd_win, cmd_y, cmd_x); + + // echo off, and get some more input + noecho(); + ch = wgetch(cmd_win); + + // if delete pressed, go back and delete it + if (ch == 127) { + if (size > 0) { + getyx(cmd_win, cmd_y, cmd_x); + wmove(cmd_win, cmd_y, cmd_x-1); + wdelch(cmd_win); + size--; + } + } + // else if not error or newline, show it and store it + else if (ch != ERR && ch != '\n') { + waddch(cmd_win, ch); + command[size++] = ch; + } + + echo(); + } + + command[size++] = '\0'; + + // newline was hit, check if /quit command issued + if (strcmp(command, "/quit") == 0) { + break; + } else { + // send the message + jabber_send(command); + + // show it in the main window + wprintw(main_win, "me: %s\n", command); + wrefresh(main_win); + + // move back to the command window and clear it + wclear(cmd_win); + wmove(cmd_win, 0, 0); + wrefresh(cmd_win); + } + } + + jabber_disconnect(); +} + diff --git a/app.h b/app.h new file mode 100644 index 00000000..6019742d --- /dev/null +++ b/app.h @@ -0,0 +1,6 @@ +#ifndef APP_H +#define APP_H + +void start_profanity(void); + +#endif diff --git a/jabber.c b/jabber.c index 331ab6c5..cd41a8a6 100644 --- a/jabber.c +++ b/jabber.c @@ -1,15 +1,73 @@ #include -#include -#include -#include "windows.h" +#include "jabber.h" #include "log.h" +#include "windows.h" +// log reference extern FILE *logp; -extern WINDOW *main_win; +// private XMPP structs +static xmpp_log_t *_log; +static xmpp_ctx_t *_ctx; +static xmpp_conn_t *_conn; -int in_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, +// private XMPP handlers +static void _jabber_conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, + const int error, xmpp_stream_error_t * const stream_error, + void * const userdata); + +static int _jabber_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, + void * const userdata); + +void jabber_connect(char *user, char *passwd) +{ + xmpp_initialize(); + _log = xmpp_get_file_logger(); + _ctx = xmpp_ctx_new(NULL, _log); + _conn = xmpp_conn_new(_ctx); + + xmpp_conn_set_jid(_conn, user); + xmpp_conn_set_pass(_conn, passwd); + xmpp_connect_client(_conn, NULL, 0, _jabber_conn_handler, _ctx); + +} + +void jabber_disconnect(void) +{ + xmpp_conn_release(_conn); + xmpp_ctx_free(_ctx); + xmpp_shutdown(); +} + +void jabber_process_events(void) +{ + xmpp_run_once(_ctx, 10); +} + + +void jabber_send(char *msg) +{ + xmpp_stanza_t *reply, *body, *text; + + reply = xmpp_stanza_new(_ctx); + xmpp_stanza_set_name(reply, "message"); + xmpp_stanza_set_type(reply, "chat"); + xmpp_stanza_set_attribute(reply, "to", "boothj5@localhost"); + + body = xmpp_stanza_new(_ctx); + xmpp_stanza_set_name(body, "body"); + + text = xmpp_stanza_new(_ctx); + xmpp_stanza_set_text(text, msg); + xmpp_stanza_add_child(body, text); + xmpp_stanza_add_child(reply, body); + + xmpp_send(_conn, reply); + xmpp_stanza_release(reply); +} + +static int _jabber_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { char *message; @@ -28,7 +86,7 @@ int in_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, return 1; } -void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, +static void _jabber_conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, const int error, xmpp_stream_error_t * const stream_error, void * const userdata) { @@ -36,8 +94,8 @@ void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, if (status == XMPP_CONN_CONNECT) { xmpp_stanza_t* pres; - logmsg(CONN, "connected"); - xmpp_handler_add(conn,in_message_handler, NULL, "message", NULL, ctx); + log_msg(CONN, "connected"); + xmpp_handler_add(conn, _jabber_message_handler, NULL, "message", NULL, ctx); pres = xmpp_stanza_new(ctx); xmpp_stanza_set_name(pres, "presence"); @@ -45,31 +103,7 @@ void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, xmpp_stanza_release(pres); } else { - logmsg(CONN, "disconnected"); + log_msg(CONN, "disconnected"); xmpp_stop(ctx); } } - -void prof_send(char *msg, xmpp_ctx_t *ctx, xmpp_conn_t *conn) -{ - xmpp_stanza_t *reply, *body, *text; - - reply = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(reply, "message"); - xmpp_stanza_set_type(reply, "chat"); - xmpp_stanza_set_attribute(reply, "to", "boothj5@localhost"); - - body = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(body, "body"); - - text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(text, msg); - xmpp_stanza_add_child(body, text); - xmpp_stanza_add_child(reply, body); - - xmpp_send(conn, reply); - xmpp_stanza_release(reply); -} - - - diff --git a/jabber.h b/jabber.h index f83cb128..6a45edf6 100644 --- a/jabber.h +++ b/jabber.h @@ -1,15 +1,9 @@ #ifndef JABBER_H #define JABBER_H -#include - -int in_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, - void * const userdata); - -void conn_handler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, - const int error, xmpp_stream_error_t * const stream_error, - void * const userdata); - -void prof_send(char *msg, xmpp_ctx_t *ctx, xmpp_conn_t *conn); +void jabber_connect(char *user, char *passwd); +void jabber_disconnect(void); +void jabber_process_events(void); +void jabber_send(char *msg); #endif diff --git a/log.c b/log.c index 2eb49a1d..94489bea 100644 --- a/log.c +++ b/log.c @@ -18,16 +18,21 @@ xmpp_log_t *xmpp_get_file_logger() void xmpp_file_logger(void * const userdata, const xmpp_log_level_t level, const char * const area, const char * const msg) { - logmsg(area, msg); + log_msg(area, msg); } -void logmsg(const char * const area, const char * const msg) +void log_msg(const char * const area, const char * const msg) { fprintf(logp, "%s DEBUG: %s\n", area, msg); } -void start_log(void) +void log_init(void) { logp = fopen("profanity.log", "a"); - logmsg(PROF, "Starting Profanity..."); + log_msg(PROF, "Starting Profanity..."); +} + +void log_close(void) +{ + fclose(logp); } diff --git a/log.h b/log.h index bf044b58..1aad4872 100644 --- a/log.h +++ b/log.h @@ -1,13 +1,20 @@ #ifndef LOG_H #define LOG_H +#include + +#include + +// log areas #define PROF "prof" #define CONN "conn" +// file log FILE *logp; xmpp_log_t *xmpp_get_file_logger(); -void logmsg(const char * const area, const char * const msg); -void start_log(void); +void log_init(void); +void log_msg(const char * const area, const char * const msg); +void log_close(void); #endif diff --git a/profanity.c b/profanity.c index d423747f..7ca3e52c 100644 --- a/profanity.c +++ b/profanity.c @@ -1,167 +1,16 @@ -#include -#include -#include -#include -#include -#include - #include "log.h" #include "windows.h" -#include "jabber.h" - -// reference to log -extern FILE *logp; - -// window references -extern WINDOW *title_bar; -extern WINDOW *cmd_bar; -extern WINDOW *cmd_win; -extern WINDOW *main_win; - -// curses functions -void event_loop(xmpp_ctx_t *ctx, xmpp_conn_t *conn); +#include "app.h" int main(void) { - char cmd[50]; + log_init(); + gui_init(); - xmpp_ctx_t *ctx; - xmpp_conn_t *conn; - xmpp_log_t *log; - - start_log(); - - // initialise curses, and create windows - initgui(); - - // set cursor in command window and loop on input - wmove(cmd_win, 0, 0); - while (TRUE) { - wgetstr(cmd_win, cmd); - - // handle quit - if (strcmp(cmd, "/quit") == 0) { - break; - // handle connect - } else if (strncmp(cmd, "/connect ", 9) == 0) { - char *user; - char passwd[20]; - - user = strndup(cmd+9, strlen(cmd)-9); - - mvwprintw(cmd_bar, 0, 0, "Enter password:"); - wrefresh(cmd_bar); - - wclear(cmd_win); - noecho(); - mvwgetstr(cmd_win, 0, 0, passwd); - echo(); - - mvwprintw(cmd_bar, 0, 0, "%s", user); - wrefresh(cmd_bar); - - wclear(cmd_win); - wmove(cmd_win, 0, 0); - wrefresh(cmd_win); - - char loginmsg[100]; - sprintf(loginmsg, "User <%s> logged in", user); - logmsg(PROF, loginmsg); - - xmpp_initialize(); - - log = xmpp_get_file_logger(); - ctx = xmpp_ctx_new(NULL, log); - conn = xmpp_conn_new(ctx); - - xmpp_conn_set_jid(conn, user); - xmpp_conn_set_pass(conn, passwd); - xmpp_connect_client(conn, NULL, 0, conn_handler, ctx); - - event_loop(ctx, conn); - - break; - } else { - // echo ignore - wclear(cmd_win); - wmove(cmd_win, 0, 0); - } - } + start_profanity(); - endwin(); - fclose(logp); + gui_close(); + log_close(); return 0; } - -void event_loop(xmpp_ctx_t *ctx, xmpp_conn_t *conn) -{ - int cmd_y = 0; - int cmd_x = 0; - - wtimeout(cmd_win, 0); - - while(TRUE) { - int ch = ERR; - char command[100]; - int size = 0; - - // while not enter - while(ch != '\n') { - usleep(1); - // handle incoming messages - xmpp_run_once(ctx, 10); - - // move cursor back to cmd_win - getyx(cmd_win, cmd_y, cmd_x); - wmove(cmd_win, cmd_y, cmd_x); - - // echo off, and get some more input - noecho(); - ch = wgetch(cmd_win); - - // if delete pressed, go back and delete it - if (ch == 127) { - if (size > 0) { - getyx(cmd_win, cmd_y, cmd_x); - wmove(cmd_win, cmd_y, cmd_x-1); - wdelch(cmd_win); - size--; - } - } - // else if not error or newline, show it and store it - else if (ch != ERR && ch != '\n') { - waddch(cmd_win, ch); - command[size++] = ch; - } - - echo(); - } - - command[size++] = '\0'; - - // newline was hit, check if /quit command issued - if (strcmp(command, "/quit") == 0) { - break; - } else { - // send the message - prof_send(command, ctx, conn); - - // show it in the main window - wprintw(main_win, "me: %s\n", command); - wrefresh(main_win); - - // move back to the command window and clear it - wclear(cmd_win); - wmove(cmd_win, 0, 0); - wrefresh(cmd_win); - } - } - - xmpp_conn_release(conn); - xmpp_ctx_free(ctx); - - xmpp_shutdown(); - -} - diff --git a/windows.c b/windows.c index 9b534d88..0920fef0 100644 --- a/windows.c +++ b/windows.c @@ -13,7 +13,7 @@ static void create_command_bar(void); static void create_command_window(void); static void create_main_window(void); -void initgui(void) +void gui_init(void) { initscr(); cbreak(); @@ -40,6 +40,42 @@ void initgui(void) wrefresh(cmd_win); create_main_window(); wrefresh(main_win); + + wmove(cmd_win, 0, 0); +} + +void gui_close(void) +{ + endwin(); +} + +void show_incomming_msg(char *from, char *message) +{ + char line[100]; + sprintf(line, "%s: %s\n", from, message); + + wprintw(main_win, line); + wrefresh(main_win); +} + +void cmd_get_command_str(char *cmd) +{ + wmove(cmd_win, 0, 0); + wgetstr(cmd_win, cmd); +} + +void cmd_get_password(char *passwd) +{ + wclear(cmd_win); + noecho(); + mvwgetstr(cmd_win, 0, 0, passwd); + echo(); +} + +void bar_print_message(char *msg) +{ + mvwprintw(cmd_bar, 0, 0, msg); + wrefresh(cmd_bar); } static void create_title_bar(void) @@ -81,11 +117,3 @@ static void create_main_window(void) scrollok(main_win, TRUE); } -void show_incomming_msg(char *from, char *message) -{ - char line[100]; - sprintf(line, "%s: %s\n", from, message); - - wprintw(main_win, line); - wrefresh(main_win); -} diff --git a/windows.h b/windows.h index 546f5b90..3ef373e1 100644 --- a/windows.h +++ b/windows.h @@ -1,14 +1,20 @@ #ifndef WINDOWS_H #define WINDOWS_h +#include +#include + // windows WINDOW *title_bar; WINDOW *cmd_bar; WINDOW *cmd_win; WINDOW *main_win; -// window creation -void initgui(void); +void gui_init(void); +void gui_close(void); void show_incomming_msg(char *from, char *message); +void cmd_get_command_str(char *cmd); +void cmd_get_password(char *passwd); +void bar_print_message(char *msg); #endif