Mercurial > pidgin
comparison libfaim/aim_rxqueue.c @ 445:e4c34ca88d9b
[gaim-migrate @ 455]
Hehehehehe
Libfaim got updated, gaim got updated. btw, gaim/faim can't sign in yet,
don't ask me why. it's not my fault.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Thu, 29 Jun 2000 20:40:28 +0000 |
parents | 9d258a0aa560 |
children | 6e318907bcce |
comparison
equal
deleted
inserted
replaced
444:e7885c54ed2f | 445:e4c34ca88d9b |
---|---|
12 * Grab a single command sequence off the socket, and enqueue | 12 * Grab a single command sequence off the socket, and enqueue |
13 * it in the incoming event queue in a seperate struct. | 13 * it in the incoming event queue in a seperate struct. |
14 */ | 14 */ |
15 int aim_get_command(struct aim_session_t *sess, struct aim_conn_t *conn) | 15 int aim_get_command(struct aim_session_t *sess, struct aim_conn_t *conn) |
16 { | 16 { |
17 u_char generic[6]; | 17 unsigned char generic[6]; |
18 struct command_rx_struct *newrx = NULL; | 18 struct command_rx_struct *newrx = NULL; |
19 | 19 |
20 if (!sess || !conn) | 20 if (!sess || !conn) |
21 return 0; | 21 return 0; |
22 | 22 |
25 | 25 |
26 /* | 26 /* |
27 * Rendezvous (client-client) connections do not speak | 27 * Rendezvous (client-client) connections do not speak |
28 * FLAP, so this function will break on them. | 28 * FLAP, so this function will break on them. |
29 */ | 29 */ |
30 if (conn->type > 0x01000) | 30 if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) |
31 return 0; | 31 return aim_get_command_rendezvous(sess, conn); |
32 | 32 |
33 /* | 33 /* |
34 * Read FLAP header. Six bytes: | 34 * Read FLAP header. Six bytes: |
35 * | 35 * |
36 * 0 char -- Always 0x2a | 36 * 0 char -- Always 0x2a |
38 * 2 short -- Sequence number | 38 * 2 short -- Sequence number |
39 * 4 short -- Number of data bytes that follow. | 39 * 4 short -- Number of data bytes that follow. |
40 */ | 40 */ |
41 faim_mutex_lock(&conn->active); | 41 faim_mutex_lock(&conn->active); |
42 if (read(conn->fd, generic, 6) < 6){ | 42 if (read(conn->fd, generic, 6) < 6){ |
43 aim_conn_close(conn); | 43 aim_conn_kill(sess, &conn); |
44 faim_mutex_unlock(&conn->active); | 44 faim_mutex_unlock(&conn->active); |
45 return -1; | 45 return -1; |
46 } | 46 } |
47 faim_mutex_unlock(&conn->active); | |
48 | 47 |
49 /* | 48 /* |
50 * This shouldn't happen unless the socket breaks, the server breaks, | 49 * This shouldn't happen unless the socket breaks, the server breaks, |
51 * or we break. We must handle it just in case. | 50 * or we break. We must handle it just in case. |
52 */ | 51 */ |
53 if (generic[0] != 0x2a) { | 52 if (generic[0] != 0x2a) { |
54 faimdprintf(1, "Bad incoming data!"); | 53 faimdprintf(1, "Bad incoming data!"); |
54 faim_mutex_unlock(&conn->active); | |
55 return -1; | 55 return -1; |
56 } | 56 } |
57 | 57 |
58 /* allocate a new struct */ | 58 /* allocate a new struct */ |
59 newrx = (struct command_rx_struct *)malloc(sizeof(struct command_rx_struct)); | 59 if (!(newrx = (struct command_rx_struct *)malloc(sizeof(struct command_rx_struct)))) { |
60 if (!newrx) | 60 faim_mutex_unlock(&conn->active); |
61 return -1; | 61 return -1; |
62 } | |
62 memset(newrx, 0x00, sizeof(struct command_rx_struct)); | 63 memset(newrx, 0x00, sizeof(struct command_rx_struct)); |
63 | 64 |
64 newrx->lock = 1; /* lock the struct */ | 65 newrx->lock = 1; /* lock the struct */ |
65 | 66 |
67 /* we're doing OSCAR if we're here */ | |
68 newrx->hdrtype = AIM_FRAMETYPE_OSCAR; | |
69 | |
66 /* store channel -- byte 2 */ | 70 /* store channel -- byte 2 */ |
67 newrx->type = (char) generic[1]; | 71 newrx->hdr.oscar.type = (char) generic[1]; |
68 | 72 |
69 /* store seqnum -- bytes 3 and 4 */ | 73 /* store seqnum -- bytes 3 and 4 */ |
70 newrx->seqnum = aimutil_get16(generic+2); | 74 newrx->hdr.oscar.seqnum = aimutil_get16(generic+2); |
71 | 75 |
72 /* store commandlen -- bytes 5 and 6 */ | 76 /* store commandlen -- bytes 5 and 6 */ |
73 newrx->commandlen = aimutil_get16(generic+4); | 77 newrx->commandlen = aimutil_get16(generic+4); |
74 | 78 |
75 newrx->nofree = 0; /* free by default */ | 79 newrx->nofree = 0; /* free by default */ |
76 | 80 |
77 /* malloc for data portion */ | 81 /* malloc for data portion */ |
78 newrx->data = (u_char *) malloc(newrx->commandlen); | 82 if (!(newrx->data = (u_char *) malloc(newrx->commandlen))) { |
79 if (!newrx->data) { | |
80 free(newrx); | 83 free(newrx); |
84 faim_mutex_unlock(&conn->active); | |
81 return -1; | 85 return -1; |
82 } | 86 } |
83 | 87 |
84 /* read the data portion of the packet */ | 88 /* read the data portion of the packet */ |
85 faim_mutex_lock(&conn->active); | |
86 if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){ | 89 if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){ |
87 free(newrx->data); | 90 free(newrx->data); |
88 free(newrx); | 91 free(newrx); |
89 aim_conn_close(conn); | 92 aim_conn_kill(sess, &conn); |
90 faim_mutex_unlock(&conn->active); | 93 faim_mutex_unlock(&conn->active); |
91 return -1; | 94 return -1; |
92 } | 95 } |
93 faim_mutex_unlock(&conn->active); | 96 faim_mutex_unlock(&conn->active); |
94 | 97 |
117 newrx->conn->lastactivity = time(NULL); | 120 newrx->conn->lastactivity = time(NULL); |
118 | 121 |
119 return 0; | 122 return 0; |
120 } | 123 } |
121 | 124 |
125 int aim_get_command_rendezvous(struct aim_session_t *sess, struct aim_conn_t *conn) | |
126 { | |
127 unsigned char hdrbuf1[6]; | |
128 unsigned char *hdr = NULL; | |
129 int hdrlen, hdrtype; | |
130 int payloadlength = 0; | |
131 int flags = 0; | |
132 char *snptr = NULL; | |
133 | |
134 if (read(conn->fd, hdrbuf1, 6) < 6) { | |
135 perror("read"); | |
136 printf("faim: rend: read error\n"); | |
137 aim_conn_kill(sess, &conn); | |
138 return -1; | |
139 } | |
140 | |
141 hdrlen = aimutil_get16(hdrbuf1+4); | |
142 | |
143 hdrlen -= 6; | |
144 hdr = malloc(hdrlen); | |
145 | |
146 faim_mutex_lock(&conn->active); | |
147 if (read(conn->fd, hdr, hdrlen) < hdrlen) { | |
148 perror("read"); | |
149 printf("faim: rend: read2 error\n"); | |
150 free(hdr); | |
151 faim_mutex_unlock(&conn->active); | |
152 aim_conn_kill(sess, &conn); | |
153 return -1; | |
154 } | |
155 | |
156 hdrtype = aimutil_get16(hdr); | |
157 | |
158 switch (hdrtype) { | |
159 case 0x0001: { | |
160 payloadlength = aimutil_get32(hdr+22); | |
161 flags = aimutil_get16(hdr+32); | |
162 snptr = hdr+38; | |
163 | |
164 printf("OFT frame: %04x / %04x / %04x / %s\n", hdrtype, payloadlength, flags, snptr); | |
165 | |
166 if (flags == 0x000e) { | |
167 printf("directim: %s has started typing\n", snptr); | |
168 } else if ((flags == 0x0000) && payloadlength) { | |
169 unsigned char *buf; | |
170 buf = malloc(payloadlength+1); | |
171 | |
172 /* XXX theres got to be a better way */ | |
173 faim_mutex_lock(&conn->active); | |
174 if (recv(conn->fd, buf, payloadlength, MSG_WAITALL) < payloadlength) { | |
175 perror("read"); | |
176 printf("faim: rend: read3 error\n"); | |
177 free(buf); | |
178 faim_mutex_unlock(&conn->active); | |
179 aim_conn_kill(sess, &conn); | |
180 return -1; | |
181 } | |
182 faim_mutex_unlock(&conn->active); | |
183 buf[payloadlength] = '\0'; | |
184 printf("directim: %s/%04x/%04x/%s\n", snptr, payloadlength, flags, buf); | |
185 aim_send_im_direct(sess, conn, buf); | |
186 free(buf); | |
187 } | |
188 break; | |
189 } | |
190 default: | |
191 printf("OFT frame: type %04x\n", hdrtype); | |
192 /* data connection may be unreliable here */ | |
193 break; | |
194 } /* switch */ | |
195 | |
196 free(hdr); | |
197 | |
198 return 0; | |
199 } | |
200 | |
122 /* | 201 /* |
123 * Purge recieve queue of all handled commands (->handled==1). Also | 202 * Purge recieve queue of all handled commands (->handled==1). Also |
124 * allows for selective freeing using ->nofree so that the client can | 203 * allows for selective freeing using ->nofree so that the client can |
125 * keep the data for various purposes. | 204 * keep the data for various purposes. |
126 * | 205 * |
142 if (sess->queue_incoming->handled) { | 221 if (sess->queue_incoming->handled) { |
143 tmp = sess->queue_incoming; | 222 tmp = sess->queue_incoming; |
144 sess->queue_incoming = NULL; | 223 sess->queue_incoming = NULL; |
145 | 224 |
146 if (!tmp->nofree) { | 225 if (!tmp->nofree) { |
226 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) | |
227 free(tmp->hdr.oft.hdr2); | |
147 free(tmp->data); | 228 free(tmp->data); |
148 free(tmp); | 229 free(tmp); |
149 } else | 230 } else |
150 tmp->next = NULL; | 231 tmp->next = NULL; |
151 } | 232 } |
155 for(cur = sess->queue_incoming; cur->next != NULL; ) { | 236 for(cur = sess->queue_incoming; cur->next != NULL; ) { |
156 if (cur->next->handled) { | 237 if (cur->next->handled) { |
157 tmp = cur->next; | 238 tmp = cur->next; |
158 cur->next = tmp->next; | 239 cur->next = tmp->next; |
159 if (!tmp->nofree) { | 240 if (!tmp->nofree) { |
241 if (tmp->hdrtype == AIM_FRAMETYPE_OFT) | |
242 free(tmp->hdr.oft.hdr2); | |
160 free(tmp->data); | 243 free(tmp->data); |
161 free(tmp); | 244 free(tmp); |
162 } else | 245 } else |
163 tmp->next = NULL; | 246 tmp->next = NULL; |
164 } | 247 } |
174 break; | 257 break; |
175 } | 258 } |
176 | 259 |
177 return; | 260 return; |
178 } | 261 } |
262 | |
263 /* | |
264 * Since aim_get_command will aim_conn_kill dead connections, we need | |
265 * to clean up the rxqueue of unprocessed connections on that socket. | |
266 * | |
267 * XXX: this is something that was handled better in the old connection | |
268 * handling method, but eh. | |
269 */ | |
270 void aim_rxqueue_cleanbyconn(struct aim_session_t *sess, struct aim_conn_t *conn) | |
271 { | |
272 struct command_rx_struct *currx; | |
273 | |
274 for (currx = sess->queue_incoming; currx; currx = currx->next) { | |
275 if ((!currx->handled) && (currx->conn == conn)) | |
276 currx->handled = 1; | |
277 } | |
278 return; | |
279 } |