Mercurial > pidgin.yaz
annotate libfaim/aim_ft.c @ 807:632d781c29da
[gaim-migrate @ 817]
ha!
actually, this shouldn't do anything. i just think it's fun to print the same message over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over and over
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Thu, 31 Aug 2000 02:12:58 +0000 |
parents | a79bbed31f7e |
children | 595ac7759563 |
rev | line source |
---|---|
503 | 1 #include <faim/aim.h> |
2 | |
3 #include <sys/utsname.h> /* for aim_directim_initiate */ | |
4 #include <arpa/inet.h> /* for inet_ntoa */ | |
5 | |
640
2c0a7d245bd2
[gaim-migrate @ 650]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
503
diff
changeset
|
6 #include "config.h" |
2c0a7d245bd2
[gaim-migrate @ 650]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
503
diff
changeset
|
7 |
503 | 8 /* aim_msgcookies.c is mostly new. just look at the diff and replace yours, easiest. */ |
9 | |
10 /* | |
11 function name where i had it | |
12 aim_send_im_direct aim_im.c | |
13 aim_directim_initiate aim_im.c | |
14 aim_filetransfer_accept aim_im.c | |
15 aim_getlisting aim_misc.c (?!) -- prototype function. can be ignored. | |
16 establish aim_misc.c | |
17 aim_get_command_rendezvous aim_rxqueue.c | |
18 oft_getfh aim_rxqueue.c | |
19 */ | |
20 | |
21 int aim_handlerendconnect(struct aim_session_t *sess, struct aim_conn_t *cur) | |
22 { | |
23 int acceptfd = 0; | |
24 rxcallback_t userfunc; | |
25 struct sockaddr cliaddr; | |
26 socklen_t clilen = sizeof(cliaddr); | |
27 int ret = 0; | |
28 | |
29 /* | |
30 * Listener sockets only have incoming connections. No data. | |
31 */ | |
32 if( (acceptfd = accept(cur->fd, &cliaddr, &clilen)) == -1) | |
33 return -1; | |
34 | |
35 if (cliaddr.sa_family != AF_INET) /* just in case IPv6 really is happening */ | |
36 return -1; | |
37 | |
38 switch(cur->subtype) { | |
39 case AIM_CONN_SUBTYPE_OFT_DIRECTIM: { | |
40 struct aim_directim_priv *priv; | |
41 | |
42 priv = (struct aim_directim_priv *)calloc(1, sizeof(struct aim_directim_priv)); | |
43 | |
44 snprintf(priv->ip, sizeof(priv->ip), "%s:%u", inet_ntoa(((struct sockaddr_in *)&cliaddr)->sin_addr), ntohs(((struct sockaddr_in *)&cliaddr)->sin_port)); | |
45 | |
46 if(!cur->priv) | |
47 cur->priv = priv; /* what happens if there is one?! -- mid */ | |
48 | |
49 cur->type = AIM_CONN_TYPE_RENDEZVOUS; | |
50 close(cur->fd); /* should we really do this? seems like the client should decide. maybe clone the connection and keep the listener open. -- mid */ | |
51 cur->fd = acceptfd; | |
52 | |
53 if ( (userfunc = aim_callhandler(cur, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE))) | |
54 ret = userfunc(sess, NULL, cur); | |
55 | |
56 break; | |
57 } | |
58 case AIM_CONN_SUBTYPE_OFT_GETFILE: { | |
59 struct aim_filetransfer_priv *priv; | |
60 | |
61 priv->state = 0; | |
62 | |
63 priv = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)); | |
64 | |
65 snprintf(priv->ip, sizeof(priv->ip), "%s:%u", inet_ntoa(((struct sockaddr_in *)&cliaddr)->sin_addr), ntohs(((struct sockaddr_in *)&cliaddr)->sin_port)); | |
66 | |
67 if(!cur->priv) | |
68 cur->priv = priv; | |
69 | |
70 if ( (userfunc = aim_callhandler(cur, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEINITIATE))) | |
71 ret = userfunc(sess, NULL, cur); | |
72 break; | |
73 } | |
74 default: { | |
75 /* XXX */ | |
76 } | |
77 } | |
78 return ret; | |
79 } | |
80 | |
81 | |
82 /* | |
83 * aim_send_im_direct: | |
84 * sess - session | |
85 * conn - directim connection | |
86 * msg - null-terminated string to send | |
87 */ | |
88 | |
89 int aim_send_im_direct(struct aim_session_t *sess, | |
90 struct aim_conn_t *conn, | |
91 char *msg) | |
92 { | |
93 struct command_tx_struct *newpacket , *newpacket2; | |
94 | |
95 /* newpacket contains a real header with data, newpacket2 is just a | |
96 null packet, with a cookie and a lot of 0x00s. newpacket is the | |
97 "i'm sending", newpacket2 is the "i'm typing".*/ | |
98 | |
99 /* uhm. the client should send those as two seperate things -- mid */ | |
100 | |
101 struct aim_directim_priv *priv = NULL; | |
102 int i; | |
103 | |
104 if (strlen(msg) >= MAXMSGLEN) | |
105 return -1; | |
106 | |
107 if (!sess || !conn || !(conn->type) || (conn->type != AIM_CONN_TYPE_RENDEZVOUS) || !conn->priv) { | |
108 printf("faim: directim: invalid arguments\n"); | |
109 return -1; | |
110 }; | |
111 | |
112 priv = (struct aim_directim_priv *)conn->priv; | |
113 | |
114 /* NULLish Header */ | |
115 | |
116 if (!(newpacket2 = aim_tx_new(AIM_FRAMETYPE_OFT, 0x0001, conn, 0))) { | |
117 printf("faim: directim: tx_new2 failed\n"); | |
118 return -1; | |
119 } | |
120 | |
121 newpacket2->lock = 1; /* lock struct */ | |
122 | |
123 memcpy(newpacket2->hdr.oft.magic, "ODC2", 4); | |
124 newpacket2->hdr.oft.hdr2len = 0x44; | |
125 | |
126 if (!(newpacket2->hdr.oft.hdr2 = calloc(1,newpacket2->hdr.oft.hdr2len))) { | |
127 free(newpacket2); | |
128 return -1; | |
129 } | |
130 | |
131 i = 0; | |
132 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0006); | |
133 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
134 | |
135 i += aimutil_putstr(newpacket2->hdr.oft.hdr2+i, priv->cookie, 8); | |
136 | |
137 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
138 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
139 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
140 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
141 | |
142 i += aimutil_put32(newpacket2->hdr.oft.hdr2+i, 0x00000000); | |
143 | |
144 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
145 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
146 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
147 | |
148 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x000e); | |
149 | |
150 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
151 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
152 | |
153 i += aimutil_putstr(newpacket2->hdr.oft.hdr2+i, sess->logininfo.screen_name, strlen(sess->logininfo.screen_name)); | |
154 | |
155 i = 52; /* 0x34 */ | |
156 i += aimutil_put8(newpacket2->hdr.oft.hdr2+i, 0x00); /* 53 */ | |
157 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); /* 55 */ | |
158 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
159 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
160 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000);/* 61 */ | |
161 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000); | |
162 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000);/* 65 */ | |
163 i += aimutil_put16(newpacket2->hdr.oft.hdr2+i, 0x0000);/* end of hdr2 */ | |
164 | |
165 newpacket2->lock = 0; | |
166 newpacket2->data = NULL; | |
167 | |
168 aim_tx_enqueue(sess, newpacket2); | |
169 | |
170 /* Header packet */ | |
171 | |
172 if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OFT, 0x0001, conn, strlen(msg)))) { | |
173 printf("faim: directim: tx_new failed\n"); | |
174 return -1; | |
175 } | |
176 | |
177 newpacket->lock = 1; /* lock struct */ | |
178 | |
179 memcpy(newpacket->hdr.oft.magic, "ODC2", 4); | |
180 newpacket->hdr.oft.hdr2len = 0x54; | |
181 | |
182 if (!(newpacket->hdr.oft.hdr2 = calloc(1,newpacket->hdr.oft.hdr2len))) { | |
183 free(newpacket); | |
184 return -1; | |
185 } | |
186 | |
187 i = 0; | |
188 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0006); | |
189 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
190 | |
191 i += aimutil_putstr(newpacket->hdr.oft.hdr2+i, priv->cookie, 8); | |
192 | |
193 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
194 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
195 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
196 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
197 | |
198 i += aimutil_put32(newpacket->hdr.oft.hdr2+i, strlen(msg)); | |
199 | |
200 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
201 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
202 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
203 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
204 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
205 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
206 | |
207 i += aimutil_putstr(newpacket->hdr.oft.hdr2+i, sess->logininfo.screen_name, strlen(sess->logininfo.screen_name)); | |
208 | |
209 i = 52; /* 0x34 */ | |
210 i += aimutil_put8(newpacket->hdr.oft.hdr2+i, 0x00); /* 53 */ | |
211 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); /* 55 */ | |
212 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
213 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
214 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);/* 61 */ | |
215 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000); | |
216 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);/* 65 */ | |
217 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);/* end of hdr2 */ | |
218 | |
219 /* values grabbed from a dump */ | |
220 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0008); /* 69 */ | |
221 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x000c); | |
222 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0000);/* 71 */ | |
223 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x1466);/* 73 */ | |
224 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x0001);/* 73 */ | |
225 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x2e0f); | |
226 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0x393e); | |
227 i += aimutil_put16(newpacket->hdr.oft.hdr2+i, 0xcac8); | |
228 | |
229 memcpy(newpacket->data, msg, strlen(msg)); | |
230 | |
231 newpacket->lock = 0; | |
232 | |
233 aim_tx_enqueue(sess, newpacket); | |
234 | |
235 return 0; | |
236 } | |
237 | |
238 /* | |
239 * aim_directim_intitiate: | |
240 * For those times when we want to open up the directim channel ourselves. | |
241 * sess is your session, | |
242 * conn is the BOS conn, | |
243 * priv is a dummy priv value (we'll let it get filled in later) (if | |
244 * you pass a NULL, we alloc one) | |
245 * destsn is the SN to connect to. | |
246 */ | |
247 | |
248 | |
249 struct aim_conn_t *aim_directim_initiate(struct aim_session_t *sess, | |
250 struct aim_conn_t *conn, | |
251 struct aim_directim_priv *priv, | |
252 char *destsn) | |
253 { | |
254 struct command_tx_struct *newpacket; | |
255 struct aim_conn_t *newconn; | |
256 | |
257 struct aim_msgcookie_t *cookie; | |
258 | |
259 int curbyte, i, listenfd; | |
260 short port = 4443; | |
261 | |
262 struct hostent *hptr; | |
263 struct utsname myname; | |
264 | |
265 char cap[16]; | |
266 char d[4]; /* XXX: IPv6. *cough* */ | |
267 | |
268 /* | |
269 * Open our socket | |
270 */ | |
271 | |
272 if( (listenfd = aim_listenestablish(port)) == -1) | |
273 return NULL; | |
274 | |
275 /* | |
276 * get our local IP | |
277 */ | |
278 | |
279 if(uname(&myname) < 0) | |
280 return NULL; | |
281 | |
282 if( (hptr = gethostbyname(myname.nodename)) == NULL) | |
283 return NULL; | |
284 | |
285 memcpy(&d, hptr->h_addr_list[0], 4); /* XXX: this probably isn't quite kosher, but it works */ | |
286 | |
287 aim_putcap(cap, 16, AIM_CAPS_IMIMAGE); | |
288 | |
289 /* | |
290 * create the OSCAR packet | |
291 */ | |
292 | |
293 if (!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+8+2+1+strlen(destsn)+4+4+0x32))) | |
294 return NULL; | |
295 | |
296 newpacket->lock = 1; /* lock struct */ | |
297 | |
298 curbyte = 0; | |
299 curbyte += aim_putsnac(newpacket->data+curbyte, | |
300 0x0004, 0x0006, 0x0000, sess->snac_nextid); | |
301 | |
302 /* | |
303 * Generate a random message cookie | |
304 * This cookie needs to be alphanumeric and NULL-terminated to be TOC-compatible. | |
305 */ | |
306 for (i=0;i<7;i++) | |
307 curbyte += aimutil_put8(newpacket->data+curbyte, 0x30 + ((u_char) random() % 20)); | |
308 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); | |
309 | |
310 /* | |
311 * grab all the data for cookie caching. | |
312 */ | |
313 cookie = (struct aim_msgcookie_t *)calloc(1, sizeof(struct aim_msgcookie_t)); | |
314 | |
315 memcpy(cookie->cookie, newpacket->data+curbyte-8, 8); | |
316 cookie->type = AIM_COOKIETYPE_OFTIM; | |
317 | |
318 if(!priv) | |
319 priv = (struct aim_directim_priv *)calloc(1, sizeof(struct aim_directim_priv)); | |
320 | |
321 memcpy(priv->cookie, cookie, 8); | |
322 memcpy(priv->sn, destsn, sizeof(priv->sn)); | |
323 | |
324 cookie->data = priv; | |
325 | |
326 aim_cachecookie(sess, cookie); /* cache da cookie */ | |
327 | |
328 /* | |
329 * Channel ID | |
330 */ | |
331 curbyte += aimutil_put16(newpacket->data+curbyte,0x0002); | |
332 | |
333 /* | |
334 * Destination SN (prepended with byte length) | |
335 */ | |
336 curbyte += aimutil_put8(newpacket->data+curbyte,strlen(destsn)); | |
337 curbyte += aimutil_putstr(newpacket->data+curbyte, destsn, strlen(destsn)); | |
338 | |
339 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); | |
340 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); | |
341 | |
342 /* | |
343 * enTLV start | |
344 */ | |
345 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); | |
346 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0032); | |
347 | |
348 /* | |
349 * Flag data / ICBM Parameters? | |
350 */ | |
351 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); | |
352 curbyte += aimutil_put8(newpacket->data+curbyte, 0x00); | |
353 | |
354 /* | |
355 * Cookie | |
356 */ | |
357 curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cookie, 8); | |
358 | |
359 /* | |
360 * Capability String | |
361 */ | |
362 curbyte += aimutil_putstr(newpacket->data+curbyte, (char *)cap, 0x10); | |
363 | |
364 /* | |
365 * 000a/0002 : 0001 | |
366 */ | |
367 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000a); | |
368 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); | |
369 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0001); | |
370 | |
371 /* | |
372 * 0003/0004: IP address | |
373 */ | |
374 | |
375 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0003); | |
376 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0004); | |
377 | |
378 for(i = 0; i < 4; i++) | |
379 curbyte += aimutil_put8(newpacket->data+curbyte, d[i]); /* already in network byte order */ | |
380 | |
381 /* | |
382 * 0005/0002: Port | |
383 */ | |
384 | |
385 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); | |
386 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); | |
387 curbyte += aimutil_put16(newpacket->data+curbyte, port); | |
388 | |
389 /* | |
390 * 000f/0000: umm.. dunno. Zigamorph[1]? | |
391 * [1]: see esr's TNHD. | |
392 */ | |
393 | |
394 curbyte += aimutil_put16(newpacket->data+curbyte, 0x000f); | |
395 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0000); | |
396 | |
397 printf("curbyte: 0x%x\n",curbyte); | |
398 | |
399 newpacket->commandlen = curbyte; | |
400 newpacket->lock = 0; | |
401 | |
402 aim_tx_enqueue(sess, newpacket); | |
403 | |
404 /* | |
405 * allocate and set up our connection | |
406 */ | |
407 | |
408 i = fcntl(listenfd, F_GETFL, 0); | |
409 fcntl(listenfd, F_SETFL, i | O_NONBLOCK); | |
410 | |
411 newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS_OUT, NULL); | |
412 if (!newconn) { | |
413 perror("aim_newconn"); | |
414 aim_conn_kill(sess, &newconn); | |
415 return NULL; | |
416 } | |
417 | |
418 newconn->fd = listenfd; | |
419 newconn->subtype = AIM_CONN_SUBTYPE_OFT_DIRECTIM; | |
420 newconn->priv = priv; | |
421 printf("faim: listening (fd = %d, unconnected)\n", newconn->fd); | |
422 | |
423 /* | |
424 * XXX We need some way of closing the listener socket after | |
425 * n seconds of no connection. -- mid | |
426 */ | |
427 | |
428 #ifdef USE_SNAC_FOR_IMS | |
429 { | |
430 struct aim_snac_t snac; | |
431 | |
432 snac.id = sess->snac_nextid; | |
433 snac.family = 0x0004; | |
434 snac.type = 0x0006; | |
435 snac.flags = 0x0000; | |
436 | |
437 snac.data = malloc(strlen(destsn)+1); | |
438 memcpy(snac.data, destsn, strlen(destsn)+1); | |
439 | |
440 aim_newsnac(sess, &snac); | |
441 | |
442 aim_cleansnacs(sess, 60); /* clean out all SNACs over 60sec old */ | |
443 } | |
444 #endif | |
445 | |
446 return (newconn); | |
447 } | |
448 | |
449 | |
450 struct aim_conn_t *aim_directim_connect(struct aim_session_t *sess, | |
451 struct aim_conn_t *conn, | |
452 struct aim_directim_priv *priv ) | |
453 { | |
454 struct aim_conn_t *newconn = NULL;; | |
455 | |
456 newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, priv->ip); | |
457 if (!newconn || (newconn->fd == -1)) { | |
458 printf("could not connect to %s\n", priv->ip); | |
459 perror("aim_newconn"); | |
460 aim_conn_kill(sess, &newconn); | |
461 return NULL; | |
462 } else { | |
463 newconn->subtype = AIM_CONN_SUBTYPE_OFT_DIRECTIM; | |
464 newconn->priv = priv; | |
465 printf("faim: connected to peer (fd = %d)\n", newconn->fd); | |
466 return newconn; | |
467 } | |
468 return newconn; | |
469 } | |
470 | |
471 u_long aim_accepttransfer(struct aim_session_t *sess, | |
472 struct aim_conn_t *conn, | |
473 struct aim_conn_t *oftconn, | |
474 char *sn, | |
475 char *cookie, | |
476 unsigned short rendid) | |
477 { | |
478 struct command_tx_struct *newpacket, *newoft; | |
479 struct aim_fileheader_t *listingfh; | |
480 int curbyte, i; | |
481 /* now for the oft bits */ | |
482 | |
483 if(rendid == AIM_CAPS_GETFILE) { | |
484 printf("jbm: getfile request accept\n"); | |
485 if(!(newoft = aim_tx_new(AIM_FRAMETYPE_OFT, 0x1108, oftconn, 0))) { | |
486 printf("faim: accept_transfer: tx_new OFT failed\n"); | |
487 return -1; | |
488 } | |
489 | |
490 newoft->lock = 1; | |
491 | |
492 memcpy(newoft->hdr.oft.magic, "OFT2", 4); | |
493 newoft->hdr.oft.hdr2len = 0xf8; /* 0x100 - 8 */ | |
494 | |
495 if (!(newoft->hdr.oft.hdr2 = calloc(1,newoft->hdr.oft.hdr2len))) { | |
496 free(newoft); | |
497 return -1; | |
498 } | |
499 | |
500 listingfh = aim_getlisting(sess); | |
501 | |
502 memcpy(listingfh->bcookie, cookie, 8); | |
503 | |
504 curbyte = 0; | |
505 | |
506 for(i = 0; i < 8; i++) | |
507 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, cookie[i]); | |
508 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->encrypt); | |
509 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->compress); | |
510 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->totfiles); | |
511 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->filesleft); | |
512 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->totparts); | |
513 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->partsleft); | |
514 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->totsize); | |
515 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->size); | |
516 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->modtime); | |
517 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->checksum); | |
518 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->rfrcsum); | |
519 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->rfsize); | |
520 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->cretime); | |
521 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->rfcsum); | |
522 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->nrecvd); | |
523 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->recvcsum); | |
524 | |
525 memcpy(newoft->hdr.oft.hdr2+curbyte, listingfh->idstring, 32); | |
526 curbyte += 32; | |
527 | |
528 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, listingfh->flags); | |
529 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, listingfh->lnameoffset); | |
530 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, listingfh->lsizeoffset); | |
531 | |
532 memcpy(newoft->hdr.oft.hdr2+curbyte, listingfh->dummy, 69); | |
533 curbyte += 69; | |
534 | |
535 memcpy(newoft->hdr.oft.hdr2+curbyte, listingfh->macfileinfo, 16); | |
536 curbyte += 16; | |
537 | |
538 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->nencode); | |
539 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->nlanguage); | |
540 | |
541 memcpy(newoft->hdr.oft.hdr2+curbyte, listingfh->name, 64); | |
542 curbyte += 64; | |
543 | |
544 free(listingfh); | |
545 | |
546 newoft->lock = 0; | |
547 aim_tx_enqueue(sess, newoft); | |
548 printf("faim: getfile: OFT listing enqueued.\n"); | |
549 | |
550 } | |
551 | |
552 | |
553 if(!(newpacket = aim_tx_new(AIM_FRAMETYPE_OSCAR, 0x0002, conn, 10+8+2+1+strlen(sn)+4+2+8+16))) | |
554 return -1; | |
555 | |
556 newpacket->lock = 1; | |
557 | |
558 curbyte = aim_putsnac(newpacket->data, 0x0004, 0x0006, 0x0000, sess->snac_nextid); | |
559 for (i = 0; i < 8; i++) | |
560 curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); | |
561 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002); | |
562 curbyte += aimutil_put8(newpacket->data+curbyte, strlen(sn)); | |
563 curbyte += aimutil_putstr(newpacket->data+curbyte, sn, strlen(sn)); | |
564 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0005); | |
565 curbyte += aimutil_put16(newpacket->data+curbyte, 0x001a); | |
566 curbyte += aimutil_put16(newpacket->data+curbyte, 0x0002 /* accept */); | |
567 for (i = 0; i < 8; i++) | |
568 curbyte += aimutil_put8(newpacket->data+curbyte, cookie[i]); | |
569 curbyte += aim_putcap(newpacket->data+curbyte, 0x10, rendid); | |
570 | |
571 newpacket->lock = 0; | |
572 aim_tx_enqueue(sess, newpacket); | |
573 | |
574 | |
575 | |
576 return (sess->snac_nextid++); | |
577 } | |
578 | |
579 /* | |
580 * aim_getlisting() | |
581 * | |
582 * Get file listing.txt info. where else to put it? i | |
583 * dunno. client-side issue for sure tho. for now we just side-step | |
584 * the issue with a nice default. =) | |
585 * | |
586 */ | |
587 | |
588 struct aim_fileheader_t *aim_getlisting(struct aim_session_t *sess) | |
589 { | |
590 struct aim_fileheader_t *fh; | |
591 | |
592 if(!(fh = (struct aim_fileheader_t*)calloc(1, sizeof(struct aim_fileheader_t)))) | |
593 return NULL; | |
594 | |
595 fh->encrypt = 0x0000; | |
596 fh->compress = 0x0000; | |
597 fh->totfiles = 0x0001; | |
598 fh->filesleft = 0x0001; | |
599 fh->totparts = 0x0001; | |
600 fh->partsleft = 0x0001; | |
601 fh->totsize = 0x00000064; | |
602 fh->size = 0x00000024; /* ls -l listing.txt */ | |
603 fh->modtime = (int)time(NULL); /*0x39441fb4; */ | |
604 fh->checksum = 0xb8350000; | |
605 fh->rfcsum = 0x00000000; | |
606 fh->rfsize = 0x00000000; | |
607 fh->cretime = 0x00000000; | |
608 fh->rfcsum = 0x00000000; | |
609 fh->nrecvd = 0x00000000; | |
610 fh->recvcsum = 0x00000000; | |
611 | |
612 memset(fh->idstring, 0, 32/*sizeof(fh->idstring)*/); | |
613 memcpy(fh->idstring, "OFT_Windows ICBMFT V1.1 32", 32/*sizeof(fh->idstring)*/); | |
614 memset(fh->idstring+strlen(fh->idstring), 0, 32-strlen(fh->idstring)); /* jbm hack */ | |
615 | |
616 fh->flags = 0x02; | |
617 fh->lnameoffset = 0x1a; | |
618 fh->lsizeoffset = 0x10; | |
619 | |
620 memset(fh->dummy, 0, 69/*sizeof(fh->dummy)*/); | |
621 /* fh->dummy = ;*/ | |
622 | |
623 memset(fh->macfileinfo, 0, 16/*sizeof(fh->macfileinfo)*/); | |
624 /* fh->macfileinfo = ; */ | |
625 | |
626 fh->nencode = 0x0000; | |
627 fh->nlanguage = 0x0000; | |
628 | |
629 memset(fh->name, 0, 64/*sizeof(fh->name)*/); | |
630 memcpy(fh->name, "listing.txt", 64 /*sizeof(fh->name)*/); | |
631 memset(fh->name+strlen(fh->name), 0, 64-strlen(fh->name)); /* jbm hack */ | |
632 | |
633 printf("jbm: fh name %s / %s\n", fh->name, (fh->name+(strlen(fh->name)))); | |
634 return fh; | |
635 } | |
636 | |
637 /* | |
638 * establish: create a listening socket on a port. you need to call | |
639 * accept() when it's connected. | |
640 * portnum is the port number to bind to. | |
641 * returns your fd | |
642 */ | |
643 | |
644 int aim_listenestablish(u_short portnum) | |
645 { | |
640
2c0a7d245bd2
[gaim-migrate @ 650]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
503
diff
changeset
|
646 #if HAVE_GETADDRINFO |
503 | 647 int listenfd; |
648 const int on = 1; | |
649 struct addrinfo hints, *res, *ressave; | |
650 char serv[5]; | |
651 sprintf(serv, "%d", portnum); | |
652 memset(&hints, 0, sizeof(struct addrinfo)); | |
653 hints.ai_flags = AI_PASSIVE; | |
654 hints.ai_family = AF_UNSPEC; | |
655 hints.ai_socktype = SOCK_STREAM; | |
656 if (getaddrinfo(NULL/*any IP*/, serv, &hints, &res) != 0) { | |
657 perror("getaddrinfo"); | |
658 return -1; | |
659 } | |
660 ressave = res; | |
661 do { | |
662 listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | |
663 if (listenfd < 0) | |
664 continue; | |
665 setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); | |
666 if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0) | |
667 break; /* success */ | |
668 close(listenfd); | |
669 } while ( (res = res->ai_next) ); | |
670 if (!res) | |
671 return -1; | |
672 if (listen(listenfd, 1024)!=0) { | |
673 perror("listen"); | |
674 return -1; | |
675 } | |
676 freeaddrinfo(ressave); | |
677 return listenfd; | |
640
2c0a7d245bd2
[gaim-migrate @ 650]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
503
diff
changeset
|
678 #else |
2c0a7d245bd2
[gaim-migrate @ 650]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
503
diff
changeset
|
679 return -1; |
2c0a7d245bd2
[gaim-migrate @ 650]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
503
diff
changeset
|
680 #endif |
503 | 681 } |
682 | |
683 int aim_get_command_rendezvous(struct aim_session_t *sess, struct aim_conn_t *conn) | |
684 { | |
685 | |
686 /* XXX: NOT THREAD SAFE RIGHT NOW. the locks are acting up. deal. -- jbm */ | |
687 | |
688 unsigned char hdrbuf1[6]; | |
689 unsigned char *hdr = NULL; | |
690 int hdrlen, hdrtype; | |
691 int flags = 0; | |
692 rxcallback_t userfunc = NULL; | |
693 | |
694 | |
695 memset(hdrbuf1, 0, sizeof(hdrbuf1)); | |
696 | |
697 faim_mutex_lock(&conn->active); /* gets locked down for the entirety */ | |
698 | |
699 if ( (hdrlen = read(conn->fd, hdrbuf1, 6)) < 6) { | |
700 if(hdrlen < 0) | |
701 perror("read"); | |
702 printf("faim: rend: read error (fd: %i) %02x%02x%02x%02x%02x%02x (%i)\n", conn->fd, hdrbuf1[0],hdrbuf1[1],hdrbuf1[0],hdrbuf1[0],hdrbuf1[0],hdrbuf1[0],hdrlen); | |
703 faim_mutex_unlock(&conn->active); | |
704 aim_conn_close(conn); | |
705 return -1; | |
706 } | |
707 | |
708 hdrlen = aimutil_get16(hdrbuf1+4); | |
709 | |
710 hdrlen -= 6; | |
711 if (!(hdr = malloc(hdrlen))) | |
712 return -1; | |
713 | |
714 if (read(conn->fd, hdr, hdrlen) < hdrlen) { | |
715 perror("read"); | |
716 printf("faim: rend: read2 error\n"); | |
717 free(hdr); | |
718 faim_mutex_unlock(&conn->active); | |
719 aim_conn_close(conn); | |
720 return 0; /* see comment on previous read check */ | |
721 } | |
722 | |
723 hdrtype = aimutil_get16(hdr); | |
724 | |
725 switch (hdrtype) { | |
726 case 0x0001: { /* directim */ | |
727 int payloadlength = 0; | |
728 char *snptr = NULL; | |
729 struct aim_directim_priv *priv; | |
730 int i; | |
731 | |
732 priv = (struct aim_directim_priv *)calloc(1, sizeof(struct aim_directim_priv)); | |
733 | |
734 payloadlength = aimutil_get32(hdr+22); | |
735 flags = aimutil_get16(hdr+32); | |
736 snptr = hdr+38; | |
737 | |
738 strncpy(priv->sn, snptr, MAXSNLEN); | |
739 | |
740 #if 0 | |
741 printf("faim: OFT frame: %04x / %04x / %04x / %s\n", hdrtype, payloadlength, flags, snptr); | |
742 #endif | |
743 | |
744 if (flags == 0x000e) { | |
745 faim_mutex_unlock(&conn->active); | |
746 if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)) ) | |
747 return userfunc(sess, NULL, snptr); | |
748 } else if ((flags == 0x0000) && payloadlength) { | |
749 unsigned char *msg; | |
750 | |
751 if(! (msg = calloc(1, payloadlength+1)) ) { | |
752 faim_mutex_unlock(&conn->active); | |
753 return 0; | |
754 } | |
755 | |
756 if (recv(conn->fd, msg, payloadlength, MSG_WAITALL) < payloadlength) { | |
757 perror("read"); | |
758 printf("faim: rend: read3 error\n"); | |
759 free(msg); | |
760 faim_mutex_unlock(&conn->active); | |
761 aim_conn_close(conn); | |
762 return -1; | |
763 } | |
764 faim_mutex_unlock(&conn->active); | |
765 msg[payloadlength] = '\0'; | |
766 #if 0 | |
767 printf("faim: directim: %s/%04x/%04x/%s\n", snptr, payloadlength, flags, msg); | |
768 #endif | |
769 | |
770 if ( (userfunc = aim_callhandler(conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)) ) | |
771 i = userfunc(sess, NULL, conn, snptr, msg); | |
772 | |
773 free(msg); | |
774 return i; | |
775 } | |
776 break; | |
777 } | |
778 case 0x1209: { /* get file first */ | |
779 struct aim_filetransfer_priv *ft; | |
780 struct aim_fileheader_t *fh; | |
781 struct aim_msgcookie_t *cook; | |
782 | |
783 int commandlen; | |
784 char *data; | |
785 | |
786 printf("faim: rend: fileget 0x1209\n"); | |
787 | |
788 if(hdrlen != 0x100) | |
789 printf("faim: fileget_command(1209): um. hdrlen != 0x100.. 0x%x\n", hdrlen); | |
790 | |
791 if(!(ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)))) { | |
792 printf("faim: couldn't malloc ft. um. bad. bad bad. file transfer will likely fail, sorry.\n"); | |
793 faim_mutex_unlock(&conn->active); | |
794 return 0; | |
795 } | |
796 | |
797 fh = aim_oft_getfh(hdr); | |
798 | |
799 memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); | |
800 | |
801 cook = aim_checkcookie(sess, ft->fh.bcookie, AIM_COOKIETYPE_OFTGET); | |
802 | |
803 if(cook->data) | |
804 free(cook->data); /* XXX */ | |
805 | |
806 cook->data = ft; | |
807 | |
808 aim_cachecookie(sess, cook); | |
809 | |
810 commandlen = 36; | |
811 | |
812 data = calloc(1, commandlen); | |
813 memcpy(data, "01/01/1999 00:00 100 file.txt\r\n", commandlen); | |
814 | |
815 if (write(conn->fd, data, commandlen) != commandlen) { | |
816 perror("listing write error"); | |
817 } | |
818 faim_mutex_unlock(&conn->active); | |
819 | |
820 printf("jbm: hit end of 1209\n"); | |
821 | |
822 break; | |
823 } | |
824 case 0x120b: { /* get file second */ | |
825 struct aim_filetransfer_priv *ft; | |
826 struct aim_msgcookie_t *cook; | |
827 | |
828 struct aim_fileheader_t *fh; | |
829 | |
830 printf("faim: rend: fileget 120b\n"); | |
831 | |
832 if(!(ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)))) { | |
833 printf("faim: couldn't malloc ft. um. bad. bad bad. file transfer will likely fail, sorry.\n"); | |
834 faim_mutex_unlock(&conn->active); | |
835 return 0; | |
836 } | |
837 | |
838 if(hdrlen != 0x100) | |
839 printf("faim: fileget_command(120b): um. hdrlen != 0x100..\n"); | |
840 | |
841 fh = aim_oft_getfh(hdr); | |
842 | |
843 memcpy(&(ft->fh), fh, sizeof(struct aim_fileheader_t)); | |
844 | |
845 cook = aim_checkcookie(sess, ft->fh.bcookie, AIM_COOKIETYPE_OFTGET); | |
846 | |
847 if(cook->data) | |
848 free(cook->data); /* XXX: integrate cookie caching */ | |
849 | |
850 cook->data = ft; | |
851 | |
852 aim_cachecookie(sess, cook); | |
853 | |
854 faim_mutex_unlock(&conn->active); | |
855 | |
856 break; | |
857 } | |
858 case 0x120c: { /* yet more get file */ | |
859 struct aim_filetransfer_priv *ft; | |
860 struct aim_msgcookie_t *cook; | |
861 struct aim_fileheader_t *listingfh; | |
862 struct command_tx_struct *newoft; | |
863 int curbyte, i; | |
864 | |
865 printf("faim: rend: fileget 120c\n"); | |
866 | |
867 if(!(ft = (struct aim_filetransfer_priv *)calloc(1, sizeof(struct aim_filetransfer_priv)))) { | |
868 printf("faim: couldn't malloc ft. um. bad. bad bad. file transfer will likely fail, sorry.\n"); | |
869 faim_mutex_unlock(&conn->active); | |
870 return 0; | |
871 } | |
872 | |
873 if(hdrlen != 0x100) | |
874 printf("faim: fileget_command(120c): um. hdrlen != 0x100..\n"); | |
875 | |
876 listingfh = aim_oft_getfh((char *)hdr); | |
877 | |
878 memcpy(&(ft->fh), listingfh, sizeof(struct aim_fileheader_t)); | |
879 | |
880 cook = aim_checkcookie(sess, ft->fh.bcookie, AIM_COOKIETYPE_OFTGET); | |
881 | |
882 if(cook->data) | |
883 free(cook->data); /* XXX */ | |
884 | |
885 cook->data = ft; | |
886 | |
887 aim_cachecookie(sess, cook); | |
888 | |
889 faim_mutex_unlock(&conn->active); | |
890 | |
891 printf("faim: fileget: %s seems to want %s\n", ft->sn, ft->fh.name); | |
892 | |
893 if(!(newoft = aim_tx_new(AIM_FRAMETYPE_OFT, 0x0101, conn, 0/*listingfh->size*/))) { | |
894 printf("faim: send_final_transfer: tx_new OFT failed\n"); | |
895 return 0; | |
896 } | |
897 | |
898 /* XXX: actually implement Real Handling of all this */ | |
899 | |
900 printf("jbm: listingfh->size: 0x%lx\n", listingfh->size); | |
901 | |
902 newoft->lock = 1; | |
903 | |
904 /* if(!(newoft->data = calloc(1, listingfh->size))) { | |
905 printf("newoft data malloc failed. bombing.\n"); | |
906 return 0; | |
907 }*/ | |
908 | |
909 if(newoft->commandlen > 0) { | |
910 int i; | |
911 bzero(newoft->data, newoft->commandlen); | |
912 for(i = 0; i < newoft->commandlen; i++) | |
913 newoft->data[i] = 0x30 + (i%10); | |
914 | |
915 // memcpy(newoft->data, "This has been a Test\r\n-josh\r\n", newoft->commandlen); | |
916 } | |
917 | |
918 memcpy(newoft->hdr.oft.magic, "OFT2", 4); | |
919 newoft->hdr.oft.hdr2len = 0xf8; /* 0x100 - 8 */ | |
920 | |
921 if (!(newoft->hdr.oft.hdr2 = calloc(1,newoft->hdr.oft.hdr2len))) { | |
922 if(newoft->data) | |
923 free(newoft->data); /* XXX: make this into a destructor function */ | |
924 free(newoft); | |
925 return 0; | |
926 } | |
927 | |
928 memcpy(listingfh->bcookie, ft->fh.bcookie, 8); | |
929 | |
930 curbyte = 0; | |
931 | |
932 for(i = 0; i < 8; i++) | |
933 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, listingfh->bcookie[i]); | |
934 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->encrypt); | |
935 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->compress); | |
936 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->totfiles); | |
937 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->filesleft); | |
938 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->totparts); | |
939 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->partsleft); | |
940 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->totsize); | |
941 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->size); | |
942 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->modtime); | |
943 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->checksum); | |
944 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->rfrcsum); | |
945 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->rfsize); | |
946 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->cretime); | |
947 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, listingfh->rfcsum); | |
948 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, 0 /*listingfh->nrecvd*/); | |
949 curbyte += aimutil_put32(newoft->hdr.oft.hdr2+curbyte, 0/*listingfh->recvcsum*/); | |
950 | |
951 strncpy(newoft->hdr.oft.hdr2+curbyte, listingfh->idstring, 32); | |
952 curbyte += 32; | |
953 | |
954 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, 0x20 /*listingfh->flags */); | |
955 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, listingfh->lnameoffset); | |
956 curbyte += aimutil_put8(newoft->hdr.oft.hdr2+curbyte, listingfh->lsizeoffset); | |
957 | |
958 memcpy(newoft->hdr.oft.hdr2+curbyte, listingfh->dummy, 69); | |
959 curbyte += 69; | |
960 | |
961 memcpy(newoft->hdr.oft.hdr2+curbyte, listingfh->macfileinfo, 16); | |
962 curbyte += 16; | |
963 | |
964 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->nencode); | |
965 curbyte += aimutil_put16(newoft->hdr.oft.hdr2+curbyte, listingfh->nlanguage); | |
966 | |
967 strncpy(newoft->hdr.oft.hdr2+curbyte, listingfh->name, 64); | |
968 curbyte += 64; | |
969 | |
970 free(listingfh); | |
971 | |
972 newoft->lock = 0; | |
973 aim_tx_enqueue(sess, newoft); | |
974 printf("jbm: OFT listing enqueued.\n"); | |
975 | |
976 break; | |
977 } | |
978 case 0x0202: { /* get file: ready to recieve data */ | |
979 char *c; | |
980 int i; | |
981 | |
982 struct aim_fileheader_t *fh; | |
983 fh = aim_oft_getfh((char *)hdr); | |
984 | |
985 c = (char *)calloc(1, fh->size); | |
986 | |
987 printf("looks like we're ready to send data.(oft 0x0202)\n"); | |
988 | |
989 | |
990 | |
991 for(i = 0; i < fh->size; i++) | |
992 c[i] = 0x30 + (i%10); | |
993 | |
994 if ( (i = write(conn->fd, c, fh->size)) != fh->size ) { | |
995 printf("whoopsy, didn't write it all...\n"); | |
996 } | |
997 | |
998 faim_mutex_unlock(&conn->active); | |
999 | |
1000 break; | |
1001 } | |
1002 case 0x0204: { /* get file: finished. close it up */ | |
1003 printf("looks like we're done with a transfer (oft 0x0204)\n"); | |
1004 faim_mutex_unlock(&conn->active); | |
1005 aim_conn_close(conn); | |
1006 break; | |
1007 } | |
1008 default: { | |
1009 printf("OFT frame: type %04x\n", hdrtype); | |
1010 /* data connection may be unreliable here */ | |
1011 faim_mutex_unlock(&conn->active); | |
1012 break; | |
1013 } | |
1014 } /* switch */ | |
1015 | |
1016 free(hdr); | |
1017 | |
1018 return 0; | |
1019 } | |
1020 | |
1021 /* | |
1022 * this currently feeds totally bogus data | |
1023 */ | |
1024 | |
1025 struct aim_fileheader_t *aim_oft_getfh(char *hdr) | |
1026 { | |
1027 struct aim_fileheader_t *fh; | |
1028 int i, j; | |
1029 | |
1030 if(!(fh = calloc(1, sizeof(struct aim_fileheader_t)))) | |
1031 return NULL; | |
1032 | |
1033 /* [0] and [1] are the type. we can ignore those here. */ | |
1034 | |
1035 i = 2; | |
1036 | |
1037 for(j = 0; j < 8; j++, i++) | |
1038 fh->bcookie[j] = hdr[i]; | |
1039 fh->encrypt = aimutil_get16(hdr+i); | |
1040 i += 2; | |
1041 fh->compress = aimutil_get16(hdr+i); | |
1042 i += 2; | |
1043 fh->totfiles = aimutil_get16(hdr+i); | |
1044 i += 2; | |
1045 fh->filesleft = aimutil_get16(hdr+i); | |
1046 i += 2; | |
1047 fh->totparts = aimutil_get16(hdr+i); | |
1048 i += 2; | |
1049 fh->partsleft = aimutil_get16(hdr+i); | |
1050 i += 2; | |
1051 fh->totsize = aimutil_get32(hdr+i); | |
1052 i += 4; | |
1053 fh->size = aimutil_get32(hdr+i); | |
1054 i += 4; | |
1055 fh->modtime = aimutil_get32(hdr+i); | |
1056 i += 4; | |
1057 fh->checksum = aimutil_get32(hdr+i); | |
1058 i += 4; | |
1059 fh->rfrcsum = aimutil_get32(hdr+i); | |
1060 i += 4; | |
1061 fh->rfsize = aimutil_get32(hdr+i); | |
1062 i += 4; | |
1063 fh->cretime = aimutil_get32(hdr+i); | |
1064 i += 4; | |
1065 fh->rfcsum = aimutil_get32(hdr+i); | |
1066 i += 4; | |
1067 fh->nrecvd = aimutil_get32(hdr+i); | |
1068 i += 4; | |
1069 fh->recvcsum = aimutil_get32(hdr+i); | |
1070 i += 4; | |
1071 | |
1072 memcpy(fh->idstring, hdr+i, 32); | |
1073 i += 32; | |
1074 | |
1075 fh->flags = aimutil_get8(hdr+i); | |
1076 i += 1; | |
1077 fh->lnameoffset = aimutil_get8(hdr+i); | |
1078 i += 1; | |
1079 fh->lsizeoffset = aimutil_get8(hdr+i); | |
1080 i += 1; | |
1081 | |
1082 memcpy(fh->dummy, hdr+i, 69); | |
1083 i += 69; | |
1084 | |
1085 memcpy(fh->macfileinfo, hdr+i, 16); | |
1086 i += 16; | |
1087 | |
1088 fh->nencode = aimutil_get16(hdr+i); | |
1089 i += 2; | |
1090 fh->nlanguage = aimutil_get16(hdr+i); | |
1091 i += 2; | |
1092 | |
1093 memcpy(fh->name, hdr+i, 64); | |
1094 i += 64; | |
1095 | |
1096 return fh; | |
1097 } |