Mercurial > pidgin
diff libfaim/aim_conn.c @ 237:6ced2f1c8b24
[gaim-migrate @ 247]
How cool is this, libfaim is making a comeback. I completely redid everything,
as was necessary because of the updates to libfaim since gaim 0.9.7. You can
sign on and send/recv IMs, but there's a bad lag between display updates that
I haven't figured out how to fix yet.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Sat, 20 May 2000 00:30:53 +0000 |
parents | 68b230f8da5f |
children | 501e09c51cbc |
line wrap: on
line diff
--- a/libfaim/aim_conn.c Thu May 18 18:20:18 2000 +0000 +++ b/libfaim/aim_conn.c Sat May 20 00:30:53 2000 +0000 @@ -6,26 +6,31 @@ * */ -#include "aim.h" +#include <aim.h> -void aim_connrst(void) +void aim_connrst(struct aim_session_t *sess) { int i; for (i = 0; i < AIM_CONN_MAX; i++) { - aim_conns[i].fd = -1; - aim_conns[i].type = -1; - aim_conns[i].status = 0; + sess->conns[i].fd = -1; + sess->conns[i].type = -1; + sess->conns[i].status = 0; + sess->conns[i].seqnum = 0; + sess->conns[i].lastactivity = 0; + sess->conns[i].forcedlatency = 0; + aim_clearhandlers(&(sess->conns[i])); + sess->conns[i].handlerlist = NULL; } } -struct aim_conn_t *aim_conn_getnext(void) +struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) { int i; for (i=0;i<AIM_CONN_MAX;i++) - if (aim_conns[i].fd == -1) - return &(aim_conns[i]); + if (sess->conns[i].fd == -1) + return &(sess->conns[i]); return NULL; } @@ -35,14 +40,23 @@ close(deadconn->fd); deadconn->fd = -1; deadconn->type = -1; + deadconn->seqnum = 0; + deadconn->lastactivity = 0; + deadconn->forcedlatency = 0; + aim_clearhandlers(deadconn); + deadconn->handlerlist = NULL; + if (deadconn->priv) + free(deadconn->priv); + deadconn->priv = NULL; } -struct aim_conn_t *aim_getconn_type(int type) +struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess, + int type) { int i; for (i=0; i<AIM_CONN_MAX; i++) - if (aim_conns[i].type == type) - return &(aim_conns[i]); + if (sess->conns[i].type == type) + return &(sess->conns[i]); return NULL; } @@ -55,20 +69,28 @@ * FIXME: Return errors in a more sane way. * */ -struct aim_conn_t *aim_newconn(int type, char *dest) +struct aim_conn_t *aim_newconn(struct aim_session_t *sess, + int type, char *dest) { struct aim_conn_t *connstruct; int ret; struct sockaddr_in sa; struct hostent *hp; - int port = FAIM_LOGIN_PORT; + u_short port = FAIM_LOGIN_PORT; + char *host = NULL; int i=0; - if (!dest || ((connstruct=aim_conn_getnext())==NULL)) + if ((connstruct=aim_conn_getnext(sess))==NULL) return NULL; connstruct->type = type; + if (!dest) { /* just allocate a struct */ + connstruct->fd = -1; + connstruct->status = 0; + return connstruct; + } + /* * As of 23 Jul 1999, AOL now sends the port number, preceded by a * colon, in the BOS redirect. This fatally breaks all previous @@ -77,15 +99,21 @@ * We put this here to catch every case. * */ - for(i=0;(i<strlen(dest));i++) - if (dest[i] == ':') break; - if (i<strlen(dest)) - { - port = atoi(dest+i); - dest[i] = '\0'; + + for(i=0;i<strlen(dest);i++) + { + if (dest[i] == ':') { + port = atoi(&(dest[i+1])); + break; } + } + host = (char *)malloc(i+1); + strncpy(host, dest, i); + host[i] = '\0'; - hp = gethostbyname2(dest, AF_INET); + hp = gethostbyname2(host, AF_INET); + free(host); + if (hp == NULL) { connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR); @@ -105,26 +133,26 @@ connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); return connstruct; } - + return connstruct; } -int aim_conngetmaxfd(void) +int aim_conngetmaxfd(struct aim_session_t *sess) { int i,j; j=0; for (i=0;i<AIM_CONN_MAX;i++) - if(aim_conns[i].fd > j) - j = aim_conns[i].fd; + if(sess->conns[i].fd > j) + j = sess->conns[i].fd; return j; } -int aim_countconn(void) +int aim_countconn(struct aim_session_t *sess) { int i,cnt; cnt = 0; for (i=0;i<AIM_CONN_MAX;i++) - if (aim_conns[i].fd > -1) + if (sess->conns[i].fd > -1) cnt++; return cnt; } @@ -135,46 +163,51 @@ * Waits for a socket with data or for timeout, whichever comes first. * See select(2). * + * Return codes in *status: + * -1 error in select() (NULL returned) + * 0 no events pending (NULL returned) + * 1 outgoing data pending (NULL returned) + * 2 incoming data pending (connection with pending data returned) + * */ -struct aim_conn_t *aim_select(struct timeval *timeout) +struct aim_conn_t *aim_select(struct aim_session_t *sess, + struct timeval *timeout, int *status) { fd_set fds; - fd_set errfds; int i; - if (aim_countconn() <= 0) + if (aim_countconn(sess) <= 0) return 0; - + + /* + * If we have data waiting to be sent, return immediatly + */ + if (sess->queue_outgoing != NULL) { + *status = 1; + return NULL; + } + FD_ZERO(&fds); - FD_ZERO(&errfds); for(i=0;i<AIM_CONN_MAX;i++) - if (aim_conns[i].fd>-1) - { - FD_SET(aim_conns[i].fd, &fds); - FD_SET(aim_conns[i].fd, &errfds); - } + if (sess->conns[i].fd>-1) + FD_SET(sess->conns[i].fd, &fds); - i = select(aim_conngetmaxfd()+1, &fds, NULL, &errfds, timeout); - if (i>=1) - { - int j; - for (j=0;j<AIM_CONN_MAX;j++) - { - if ((FD_ISSET(aim_conns[j].fd, &errfds))) - { - /* got an exception; close whats left of it up */ - aim_conn_close(&(aim_conns[j])); - return (struct aim_conn_t *)-1; + if ((i = select(aim_conngetmaxfd(sess)+1, &fds, NULL, NULL, timeout))>=1) { + int j; + for (j=0;j<AIM_CONN_MAX;j++) { + if (sess->conns[j].fd > -1) { + if ((FD_ISSET(sess->conns[j].fd, &fds))) { + *status = 2; + return &(sess->conns[j]); /* return the first waiting struct */ } - else if ((FD_ISSET(aim_conns[j].fd, &fds))) - return &(aim_conns[j]); /* return the first waiting struct */ - } - /* should never get here */ - } - else - return (struct aim_conn_t *)i; /* no waiting or error, return -- FIXME: return type funnies */ - return NULL; /* NO REACH */ + } + } + /* should never get here */ + } + + *status = i; /* may be 0 or -1 */ + return NULL; /* no waiting or error, return */ } int aim_conn_isready(struct aim_conn_t *conn) @@ -193,3 +226,47 @@ return -1; } +int aim_conn_setlatency(struct aim_conn_t *conn, int newval) +{ + if (!conn) + return -1; + + conn->forcedlatency = newval; + conn->lastactivity = 0; /* reset this just to make sure */ + + return 0; +} + +void aim_session_init(struct aim_session_t *sess) +{ + int i; + + if (!sess) + return; + + memset(sess->logininfo.screen_name, 0x00, MAXSNLEN); + sess->logininfo.BOSIP = NULL; + memset(sess->logininfo.cookie, 0x00, AIM_COOKIELEN); + sess->logininfo.email = NULL; + sess->logininfo.regstatus = 0x00; + + for (i = 0; i < AIM_CONN_MAX; i++) + { + sess->conns[i].fd = -1; + sess->conns[i].type = -1; + sess->conns[i].status = 0; + sess->conns[i].seqnum = 0; + sess->conns[i].lastactivity = 0; + sess->conns[i].forcedlatency = 0; + sess->conns[i].handlerlist = NULL; + sess->conns[i].priv = NULL; + } + + sess->queue_outgoing = NULL; + sess->queue_incoming = NULL; + sess->pendingjoin = NULL; + sess->outstanding_snacs = NULL; + sess->snac_nextid = 0x00000001; + + return; +}