comparison libfaim/aim_conn.c @ 338:9d258a0aa560

[gaim-migrate @ 348] Whoa, all kinds of things happened here. The applet looks better. The preferences dialog changes based on your compile-time options (oscar, gnome). Whispering works again. libfaim got updated; it can almost do RVOUS stuff, and hopefully soon can make requests too. The applet doesn't need to have its sounds go through GNOME, although it still can. There is code to facilitate SOCKS5 support (all that needs to be done is to actually write the code to communicate with the proxy server). committer: Tailor Script <tailor@pidgin.im>
author Eric Warmenhoven <eric@warmenhoven.org>
date Tue, 06 Jun 2000 09:55:30 +0000
parents 0f14e6d8a51b
children e4c34ca88d9b
comparison
equal deleted inserted replaced
337:f5b199e20d12 338:9d258a0aa560
6 * 6 *
7 */ 7 */
8 8
9 #include <faim/aim.h> 9 #include <faim/aim.h>
10 10
11 /*
12 * Clears out connection list, killing remaining connections.
13 */
11 void aim_connrst(struct aim_session_t *sess) 14 void aim_connrst(struct aim_session_t *sess)
12 { 15 {
13 int i; 16 faim_mutex_init(&sess->connlistlock, NULL);
14 for (i = 0; i < AIM_CONN_MAX; i++) { 17 if (sess->connlist) {
15 aim_conn_close(&sess->conns[i]); 18 struct aim_conn_t *cur = sess->connlist, *tmp;
16 } 19
17 } 20 while(cur) {
18 21 tmp = cur->next;
22 aim_conn_close(cur);
23 free(cur);
24 cur = tmp;
25 }
26 }
27 sess->connlist = NULL;
28 return;
29 }
30
31 /*
32 * Gets a new connection structure.
33 */
19 struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess) 34 struct aim_conn_t *aim_conn_getnext(struct aim_session_t *sess)
20 { 35 {
21 int i; 36 struct aim_conn_t *newconn, *cur;
22 for (i=0;i<AIM_CONN_MAX;i++) 37
23 if (sess->conns[i].fd == -1) 38 if (!(newconn = malloc(sizeof(struct aim_conn_t))))
24 return &(sess->conns[i]); 39 return NULL;
25 return NULL; 40
41 memset(newconn, 0, sizeof(struct aim_conn_t));
42 aim_conn_close(newconn);
43 newconn->next = NULL;
44
45 faim_mutex_lock(&sess->connlistlock);
46 if (sess->connlist == NULL)
47 sess->connlist = newconn;
48 else {
49 for (cur = sess->connlist; cur->next; cur = cur->next)
50 ;
51 cur->next = newconn;
52 }
53 faim_mutex_unlock(&sess->connlistlock);
54
55 return newconn;
56 }
57
58 void aim_conn_kill(struct aim_session_t *sess, struct aim_conn_t **deadconn)
59 {
60 struct aim_conn_t *cur;
61
62 if (!deadconn || !*deadconn)
63 return;
64
65 faim_mutex_lock(&sess->connlistlock);
66 if (sess->connlist == NULL)
67 ;
68 else if (sess->connlist->next == NULL) {
69 if (sess->connlist == *deadconn)
70 sess->connlist = NULL;
71 } else {
72 cur = sess->connlist;
73 while (cur->next) {
74 if (cur->next == *deadconn) {
75 cur->next = cur->next->next;
76 break;
77 }
78 cur = cur->next;
79 }
80 }
81 faim_mutex_unlock(&sess->connlistlock);
82
83 aim_conn_close(*deadconn);
84 free(*deadconn);
85 deadconn = NULL;
86
87 return;
26 } 88 }
27 89
28 void aim_conn_close(struct aim_conn_t *deadconn) 90 void aim_conn_close(struct aim_conn_t *deadconn)
29 { 91 {
30 if (deadconn->fd >= 3) 92 if (deadconn->fd >= 3)
45 } 107 }
46 108
47 struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess, 109 struct aim_conn_t *aim_getconn_type(struct aim_session_t *sess,
48 int type) 110 int type)
49 { 111 {
50 int i; 112 struct aim_conn_t *cur;
51 for (i=0; i<AIM_CONN_MAX; i++) 113
52 if (sess->conns[i].type == type) 114 faim_mutex_lock(&sess->connlistlock);
53 return &(sess->conns[i]); 115 for (cur = sess->connlist; cur; cur = cur->next) {
54 return NULL; 116 if (cur->type == type)
117 break;
118 }
119 faim_mutex_unlock(&sess->connlistlock);
120 return cur;
55 } 121 }
56 122
57 /* 123 /*
58 * aim_newconn(type, dest) 124 * aim_newconn(type, dest)
59 * 125 *
71 struct sockaddr_in sa; 137 struct sockaddr_in sa;
72 struct hostent *hp; 138 struct hostent *hp;
73 u_short port = FAIM_LOGIN_PORT; 139 u_short port = FAIM_LOGIN_PORT;
74 char *host = NULL; 140 char *host = NULL;
75 int i=0; 141 int i=0;
76 142
77 if ((connstruct=aim_conn_getnext(sess))==NULL) 143 if ((connstruct=aim_conn_getnext(sess))==NULL)
78 return NULL; 144 return NULL;
79 145
146 faim_mutex_lock(&connstruct->active);
147
80 connstruct->type = type; 148 connstruct->type = type;
81 149
82 if (!dest) { /* just allocate a struct */ 150 if (!dest) { /* just allocate a struct */
83 connstruct->fd = -1; 151 connstruct->fd = -1;
84 connstruct->status = 0; 152 connstruct->status = 0;
153 faim_mutex_unlock(&connstruct->active);
85 return connstruct; 154 return connstruct;
86 } 155 }
87 156
88 /* 157 /*
89 * As of 23 Jul 1999, AOL now sends the port number, preceded by a 158 * As of 23 Jul 1999, AOL now sends the port number, preceded by a
102 } 171 }
103 host = (char *)malloc(i+1); 172 host = (char *)malloc(i+1);
104 strncpy(host, dest, i); 173 strncpy(host, dest, i);
105 host[i] = '\0'; 174 host[i] = '\0';
106 175
107 hp = gethostbyname2(host, AF_INET); 176 hp = gethostbyname(host);
108 free(host); 177 free(host);
109 178
110 if (hp == NULL) { 179 if (hp == NULL) {
111 connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR); 180 connstruct->status = (h_errno | AIM_CONN_STATUS_RESOLVERR);
181 faim_mutex_unlock(&connstruct->active);
112 return connstruct; 182 return connstruct;
113 } 183 }
114 184
115 memset(&sa.sin_zero, 0, 8); 185 memset(&sa.sin_zero, 0, 8);
116 sa.sin_port = htons(port); 186 sa.sin_port = htons(port);
120 connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0); 190 connstruct->fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
121 ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)); 191 ret = connect(connstruct->fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));
122 if(ret < 0) { 192 if(ret < 0) {
123 connstruct->fd = -1; 193 connstruct->fd = -1;
124 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR); 194 connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
195 faim_mutex_unlock(&connstruct->active);
125 return connstruct; 196 return connstruct;
126 } 197 }
127 198
199 faim_mutex_unlock(&connstruct->active);
200
128 return connstruct; 201 return connstruct;
129 } 202 }
130 203
131 int aim_conngetmaxfd(struct aim_session_t *sess) 204 int aim_conngetmaxfd(struct aim_session_t *sess)
132 { 205 {
133 int i,j; 206 int j = 0;
134 207 struct aim_conn_t *cur;
135 for (i=0,j=0;i<AIM_CONN_MAX;i++) 208
136 if(sess->conns[i].fd > j) 209 faim_mutex_lock(&sess->connlistlock);
137 j = sess->conns[i].fd; 210 for (cur = sess->connlist; cur; cur = cur->next) {
211 if (cur->fd > j)
212 j = cur->fd;
213 }
214 faim_mutex_unlock(&sess->connlistlock);
215
138 return j; 216 return j;
139 } 217 }
140 218
141 int aim_countconn(struct aim_session_t *sess) 219 int aim_countconn(struct aim_session_t *sess)
142 { 220 {
143 int i,cnt; 221 int cnt = 0;
144 222 struct aim_conn_t *cur;
145 for (i=0,cnt=0;i<AIM_CONN_MAX;i++) 223
146 if (sess->conns[i].fd > -1) 224 faim_mutex_lock(&sess->connlistlock);
147 cnt++; 225 for (cur = sess->connlist; cur; cur = cur->next)
226 cnt++;
227 faim_mutex_unlock(&sess->connlistlock);
228
148 return cnt; 229 return cnt;
149 } 230 }
150 231
151 /* 232 /*
152 * aim_select(timeout) 233 * aim_select(timeout)
158 * -1 error in select() (NULL returned) 239 * -1 error in select() (NULL returned)
159 * 0 no events pending (NULL returned) 240 * 0 no events pending (NULL returned)
160 * 1 outgoing data pending (NULL returned) 241 * 1 outgoing data pending (NULL returned)
161 * 2 incoming data pending (connection with pending data returned) 242 * 2 incoming data pending (connection with pending data returned)
162 * 243 *
244 * XXX: we could probably stand to do a little courser locking here.
245 *
163 */ 246 */
164 struct aim_conn_t *aim_select(struct aim_session_t *sess, 247 struct aim_conn_t *aim_select(struct aim_session_t *sess,
165 struct timeval *timeout, int *status) 248 struct timeval *timeout, int *status)
166 { 249 {
250 struct aim_conn_t *cur;
167 fd_set fds; 251 fd_set fds;
252 int maxfd = 0;
168 int i; 253 int i;
169 254
170 if (aim_countconn(sess) <= 0) 255 faim_mutex_lock(&sess->connlistlock);
256 if (sess->connlist == NULL) {
257 faim_mutex_unlock(&sess->connlistlock);
171 return 0; 258 return 0;
259 }
260 faim_mutex_unlock(&sess->connlistlock);
172 261
173 /* 262 /*
174 * If we have data waiting to be sent, return immediatly 263 * If we have data waiting to be sent, return immediatly
175 */ 264 */
176 if (sess->queue_outgoing != NULL) { 265 if (sess->queue_outgoing != NULL) {
177 *status = 1; 266 *status = 1;
178 return NULL; 267 return NULL;
179 } 268 }
180 269
181 FD_ZERO(&fds); 270 FD_ZERO(&fds);
182 271 maxfd = 0;
183 for(i=0;i<AIM_CONN_MAX;i++) 272
184 if (sess->conns[i].fd>-1) 273 faim_mutex_lock(&sess->connlistlock);
185 FD_SET(sess->conns[i].fd, &fds); 274 for (cur = sess->connlist; cur; cur = cur->next) {
186 275 FD_SET(cur->fd, &fds);
187 if ((i = select(aim_conngetmaxfd(sess)+1, &fds, NULL, NULL, timeout))>=1) { 276 if (cur->fd > maxfd)
188 int j; 277 maxfd = cur->fd;
189 for (j=0;j<AIM_CONN_MAX;j++) { 278 }
190 if (sess->conns[j].fd > -1) { 279 faim_mutex_unlock(&sess->connlistlock);
191 if ((FD_ISSET(sess->conns[j].fd, &fds))) { 280
192 *status = 2; 281 if ((i = select(maxfd+1, &fds, NULL, NULL, timeout))>=1) {
193 return &(sess->conns[j]); /* return the first waiting struct */ 282 faim_mutex_lock(&sess->connlistlock);
194 } 283 for (cur = sess->connlist; cur; cur = cur->next) {
195 } 284 if (FD_ISSET(cur->fd, &fds)) {
196 } 285 *status = 2;
197 /* should never get here */ 286 faim_mutex_unlock(&sess->connlistlock);
198 } 287 return cur;
199 288 }
289 }
290 }
291
292 faim_mutex_unlock(&sess->connlistlock);
200 *status = i; /* may be 0 or -1 */ 293 *status = i; /* may be 0 or -1 */
201 return NULL; /* no waiting or error, return */ 294 return NULL; /* no waiting or error, return */
202 } 295 }
203 296
204 int aim_conn_isready(struct aim_conn_t *conn) 297 int aim_conn_isready(struct aim_conn_t *conn)
205 { 298 {
206 if (conn) 299 if (conn)
207 return (conn->status & 0x0001); 300 return (conn->status & 0x0001);
208 else 301 return -1;
209 return -1;
210 } 302 }
211 303
212 int aim_conn_setstatus(struct aim_conn_t *conn, int status) 304 int aim_conn_setstatus(struct aim_conn_t *conn, int status)
213 { 305 {
214 if (conn) 306 int val;
215 return (conn->status ^= status); 307
216 else
217 return -1;
218 }
219
220 int aim_conn_setlatency(struct aim_conn_t *conn, int newval)
221 {
222 if (!conn) 308 if (!conn)
223 return -1; 309 return -1;
224 310
311 faim_mutex_lock(&conn->active);
312 val = conn->status ^= status;
313 faim_mutex_unlock(&conn->active);
314 return val;
315 }
316
317 int aim_conn_setlatency(struct aim_conn_t *conn, int newval)
318 {
319 if (!conn)
320 return -1;
321
322 faim_mutex_lock(&conn->active);
225 conn->forcedlatency = newval; 323 conn->forcedlatency = newval;
226 conn->lastactivity = 0; /* reset this just to make sure */ 324 conn->lastactivity = 0; /* reset this just to make sure */
325 faim_mutex_unlock(&conn->active);
227 326
228 return 0; 327 return 0;
229 } 328 }
230 329
231 void aim_session_init(struct aim_session_t *sess) 330 void aim_session_init(struct aim_session_t *sess)
232 { 331 {
233 if (!sess) 332 if (!sess)
234 return; 333 return;
235 334
236 memset(sess->logininfo.screen_name, 0x00, MAXSNLEN); 335 memset(sess, 0, sizeof(struct aim_session_t));
237 sess->logininfo.BOSIP = NULL;
238 memset(sess->logininfo.cookie, 0x00, AIM_COOKIELEN);
239 sess->logininfo.email = NULL;
240 sess->logininfo.regstatus = 0x00;
241
242 memset(sess->conns, 0, sizeof(struct aim_conn_t)*AIM_CONN_MAX);
243 aim_connrst(sess); 336 aim_connrst(sess);
244
245 sess->queue_outgoing = NULL; 337 sess->queue_outgoing = NULL;
246 sess->queue_incoming = NULL; 338 sess->queue_incoming = NULL;
247 sess->pendingjoin = NULL; 339 sess->pendingjoin = NULL;
248 sess->outstanding_snacs = NULL; 340 sess->outstanding_snacs = NULL;
249 sess->snac_nextid = 0x00000001; 341 sess->snac_nextid = 0x00000001;