Mercurial > pidgin
comparison src/protocols/oscar/conn.c @ 13253:87a7c3077c19
[gaim-migrate @ 15619]
More cleaning up of oscar. Renamed some functions to be more clear.
Got rid of some stuff that wasn't used. Inlined some small things
in conn.c that were only used once.
The goals of all this are
1. Non-blocking I/O for all connections
2. p2p stuff won't use the same struct as oscar connections, because
that's stupid
3. The oscar PRPL should be less scary
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 12 Feb 2006 21:27:04 +0000 |
parents | 2871c385c45a |
children | e9802db22b06 |
comparison
equal
deleted
inserted
replaced
13252:2871c385c45a | 13253:87a7c3077c19 |
---|---|
24 * Does all this gloriously nifty connection handling stuff... | 24 * Does all this gloriously nifty connection handling stuff... |
25 * | 25 * |
26 */ | 26 */ |
27 | 27 |
28 #include "oscar.h" | 28 #include "oscar.h" |
29 | |
30 /* This is defined in oscar.h, but only when !FAIM_INTERNAL, since the rest of | |
31 * the library is not allowed to call it. */ | |
32 faim_export void aim_conn_kill(OscarSession *sess, OscarConnection **deadconn); | |
33 | 29 |
34 #ifndef _WIN32 | 30 #ifndef _WIN32 |
35 #include <netdb.h> | 31 #include <netdb.h> |
36 #include <sys/socket.h> | 32 #include <sys/socket.h> |
37 #include <netinet/in.h> | 33 #include <netinet/in.h> |
42 #endif | 38 #endif |
43 | 39 |
44 /** | 40 /** |
45 * In OSCAR, every connection has a set of SNAC groups associated | 41 * In OSCAR, every connection has a set of SNAC groups associated |
46 * with it. These are the groups that you can send over this connection | 42 * with it. These are the groups that you can send over this connection |
47 * without being guaranteed a "Not supported" SNAC error. | 43 * without being guaranteed a "Not supported" SNAC error. |
48 * | 44 * |
49 * The grand theory of things says that these associations transcend | 45 * The grand theory of things says that these associations transcend |
50 * what libfaim calls "connection types" (conn->type). You can probably | 46 * what libfaim calls "connection types" (conn->type). You can probably |
51 * see the elegance here, but since I want to revel in it for a bit, you | 47 * see the elegance here, but since I want to revel in it for a bit, you |
52 * get to hear it all spelled out. | 48 * get to hear it all spelled out. |
53 * | 49 * |
54 * So let us say that you have your core BOS connection running. One | 50 * So let us say that you have your core BOS connection running. One |
55 * of your modules has just given you a SNAC of the group 0x0004 to send | 51 * of your modules has just given you a SNAC of the group 0x0004 to send |
56 * you. Maybe an IM destined for some twit in Greenland. So you start | 52 * you. Maybe an IM destined for some twit in Greenland. So you start |
57 * at the top of your connection list, looking for a connection that | 53 * at the top of your connection list, looking for a connection that |
58 * claims to support group 0x0004. You find one. Why, that neat BOS | 54 * claims to support group 0x0004. You find one. Why, that neat BOS |
59 * connection of yours can do that. So you send it on its way. | 55 * connection of yours can do that. So you send it on its way. |
60 * | 56 * |
61 * Now, say, that fellow from Greenland has friends and they all want to | 57 * Now, say, that fellow from Greenland has friends and they all want to |
62 * meet up with you in a lame chat room. This has landed you a SNAC | 58 * meet up with you in a lame chat room. This has landed you a SNAC |
70 * marked the need for a connection supporting group 0x000e. A few seconds | 66 * marked the need for a connection supporting group 0x000e. A few seconds |
71 * later, you receive a service redirect with an IP address and a cookie in | 67 * later, you receive a service redirect with an IP address and a cookie in |
72 * it. Great, you say. Now I have something to do. Off you go, making | 68 * it. Great, you say. Now I have something to do. Off you go, making |
73 * that connection. One of the first things you get from this new server | 69 * that connection. One of the first things you get from this new server |
74 * is a message saying that indeed it does support the group you were looking | 70 * is a message saying that indeed it does support the group you were looking |
75 * for. So you continue and send rate confirmation and all that. | 71 * for. So you continue and send rate confirmation and all that. |
76 * | 72 * |
77 * Then you remember you had that SNAC to send, and now you have a means to | 73 * Then you remember you had that SNAC to send, and now you have a means to |
78 * do it, and you do, and everyone is happy. Except the Greenlander, who is | 74 * do it, and you do, and everyone is happy. Except the Greenlander, who is |
79 * still stuck in the bitter cold. | 75 * still stuck in the bitter cold. |
80 * | 76 * |
81 * Oh, and this is useful for building the Migration SNACs, too. In the | 77 * Oh, and this is useful for building the Migration SNACs, too. In the |
84 * | 80 * |
85 * Just to make me look better, I'll say that I've known about this great | 81 * Just to make me look better, I'll say that I've known about this great |
86 * scheme for quite some time now. But I still haven't convinced myself | 82 * scheme for quite some time now. But I still haven't convinced myself |
87 * to make libfaim work that way. It would take a fair amount of effort, | 83 * to make libfaim work that way. It would take a fair amount of effort, |
88 * and probably some client API changes as well. (Whenever I don't want | 84 * and probably some client API changes as well. (Whenever I don't want |
89 * to do something, I just say it would change the client API. Then I | 85 * to do something, I just say it would change the client API. Then I |
90 * instantly have a couple of supporters of not doing it.) | 86 * instantly have a couple of supporters of not doing it.) |
91 * | 87 * |
92 * Generally, addgroup is only called by the internal handling of the | 88 * Generally, addgroup is only called by the internal handling of the |
93 * server ready SNAC. So if you want to do something before that, you'll | 89 * server ready SNAC. So if you want to do something before that, you'll |
94 * have to be more creative. That is done rather early, though, so I don't | 90 * have to be more creative. That is done rather early, though, so I don't |
95 * think you have to worry about it. Unless you're me. I care deeply | 91 * think you have to worry about it. Unless you're me. I care deeply |
96 * about such inane things. | 92 * about such inane things. |
97 * | 93 * |
98 */ | 94 */ |
99 faim_internal void aim_conn_addgroup(OscarConnection *conn, guint16 group) | 95 void |
96 aim_conn_addgroup(OscarConnection *conn, guint16 group) | |
100 { | 97 { |
101 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside; | 98 aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside; |
102 struct snacgroup *sg; | 99 struct snacgroup *sg; |
103 | 100 |
104 if (!(sg = malloc(sizeof(struct snacgroup)))) | 101 sg = malloc(sizeof(struct snacgroup)); |
105 return; | |
106 | 102 |
107 gaim_debug_misc("oscar", "adding group 0x%04x\n", group); | 103 gaim_debug_misc("oscar", "adding group 0x%04x\n", group); |
108 sg->group = group; | 104 sg->group = group; |
109 | 105 |
110 sg->next = ins->groups; | 106 sg->next = ins->groups; |
111 ins->groups = sg; | 107 ins->groups = sg; |
112 | 108 } |
113 return; | 109 |
114 } | 110 OscarConnection * |
115 | 111 aim_conn_findbygroup(OscarSession *sess, guint16 group) |
116 faim_export OscarConnection *aim_conn_findbygroup(OscarSession *sess, guint16 group) | |
117 { | 112 { |
118 OscarConnection *cur; | 113 OscarConnection *cur; |
119 | 114 |
120 for (cur = sess->connlist; cur; cur = cur->next) { | 115 for (cur = sess->connlist; cur; cur = cur->next) |
116 { | |
121 aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside; | 117 aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside; |
122 struct snacgroup *sg; | 118 struct snacgroup *sg; |
123 | 119 |
124 for (sg = ins->groups; sg; sg = sg->next) { | 120 for (sg = ins->groups; sg; sg = sg->next) |
121 { | |
125 if (sg->group == group) | 122 if (sg->group == group) |
126 return cur; | 123 return cur; |
127 } | 124 } |
128 } | 125 } |
129 | 126 |
130 return NULL; | 127 return NULL; |
131 } | 128 } |
132 | 129 |
133 static void connkill_snacgroups(struct snacgroup **head) | 130 static void |
131 connkill_snacgroups(struct snacgroup *head) | |
134 { | 132 { |
135 struct snacgroup *sg; | 133 struct snacgroup *sg; |
136 | 134 |
137 for (sg = *head; sg; ) { | 135 for (sg = head; sg; ) |
136 { | |
138 struct snacgroup *tmp; | 137 struct snacgroup *tmp; |
139 | 138 |
140 tmp = sg->next; | 139 tmp = sg->next; |
141 free(sg); | 140 free(sg); |
142 sg = tmp; | 141 sg = tmp; |
143 } | 142 } |
144 | 143 } |
145 *head = NULL; | 144 |
146 | 145 static void |
147 return; | 146 connkill_rates(struct rateclass *head) |
148 } | |
149 | |
150 static void connkill_rates(struct rateclass **head) | |
151 { | 147 { |
152 struct rateclass *rc; | 148 struct rateclass *rc; |
153 | 149 |
154 for (rc = *head; rc; ) { | 150 for (rc = head; rc; ) |
151 { | |
155 struct rateclass *tmp; | 152 struct rateclass *tmp; |
156 struct snacpair *sp; | 153 struct snacpair *sp; |
157 | 154 |
158 tmp = rc->next; | 155 tmp = rc->next; |
159 | 156 |
166 } | 163 } |
167 free(rc); | 164 free(rc); |
168 | 165 |
169 rc = tmp; | 166 rc = tmp; |
170 } | 167 } |
171 | 168 } |
172 *head = NULL; | 169 |
173 | 170 static void |
174 return; | 171 connkill_real(OscarSession *sess, OscarConnection *conn) |
175 } | 172 { |
176 | 173 |
177 static void connkill_real(OscarSession *sess, OscarConnection **deadconn) | 174 aim_rxqueue_cleanbyconn(sess, conn); |
178 { | 175 aim_tx_cleanqueue(sess, conn); |
179 | 176 |
180 aim_rxqueue_cleanbyconn(sess, *deadconn); | 177 if (conn->fd != -1) |
181 aim_tx_cleanqueue(sess, *deadconn); | 178 aim_conn_close(conn); |
182 | |
183 if ((*deadconn)->fd != -1) | |
184 aim_conn_close(*deadconn); | |
185 | 179 |
186 /* | 180 /* |
187 * This will free ->internal if it necessary... | 181 * This will free ->internal if it necessary... |
188 */ | 182 */ |
189 if ((*deadconn)->type == AIM_CONN_TYPE_CHAT) | 183 if (conn->type == AIM_CONN_TYPE_CHAT) |
190 aim_conn_kill_chat(sess, *deadconn); | 184 aim_conn_kill_chat(sess, conn); |
191 | 185 |
192 if ((*deadconn)->inside) { | 186 if (conn->inside) |
193 aim_conn_inside_t *inside = (aim_conn_inside_t *)(*deadconn)->inside; | 187 { |
194 | 188 aim_conn_inside_t *inside = (aim_conn_inside_t *)conn->inside; |
195 connkill_snacgroups(&inside->groups); | 189 |
196 connkill_rates(&inside->rates); | 190 connkill_snacgroups(inside->groups); |
191 connkill_rates(inside->rates); | |
197 | 192 |
198 free(inside); | 193 free(inside); |
199 } | 194 } |
200 | 195 |
201 free(*deadconn); | 196 gaim_circ_buffer_destroy(conn->buffer_outgoing); |
202 *deadconn = NULL; | 197 free(conn); |
203 | |
204 return; | |
205 } | 198 } |
206 | 199 |
207 /** | 200 /** |
208 * This sends an empty channel 4 SNAC. This is sent to signify | 201 * This sends an empty channel 4 SNAC. This is sent to signify |
209 * that we're logging off. This shouldn't really be necessary-- | 202 * that we're logging off. This shouldn't really be necessary-- |
216 FlapFrame *fr; | 209 FlapFrame *fr; |
217 | 210 |
218 if (!sess || !conn) | 211 if (!sess || !conn) |
219 return -EINVAL; | 212 return -EINVAL; |
220 | 213 |
221 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x04, 0))) | 214 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x04, 0))) |
222 return -ENOMEM; | 215 return -ENOMEM; |
223 | 216 |
224 aim_tx_enqueue(sess, fr); | 217 aim_tx_enqueue(sess, fr); |
225 | 218 |
226 return 0; | 219 return 0; |
227 } | 220 } |
228 | 221 |
229 /** | 222 /** |
230 * Clears out the connection list, killing remaining connections. | |
231 * | |
232 * @param sess Session to be cleared. | |
233 */ | |
234 static void aim_connrst(OscarSession *sess) | |
235 { | |
236 | |
237 if (sess->connlist) { | |
238 OscarConnection *cur = sess->connlist, *tmp; | |
239 | |
240 /* Attempt to send the log-off packet */ | |
241 if (cur->type == AIM_CONN_TYPE_BOS) | |
242 aim_flap_close(sess, cur); | |
243 | |
244 while (cur) { | |
245 tmp = cur->next; | |
246 aim_conn_close(cur); | |
247 connkill_real(sess, &cur); | |
248 cur = tmp; | |
249 } | |
250 } | |
251 | |
252 sess->connlist = NULL; | |
253 | |
254 return; | |
255 } | |
256 | |
257 /** | |
258 * Initializes and/or resets a connection structure to the default values. | |
259 * | |
260 * @param deadconn Connection to be reset. | |
261 */ | |
262 static void aim_conn_init(OscarConnection *deadconn) | |
263 { | |
264 | |
265 if (!deadconn) | |
266 return; | |
267 | |
268 deadconn->fd = -1; | |
269 deadconn->subtype = -1; | |
270 deadconn->type = -1; | |
271 deadconn->seqnum = 0; | |
272 deadconn->lastactivity = 0; | |
273 deadconn->forcedlatency = 0; | |
274 deadconn->handlerlist = NULL; | |
275 deadconn->priv = NULL; | |
276 memset(deadconn->inside, 0, sizeof(aim_conn_inside_t)); | |
277 | |
278 return; | |
279 } | |
280 | |
281 /** | |
282 * Allocate a new empty connection structure. | 223 * Allocate a new empty connection structure. |
283 * | 224 * |
284 * @param sess Session | 225 * @param sess The oscar session associated with this connection. |
285 * @return Returns the new connection structure. | 226 * @return Returns the new connection structure. |
286 */ | 227 */ |
287 static OscarConnection *aim_conn_getnext(OscarSession *sess) | 228 static OscarConnection * |
288 { | 229 aim_conn_getnext(OscarSession *sess) |
289 OscarConnection *newconn; | 230 { |
290 | 231 OscarConnection *conn; |
291 if (!(newconn = malloc(sizeof(OscarConnection)))) | 232 |
292 return NULL; | 233 conn = g_new0(OscarConnection, 1); |
293 memset(newconn, 0, sizeof(OscarConnection)); | 234 conn->inside = g_new0(aim_conn_inside_t, 1); |
294 | 235 conn->buffer_outgoing = gaim_circ_buffer_new(-1); |
295 if (!(newconn->inside = malloc(sizeof(aim_conn_inside_t)))) { | 236 conn->fd = -1; |
296 free(newconn); | 237 conn->subtype = -1; |
297 return NULL; | 238 conn->type = -1; |
298 } | 239 conn->seqnum = 0; |
299 memset(newconn->inside, 0, sizeof(aim_conn_inside_t)); | 240 conn->lastactivity = 0; |
300 | 241 conn->forcedlatency = 0; |
301 aim_conn_init(newconn); | 242 conn->handlerlist = NULL; |
302 | 243 |
303 newconn->next = sess->connlist; | 244 conn->next = sess->connlist; |
304 sess->connlist = newconn; | 245 sess->connlist = conn; |
305 | 246 |
306 return newconn; | 247 return conn; |
307 } | 248 } |
308 | 249 |
309 /** | 250 /** |
310 * Close, clear, and free a connection structure. Should never be | 251 * Close, clear, and free a connection structure. Should never be |
311 * called from within libfaim. | 252 * called from within libfaim. |
312 * | 253 * |
313 * @param sess Session for the connection. | 254 * @param sess Session for the connection. |
314 * @param deadconn Connection to be freed. | 255 * @param deadconn Connection to be freed. |
315 */ | 256 */ |
316 faim_export void aim_conn_kill(OscarSession *sess, OscarConnection **deadconn) | 257 void |
258 aim_conn_kill(OscarSession *sess, OscarConnection **deadconn) | |
317 { | 259 { |
318 OscarConnection *cur, **prev; | 260 OscarConnection *cur, **prev; |
319 | 261 |
320 if (!deadconn || !*deadconn) | 262 if (!deadconn || !*deadconn) |
321 return; | 263 return; |
329 } | 271 } |
330 | 272 |
331 if (!cur) | 273 if (!cur) |
332 return; /* oops */ | 274 return; /* oops */ |
333 | 275 |
334 connkill_real(sess, &cur); | 276 connkill_real(sess, cur); |
335 | |
336 return; | |
337 } | 277 } |
338 | 278 |
339 /** | 279 /** |
340 * Close (but not free) a connection. | 280 * Close (but not free) a connection. |
341 * | 281 * |
342 * This leaves everything untouched except for clearing the | 282 * This leaves everything untouched except for clearing the |
343 * handler list and setting the fd to -1 (used to recognize | 283 * handler list and setting the fd to -1 (used to recognize |
344 * dead connections). It will also remove cookies if necessary. | 284 * dead connections). It will also remove cookies if necessary. |
345 * | 285 * |
346 * Why only if fd >= 3? Seems rather implementation specific... | 286 * Why only if fd >= 3? Seems rather implementation specific... |
347 * fd's do not have to be distributed in a particular order, do they? | 287 * fd's do not have to be distributed in a particular order, do they? |
348 * | 288 * |
349 * @param deadconn The connection to close. | 289 * @param deadconn The connection to close. |
350 */ | 290 */ |
351 faim_export void aim_conn_close(OscarConnection *deadconn) | 291 void |
292 aim_conn_close(OscarConnection *deadconn) | |
352 { | 293 { |
353 aim_rxcallback_t userfunc; | 294 aim_rxcallback_t userfunc; |
354 | 295 |
355 if (deadconn->fd >= 0) | 296 if (deadconn->fd >= 0) |
356 close(deadconn->fd); | 297 close(deadconn->fd); |
360 if ((userfunc = aim_callhandler(deadconn->sessv, deadconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNDEAD))) | 301 if ((userfunc = aim_callhandler(deadconn->sessv, deadconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNDEAD))) |
361 userfunc(deadconn->sessv, NULL, deadconn); | 302 userfunc(deadconn->sessv, NULL, deadconn); |
362 | 303 |
363 if (deadconn->handlerlist) | 304 if (deadconn->handlerlist) |
364 aim_clearhandlers(deadconn); | 305 aim_clearhandlers(deadconn); |
365 | 306 } |
366 return; | 307 |
367 } | 308 /** |
368 | 309 * Locates a connection of the specified type in the |
369 /** | |
370 * Locates a connection of the specified type in the | |
371 * specified session. | 310 * specified session. |
372 * | 311 * |
373 * XXX - Except for rendezvous, all uses of this should be removed and | 312 * XXX - Except for rendezvous, all uses of this should be removed and |
374 * aim_conn_findbygroup() should be used instead. | 313 * aim_conn_findbygroup() should be used instead. |
375 * | 314 * |
376 * @param sess The session to search. | 315 * @param sess The session to search. |
377 * @param type The type of connection to look for. | 316 * @param type The type of connection to look for. |
378 * @return Returns the first connection found of the given target type, | 317 * @return Returns the first connection found of the given target type, |
379 * or NULL if none could be found. | 318 * or NULL if none could be found. |
380 */ | 319 */ |
381 faim_export OscarConnection *aim_getconn_type(OscarSession *sess, int type) | 320 OscarConnection * |
321 aim_getconn_type(OscarSession *sess, int type) | |
382 { | 322 { |
383 OscarConnection *cur; | 323 OscarConnection *cur; |
384 | 324 |
385 for (cur = sess->connlist; cur; cur = cur->next) { | 325 for (cur = sess->connlist; cur; cur = cur->next) { |
386 if ((cur->type == type) && | 326 if ((cur->type == type) && |
389 } | 329 } |
390 | 330 |
391 return cur; | 331 return cur; |
392 } | 332 } |
393 | 333 |
394 faim_export OscarConnection *aim_getconn_type_all(OscarSession *sess, int type) | 334 OscarConnection * |
335 aim_getconn_type_all(OscarSession *sess, int type) | |
395 { | 336 { |
396 OscarConnection *cur; | 337 OscarConnection *cur; |
397 | 338 |
398 for (cur = sess->connlist; cur; cur = cur->next) { | 339 for (cur = sess->connlist; cur; cur = cur->next) { |
399 if (cur->type == type) | 340 if (cur->type == type) |
402 | 343 |
403 return cur; | 344 return cur; |
404 } | 345 } |
405 | 346 |
406 /* If you pass -1 for the fd, you'll get what you ask for. Gibberish. */ | 347 /* If you pass -1 for the fd, you'll get what you ask for. Gibberish. */ |
407 faim_export OscarConnection *aim_getconn_fd(OscarSession *sess, int fd) | 348 OscarConnection * |
349 aim_getconn_fd(OscarSession *sess, int fd) | |
408 { | 350 { |
409 OscarConnection *cur; | 351 OscarConnection *cur; |
410 | 352 |
411 for (cur = sess->connlist; cur; cur = cur->next) { | 353 for (cur = sess->connlist; cur; cur = cur->next) { |
412 if (cur->fd == fd) | 354 if (cur->fd == fd) |
418 | 360 |
419 /** | 361 /** |
420 * Clone an OscarConnection. | 362 * Clone an OscarConnection. |
421 * | 363 * |
422 * A new connection is allocated, and the values are filled in | 364 * A new connection is allocated, and the values are filled in |
423 * appropriately. Note that this function sets the new connnection's | 365 * appropriately. |
424 * ->priv pointer to be equal to that of its parent: only the pointer | |
425 * is copied, not the data it points to. | |
426 * | 366 * |
427 * @param sess The session containing this connection. | 367 * @param sess The session containing this connection. |
428 * @param src The connection to clone. | 368 * @param src The connection to clone. |
429 * @return Returns a pointer to the new OscarConnection, or %NULL on error. | 369 * @return Returns a pointer to the new OscarConnection, or %NULL on error. |
430 */ | 370 */ |
431 faim_internal OscarConnection *aim_cloneconn(OscarSession *sess, OscarConnection *src) | 371 OscarConnection * |
372 aim_cloneconn(OscarSession *sess, OscarConnection *src) | |
432 { | 373 { |
433 OscarConnection *conn; | 374 OscarConnection *conn; |
434 | 375 |
435 if (!(conn = aim_conn_getnext(sess))) | 376 if (!(conn = aim_conn_getnext(sess))) |
436 return NULL; | 377 return NULL; |
437 | 378 |
438 conn->fd = src->fd; | 379 conn->fd = src->fd; |
439 conn->type = src->type; | 380 conn->type = src->type; |
440 conn->subtype = src->subtype; | 381 conn->subtype = src->subtype; |
441 conn->seqnum = src->seqnum; | 382 conn->seqnum = src->seqnum; |
442 conn->priv = src->priv; | |
443 conn->internal = src->internal; | 383 conn->internal = src->internal; |
444 conn->lastactivity = src->lastactivity; | 384 conn->lastactivity = src->lastactivity; |
445 conn->forcedlatency = src->forcedlatency; | 385 conn->forcedlatency = src->forcedlatency; |
446 conn->sessv = src->sessv; | 386 conn->sessv = src->sessv; |
447 aim_clonehandlers(sess, conn, src); | 387 aim_clonehandlers(sess, conn, src); |
449 if (src->inside) { | 389 if (src->inside) { |
450 /* | 390 /* |
451 * XXX should clone this section as well, but since currently | 391 * XXX should clone this section as well, but since currently |
452 * this function only gets called for some of that rendezvous | 392 * this function only gets called for some of that rendezvous |
453 * crap, and not on SNAC connections, its probably okay for | 393 * crap, and not on SNAC connections, its probably okay for |
454 * now. | 394 * now. |
455 * | 395 * |
456 */ | 396 */ |
457 } | 397 } |
458 | 398 |
459 return conn; | 399 return conn; |
468 * FIXME: Return errors in a more sane way. | 408 * FIXME: Return errors in a more sane way. |
469 * | 409 * |
470 * @param sess Session to create connection in | 410 * @param sess Session to create connection in |
471 * @param type Type of connection to create | 411 * @param type Type of connection to create |
472 */ | 412 */ |
473 faim_export OscarConnection *aim_newconn(OscarSession *sess, int type) | 413 OscarConnection * |
414 aim_newconn(OscarSession *sess, int type) | |
474 { | 415 { |
475 OscarConnection *conn; | 416 OscarConnection *conn; |
476 | 417 |
477 if (!(conn = aim_conn_getnext(sess))) | 418 if (!(conn = aim_conn_getnext(sess))) |
478 return NULL; | 419 return NULL; |
516 * | 457 * |
517 * @param conn Conn to set latency for. | 458 * @param conn Conn to set latency for. |
518 * @param newval Number of seconds to force between transmits. | 459 * @param newval Number of seconds to force between transmits. |
519 * @return Returns -1 if the connection does not exist, zero otherwise. | 460 * @return Returns -1 if the connection does not exist, zero otherwise. |
520 */ | 461 */ |
521 faim_export int aim_conn_setlatency(OscarConnection *conn, int newval) | 462 int |
463 aim_conn_setlatency(OscarConnection *conn, int newval) | |
522 { | 464 { |
523 | 465 |
524 if (!conn) | 466 if (!conn) |
525 return -1; | 467 return -1; |
526 | 468 |
529 | 471 |
530 return 0; | 472 return 0; |
531 } | 473 } |
532 | 474 |
533 /** | 475 /** |
534 * Initializes a session structure by setting the initial values | 476 * Allocates a new OscarSession and initializes it with default values. |
535 * stuff in the OscarSession struct. | 477 */ |
536 * | 478 OscarSession * |
537 * @param sess Session to initialize. | 479 oscar_session_new(void) |
538 * @param nonblocking Set to true if you want connections to be non-blocking. | 480 { |
539 */ | 481 OscarSession *sess; |
540 faim_export void aim_session_init(OscarSession *sess, guint8 nonblocking) | 482 |
541 { | 483 sess = g_new(OscarSession, 1); |
542 | 484 |
543 if (!sess) | |
544 return; | |
545 | |
546 memset(sess, 0, sizeof(OscarSession)); | |
547 aim_connrst(sess); | |
548 sess->queue_outgoing = NULL; | 485 sess->queue_outgoing = NULL; |
549 sess->queue_incoming = NULL; | 486 sess->queue_incoming = NULL; |
550 aim_initsnachash(sess); | 487 aim_initsnachash(sess); |
551 sess->msgcookies = NULL; | 488 sess->msgcookies = NULL; |
552 sess->nonblocking = nonblocking; | |
553 sess->modlistv = NULL; | 489 sess->modlistv = NULL; |
554 sess->snacid_next = 0x00000001; | 490 sess->snacid_next = 0x00000001; |
555 | 491 |
556 sess->locate.userinfo = NULL; | 492 sess->locate.userinfo = NULL; |
557 sess->locate.torequest = NULL; | 493 sess->locate.torequest = NULL; |
601 aim__registermodule(sess, icq_modfirst); /* XXX - Make sure this isn't sent for AIM */ | 537 aim__registermodule(sess, icq_modfirst); /* XXX - Make sure this isn't sent for AIM */ |
602 /* missing 0x16 */ | 538 /* missing 0x16 */ |
603 aim__registermodule(sess, auth_modfirst); | 539 aim__registermodule(sess, auth_modfirst); |
604 aim__registermodule(sess, email_modfirst); | 540 aim__registermodule(sess, email_modfirst); |
605 | 541 |
606 return; | 542 return sess; |
607 } | 543 } |
608 | 544 |
609 /** | 545 /** |
610 * Logoff and deallocate a session. | 546 * Logoff and deallocate a session. |
611 * | 547 * |
612 * @param sess Session to kill | 548 * @param sess Session to kill |
613 */ | 549 */ |
614 faim_export void aim_session_kill(OscarSession *sess) | 550 void |
551 oscar_session_destroy(OscarSession *sess) | |
615 { | 552 { |
616 aim_cleansnacs(sess, -1); | 553 aim_cleansnacs(sess, -1); |
617 | 554 |
618 aim_logoff(sess); | 555 if (sess->connlist) { |
556 OscarConnection *cur = sess->connlist, *tmp; | |
557 | |
558 /* Attempt to send the log-off packet */ | |
559 if (cur->type == AIM_CONN_TYPE_BOS) | |
560 aim_flap_close(sess, cur); | |
561 | |
562 while (cur) { | |
563 tmp = cur->next; | |
564 aim_conn_close(cur); | |
565 connkill_real(sess, cur); | |
566 cur = tmp; | |
567 } | |
568 } | |
569 sess->connlist = NULL; | |
619 | 570 |
620 aim__shutdownmodules(sess); | 571 aim__shutdownmodules(sess); |
621 | 572 |
622 return; | 573 g_free(sess); |
623 } | 574 } |
624 | 575 |
625 /** | 576 /** |
626 * Determine if a connection is connecting. | 577 * Determine if a connection is connecting. |
627 * | 578 * |
628 * @param conn Connection to examine. | 579 * @param conn Connection to examine. |
629 * @return Returns nonzero if the connection is in the process of | 580 * @return Returns nonzero if the connection is in the process of |
630 * connecting (or if it just completed and | 581 * connecting (or if it just completed and |
631 * aim_conn_completeconnect() has yet to be called on it). | 582 * aim_conn_completeconnect() has yet to be called on it). |
632 */ | 583 */ |
633 faim_export int aim_conn_isconnecting(OscarConnection *conn) | 584 int |
585 aim_conn_isconnecting(OscarConnection *conn) | |
634 { | 586 { |
635 | 587 |
636 if (!conn) | 588 if (!conn) |
637 return 0; | 589 return 0; |
638 | 590 |
640 } | 592 } |
641 | 593 |
642 /* | 594 /* |
643 * XXX this is nearly as ugly as proxyconnect(). | 595 * XXX this is nearly as ugly as proxyconnect(). |
644 */ | 596 */ |
645 faim_export int aim_conn_completeconnect(OscarSession *sess, OscarConnection *conn) | 597 int |
598 aim_conn_completeconnect(OscarSession *sess, OscarConnection *conn) | |
646 { | 599 { |
647 aim_rxcallback_t userfunc; | 600 aim_rxcallback_t userfunc; |
648 | 601 |
649 if (!conn || (conn->fd == -1)) | 602 if (!conn || (conn->fd == -1)) |
650 return -1; | 603 return -1; |
663 aim_tx_flushqueue(sess); | 616 aim_tx_flushqueue(sess); |
664 | 617 |
665 return 0; | 618 return 0; |
666 } | 619 } |
667 | 620 |
668 faim_export OscarSession *aim_conn_getsess(OscarConnection *conn) | 621 OscarSession * |
622 aim_conn_getsess(OscarConnection *conn) | |
669 { | 623 { |
670 | 624 |
671 if (!conn) | 625 if (!conn) |
672 return NULL; | 626 return NULL; |
673 | 627 |
674 return (OscarSession *)conn->sessv; | 628 return (OscarSession *)conn->sessv; |
675 } | 629 } |
676 | 630 |
677 /** | 631 /** |
678 * Close -ALL- open connections. | |
679 * | |
680 * @param sess The session. | |
681 * @return Zero. | |
682 */ | |
683 faim_export int aim_logoff(OscarSession *sess) | |
684 { | |
685 aim_connrst(sess); /* in case we want to connect again */ | |
686 | |
687 return 0; | |
688 } | |
689 | |
690 /** | |
691 * No-op. This sends an empty channel 5 SNAC. WinAIM 4.x and higher | 632 * No-op. This sends an empty channel 5 SNAC. WinAIM 4.x and higher |
692 * sends these _every minute_ to keep the connection alive. | 633 * sends these _every minute_ to keep the connection alive. |
693 */ | 634 */ |
694 faim_export int aim_flap_nop(OscarSession *sess, OscarConnection *conn) | 635 int |
636 aim_flap_nop(OscarSession *sess, OscarConnection *conn) | |
695 { | 637 { |
696 FlapFrame *fr; | 638 FlapFrame *fr; |
697 | 639 |
698 if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0))) | 640 if (!(fr = flap_frame_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0))) |
699 return -ENOMEM; | 641 return -ENOMEM; |
700 | 642 |
701 aim_tx_enqueue(sess, fr); | 643 aim_tx_enqueue(sess, fr); |
702 | 644 |
703 /* clean out SNACs over 60sec old */ | 645 /* clean out SNACs over 60sec old */ |