Mercurial > pidgin
annotate libfaim/aim_rxqueue.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 |
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 { |
237 | 17 u_char generic[6]; |
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 */ |
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
30 if (conn->type > 0x01000) |
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
31 return 0; |
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
32 |
9d258a0aa560
[gaim-migrate @ 348]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
283
diff
changeset
|
33 /* |
237 | 34 * Read FLAP header. Six bytes: |
35 * | |
36 * 0 char -- Always 0x2a | |
37 * 1 char -- Channel ID. Usually 2 -- 1 and 4 are used during login. | |
38 * 2 short -- Sequence number | |
39 * 4 short -- Number of data bytes that follow. | |
40 */ | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
41 faim_mutex_lock(&conn->active); |
237 | 42 if (read(conn->fd, generic, 6) < 6){ |
43 aim_conn_close(conn); | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
44 faim_mutex_unlock(&conn->active); |
237 | 45 return -1; |
46 } | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
47 faim_mutex_unlock(&conn->active); |
2 | 48 |
237 | 49 /* |
50 * This shouldn't happen unless the socket breaks, the server breaks, | |
51 * or we break. We must handle it just in case. | |
52 */ | |
53 if (generic[0] != 0x2a) { | |
54 faimdprintf(1, "Bad incoming data!"); | |
55 return -1; | |
56 } | |
2 | 57 |
58 /* allocate a new struct */ | |
237 | 59 newrx = (struct command_rx_struct *)malloc(sizeof(struct command_rx_struct)); |
60 if (!newrx) | |
61 return -1; | |
62 memset(newrx, 0x00, sizeof(struct command_rx_struct)); | |
2 | 63 |
237 | 64 newrx->lock = 1; /* lock the struct */ |
65 | |
66 /* store channel -- byte 2 */ | |
67 newrx->type = (char) generic[1]; | |
2 | 68 |
69 /* store seqnum -- bytes 3 and 4 */ | |
237 | 70 newrx->seqnum = aimutil_get16(generic+2); |
2 | 71 |
72 /* store commandlen -- bytes 5 and 6 */ | |
237 | 73 newrx->commandlen = aimutil_get16(generic+4); |
74 | |
75 newrx->nofree = 0; /* free by default */ | |
2 | 76 |
77 /* malloc for data portion */ | |
237 | 78 newrx->data = (u_char *) malloc(newrx->commandlen); |
79 if (!newrx->data) { | |
80 free(newrx); | |
81 return -1; | |
82 } | |
2 | 83 |
84 /* read the data portion of the packet */ | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
85 faim_mutex_lock(&conn->active); |
237 | 86 if (read(conn->fd, newrx->data, newrx->commandlen) < newrx->commandlen){ |
87 free(newrx->data); | |
88 free(newrx); | |
89 aim_conn_close(conn); | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
90 faim_mutex_unlock(&conn->active); |
237 | 91 return -1; |
92 } | |
279
501e09c51cbc
[gaim-migrate @ 289]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
237
diff
changeset
|
93 faim_mutex_unlock(&conn->active); |
2 | 94 |
237 | 95 newrx->conn = conn; |
2 | 96 |
237 | 97 newrx->next = NULL; /* this will always be at the bottom */ |
98 newrx->lock = 0; /* unlock */ | |
2 | 99 |
100 /* enqueue this packet */ | |
237 | 101 if (sess->queue_incoming == NULL) { |
102 sess->queue_incoming = newrx; | |
103 } else { | |
104 struct command_rx_struct *cur; | |
105 | |
106 /* | |
107 * This append operation takes a while. It might be faster | |
108 * if we maintain a pointer to the last entry in the queue | |
109 * and just update that. Need to determine if the overhead | |
110 * to maintain that is lower than the overhead for this loop. | |
111 */ | |
112 for (cur = sess->queue_incoming; cur->next; cur = cur->next) | |
113 ; | |
114 cur->next = newrx; | |
115 } | |
116 | |
117 newrx->conn->lastactivity = time(NULL); | |
2 | 118 |
119 return 0; | |
120 } | |
121 | |
122 /* | |
237 | 123 * Purge recieve queue of all handled commands (->handled==1). Also |
124 * allows for selective freeing using ->nofree so that the client can | |
125 * keep the data for various purposes. | |
126 * | |
127 * If ->nofree is nonzero, the frame will be delinked from the global list, | |
128 * but will not be free'ed. The client _must_ keep a pointer to the | |
129 * data -- libfaim will not! If the client marks ->nofree but | |
130 * does not keep a pointer, it's lost forever. | |
131 * | |
2 | 132 */ |
237 | 133 void aim_purge_rxqueue(struct aim_session_t *sess) |
2 | 134 { |
237 | 135 struct command_rx_struct *cur = NULL; |
136 struct command_rx_struct *tmp; | |
2 | 137 |
237 | 138 if (sess->queue_incoming == NULL) |
139 return; | |
140 | |
141 if (sess->queue_incoming->next == NULL) { | |
142 if (sess->queue_incoming->handled) { | |
143 tmp = sess->queue_incoming; | |
144 sess->queue_incoming = NULL; | |
145 | |
146 if (!tmp->nofree) { | |
147 free(tmp->data); | |
148 free(tmp); | |
149 } else | |
150 tmp->next = NULL; | |
2 | 151 } |
237 | 152 return; |
153 } | |
2 | 154 |
237 | 155 for(cur = sess->queue_incoming; cur->next != NULL; ) { |
156 if (cur->next->handled) { | |
157 tmp = cur->next; | |
158 cur->next = tmp->next; | |
159 if (!tmp->nofree) { | |
160 free(tmp->data); | |
161 free(tmp); | |
162 } else | |
163 tmp->next = NULL; | |
164 } | |
165 cur = cur->next; | |
2 | 166 |
237 | 167 /* |
168 * Be careful here. Because of the way we just | |
169 * manipulated the pointer, cur may be NULL and | |
170 * the for() will segfault doing the check unless | |
171 * we find this case first. | |
172 */ | |
173 if (cur == NULL) | |
174 break; | |
175 } | |
176 | |
177 return; | |
2 | 178 } |