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 } |
