5 * Does all this gloriously nifty connection handling stuff...
11 void aim_connrst(void)
14 for (i = 0; i < AIM_CONN_MAX; i++)
17 aim_conns[i].type = -1;
18 aim_conns[i].status = 0;
19 aim_conns[i].seqnum = 0;
20 aim_conns[i].lastactivity = 0;
21 aim_conns[i].forcedlatency = 0;
22 aim_clearhandlers(&aim_conns[i]);
23 aim_conns[i].handlerlist = NULL;
28 struct aim_conn_t *aim_conn_getnext(void)
31 for (i=0;i<AIM_CONN_MAX;i++)
32 if (aim_conns[i].fd == -1)
33 return &(aim_conns[i]);
37 void aim_conn_close(struct aim_conn_t *deadconn)
39 if (deadconn->fd >= 3)
44 deadconn->lastactivity = 0;
45 deadconn->forcedlatency = 0;
46 aim_clearhandlers(deadconn);
47 deadconn->handlerlist = NULL;
50 struct aim_conn_t *aim_getconn_type(int type)
53 for (i=0; i<AIM_CONN_MAX; i++)
54 if (aim_conns[i].type == type)
55 return &(aim_conns[i]);
60 * aim_newconn(type, dest)
62 * Opens a new connection to the specified dest host of type type.
64 * TODO: fix for proxies
65 * FIXME: Return errors in a more sane way.
68 struct aim_conn_t *aim_newconn(int type, char *dest)
70 struct aim_conn_t *connstruct;
72 struct sockaddr_in sa;
74 u_short port = FAIM_LOGIN_PORT;
77 if (!dest || ((connstruct=aim_conn_getnext())==NULL))
80 connstruct->type = type;
83 * As of 23 Jul 1999, AOL now sends the port number, preceded by a
84 * colon, in the BOS redirect. This fatally breaks all previous
85 * libfaims. Bad, bad AOL.
87 * We put this here to catch every case.
91 for(i=0;(i<strlen(dest));i++)
93 port = atoi(&(dest[i+1]));
98 hp = gethostbyname2(dest, AF_INET);
101 connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR);
105 memset(&sa.sin_zero, 0, 8);
106 sa.sin_port = htons(port);
107 memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
108 sa.sin_family = hp->h_addrtype;
110 connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
111 ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));
115 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
122 int aim_conngetmaxfd(void)
126 for (i=0;i<AIM_CONN_MAX;i++)
127 if(aim_conns[i].fd > j)
132 int aim_countconn(void)
136 for (i=0;i<AIM_CONN_MAX;i++)
137 if (aim_conns[i].fd > -1)
143 * aim_select(timeout)
145 * Waits for a socket with data or for timeout, whichever comes first.
149 struct aim_conn_t *aim_select(struct timeval *timeout)
155 if (aim_countconn() <= 0)
159 * If we have data waiting to be sent, return immediatly
161 if (aim_queue_outgoing)
162 return (struct aim_conn_t *)1;
167 for(i=0;i<AIM_CONN_MAX;i++)
168 if (aim_conns[i].fd>-1)
170 FD_SET(aim_conns[i].fd, &fds);
171 FD_SET(aim_conns[i].fd, &errfds);
174 i = select(aim_conngetmaxfd()+1, &fds, NULL, &errfds, timeout);
178 for (j=0;j<AIM_CONN_MAX;j++)
180 if (aim_conns[j].fd > -1)
182 if ((FD_ISSET(aim_conns[j].fd, &errfds)))
184 /* got an exception; close whats left of it up */
185 aim_conn_close(&(aim_conns[j]));
186 return (struct aim_conn_t *)-1;
188 else if ((FD_ISSET(aim_conns[j].fd, &fds)))
189 return &(aim_conns[j]); /* return the first waiting struct */
192 /* should never get here */
195 return (struct aim_conn_t *)i; /* no waiting or error, return -- FIXME: return type funnies */
196 return NULL; /* NO REACH */
199 int aim_conn_isready(struct aim_conn_t *conn)
202 return (conn->status & 0x0001);
207 int aim_conn_setstatus(struct aim_conn_t *conn, int status)
210 return (conn->status ^= status);
215 int aim_conn_setlatency(struct aim_conn_t *conn, int newval)
220 conn->forcedlatency = newval;
221 conn->lastactivity = 0; /* reset this just to make sure */