Mercurial > pidgin
annotate libfaim/aim_rxqueue.c @ 780:c714def9cebb
[gaim-migrate @ 790]
You may be a geek if...
You've ever used a computer on Friday, Saturday and Sunday of the
same weekend.
You find yourself interrupting computer store salesman to correct
something he said.
The first thing you notice when walking in a business is their
computer system. ...and offer advice on how you would change it.
You've ever mounted a magnetic tape reel.
You own any shareware.
You know more IP addresses than phone numbers.
You've ever accidentally dialed an IP address.
Your friends use you as tech support.
You've ever named a computer.
You have your local computer store on speed dial.
You can't carry on a conversation without talking about computers.
Co-workers have to E-mail you about the fire alarm to get you out of
the building.
You've ever found "stray" diskettes when doing laundry.
Your computer has it's own phone line - but your teenager doesn't.
You check the national weather service web page for current weather
conditions (rather than look out the window).
You know more URLs than street addresses.
Your pet has a web page.
You get really excited when Yahoo adds your link.
committer: Tailor Script <tailor@pidgin.im>
| author | Eric Warmenhoven <eric@warmenhoven.org> |
|---|---|
| date | Tue, 29 Aug 2000 03:59:01 +0000 |
| parents | 6e318907bcce |
| children | 9a123b171f46 |
| rev | line source |
|---|---|
| 2 | 1 /* |
| 237 | 2 * aim_rxqueue.c |
| 3 * | |
| 4 * This file contains the management routines for the receive | |
| 5 * (incoming packet) queue. The actual packet handlers are in | |
| 6 * aim_rxhandlers.c. | |
| 2 | 7 */ |
| 8 | |
|
283
0f14e6d8a51b
[gaim-migrate @ 293]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
279
diff
changeset
|
9 #include <faim/aim.h> |
| 2 | 10 |
| 11 /* | |
| 237 | 12 * Grab a single command sequence off the socket, and enqueue |
| 13 * it in the incoming event queue in a seperate struct. | |
| 14 */ | |
| 15 int aim_get_command(struct aim_session_t *sess, struct aim_conn_t *conn) | |
| 2 | 16 { |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
17 unsigned char generic[6]; |
| 237 | 18 struct command_rx_struct *newrx = NULL; |
| 2 | 19 |
| 237 | 20 if (!sess || !conn) |
| 21 return 0; | |
| 2 | 22 |
| 237 | 23 if (conn->fd < 3) /* can happen when people abuse the interface */ |
| 24 return 0; | |
| 2 | 25 |
| 237 | 26 /* |
|
338
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
27 * Rendezvous (client-client) connections do not speak |
|
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
28 * FLAP, so this function will break on them. |
|
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
29 */ |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
30 if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
31 return aim_get_command_rendezvous(sess, conn); |
|
503
6e318907bcce
[gaim-migrate @ 513]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
445
diff
changeset
|
32 if (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) |
|
6e318907bcce
[gaim-migrate @ 513]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
445
diff
changeset
|
33 return 0; |
|
338
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
34 |
|
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
35 /* |
| 237 | 36 * Read FLAP header. Six bytes: |
| 37 * | |
| 38 * 0 char -- Always 0x2a | |
| 39 * 1 char -- Channel ID. Usually 2 -- 1 and 4 are used during login. | |
| 40 * 2 short -- Sequence number | |
| 41 * 4 short -- Number of data bytes that follow. | |
| 42 */ | |
|
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
43 faim_mutex_lock(&conn->active); |
| 237 | 44 if (read(conn->fd, generic, 6) < 6){ |
|
503
6e318907bcce
[gaim-migrate @ 513]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
445
diff
changeset
|
45 aim_conn_close(conn); |
|
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
46 faim_mutex_unlock(&conn->active); |
| 237 | 47 return -1; |
| 48 } | |
| 2 | 49 |
| 237 | 50 /* |
| 51 * This shouldn't happen unless the socket breaks, the server breaks, | |
| 52 * or we break. We must handle it just in case. | |
| 53 */ | |
| 54 if (generic[0] != 0x2a) { | |
| 55 faimdprintf(1, "Bad incoming data!"); | |
|
503
6e318907bcce
[gaim-migrate @ 513]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
445
diff
changeset
|
56 aim_conn_close(conn); |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
57 faim_mutex_unlock(&conn->active); |
| 237 | 58 return -1; |
| 59 } | |
| 2 | 60 |
| 61 /* allocate a new struct */ | |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
62 if (!(newrx = (struct command_rx_struct *)malloc(sizeof(struct command_rx_struct)))) { |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
63 faim_mutex_unlock(&conn->active); |
| 237 | 64 return -1; |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
65 } |
| 237 | 66 memset(newrx, 0x00, sizeof(struct command_rx_struct)); |
| 2 | 67 |
| 237 | 68 newrx->lock = 1; /* lock the struct */ |
| 69 | |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
70 /* we're doing OSCAR if we're here */ |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
71 newrx->hdrtype = AIM_FRAMETYPE_OSCAR; |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
72 |
| 237 | 73 /* store channel -- byte 2 */ |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
74 newrx->hdr.oscar.type = (char) generic[1]; |
| 2 | 75 |
| 76 /* store seqnum -- bytes 3 and 4 */ | |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
77 newrx->hdr.oscar.seqnum = aimutil_get16(generic+2); |
| 2 | 78 |
| 79 /* store commandlen -- bytes 5 and 6 */ | |
| 237 | 80 newrx->commandlen = aimutil_get16(generic+4); |
| 81 | |
| 82 newrx->nofree = 0; /* free by default */ | |
| 2 | 83 |
| 84 /* malloc for data portion */ | |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
85 if (!(newrx->data = (u_char *) malloc(newrx->commandlen))) { |
| 237 | 86 free(newrx); |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
87 faim_mutex_unlock(&conn->active); |
| 237 | 88 return -1; |
| 89 } | |
| 2 | 90 |
| 91 /* read the data portion of the packet */ | |
| 237 | 92 if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){ |
| 93 free(newrx->data); | |
| 94 free(newrx); | |
|
503
6e318907bcce
[gaim-migrate @ 513]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
445
diff
changeset
|
95 aim_conn_close(conn); |
|
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
96 faim_mutex_unlock(&conn->active); |
| 237 | 97 return -1; |
| 98 } | |
|
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
99 faim_mutex_unlock(&conn->active); |
| 2 | 100 |
| 237 | 101 newrx->conn = conn; |
| 2 | 102 |
| 237 | 103 newrx->next = NULL; /* this will always be at the bottom */ |
| 104 newrx->lock = 0; /* unlock */ | |
| 2 | 105 |
| 106 /* enqueue this packet */ | |
| 237 | 107 if (sess->queue_incoming == NULL) { |
| 108 sess->queue_incoming = newrx; | |
| 109 } else { | |
| 110 struct command_rx_struct *cur; | |
| 111 | |
| 112 /* | |
| 113 * This append operation takes a while. It might be faster | |
| 114 * if we maintain a pointer to the last entry in the queue | |
| 115 * and just update that. Need to determine if the overhead | |
| 116 * to maintain that is lower than the overhead for this loop. | |
| 117 */ | |
| 118 for (cur = sess->queue_incoming; cur->next; cur = cur->next) | |
| 119 ; | |
| 120 cur->next = newrx; | |
| 121 } | |
| 122 | |
| 123 newrx->conn->lastactivity = time(NULL); | |
| 2 | 124 |
| 125 return 0; | |
| 126 } | |
| 127 | |
| 128 /* | |
| 237 | 129 * Purge recieve queue of all handled commands (->handled==1). Also |
| 130 * allows for selective freeing using ->nofree so that the client can | |
| 131 * keep the data for various purposes. | |
| 132 * | |
| 133 * If ->nofree is nonzero, the frame will be delinked from the global list, | |
| 134 * but will not be free'ed. The client _must_ keep a pointer to the | |
| 135 * data -- libfaim will not! If the client marks ->nofree but | |
| 136 * does not keep a pointer, it's lost forever. | |
| 137 * | |
| 2 | 138 */ |
| 237 | 139 void aim_purge_rxqueue(struct aim_session_t *sess) |
| 2 | 140 { |
| 237 | 141 struct command_rx_struct *cur = NULL; |
| 142 struct command_rx_struct *tmp; | |
| 2 | 143 |
| 237 | 144 if (sess->queue_incoming == NULL) |
| 145 return; | |
| 146 | |
| 147 if (sess->queue_incoming->next == NULL) { | |
| 148 if (sess->queue_incoming->handled) { | |
| 149 tmp = sess->queue_incoming; | |
| 150 sess->queue_incoming = NULL; | |
| 151 | |
| 152 if (!tmp->nofree) { | |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
153 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
154 free(tmp->hdr.oft.hdr2); |
| 237 | 155 free(tmp->data); |
| 156 free(tmp); | |
| 157 } else | |
| 158 tmp->next = NULL; | |
| 2 | 159 } |
| 237 | 160 return; |
| 161 } | |
| 2 | 162 |
| 237 | 163 for(cur = sess->queue_incoming; cur->next != NULL; ) { |
| 164 if (cur->next->handled) { | |
| 165 tmp = cur->next; | |
| 166 cur->next = tmp->next; | |
| 167 if (!tmp->nofree) { | |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
168 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
169 free(tmp->hdr.oft.hdr2); |
| 237 | 170 free(tmp->data); |
| 171 free(tmp); | |
| 172 } else | |
| 173 tmp->next = NULL; | |
| 174 } | |
| 175 cur = cur->next; | |
| 2 | 176 |
| 237 | 177 /* |
| 178 * Be careful here. Because of the way we just | |
| 179 * manipulated the pointer, cur may be NULL and | |
| 180 * the for() will segfault doing the check unless | |
| 181 * we find this case first. | |
| 182 */ | |
| 183 if (cur == NULL) | |
| 184 break; | |
| 185 } | |
| 186 | |
| 187 return; | |
| 2 | 188 } |
|
445
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
189 |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
190 /* |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
191 * Since aim_get_command will aim_conn_kill dead connections, we need |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
192 * to clean up the rxqueue of unprocessed connections on that socket. |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
193 * |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
194 * XXX: this is something that was handled better in the old connection |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
195 * handling method, but eh. |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
196 */ |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
197 void aim_rxqueue_cleanbyconn(struct aim_session_t *sess, struct aim_conn_t *conn) |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
198 { |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
199 struct command_rx_struct *currx; |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
200 |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
201 for (currx = sess->queue_incoming; currx; currx = currx->next) { |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
202 if ((!currx->handled) && (currx->conn == conn)) |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
203 currx->handled = 1; |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
204 } |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
205 return; |
|
e4c34ca88d9b
[gaim-migrate @ 455]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
338
diff
changeset
|
206 } |
