From: mid Date: Tue, 13 Mar 2001 20:28:19 +0000 (+0000) Subject: - Tue Mar 13 20:23:04 UTC 2001 X-Git-Tag: rel_0_99_2~64 X-Git-Url: http://andersk.mit.edu/gitweb/libfaim.git/commitdiff_plain/b562f484224d58e2cadbee119637d753619a2907 - Tue Mar 13 20:23:04 UTC 2001 - Fiddle with faimtest a bit. --- diff --git a/CHANGES b/CHANGES index 24953d7..b0b18be 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ No release numbers ------------------ + - Tue Mar 13 20:23:04 UTC 2001 + - Fiddle with faimtest a bit. + - Sun Mar 11 06:02:19 UTC 2001 - Banish socklen_t. diff --git a/configure.in b/configure.in index c7586a2..5827443 100644 --- a/configure.in +++ b/configure.in @@ -28,8 +28,6 @@ if test "$enable_debug" = yes ; then CFLAGS="$CFLAGS -Wall -g" fi -AC_SUBST(CFLAGS) - dnl Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT @@ -50,6 +48,14 @@ AC_FUNC_STRFTIME AC_FUNC_VPRINTF AC_CHECK_FUNCS(gethostname gettimeofday select socket strdup strstr strtol uname) +AC_CHECK_LIB(readline, rl_callback_handler_install, + READLINELIB="-lreadline", + AC_MSG_ERROR(unable to find GNU readline); +) + +AC_SUBST(CFLAGS) +AC_SUBST(READLINELIB) + AC_OUTPUT([ Makefile include/Makefile diff --git a/utils/faimtest/Makefile.am b/utils/faimtest/Makefile.am index a6f63d8..e2a1ce4 100644 --- a/utils/faimtest/Makefile.am +++ b/utils/faimtest/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS = faimtest -faimtest_SOURCES = faimtest.c +faimtest_SOURCES = faimtest.h faimtest.c commands.c INCLUDES = -I$(top_srcdir)/include -faimtest_LDADD = -L$(top_srcdir)/src/.libs -lfaim +faimtest_LDADD = -L$(top_srcdir)/src/.libs -lfaim @READLINELIB@ faimtest_DEPENDENCIES = $(top_srcdir)/src/.libs/libfaim.a diff --git a/utils/faimtest/commands.c b/utils/faimtest/commands.c new file mode 100644 index 0000000..baab3cb --- /dev/null +++ b/utils/faimtest/commands.c @@ -0,0 +1,218 @@ + +#include "faimtest.h" +#include +#include + +static int cmd_help(char *arg); +static int cmd_quit(char *arg); +static int cmd_login(char *arg); +static int cmd_logout(char *arg); +static int cmd_connlist(char *arg); + +struct { + char *name; + Function *func; + char *doc; +} cmdlist[] = { + { "help", cmd_help, "Help"}, + { "quit", cmd_quit, "Quit"}, + { "login", cmd_login, "Log into AIM"}, + { "logout", cmd_login, "Log out of AIM"}, + { "connlist", cmd_connlist, "List open connections"}, + { (char *)NULL, (Function *)NULL, (char *)NULL } +}; + +static char *stripwhite (char *string) +{ + char *s, *t; + + for (s = string; whitespace(*s); s++) + ; + + if (*s == 0) + return (s); + + t = s + strlen (s) - 1; + while (t > s && whitespace (*t)) + t--; + *++t = '\0'; + + return s; +} + +static char *cmdgenerator(char *text, int state) +{ + static int list_index, len; + char *name; + + if (!state) { + list_index = 0; + len = strlen (text); + } + + while ((name = cmdlist[list_index].name)) { + list_index++; + if (strncmp (name, text, len) == 0) + return (strdup(name)); + } + + /* If no names matched, then return NULL. */ + return (char *)NULL; +} + +static char **cmdcomplete(char *text, int start, int end) +{ + char **matches; + + matches = (char **)NULL; + + /* + * If this word is at the start of the line, then it is a command + * to complete. Otherwise it is the name of a file in the current + * directory. + */ + if (start == 0) + matches = completion_matches(text, cmdgenerator); + + return matches; +} + +static Function *cmdfind(char *name) +{ + int i; + + for (i = 0; cmdlist[i].name; i++) + if (strcmp (name, cmdlist[i].name) == 0) + return cmdlist[i].func; + + return NULL; +} + +static int cmdexec(char *line) +{ + int i; + Function *cmd; + char *word; + + /* Isolate the command word. */ + i = 0; + while (line[i] && whitespace (line[i])) + i++; + word = line + i; + + while (line[i] && !whitespace (line[i])) + i++; + + if (line[i]) + line[i++] = '\0'; + + if (!(cmd = cmdfind(word))) { + fprintf(stderr, "%s: invalid command\n", word); + return -1; + } + /* Get argument to command, if any. */ + while (whitespace (line[i])) + i++; + + word = line + i; + + /* Call the function. */ + return cmd(word); +} + +static void fullline(void) +{ + char *stripped; + + stripped = stripwhite(rl_line_buffer); + + if (*stripped) { + add_history(stripped); + cmdexec(stripped); + } + + return; +} + +void cmd_init(void) +{ + + rl_attempted_completion_function = cmdcomplete; + + printf("Welcome to faimtest.\n"); + + rl_callback_handler_install("faimtest>", fullline); + + return; +} + +void cmd_gotkey(void) +{ + + rl_callback_read_char(); + + return; +} + +static int cmd_help(char *arg) +{ + int i; + + for (i = 0; cmdlist[i].name; i++) + printf("%16s\t\t%s\n", cmdlist[i].name, cmdlist[i].doc); + + return 0; +} + +static int cmd_quit(char *arg) +{ + keepgoing = 0; + + return 0; +} + +static int cmd_login(char *arg) +{ + char *sn = NULL, *passwd = NULL; + + if (arg) { + sn = arg; + if ((passwd = index(sn, ' '))) { + *(passwd) = '\0'; + passwd++; + } + } + + if (login(sn, passwd) != 0) + printf("login failed\n"); + + return 0; +} + +static int cmd_logout(char *arg) +{ + logout(); + + return 0; +} + +static int cmd_connlist(char *arg) +{ + extern struct aim_session_t aimsess; + struct aim_conn_t *cur; + + printf("Open connections:\n"); + for (cur = aimsess.connlist; cur; cur = cur->next) { + printf(" fd=%d type=0x%02x\n", cur->fd, cur->type); + } + + return 0; +} + +void cmd_uninit(void) +{ + + rl_callback_handler_remove(); + + return; +} diff --git a/utils/faimtest/faimtest.c b/utils/faimtest/faimtest.c index 454018f..f505747 100644 --- a/utils/faimtest/faimtest.c +++ b/utils/faimtest/faimtest.c @@ -38,12 +38,7 @@ * */ -/* - Current status: - - */ - -#include +#include "faimtest.h" static char *dprintf_ctime(void) { @@ -154,11 +149,15 @@ static char *msgerrreasons[] = { static int msgerrreasonslen = 25; static char *screenname,*password,*server=NULL; +static char *proxy = NULL, *proxyusername = NULL, *proxypass = NULL; static char *ohcaptainmycaptain = NULL; static int connected = 0; -FILE *listingfile; -char *listingpath; +struct aim_session_t aimsess; +int keepgoing = 1; + +static FILE *listingfile; +static char *listingpath; static void faimtest_debugcb(struct aim_session_t *sess, int level, const char *format, va_list va) { @@ -237,12 +236,77 @@ int initwsa(void) } #endif /* _WIN32 */ +int faimtest_init(void) +{ + struct aim_conn_t *stdinconn = NULL; + + if (!(stdinconn = aim_newconn(&aimsess, 0, NULL))) { + dprintf("unable to create connection for stdin!\n"); + return -1; + } + + stdinconn->fd = STDIN_FILENO; + + return 0; +} + +int logout(void) +{ + aim_logoff(&aimsess); + + if (faimtest_init() == -1) + dprintf("faimtest_init failed\n"); + + return 0; +} + +int login(const char *sn, const char *passwd) +{ + struct aim_conn_t *authconn; + + if (sn) + screenname = strdup(sn); + if (passwd) + password = strdup(passwd); + + if (proxy) + aim_setupproxy(&aimsess, proxy, proxyusername, proxypass); + + if (!screenname || !password) { + dprintf("need SN and password\n"); + return -1; + } + + if (!(authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER))) { + dprintf("faimtest: internal connection error while in aim_login. bailing out.\n"); + return -1; + } else if (authconn->fd == -1) { + if (authconn->status & AIM_CONN_STATUS_RESOLVERR) { + dprintf("faimtest: could not resolve authorizer name\n"); + } else if (authconn->status & AIM_CONN_STATUS_CONNERR) { + dprintf("faimtest: could not connect to authorizer\n"); + } + aim_conn_kill(&aimsess, &authconn); + return -1; + } + + aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0); + aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0); + aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0); + aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0); + + aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0); + + /* If the connection is in progress, this will just be queued */ + aim_request_login(&aimsess, authconn, screenname); + dprintf("faimtest: login request sent\n"); + + return 0; +} + int main(int argc, char **argv) { - struct aim_session_t aimsess; - struct aim_conn_t *authconn = NULL, *waitingconn = NULL; - int keepgoing = 1; - char *proxy, *proxyusername, *proxypass; + struct aim_conn_t *waitingconn = NULL; int i; int selstat = 0; @@ -267,7 +331,6 @@ int main(int argc, char **argv) case 'c': ohcaptainmycaptain = optarg; break; case 'h': default: - usage: printf("faimtest\n"); printf(" Options: \n"); printf(" -u name Screen name ($SCREENNAME)\n"); @@ -282,9 +345,6 @@ int main(int argc, char **argv) } } - if (!screenname || !password) - goto usage; - #ifdef _WIN32 if (initwsa() != 0) { dprintf("faimtest: could not initialize windows sockets\n"); @@ -311,88 +371,54 @@ int main(int argc, char **argv) free(listingname); } - if (proxy) - aim_setupproxy(&aimsess, proxy, proxyusername, proxypass); - - authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER); - - if (authconn == NULL) { - dprintf("faimtest: internal connection error while in aim_login. bailing out.\n"); - return -1; - } else if (authconn->fd == -1) { - if (authconn->status & AIM_CONN_STATUS_RESOLVERR) { - dprintf("faimtest: could not resolve authorizer name\n"); - } else if (authconn->status & AIM_CONN_STATUS_CONNERR) { - dprintf("faimtest: could not connect to authorizer\n"); - } - aim_conn_kill(&aimsess, &authconn); - return -1; - } - - aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0); - aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0); - aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0); - aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0); - - aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0); + faimtest_init(); - /* If the connection is in progress, this will just be queued */ - aim_request_login(&aimsess, authconn, screenname); - dprintf("faimtest: login request sent\n"); + cmd_init(); while (keepgoing) { waitingconn = aim_select(&aimsess, NULL, &selstat); - switch(selstat) { - case -1: /* error */ + if (selstat == -1) { /* error */ keepgoing = 0; /* fall through and hit the aim_logoff() */ - break; - - case 0: /* no events pending */ - break; - - case 1: /* outgoing data pending */ + } else if (selstat == 0) { /* no events pending */ + keepgoing = 0; + } else if (selstat == 1) { /* outgoing data pending */ aim_tx_flushqueue(&aimsess); - break; - - case 2: /* incoming data pending */ - if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { - if (aim_handlerendconnect(&aimsess, waitingconn) < 0) { - dprintf("connection error (rend out)\n"); - aim_conn_kill(&aimsess, &waitingconn); - } - break; - } - - if (aim_get_command(&aimsess, waitingconn) >= 0) { - aim_rxdispatch(&aimsess); + } else if (selstat == 2) { /* incoming data pending */ + if (waitingconn->fd == STDIN_FILENO) { + cmd_gotkey(); } else { - dvprintf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype); - /* we should have callbacks for all these, else the library will do the conn_kill for us. */ - if(waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) { - dprintf("connection error: rendezvous connection. you forgot register a disconnect callback, right?\n"); - aim_conn_kill(&aimsess, &waitingconn); - } else - aim_conn_kill(&aimsess, &waitingconn); - if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) { - dprintf("major connection error\n"); - keepgoing = 0; + if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { + if (aim_handlerendconnect(&aimsess, waitingconn) < 0) { + dprintf("connection error (rend out)\n"); + aim_conn_kill(&aimsess, &waitingconn); + } + } else { + if (aim_get_command(&aimsess, waitingconn) >= 0) { + aim_rxdispatch(&aimsess); + } else { + dvprintf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype); + /* we should have callbacks for all these, else the library will do the conn_kill for us. */ + if(waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) { + dprintf("connection error: rendezvous connection. you forgot register a disconnect callback, right?\n"); + aim_conn_kill(&aimsess, &waitingconn); + } else + aim_conn_kill(&aimsess, &waitingconn); + if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) { + dprintf("major connection error\n"); + } + } } } - - break; - - default: - break; /* invalid */ } } - /* Close up */ - dprintf("AIM just decided we didn't need to be here anymore, closing up...\n"); - /* close up all connections, dead or no */ aim_logoff(&aimsess); + printf("\n"); + cmd_uninit(); + /* Get out */ exit(0); } diff --git a/utils/faimtest/faimtest.h b/utils/faimtest/faimtest.h new file mode 100644 index 0000000..557629c --- /dev/null +++ b/utils/faimtest/faimtest.h @@ -0,0 +1,14 @@ +#ifndef __FAIMTEST_H__ +#define __FAIMTEST_H__ + +#include + +extern int keepgoing; +int login(const char *sn, const char *passwd); +int logout(void); + +void cmd_init(void); +void cmd_gotkey(void); +void cmd_uninit(void); + +#endif /* __FAIMTEST_H__ */