]> andersk Git - libfaim.git/blame_incremental - utils/faimtest/faimtest.c
- Sat Mar 24 03:16:32 UTC 2001
[libfaim.git] / utils / faimtest / faimtest.c
... / ...
CommitLineData
1/*
2 * -----------------------------------------------------------
3 * ProtoFAIM: v1.xx.xxplxx
4 * -----------------------------------------------------------
5 *
6 * This is ProtoFAIM v1.xx.xxplxx!!! Its nearly completely
7 * different than that ugly thing called v0. This app is
8 * compatible with the latest version of the libfaim library.
9 * Work is continuing.
10 *
11 * ProtoFAIM should only be used for two things...
12 * 1) Testing the libfaim backend.
13 * 2) For reference on the libfaim API when developing clients.
14 *
15 * Its very ugly. Probably always will be. Nothing is more
16 * ugly than the backend itself, however.
17 *
18 * -----------------------------------------------------------
19 *
20 * I'm releasing this code and all it's associated linkage
21 * under the GNU General Public License. For more information,
22 * please refer to http://www.fsf.org. For any questions,
23 * please contact me at the address below.
24 *
25 * Most everything:
26 * (c) 1998 Adam Fritzler, PST, mid@zigamoprh.net
27 *
28 * The password algorithms
29 * (c) 1998 Brock Wilcox, awwaiid@zigamorph.net
30 *
31 * THERE IS NO CODE FROM AOL'S AIM IN THIS CODE, NOR
32 * WAS THERE ANY DISASSEMBLAGE TO DEFINE PROTOCOL. All
33 * information was gained through painstakingly comparing
34 * TCP dumps while the AIM Java client was running. Nothing
35 * more than that, except for a lot of experimenting.
36 *
37 * -----------------------------------------------------------
38 *
39 */
40
41#include "faimtest.h"
42
43static char *dprintf_ctime(void)
44{
45 static char retbuf[64];
46 struct tm *lt;
47 struct timeval tv;
48 struct timezone tz;
49
50 gettimeofday(&tv, &tz);
51 lt = localtime((time_t *)&tv.tv_sec);
52 strftime(retbuf, 64, "%a %b %e %H:%M:%S %Z %Y", lt);
53 return retbuf;
54}
55
56#define DPRINTF_OUTSTREAM stdout
57#define dprintf(x) { \
58 fprintf(DPRINTF_OUTSTREAM, "%s %s: " x, dprintf_ctime(), "faimtest"); \
59 fflush(DPRINTF_OUTSTREAM); \
60}
61#define dvprintf(x, y...) { \
62 fprintf(DPRINTF_OUTSTREAM, "%s %s: " x, dprintf_ctime(), "faimtest", y); \
63 fflush(DPRINTF_OUTSTREAM); \
64}
65#define dinlineprintf(x) { \
66 fprintf(DPRINTF_OUTSTREAM, x); \
67 fflush(DPRINTF_OUTSTREAM); \
68}
69#define dvinlineprintf(x, y...) { \
70 fprintf(DPRINTF_OUTSTREAM, x, y); \
71 fflush(DPRINTF_OUTSTREAM); \
72}
73#define dperror(x) dvprintf("%s: %s\n", x, strerror(errno));
74
75int faimtest_parse_oncoming(struct aim_session_t *, struct command_rx_struct *, ...);
76int faimtest_parse_offgoing(struct aim_session_t *, struct command_rx_struct *, ...);
77int faimtest_parse_login_phase3d_f(struct aim_session_t *, struct command_rx_struct *, ...);
78int faimtest_parse_authresp(struct aim_session_t *, struct command_rx_struct *, ...);
79int faimtest_parse_incoming_im(struct aim_session_t *, struct command_rx_struct *command, ...);
80int faimtest_parse_userinfo(struct aim_session_t *, struct command_rx_struct *command, ...);
81int faimtest_handleredirect(struct aim_session_t *, struct command_rx_struct *command, ...);
82int faimtest_infochange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
83int faimtest_serverready(struct aim_session_t *, struct command_rx_struct *command, ...);
84int faimtest_hostversions(struct aim_session_t *sess, struct command_rx_struct *command, ...);
85int faimtest_parse_misses(struct aim_session_t *, struct command_rx_struct *command, ...);
86int faimtest_parse_msgack(struct aim_session_t *, struct command_rx_struct *command, ...);
87int faimtest_parse_motd(struct aim_session_t *, struct command_rx_struct *command, ...);
88int faimtest_parse_login(struct aim_session_t *, struct command_rx_struct *command, ...);
89int faimtest_chatnav_info(struct aim_session_t *, struct command_rx_struct *command, ...);
90int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...);
91int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
92int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...);
93int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...);
94int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
95int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
96
97int faimtest_directim_request(struct aim_session_t *sess, struct command_rx_struct *command, ...);
98int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
99int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
100int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...);
101int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
102int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...);
103
104int faimtest_getfile_filereq(struct aim_session_t *sess, struct command_rx_struct *command, ...);
105int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...);
106int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...);
107int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...);
108int faimtest_getfile_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...);
109int faimtest_getfile_listing(struct aim_session_t *sess, struct command_rx_struct *command, ...);
110int faimtest_getfile_listingreq(struct aim_session_t *sess, struct command_rx_struct *command, ...);
111int faimtest_getfile_receive(struct aim_session_t *sess, struct command_rx_struct *command, ...);
112int faimtest_getfile_state4(struct aim_session_t *sess, struct command_rx_struct *command, ...);
113
114int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...);
115int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...);
116int faimtest_parse_searcherror(struct aim_session_t *sess, struct command_rx_struct *command, ...);
117int faimtest_parse_searchreply(struct aim_session_t *sess, struct command_rx_struct *command, ...);
118int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
119int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...);
120int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
121int faimtest_parse_genericerr(struct aim_session_t *sess, struct command_rx_struct *command, ...);
122
123static char *msgerrreasons[] = {
124 "Invalid error",
125 "Invalid SNAC",
126 "Rate to host",
127 "Rate to client",
128 "Not logged on",
129 "Service unavailable",
130 "Service not defined",
131 "Obsolete SNAC",
132 "Not supported by host",
133 "Not supported by client",
134 "Refused by client",
135 "Reply too big",
136 "Responses lost",
137 "Request denied",
138 "Busted SNAC payload",
139 "Insufficient rights",
140 "In local permit/deny",
141 "Too evil (sender)",
142 "Too evil (receiver)",
143 "User temporarily unavailable",
144 "No match",
145 "List overflow",
146 "Request ambiguous",
147 "Queue full",
148 "Not while on AOL"};
149static int msgerrreasonslen = 25;
150
151static char *screenname,*password,*server=NULL;
152static char *proxy = NULL, *proxyusername = NULL, *proxypass = NULL;
153static char *ohcaptainmycaptain = NULL;
154static int connected = 0;
155
156struct aim_session_t aimsess;
157int keepgoing = 1;
158
159static FILE *listingfile;
160static char *listingpath;
161
162static void faimtest_debugcb(struct aim_session_t *sess, int level, const char *format, va_list va)
163{
164
165 vfprintf(stderr, format, va);
166
167 return;
168}
169
170int faimtest_reportinterval(struct aim_session_t *sess, struct command_rx_struct *command, ...)
171{
172 va_list ap;
173 unsigned short interval = 0;
174
175 va_start(ap, command);
176 interval = va_arg(ap, int);
177 va_end(ap);
178
179 dvprintf("aim: minimum report interval: %d (seconds?)\n", interval);
180
181 return 1;
182}
183
184int faimtest_flapversion(struct aim_session_t *sess, struct command_rx_struct *command, ...)
185{
186
187 dvprintf("faimtest: using FLAP version %u\n", aimutil_get32(command->data));
188
189#if 0
190 /*
191 * This is an alternate location for starting the login process.
192 */
193 /* XXX should do more checking to make sure its really the right AUTH conn */
194 if (command->conn->type == AIM_CONN_TYPE_AUTH) {
195 /* do NOT send a connack/flapversion, request_login will send it if needed */
196 aim_request_login(sess, command->conn, screenname);
197 dprintf("faimtest: login request sent\n");
198 }
199#endif
200
201 return 1;
202}
203
204/*
205 * This is a frivilous callback. You don't need it. I only used it for
206 * debugging non-blocking connects.
207 *
208 * If packets are sent to a conn before its fully connected, they
209 * will be queued and then transmitted when the connection completes.
210 *
211 */
212int faimtest_conncomplete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
213{
214 va_list ap;
215 struct aim_conn_t *conn;
216
217 va_start(ap, command);
218 conn = va_arg(ap, struct aim_conn_t *);
219 va_end(ap);
220
221 if (conn)
222 dvprintf("faimtest: connection on %d completed\n", conn->fd);
223
224 return 1;
225}
226
227#ifdef _WIN32
228/*
229 * This is really all thats needed to link against libfaim on win32.
230 *
231 * Note that this particular version of faimtest has never been tested
232 * on win32, but I'm fairly sure it should.
233 */
234int initwsa(void)
235{
236 WORD wVersionRequested;
237 WSADATA wsaData;
238
239 wVersionRequested = MAKEWORD(2,2);
240 return WSAStartup(wVersionRequested, &wsaData);
241}
242#endif /* _WIN32 */
243
244int faimtest_init(void)
245{
246 struct aim_conn_t *stdinconn = NULL;
247
248 if (!(stdinconn = aim_newconn(&aimsess, 0, NULL))) {
249 dprintf("unable to create connection for stdin!\n");
250 return -1;
251 }
252
253 stdinconn->fd = STDIN_FILENO;
254
255 return 0;
256}
257
258int logout(void)
259{
260
261 if (ohcaptainmycaptain)
262 aim_send_im(&aimsess, aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS), ohcaptainmycaptain, 0, "ta ta...");
263
264 aim_session_kill(&aimsess);
265
266 if (faimtest_init() == -1)
267 dprintf("faimtest_init failed\n");
268
269 return 0;
270}
271
272int login(const char *sn, const char *passwd)
273{
274 struct aim_conn_t *authconn;
275
276 if (sn)
277 screenname = strdup(sn);
278 if (passwd)
279 password = strdup(passwd);
280
281 if (proxy)
282 aim_setupproxy(&aimsess, proxy, proxyusername, proxypass);
283
284 if (!screenname || !password) {
285 dprintf("need SN and password\n");
286 return -1;
287 }
288
289 if (!(authconn = aim_newconn(&aimsess, AIM_CONN_TYPE_AUTH, server?server:FAIM_LOGIN_SERVER))) {
290 dprintf("faimtest: internal connection error while in aim_login. bailing out.\n");
291 return -1;
292 } else if (authconn->fd == -1) {
293 if (authconn->status & AIM_CONN_STATUS_RESOLVERR) {
294 dprintf("faimtest: could not resolve authorizer name\n");
295 } else if (authconn->status & AIM_CONN_STATUS_CONNERR) {
296 dprintf("faimtest: could not connect to authorizer\n");
297 }
298 aim_conn_kill(&aimsess, &authconn);
299 return -1;
300 }
301
302 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
303 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
304 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0007, faimtest_parse_login, 0);
305 aim_conn_addhandler(&aimsess, authconn, 0x0017, 0x0003, faimtest_parse_authresp, 0);
306
307 aim_conn_addhandler(&aimsess, authconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEBUGCONN_CONNECT, faimtest_debugconn_connect, 0);
308
309 /* If the connection is in progress, this will just be queued */
310 aim_request_login(&aimsess, authconn, screenname);
311 dprintf("faimtest: login request sent\n");
312
313 return 0;
314}
315
316int main(int argc, char **argv)
317{
318 struct aim_conn_t *waitingconn = NULL;
319 int i;
320 int selstat = 0;
321 static int faimtest_mode = 0;
322
323 screenname = getenv("SCREENNAME");
324 password = getenv("PASSWORD");
325 server = getenv("AUTHSERVER");
326 proxy = getenv("SOCKSPROXY");
327 proxyusername = getenv("SOCKSNAME");
328 proxypass = getenv("SOCKSPASS");
329
330 listingpath = getenv("LISTINGPATH");
331
332 while ((i = getopt(argc, argv, "u:p:a:U:P:A:l:c:hoO")) != EOF) {
333 switch (i) {
334 case 'u': screenname = optarg; break;
335 case 'p': password = optarg; break;
336 case 'a': server = optarg; break;
337 case 'U': proxyusername = optarg; break;
338 case 'P': proxypass = optarg; break;
339 case 'A': proxy = optarg; break;
340 case 'l': listingpath = optarg; break;
341 case 'c': ohcaptainmycaptain = optarg; break;
342 case 'o': faimtest_mode = 1; break; /* half old interface */
343 case 'O': faimtest_mode = 2; break; /* full old interface */
344 case 'h':
345 default:
346 printf("faimtest\n");
347 printf(" Options: \n");
348 printf(" -u name Screen name ($SCREENNAME)\n");
349 printf(" -p passwd Password ($PASSWORD)\n");
350 printf(" -a host:port Authorizer ($AUTHSERVER)\n");
351 printf(" -U name Proxy user name ($SOCKSPROXY)\n");
352 printf(" -P passwd Proxy password ($SOCKSNAME)\n");
353 printf(" -A host:port Proxy host ($SOCKSPASS)\n");
354 printf(" -l path Path to listing file ($LISTINGPATH)\n");
355 printf(" -c name Screen name of owner\n");
356 printf(" -o Login at startup, then prompt\n");
357 printf(" -O Login, never give prompt\n");
358 exit(0);
359 }
360 }
361
362#ifdef _WIN32
363 if (initwsa() != 0) {
364 dprintf("faimtest: could not initialize windows sockets\n");
365 return -1;
366 }
367#endif /* _WIN32 */
368
369 /* Pass zero as flags if you want blocking connects */
370 aim_session_init(&aimsess, AIM_SESS_FLAGS_NONBLOCKCONNECT, 1);
371 aim_setdebuggingcb(&aimsess, faimtest_debugcb); /* still needed even if debuglevel = 0 ! */
372
373 if(listingpath) {
374 char *listingname;
375 if(!(listingname = (char *)calloc(1, strlen(listingpath)+strlen("/listing.txt")))) {
376 dperror("listingname calloc");
377 exit(-1);
378 }
379 sprintf(listingname, "%s/listing.txt", listingpath);
380 if( (listingfile = fopen(listingname, "r")) == NULL) {
381 dvprintf("Couldn't open %s... disabling that shit.\n", listingname);
382 }
383
384 free(listingname);
385 }
386
387 faimtest_init();
388
389 if (faimtest_mode < 2)
390 cmd_init();
391
392 if (faimtest_mode >= 1) {
393 if (login(screenname, password) == -1) {
394 if (faimtest_mode < 2)
395 cmd_uninit();
396 exit(-1);
397 }
398 }
399
400 while (keepgoing) {
401 waitingconn = aim_select(&aimsess, NULL, &selstat);
402
403 if (selstat == -1) { /* error */
404 keepgoing = 0; /* fall through */
405 } else if (selstat == 0) { /* no events pending */
406 keepgoing = 0;
407 } else if (selstat == 1) { /* outgoing data pending */
408 aim_tx_flushqueue(&aimsess);
409 } else if (selstat == 2) { /* incoming data pending */
410 if ((faimtest_mode < 2) && (waitingconn->fd == STDIN_FILENO)) {
411 cmd_gotkey();
412 } else {
413 if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) {
414 if (aim_handlerendconnect(&aimsess, waitingconn) < 0) {
415 dprintf("connection error (rend out)\n");
416 aim_conn_kill(&aimsess, &waitingconn);
417 }
418 } else {
419 if (aim_get_command(&aimsess, waitingconn) >= 0) {
420 aim_rxdispatch(&aimsess);
421 } else {
422 dvprintf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype);
423 /* we should have callbacks for all these, else the library will do the conn_kill for us. */
424 if(waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) {
425 dprintf("connection error: rendezvous connection. you forgot register a disconnect callback, right?\n");
426 aim_conn_kill(&aimsess, &waitingconn);
427 } else
428 aim_conn_kill(&aimsess, &waitingconn);
429 if (!aim_getconn_type(&aimsess, AIM_CONN_TYPE_BOS)) {
430 dprintf("major connection error\n");
431 if (faimtest_mode == 2)
432 break;
433 }
434 }
435 }
436 }
437 }
438 }
439
440 /* close up all connections, dead or no */
441 aim_session_kill(&aimsess);
442
443 if (faimtest_mode < 2) {
444 printf("\n");
445 cmd_uninit();
446 }
447
448 /* Get out */
449 exit(0);
450}
451
452int faimtest_rateresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
453{
454
455 switch(command->conn->type) {
456 case AIM_CONN_TYPE_BOS: {
457 /* this is the new buddy list */
458 char buddies[128];
459 /* this is the new profile */
460 char profile[256];
461
462 /* Caution: Buddy1 and Buddy2 are real people! (who I don't know) */
463 snprintf(buddies, sizeof(buddies), "Buddy1&Buddy2&%s&", ohcaptainmycaptain?ohcaptainmycaptain:"blah");
464 snprintf(profile, sizeof(profile), "Hello.<br>My captain is %s. They were dumb enough to leave this message in their client, or they are using faimtest. Shame on them.", ohcaptainmycaptain);
465
466 aim_bos_ackrateresp(sess, command->conn); /* ack rate info response */
467 aim_bos_reqpersonalinfo(sess, command->conn);
468 aim_bos_reqlocaterights(sess, command->conn);
469 aim_bos_setprofile(sess, command->conn, profile, NULL, AIM_CAPS_BUDDYICON | AIM_CAPS_CHAT | AIM_CAPS_VOICE | AIM_CAPS_GETFILE | AIM_CAPS_SENDFILE | AIM_CAPS_IMIMAGE | AIM_CAPS_GAMES | AIM_CAPS_SAVESTOCKS);
470 aim_bos_reqbuddyrights(sess, command->conn);
471
472 /* send the buddy list and profile (required, even if empty) */
473 aim_bos_setbuddylist(sess, command->conn, buddies);
474
475 /* dont really know what this does */
476 aim_addicbmparam(sess, command->conn);
477 aim_bos_reqicbmparaminfo(sess, command->conn);
478
479 aim_bos_reqrights(sess, command->conn);
480 /* set group permissions -- all user classes */
481 aim_bos_setgroupperm(sess, command->conn, AIM_FLAG_ALLUSERS);
482 aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE|AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
483
484 break;
485 }
486 case AIM_CONN_TYPE_AUTH:
487 aim_bos_ackrateresp(sess, command->conn);
488 aim_auth_clientready(sess, command->conn);
489 dprintf("faimtest: connected to authorization/admin service\n");
490 break;
491
492 default:
493 dvprintf("faimtest: got rate response for unhandled connection type %04x\n", command->conn->type);
494 break;
495 }
496
497 return 1;
498}
499
500static int faimtest_icbmparaminfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
501{
502 unsigned long defflags, minmsginterval;
503 unsigned short maxicbmlen, maxsenderwarn, maxrecverwarn, maxchannel;
504 va_list ap;
505
506 va_start(ap, command);
507 maxchannel = va_arg(ap, unsigned short);
508 defflags = va_arg(ap, unsigned long);
509 maxicbmlen = va_arg(ap, unsigned short);
510 maxsenderwarn = va_arg(ap, unsigned short);
511 maxrecverwarn = va_arg(ap, unsigned short);
512 minmsginterval = va_arg(ap, unsigned long);
513 va_end(ap);
514
515 dvprintf("ICBM Parameters: maxchannel = %d, default flags = 0x%08lx, max msg len = %d, max sender evil = %f, max reciever evil = %f, min msg interval = %ld\n", maxchannel, defflags, maxicbmlen, ((float)maxsenderwarn)/10.0, ((float)maxrecverwarn)/10.0, minmsginterval);
516
517 return 1;
518}
519
520int faimtest_hostversions(struct aim_session_t *sess, struct command_rx_struct *command, ...)
521{
522 int vercount, i;
523 unsigned char *versions;
524 va_list ap;
525
526 va_start(ap, command);
527 vercount = va_arg(ap, int); /* number of family/version pairs */
528 versions = va_arg(ap, unsigned char *);
529 va_end(ap);
530
531 dprintf("faimtest: SNAC versions supported by this host: ");
532 for (i = 0; i < vercount*4; i += 4)
533 dvinlineprintf("0x%04x:0x%04x ",
534 aimutil_get16(versions+i), /* SNAC family */
535 aimutil_get16(versions+i+2) /* Version number */);
536 dinlineprintf("\n");
537
538 return 1;
539}
540
541int faimtest_accountconfirm(struct aim_session_t *sess, struct command_rx_struct *command, ...)
542{
543 int status;
544 va_list ap;
545
546 va_start(ap, command);
547 status = va_arg(ap, int); /* status code of confirmation request */
548 va_end(ap);
549
550 dvprintf("account confirmation returned status 0x%04x (%s)\n", status, (status==0x0000)?"email sent":"unknown");
551
552 return 1;
553}
554
555int faimtest_serverready(struct aim_session_t *sess, struct command_rx_struct *command, ...)
556{
557 int famcount, i;
558 unsigned short *families;
559 va_list ap;
560
561 va_start(ap, command);
562 famcount = va_arg(ap, int);
563 families = va_arg(ap, unsigned short *);
564 va_end(ap);
565
566 dvprintf("faimtest: SNAC families supported by this host (type %d): ", command->conn->type);
567 for (i = 0; i < famcount; i++)
568 dvinlineprintf("0x%04x ", families[i]);
569 dinlineprintf("\n");
570
571 switch (command->conn->type) {
572 case AIM_CONN_TYPE_AUTH:
573 aim_auth_setversions(sess, command->conn);
574 aim_bos_reqrate(sess, command->conn); /* request rate info */
575
576 dprintf("faimtest: done with auth ServerReady\n");
577 break;
578
579 case AIM_CONN_TYPE_BOS:
580
581 aim_setversions(sess, command->conn);
582 aim_bos_reqrate(sess, command->conn); /* request rate info */
583
584 dprintf("faimtest: done with BOS ServerReady\n");
585 break;
586
587 case AIM_CONN_TYPE_CHATNAV:
588 dprintf("faimtest: chatnav: got server ready\n");
589 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, faimtest_chatnav_info, 0);
590 aim_bos_reqrate(sess, command->conn);
591 aim_bos_ackrateresp(sess, command->conn);
592 aim_chatnav_clientready(sess, command->conn);
593 aim_chatnav_reqrights(sess, command->conn);
594
595 break;
596
597 case AIM_CONN_TYPE_CHAT:
598 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, faimtest_chat_join, 0);
599 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, faimtest_chat_leave, 0);
600 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, faimtest_chat_infoupdate, 0);
601 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, faimtest_chat_incomingmsg, 0);
602 aim_bos_reqrate(sess, command->conn);
603 aim_bos_ackrateresp(sess, command->conn);
604 aim_chat_clientready(sess, command->conn);
605 break;
606
607 case AIM_CONN_TYPE_RENDEZVOUS: /* empty */
608 break;
609
610 default:
611 dvprintf("faimtest: unknown connection type on Host Online (0x%04x)\n", command->conn->type);
612 }
613
614 return 1;
615}
616
617int faimtest_parse_buddyrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
618{
619 va_list ap;
620 unsigned short maxbuddies, maxwatchers;
621
622 va_start(ap, command);
623 maxbuddies = va_arg(ap, int);
624 maxwatchers = va_arg(ap, int);
625 va_end(ap);
626
627 dvprintf("faimtest: buddy list rights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
628
629 return 1;
630}
631
632int faimtest_bosrights(struct aim_session_t *sess, struct command_rx_struct *command, ...)
633{
634 unsigned short maxpermits, maxdenies;
635 va_list ap;
636
637 va_start(ap, command);
638 maxpermits = va_arg(ap, int);
639 maxdenies = va_arg(ap, int);
640 va_end(ap);
641
642 dvprintf("faimtest: BOS rights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
643
644 aim_bos_clientready(sess, command->conn);
645
646 dprintf("faimtest: officially connected to BOS.\n");
647
648 return 1;
649}
650
651int faimtest_parse_unknown(struct aim_session_t *sess, struct command_rx_struct *command, ...)
652{
653 int i = 0;
654
655 if (!sess || !command)
656 return 1;
657
658 dprintf("\nReceived unknown packet:");
659 for (i = 0; i < command->commandlen; i++) {
660 if ((i % 8) == 0)
661 dinlineprintf("\n\t");
662 dvinlineprintf("0x%2x ", command->data[i]);
663 }
664 dinlineprintf("\n\n");
665
666 return 1;
667}
668
669/*
670 handleredirect()...
671
672 This, of course, handles Service Redirects from OSCAR.
673
674 Should get passed in the following:
675 struct command_rx_struct *command
676 the raw command data
677 int serviceid
678 the destination service ID
679 char *serverip
680 the IP address of the service's server
681 char *cookie
682 the raw auth cookie
683 */
684int faimtest_handleredirect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
685{
686 va_list ap;
687 int serviceid;
688 char *ip;
689 unsigned char *cookie;
690
691 va_start(ap, command);
692 serviceid = va_arg(ap, int);
693 ip = va_arg(ap, char *);
694 cookie = va_arg(ap, unsigned char *);
695
696 switch(serviceid)
697 {
698 case 0x0005: /* Adverts */
699 {
700 struct aim_conn_t *tstconn;
701
702 tstconn = aim_newconn(sess, AIM_CONN_TYPE_ADS, ip);
703 if ((tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
704 dprintf("faimtest: unable to reconnect with authorizer\n");
705 } else {
706 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
707 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
708 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
709 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
710 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, 0x0018, faimtest_hostversions, 0);
711 aim_auth_sendcookie(sess, tstconn, cookie);
712 dprintf("sent cookie to adverts host\n");
713 }
714
715 }
716 break;
717 case 0x0007: /* Authorizer */
718 {
719 struct aim_conn_t *tstconn;
720 /* Open a connection to the Auth */
721 tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, ip);
722 if ((tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
723 dprintf("faimtest: unable to reconnect with authorizer\n");
724 } else {
725 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
726 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
727 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
728 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
729 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_GEN, 0x0018, faimtest_hostversions, 0);
730 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, faimtest_accountconfirm, 0);
731 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, faimtest_infochange, 0);
732 aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, faimtest_infochange, 0);
733 /* Send the cookie to the Auth */
734 aim_auth_sendcookie(sess, tstconn, cookie);
735 dprintf("sent cookie to authorizer host\n");
736 }
737
738 }
739 break;
740 case 0x000d: /* ChatNav */
741 {
742 struct aim_conn_t *tstconn = NULL;
743 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, ip);
744 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
745 dprintf("faimtest: unable to connect to chatnav server\n");
746 if (tstconn) aim_conn_kill(sess, &tstconn);
747 return 1;
748 }
749
750 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
751 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
752 aim_auth_sendcookie(sess, tstconn, cookie);
753 dprintf("\achatnav: connected\n");
754 }
755 break;
756 case 0x000e: /* Chat */
757 {
758 char *roomname = NULL;
759 int exchange;
760 struct aim_conn_t *tstconn = NULL;
761
762 roomname = va_arg(ap, char *);
763 exchange = va_arg(ap, int);
764
765 tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, ip);
766 if ( (tstconn==NULL) || (tstconn->status & AIM_CONN_STATUS_RESOLVERR))
767 {
768 dprintf("faimtest: unable to connect to chat server\n");
769 if (tstconn) aim_conn_kill(sess, &tstconn);
770 return 1;
771 }
772 dvprintf("faimtest: chat: connected to %s on exchange %d\n", roomname, exchange);
773
774 /*
775 * We must do this to attach the stored name to the connection!
776 */
777 aim_chat_attachname(tstconn, roomname);
778
779 aim_conn_addhandler(sess, tstconn, 0x0001, 0x0003, faimtest_serverready, 0);
780 aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
781 aim_auth_sendcookie(sess, tstconn, cookie);
782 }
783 break;
784 default:
785 dvprintf("uh oh... got redirect for unknown service 0x%04x!!\n", serviceid);
786 /* dunno */
787 }
788
789 va_end(ap);
790
791 return 1;
792}
793
794int faimtest_parse_authresp(struct aim_session_t *sess, struct command_rx_struct *command, ...)
795{
796 va_list ap;
797 struct aim_conn_t *bosconn = NULL;
798 char *sn = NULL, *bosip = NULL, *errurl = NULL, *email = NULL;
799 unsigned char *cookie = NULL;
800 int errorcode = 0, regstatus = 0;
801 int latestbuild = 0, latestbetabuild = 0;
802 char *latestrelease = NULL, *latestbeta = NULL;
803 char *latestreleaseurl = NULL, *latestbetaurl = NULL;
804 char *latestreleaseinfo = NULL, *latestbetainfo = NULL;
805
806 va_start(ap, command);
807 sn = va_arg(ap, char *);
808 errorcode = va_arg(ap, int);
809 errurl = va_arg(ap, char *);
810 regstatus = va_arg(ap, int);
811 email = va_arg(ap, char *);
812 bosip = va_arg(ap, char *);
813 cookie = va_arg(ap, unsigned char *);
814
815 latestrelease = va_arg(ap, char *);
816 latestbuild = va_arg(ap, int);
817 latestreleaseurl = va_arg(ap, char *);
818 latestreleaseinfo = va_arg(ap, char *);
819
820 latestbeta = va_arg(ap, char *);
821 latestbetabuild = va_arg(ap, int);
822 latestbetaurl = va_arg(ap, char *);
823 latestbetainfo = va_arg(ap, char *);
824
825 va_end(ap);
826
827 dvprintf("Screen name: %s\n", sn);
828
829 /*
830 * Check for error.
831 */
832 if (errorcode || !bosip || !cookie) {
833 dvprintf("Login Error Code 0x%04x\n", errorcode);
834 dvprintf("Error URL: %s\n", errurl);
835 aim_conn_kill(sess, &command->conn);
836 return 1;
837 }
838
839 dvprintf("Reg status: %2d\n", regstatus);
840 dvprintf("Email: %s\n", email);
841 dvprintf("BOS IP: %s\n", bosip);
842
843 if (latestbeta)
844 dvprintf("Latest beta version: %s, build %d, at %s (more info at %s)\n", latestbeta, latestbetabuild, latestbetaurl, latestbetainfo);
845
846 if (latestrelease)
847 dvprintf("Latest released version: %s, build %d, at %s (more info at %s)\n", latestrelease, latestbuild, latestreleaseurl, latestreleaseinfo);
848
849 dprintf("Closing auth connection...\n");
850 aim_conn_kill(sess, &command->conn);
851 if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip))) {
852 dprintf("faimtest: could not connect to BOS: internal error\n");
853 return 1;
854 } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
855 dprintf("faimtest: could not connect to BOS\n");
856 aim_conn_kill(sess, &bosconn);
857 return 1;
858 }
859
860 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
861 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, faimtest_bosrights, 0);
862 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0007, faimtest_rateresp, 0); /* rate info */
863 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
864 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, 0x0018, faimtest_hostversions, 0);
865 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_SERVERREADY, faimtest_serverready, 0);
866 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATEINFO, NULL, 0);
867 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, faimtest_handleredirect, 0);
868 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL, faimtest_reportinterval, 0);
869 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, faimtest_parse_buddyrights, 0);
870 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, faimtest_parse_oncoming, 0);
871 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, faimtest_parse_offgoing, 0);
872 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
873 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, faimtest_parse_locerr, 0);
874 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, faimtest_parse_misses, 0);
875 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, faimtest_parse_ratechange, 0);
876 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, faimtest_parse_evilnotify, 0);
877 aim_conn_addhandler(sess, bosconn, 0x000a, 0x0001, faimtest_parse_searcherror, 0);
878 aim_conn_addhandler(sess, bosconn, 0x000a, 0x0003, faimtest_parse_searchreply, 0);
879 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, faimtest_parse_msgerr, 0);
880 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, faimtest_parse_userinfo, 0);
881 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, faimtest_parse_msgack, 0);
882
883 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, faimtest_parse_motd, 0);
884
885 aim_conn_addhandler(sess, bosconn, 0x0004, 0x0005, faimtest_icbmparaminfo, 0);
886 aim_conn_addhandler(sess, bosconn, 0x0001, 0x0001, faimtest_parse_genericerr, 0);
887 aim_conn_addhandler(sess, bosconn, 0x0003, 0x0001, faimtest_parse_genericerr, 0);
888 aim_conn_addhandler(sess, bosconn, 0x0009, 0x0001, faimtest_parse_genericerr, 0);
889
890 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, faimtest_parse_connerr, 0);
891
892
893 aim_auth_sendcookie(sess, bosconn, cookie);
894
895 return 1;
896}
897
898static void printuserflags(unsigned short flags)
899{
900 if (flags & AIM_FLAG_UNCONFIRMED)
901 dinlineprintf("UNCONFIRMED ");
902 if (flags & AIM_FLAG_ADMINISTRATOR)
903 dinlineprintf("ADMINISTRATOR ");
904 if (flags & AIM_FLAG_AOL)
905 dinlineprintf("AOL ");
906 if (flags & AIM_FLAG_OSCAR_PAY)
907 dinlineprintf("OSCAR_PAY ");
908 if (flags & AIM_FLAG_FREE)
909 dinlineprintf("FREE ");
910 if (flags & AIM_FLAG_AWAY)
911 dinlineprintf("AWAY ");
912 if (flags & AIM_FLAG_UNKNOWN40)
913 dinlineprintf("ICQ? ");
914 if (flags & AIM_FLAG_UNKNOWN80)
915 dinlineprintf("UNKNOWN80 ");
916 return;
917}
918
919int faimtest_parse_userinfo(struct aim_session_t *sess, struct command_rx_struct *command, ...)
920{
921 struct aim_userinfo_s *userinfo;
922 char *prof_encoding = NULL;
923 char *prof = NULL;
924 unsigned short inforeq = 0;
925
926 va_list ap;
927 va_start(ap, command);
928 userinfo = va_arg(ap, struct aim_userinfo_s *);
929 prof_encoding = va_arg(ap, char *);
930 prof = va_arg(ap, char *);
931 inforeq = va_arg(ap, int);
932 va_end(ap);
933
934 dvprintf("faimtest: userinfo: sn: %s\n", userinfo->sn);
935 dvprintf("faimtest: userinfo: warnlevel: 0x%04x\n", userinfo->warnlevel);
936 dvprintf("faimtest: userinfo: flags: 0x%04x = ", userinfo->flags);
937 printuserflags(userinfo->flags);
938 dinlineprintf("\n");
939
940 dvprintf("faimtest: userinfo: membersince: %lu\n", userinfo->membersince);
941 dvprintf("faimtest: userinfo: onlinesince: %lu\n", userinfo->onlinesince);
942 dvprintf("faimtest: userinfo: idletime: 0x%04x\n", userinfo->idletime);
943
944 if (inforeq == AIM_GETINFO_GENERALINFO) {
945 dvprintf("faimtest: userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
946 dvprintf("faimtest: userinfo: prof: %s\n", prof ? prof : "[none]");
947 } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
948 dvprintf("faimtest: userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
949 dvprintf("faimtest: userinfo: awaymsg: %s\n", prof ? prof : "[none]");
950 } else
951 dprintf("faimtest: userinfo: unknown info request\n");
952
953 return 1;
954}
955
956static int faimtest_handlecmd(struct aim_session_t *sess, struct command_rx_struct *command, struct aim_userinfo_s *userinfo, char *tmpstr)
957{
958
959 if (!strncmp(tmpstr, "disconnect", 10)) {
960
961 logout();
962
963 } else if (strstr(tmpstr, "goodday")) {
964
965 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too.");
966
967 } else if (strstr(tmpstr, "warnme")) {
968
969 dprintf("faimtest: icbm: sending non-anon warning\n");
970 aim_send_warning(sess, command->conn, userinfo->sn, 0);
971
972 } else if (strstr(tmpstr, "anonwarn")) {
973
974 dprintf("faimtest: icbm: sending anon warning\n");
975 aim_send_warning(sess, command->conn, userinfo->sn, AIM_WARN_ANON);
976
977 } else if (strstr(tmpstr, "setdirectoryinfo")) {
978
979 dprintf("faimtest: icbm: sending backwards profile data\n");
980 aim_setdirectoryinfo(sess, command->conn, "tsrif", "elddim", "tsal", "nediam", "emankcin", "teerts", "ytic", "etats", "piz", 0, 1);
981
982 } else if (strstr(tmpstr, "setinterests")) {
983
984 dprintf("faimtest: icbm: setting fun interests\n");
985 aim_setuserinterests(sess, command->conn, "interest1", "interest2", "interest3", "interest4", "interest5", 1);
986
987 } else if (!strncmp(tmpstr, "getfile", 7)) {
988
989 if (!ohcaptainmycaptain) {
990
991 aim_send_im(sess, command->conn, userinfo->sn, AIM_IMFLAGS_ACK, "I have no owner!");
992
993 } else {
994 struct aim_conn_t *newconn;
995
996 newconn = aim_getfile_initiate(sess, command->conn, (strlen(tmpstr) < 8)?ohcaptainmycaptain:tmpstr+8);
997 dvprintf("faimtest: getting file listing from %s\n", (strlen(tmpstr) < 8)?ohcaptainmycaptain:tmpstr+8);
998 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEINITIATE, faimtest_getfile_initiate,0);
999 }
1000
1001 } else if (!strncmp(tmpstr, "open chatnav", 12)) {
1002
1003 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_CHATNAV);
1004
1005 } else if (!strncmp(tmpstr, "create", 6)) {
1006
1007 aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
1008
1009 } else if (!strncmp(tmpstr, "close chatnav", 13)) {
1010 struct aim_conn_t *chatnavconn;
1011
1012 chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV);
1013 aim_conn_kill(sess, &chatnavconn);
1014
1015 } else if (!strncmp(tmpstr, "join", 4)) {
1016
1017 aim_chat_join(sess, command->conn, 0x0004, "worlddomination");
1018
1019 } else if (!strncmp(tmpstr, "leave", 5)) {
1020
1021 aim_chat_leaveroom(sess, "worlddomination");
1022
1023 } else if (!strncmp(tmpstr, "getinfo", 7)) {
1024
1025 aim_getinfo(sess, command->conn, "75784102", AIM_GETINFO_GENERALINFO);
1026 aim_getinfo(sess, command->conn, "15853637", AIM_GETINFO_AWAYMESSAGE);
1027 aim_getinfo(sess, command->conn, "midendian", AIM_GETINFO_GENERALINFO);
1028 aim_getinfo(sess, command->conn, "midendian", AIM_GETINFO_AWAYMESSAGE);
1029
1030 } else if (!strncmp(tmpstr, "open directim", 13)) {
1031 struct aim_conn_t *newconn;
1032
1033 printf("faimtest: opening directim to %s\n", (strlen(tmpstr) < 14)?userinfo->sn:tmpstr+14);
1034 newconn = aim_directim_initiate(sess, command->conn, NULL, (strlen(tmpstr) < 14)?userinfo->sn:tmpstr+14);
1035 if(!newconn || newconn->fd == -1)
1036 printf("connection failed!\n");
1037 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, faimtest_directim_initiate,0);
1038
1039 } else if(!(strncmp(tmpstr, "lookup", 6))) {
1040
1041 aim_usersearch_address(sess, command->conn, tmpstr+7);
1042
1043 } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
1044
1045 aim_send_im(sess, command->conn, ohcaptainmycaptain, 0, "sendmsg 7900");
1046
1047 } else if (!strncmp(tmpstr, "reqauth", 7)) {
1048
1049 aim_bos_reqservice(sess, command->conn, AIM_CONN_TYPE_AUTH);
1050
1051 } else if (!strncmp(tmpstr, "reqconfirm", 10)) {
1052
1053 aim_auth_reqconfirm(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH));
1054
1055 } else if (!strncmp(tmpstr, "reqemail", 8)) {
1056
1057 aim_auth_getinfo(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), 0x0011);
1058
1059 } else if (!strncmp(tmpstr, "changepass", 8)) {
1060
1061 aim_auth_changepasswd(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWPASSWORD", "OLDPASSWORD");
1062
1063 } else if (!strncmp(tmpstr, "setemail", 8)) {
1064
1065 aim_auth_setemail(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWEMAILADDRESS");
1066
1067 } else if (!strncmp(tmpstr, "sendmsg", 7)) {
1068 int i;
1069 i = atoi(tmpstr+8);
1070 if (i < 10000) {
1071 char *newbuf;
1072 int z;
1073
1074 newbuf = malloc(i+1);
1075 for (z = 0; z < i; z++) {
1076 newbuf[z] = (z % 10)+0x30;
1077 }
1078 newbuf[i] = '\0';
1079 aim_send_im(sess, command->conn, userinfo->sn, 0, newbuf);
1080 free(newbuf);
1081 }
1082
1083 } else {
1084
1085 dprintf("unknown command.\n");
1086 aim_add_buddy(sess, command->conn, userinfo->sn);
1087
1088 }
1089
1090 return 0;
1091}
1092
1093/*
1094 * The user-level Incoming ICBM callback.
1095 *
1096 */
1097int faimtest_parse_incoming_im(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1098{
1099 int channel;
1100 va_list ap;
1101
1102 va_start(ap, command);
1103 channel = va_arg(ap, int);
1104
1105 /*
1106 * Channel 1: Standard Message
1107 */
1108 if (channel == 1) {
1109 struct aim_userinfo_s *userinfo;
1110 char *msg = NULL;
1111 u_int icbmflags = 0;
1112 char *tmpstr = NULL;
1113 unsigned short flag1, flag2;
1114 int finlen = 0;
1115 unsigned char *fingerprint = NULL;
1116 int clienttype = AIM_CLIENTTYPE_UNKNOWN;
1117
1118 userinfo = va_arg(ap, struct aim_userinfo_s *);
1119 msg = va_arg(ap, char *);
1120 icbmflags = va_arg(ap, u_int);
1121 flag1 = va_arg(ap, int);
1122 flag2 = va_arg(ap, int);
1123 finlen = va_arg(ap, int);
1124 fingerprint = va_arg(ap, unsigned char *);
1125 va_end(ap);
1126
1127 clienttype = aim_fingerprintclient(fingerprint, finlen);
1128
1129 dvprintf("faimtest: icbm: sn = \"%s\"\n", userinfo->sn);
1130 dvprintf("faimtest: icbm: probable client type: %d\n", clienttype);
1131 dvprintf("faimtest: icbm: warnlevel = 0x%04x\n", userinfo->warnlevel);
1132 dvprintf("faimtest: icbm: flags = 0x%04x = ", userinfo->flags);
1133 printuserflags(userinfo->flags);
1134 dinlineprintf("\n");
1135
1136 dvprintf("faimtest: icbm: membersince = %lu\n", userinfo->membersince);
1137 dvprintf("faimtest: icbm: onlinesince = %lu\n", userinfo->onlinesince);
1138 dvprintf("faimtest: icbm: idletime = 0x%04x\n", userinfo->idletime);
1139 dvprintf("faimtest: icbm: capabilities = 0x%04x\n", userinfo->capabilities);
1140
1141 dprintf("faimtest: icbm: icbmflags = ");
1142 if (icbmflags & AIM_IMFLAGS_AWAY)
1143 dinlineprintf("away ");
1144 if (icbmflags & AIM_IMFLAGS_ACK)
1145 dinlineprintf("ackrequest ");
1146 dinlineprintf("\n");
1147
1148 dvprintf("faimtest: icbm: encoding flags = {%04x, %04x}\n", flag1, flag2);
1149
1150 dvprintf("faimtest: icbm: message: %s\n", msg);
1151
1152 if (msg) {
1153 int i = 0;
1154
1155 while (msg[i] == '<') {
1156 if (msg[i] == '<') {
1157 while (msg[i] != '>')
1158 i++;
1159 i++;
1160 }
1161 }
1162 tmpstr = msg+i;
1163
1164 faimtest_handlecmd(sess, command, userinfo, tmpstr);
1165
1166 }
1167 }
1168 /*
1169 * Channel 2: Rendevous Request
1170 */
1171 else if (channel == 2) {
1172 struct aim_userinfo_s *userinfo;
1173 unsigned short reqclass;
1174
1175 reqclass = va_arg(ap, int);
1176 switch (reqclass) {
1177 case AIM_CAPS_VOICE: {
1178 userinfo = va_arg(ap, struct aim_userinfo_s *);
1179 va_end(ap);
1180
1181 dvprintf("faimtest: voice invitation: source sn = %s\n", userinfo->sn);
1182 dvprintf("faimtest: voice invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
1183 dvprintf("faimtest: voice invitation: \tclass = 0x%04x = ", userinfo->flags);
1184 printuserflags(userinfo->flags);
1185 dinlineprintf("\n");
1186
1187 /* we dont get membersince on chat invites! */
1188 dvprintf("faimtest: voice invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
1189 dvprintf("faimtest: voice invitation: \tidletime = 0x%04x\n", userinfo->idletime);
1190
1191 break;
1192 }
1193 case AIM_CAPS_GETFILE: {
1194 char *ip, *cookie;
1195 struct aim_conn_t *newconn;
1196 struct aim_fileheader_t *fh;
1197
1198 userinfo = va_arg(ap, struct aim_userinfo_s *);
1199 ip = va_arg(ap, char *);
1200 cookie = va_arg(ap, char *);
1201 va_end(ap);
1202
1203 dvprintf("faimtest: get file request from %s (at %s) %x\n", userinfo->sn, ip, reqclass);
1204
1205 fh = aim_getlisting(sess, listingfile);
1206
1207 newconn = aim_accepttransfer(sess, command->conn, userinfo->sn, cookie, ip, fh->totfiles, fh->totsize, fh->size, fh->checksum, reqclass);
1208
1209 if( (!newconn) || (newconn->fd == -1) ) {
1210 dprintf("faimtest: getfile: requestconn: apparent error in accepttransfer\n");
1211 if(newconn)
1212 aim_conn_kill(sess, &newconn);
1213 break;
1214 }
1215
1216 free(fh);
1217
1218 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTINGREQ, faimtest_getfile_listingreq, 0);
1219 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
1220 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
1221 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
1222
1223 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
1224
1225 dprintf("faimtest: getfile connect succeeded, handlers added.\n");
1226
1227 break;
1228 }
1229 case AIM_CAPS_SENDFILE: {
1230 dprintf("faimtest: send file!\n");
1231 break;
1232 }
1233 case AIM_CAPS_CHAT: {
1234 char *msg,*encoding,*lang;
1235 struct aim_chat_roominfo *roominfo;
1236
1237 userinfo = va_arg(ap, struct aim_userinfo_s *);
1238 roominfo = va_arg(ap, struct aim_chat_roominfo *);
1239 msg = va_arg(ap, char *);
1240 encoding = va_arg(ap, char *);
1241 lang = va_arg(ap, char *);
1242 va_end(ap);
1243
1244 dvprintf("faimtest: chat invitation: source sn = %s\n", userinfo->sn);
1245 dvprintf("faimtest: chat invitation: \twarnlevel = 0x%04x\n", userinfo->warnlevel);
1246 dvprintf("faimtest: chat invitation: \tclass = 0x%04x = ", userinfo->flags);
1247 printuserflags(userinfo->flags);
1248 dinlineprintf("\n");
1249
1250 /* we dont get membersince on chat invites! */
1251 dvprintf("faimtest: chat invitation: \tonlinesince = %lu\n", userinfo->onlinesince);
1252 dvprintf("faimtest: chat invitation: \tidletime = 0x%04x\n", userinfo->idletime);
1253
1254 dvprintf("faimtest: chat invitation: message = %s\n", msg);
1255 dvprintf("faimtest: chat invitation: room name = %s\n", roominfo->name);
1256 dvprintf("faimtest: chat invitation: encoding = %s\n", encoding);
1257 dvprintf("faimtest: chat invitation: language = %s\n", lang);
1258 dvprintf("faimtest: chat invitation: exchange = 0x%04x\n", roominfo->exchange);
1259 dvprintf("faimtest: chat invitation: instance = 0x%04x\n", roominfo->instance);
1260 dvprintf("faimtest: chat invitiation: autojoining %s...\n", roominfo->name);
1261 /*
1262 * Automatically join room...
1263 */
1264 aim_chat_join(sess, command->conn, 0x0004, roominfo->name);
1265 break;
1266 }
1267 case AIM_CAPS_IMIMAGE: {
1268 struct aim_directim_priv *priv;
1269 struct aim_conn_t *newconn;
1270
1271 dprintf("faimtest: icbm: rendezvous imimage\n");
1272
1273 userinfo = va_arg(ap, struct aim_userinfo_s *);
1274 priv = va_arg(ap, struct aim_directim_priv *);
1275 va_end(ap);
1276
1277 dvprintf("faimtest: OFT: DirectIM: request from %s (%s)\n", userinfo->sn, priv->ip);
1278
1279 newconn = aim_directim_connect(sess, command->conn, priv);
1280
1281 if ( (!newconn) || (newconn->fd == -1) ) {
1282 dprintf("faimtest: icbm: imimage: could not connect\n");
1283
1284 if (newconn)
1285 aim_conn_kill(sess, &newconn);
1286
1287 break;
1288 }
1289
1290 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
1291 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
1292 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
1293
1294 dvprintf("faimtest: OFT: DirectIM: connected to %s\n", userinfo->sn);
1295
1296 aim_send_im_direct(sess, newconn, "goodday");
1297
1298 break;
1299 }
1300 default:
1301 dvprintf("faimtest: icbm: unknown reqclass (%d)\n", reqclass);
1302 } /* switch */
1303 } else
1304 dvprintf("faimtest does not support channels > 2 (chan = %02x)\n", channel);
1305 dprintf("faimtest: icbm: done with ICBM handling\n");
1306
1307 return 1;
1308}
1309
1310int faimtest_directim_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1311{
1312 va_list ap;
1313 struct aim_directim_priv *priv;
1314 struct aim_conn_t *newconn, *listenerconn;
1315
1316 va_start(ap, command);
1317 newconn = va_arg(ap, struct aim_conn_t *);
1318 listenerconn = va_arg(ap, struct aim_conn_t *);
1319 va_end(ap);
1320
1321 aim_conn_close(listenerconn);
1322 aim_conn_kill(sess, &listenerconn);
1323
1324 priv = (struct aim_directim_priv *)newconn->priv;
1325
1326 dvprintf("faimtest: OFT: DirectIM: intitiate success to %s\n", priv->ip);
1327
1328 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, faimtest_directim_incoming, 0);
1329 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMDISCONNECT, faimtest_directim_disconnect, 0);
1330 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, faimtest_directim_typing, 0);
1331
1332 aim_send_im_direct(sess, newconn, "goodday");
1333
1334 dvprintf("faimtest: OFT: DirectIM: connected to %s\n", priv->sn);
1335
1336 return 1;
1337}
1338
1339int faimtest_directim_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1340{
1341 va_list ap;
1342 struct aim_directim_priv *priv;
1343
1344 va_start(ap, command);
1345 priv = va_arg(ap, struct aim_directim_priv *);
1346
1347 va_end(ap);
1348
1349 dprintf("faimtest: directim_connect\n");
1350
1351 return 1;
1352}
1353
1354int faimtest_directim_incoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1355{
1356 va_list ap;
1357 char *msg = NULL;
1358 struct aim_conn_t *conn;
1359 struct aim_directim_priv *priv;
1360
1361 va_start(ap, command);
1362 conn = va_arg(ap, struct aim_conn_t *);
1363 msg = va_arg(ap, char *);
1364 va_end(ap);
1365
1366 if(!(priv = conn->priv)) {
1367 dvprintf("faimtest: directim: no private struct on conn with fd %d\n", conn->fd);
1368 return -1;
1369 }
1370
1371 dvprintf("faimtest: Directim from %s: %s\n", priv->sn, msg);
1372 if (!strncmp(msg, "sendmsg", 7)) {
1373 int i;
1374 i = atoi(msg+8);
1375 if (i < 10000) {
1376 char *newbuf;
1377 int z;
1378
1379 newbuf = malloc(i+1);
1380 for (z = 0; z < i; z++) {
1381 newbuf[z] = (z % 10)+0x30;
1382 }
1383 newbuf[i] = '\0';
1384 aim_send_im_direct(sess, conn, newbuf);
1385 free(newbuf);
1386 }
1387 } else if (!strncmp(msg, "goodday", 7)) {
1388 aim_send_im_direct(sess, conn, "Good day to you, too");
1389 } else {
1390 char newmsg[1024];
1391 snprintf(newmsg, sizeof(newmsg), "unknown (%s)\n", msg);
1392 aim_send_im_direct(sess, conn, newmsg);
1393 }
1394 return 1;
1395}
1396
1397int faimtest_directim_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1398{
1399 va_list ap;
1400 struct aim_conn_t *conn;
1401 char *sn;
1402
1403 va_start(ap, command);
1404 conn = va_arg(ap, struct aim_conn_t *);
1405 sn = va_arg(ap, char *);
1406 va_end(ap);
1407
1408 dvprintf("faimtest: directim: disconnected from %s\n", sn);
1409
1410 aim_conn_kill(sess, &conn);
1411 return 1;
1412}
1413
1414int faimtest_directim_typing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1415{
1416 va_list ap;
1417 struct aim_conn_t *conn;
1418 struct aim_directim_priv *priv;
1419
1420 va_start(ap, command);
1421 conn = va_arg(ap, struct aim_conn_t *);
1422 va_end(ap);
1423
1424 if(!(priv = (struct aim_directim_priv *)conn->priv)) {
1425 dvprintf("faimtest: no private struct on conn with fd %d!\n", conn->fd);
1426 return -1;
1427 }
1428
1429 dvprintf("faimtest: ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", priv->sn);
1430 return 1;
1431}
1432
1433int faimtest_infochange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1434{
1435 unsigned short change = 0;
1436 int perms, type, length, str;
1437 char *val;
1438 va_list ap;
1439
1440 va_start(ap, command);
1441 perms = va_arg(ap, int);
1442 type = va_arg(ap, int);
1443 length = va_arg(ap, int);
1444 val = va_arg(ap, char *);
1445 str = va_arg(ap, int);
1446 va_end(ap);
1447
1448 if (aimutil_get16(command->data+2) == 0x0005)
1449 change = 1;
1450
1451 dvprintf("info%s: perms = %d, type = %x, length = %d, val = %s\n", change?" change":"", perms, type, length, str?val:"(not string)");
1452
1453 return 1;
1454}
1455
1456int faimtest_parse_oncoming(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1457{
1458 struct aim_userinfo_s *userinfo;
1459
1460 va_list ap;
1461 va_start(ap, command);
1462 userinfo = va_arg(ap, struct aim_userinfo_s *);
1463 va_end(ap);
1464
1465 dvprintf("%ld %s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = 0x%04x)\n",
1466 time(NULL),
1467 userinfo->sn, userinfo->flags,
1468 (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
1469 (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
1470 (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
1471 (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
1472 (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
1473 (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
1474 (userinfo->flags&AIM_FLAG_UNKNOWN40)?" UNKNOWN40":"",
1475 (userinfo->flags&AIM_FLAG_UNKNOWN80)?" UNKNOWN80":"",
1476 userinfo->capabilities);
1477 return 1;
1478}
1479
1480int faimtest_parse_offgoing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1481{
1482 char *sn;
1483 va_list ap;
1484
1485 va_start(ap, command);
1486 sn = va_arg(ap, char *);
1487 va_end(ap);
1488
1489 dvprintf("\n%s has left\n", sn);
1490
1491 return 1;
1492}
1493
1494int faimtest_parse_motd(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1495{
1496 static char *codes[] = {
1497 "Unknown",
1498 "Mandatory upgrade",
1499 "Advisory upgrade",
1500 "System bulletin",
1501 "Top o' the world!"};
1502 static int codeslen = 5;
1503
1504 char *msg;
1505 unsigned short id;
1506 va_list ap;
1507
1508 va_start(ap, command);
1509 id = va_arg(ap, int);
1510 msg = va_arg(ap, char *);
1511 va_end(ap);
1512
1513 dvprintf("faimtest: motd: %s (%d / %s)\n", msg, id,
1514 (id < codeslen)?codes[id]:"unknown");
1515
1516 if (!connected)
1517 connected++;
1518
1519 return 1;
1520}
1521
1522int faimtest_parse_genericerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1523{
1524 va_list ap;
1525 unsigned short reason;
1526
1527 va_start(ap, command);
1528 reason = va_arg(ap, int);
1529 va_end(ap);
1530
1531 dvprintf("faimtest: snac threw error (reason 0x%04x: %s)\n", reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1532
1533 return 1;
1534}
1535
1536int faimtest_parse_msgerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1537{
1538 va_list ap;
1539 char *destsn;
1540 unsigned short reason;
1541
1542 va_start(ap, command);
1543 reason = va_arg(ap, int);
1544 destsn = va_arg(ap, char *);
1545 va_end(ap);
1546
1547 dvprintf("faimtest: message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1548
1549 return 1;
1550}
1551
1552int faimtest_parse_locerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1553{
1554 va_list ap;
1555 char *destsn;
1556 unsigned short reason;
1557
1558 va_start(ap, command);
1559 reason = va_arg(ap, int);
1560 destsn = va_arg(ap, char *);
1561 va_end(ap);
1562
1563 dvprintf("faimtest: user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown");
1564
1565 return 1;
1566}
1567
1568/*
1569 * Handles callbacks for AIM_CB_MISSED_CALL.
1570 */
1571int faimtest_parse_misses(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1572{
1573 static char *missedreasons[] = {
1574 "Unknown",
1575 "Message too large"};
1576 static int missedreasonslen = 2;
1577
1578 va_list ap;
1579 unsigned short chan, nummissed, reason;
1580 struct aim_userinfo_s *userinfo;
1581
1582 va_start(ap, command);
1583 chan = va_arg(ap, int);
1584 userinfo = va_arg(ap, struct aim_userinfo_s *);
1585 nummissed = va_arg(ap, int);
1586 reason = va_arg(ap, int);
1587 va_end(ap);
1588
1589 dvprintf("faimtest: missed %d messages from %s (reason %d: %s)\n", nummissed, userinfo->sn, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
1590
1591 return 1;
1592}
1593
1594int faimtest_parse_login(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1595{
1596 struct client_info_s info = AIM_CLIENTINFO_KNOWNGOOD;
1597 char *key;
1598 va_list ap;
1599
1600 va_start(ap, command);
1601 key = va_arg(ap, char *);
1602 va_end(ap);
1603
1604 aim_send_login(sess, command->conn, screenname, password, &info, key);
1605
1606 return 1;
1607}
1608
1609int faimtest_chat_join(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1610{
1611 va_list ap;
1612 struct aim_userinfo_s *userinfo;
1613 int count = 0, i = 0;
1614
1615 va_start(ap, command);
1616 count = va_arg(ap, int);
1617 userinfo = va_arg(ap, struct aim_userinfo_s *);
1618 va_end(ap);
1619
1620 dvprintf("faimtest: chat: %s: New occupants have joined:\n", (char *)command->conn->priv);
1621 while (i < count)
1622 dvprintf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1623
1624 return 1;
1625}
1626
1627int faimtest_chat_leave(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1628{
1629 va_list ap;
1630 struct aim_userinfo_s *userinfo;
1631 int count = 0, i = 0;
1632
1633 va_start(ap, command);
1634 count = va_arg(ap, int);
1635 userinfo = va_arg(ap, struct aim_userinfo_s *);
1636 va_end(ap);
1637
1638 dvprintf("faimtest: chat: %s: Some occupants have left:\n", (char *)command->conn->priv);
1639
1640 for (i = 0; i < count; )
1641 dvprintf("faimtest: chat: %s: \t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1642
1643 return 1;
1644}
1645
1646int faimtest_chat_infoupdate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1647{
1648 va_list ap;
1649 struct aim_userinfo_s *userinfo;
1650 struct aim_chat_roominfo *roominfo;
1651 char *roomname;
1652 int usercount,i;
1653 char *roomdesc;
1654 unsigned short unknown_c9, unknown_d2, unknown_d5, maxmsglen;
1655 unsigned long creationtime;
1656
1657 va_start(ap, command);
1658 roominfo = va_arg(ap, struct aim_chat_roominfo *);
1659 roomname = va_arg(ap, char *);
1660 usercount= va_arg(ap, int);
1661 userinfo = va_arg(ap, struct aim_userinfo_s *);
1662 roomdesc = va_arg(ap, char *);
1663 unknown_c9 = va_arg(ap, int);
1664 creationtime = va_arg(ap, unsigned long);
1665 maxmsglen = va_arg(ap, int);
1666 unknown_d2 = va_arg(ap, int);
1667 unknown_d5 = va_arg(ap, int);
1668 va_end(ap);
1669
1670 dvprintf("faimtest: chat: %s: info update:\n", (char *)command->conn->priv);
1671 dvprintf("faimtest: chat: %s: \tRoominfo: {%04x, %s, %04x}\n",
1672 (char *)command->conn->priv,
1673 roominfo->exchange,
1674 roominfo->name,
1675 roominfo->instance);
1676 dvprintf("faimtest: chat: %s: \tRoomname: %s\n", (char *)command->conn->priv, roomname);
1677 dvprintf("faimtest: chat: %s: \tRoomdesc: %s\n", (char *)command->conn->priv, roomdesc);
1678 dvprintf("faimtest: chat: %s: \tOccupants: (%d)\n", (char *)command->conn->priv, usercount);
1679
1680 for (i = 0; i < usercount; )
1681 dvprintf("faimtest: chat: %s: \t\t%s\n", (char *)command->conn->priv, userinfo[i++].sn);
1682
1683 dvprintf("faimtest: chat: %s: \tUnknown_c9: 0x%04x\n", (char *)command->conn->priv, unknown_c9);
1684 dvprintf("faimtest: chat: %s: \tCreation time: %lu (time_t)\n", (char *)command->conn->priv, creationtime);
1685 dvprintf("faimtest: chat: %s: \tMax message length: %d bytes\n", (char *)command->conn->priv, maxmsglen);
1686 dvprintf("faimtest: chat: %s: \tUnknown_d2: 0x%04x\n", (char *)command->conn->priv, unknown_d2);
1687 dvprintf("faimtest: chat: %s: \tUnknown_d5: 0x%02x\n", (char *)command->conn->priv, unknown_d5);
1688
1689 return 1;
1690}
1691
1692int faimtest_chat_incomingmsg(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1693{
1694 va_list ap;
1695 struct aim_userinfo_s *userinfo;
1696 char *msg;
1697 char tmpbuf[1152];
1698
1699 va_start(ap, command);
1700 userinfo = va_arg(ap, struct aim_userinfo_s *);
1701 msg = va_arg(ap, char *);
1702 va_end(ap);
1703
1704 dvprintf("faimtest: chat: %s: incoming msg from %s: %s\n", (char *)command->conn->priv, userinfo->sn, msg);
1705
1706 /*
1707 * Do an echo for testing purposes. But not for ourselves ("oops!")
1708 */
1709 if (strcmp(userinfo->sn, sess->sn) != 0)
1710 {
1711 sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg);
1712 aim_chat_send_im(sess, command->conn, tmpbuf);
1713 }
1714
1715 return 1;
1716}
1717
1718int faimtest_chatnav_info(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1719{
1720 unsigned short type;
1721 va_list ap;
1722
1723 va_start(ap, command);
1724 type = va_arg(ap, int);
1725
1726 switch(type) {
1727 case 0x0002: {
1728 int maxrooms;
1729 struct aim_chat_exchangeinfo *exchanges;
1730 int exchangecount,i = 0;
1731
1732 maxrooms = va_arg(ap, int);
1733 exchangecount = va_arg(ap, int);
1734 exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
1735 va_end(ap);
1736
1737 dprintf("faimtest: chat info: Chat Rights:\n");
1738 dvprintf("faimtest: chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
1739
1740 dvprintf("faimtest: chat info: \tExchange List: (%d total)\n", exchangecount);
1741 for (i = 0; i < exchangecount; i++) {
1742 dvprintf("faimtest: chat info: \t\t%x: %s (%s/%s)\n",
1743 exchanges[i].number,
1744 exchanges[i].name,
1745 exchanges[i].charset1,
1746 exchanges[i].lang1);
1747 }
1748
1749 }
1750 break;
1751 case 0x0008: {
1752 char *fqcn, *name, *ck;
1753 unsigned short instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
1754 unsigned char createperms;
1755 unsigned long createtime;
1756
1757 fqcn = va_arg(ap, char *);
1758 instance = va_arg(ap, int);
1759 exchange = va_arg(ap, int);
1760 flags = va_arg(ap, int);
1761 createtime = va_arg(ap, unsigned long);
1762 maxmsglen = va_arg(ap, int);
1763 maxoccupancy = va_arg(ap, int);
1764 createperms = va_arg(ap, int);
1765 unknown = va_arg(ap, int);
1766 name = va_arg(ap, char *);
1767 ck = va_arg(ap, char *);
1768 va_end(ap);
1769
1770 dvprintf("faimtest: received room create reply for %s/0x%04x\n", fqcn, exchange);
1771 }
1772 break;
1773 default:
1774 va_end(ap);
1775 dvprintf("faimtest: chatnav info: unknown type (%04x)\n", type);
1776 }
1777 return 1;
1778}
1779
1780int faimtest_parse_connerr(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1781{
1782 va_list ap;
1783 unsigned short code;
1784 char *msg = NULL;
1785
1786 va_start(ap, command);
1787 code = va_arg(ap, int);
1788 msg = va_arg(ap, char *);
1789 va_end(ap);
1790
1791 dvprintf("faimtest: connerr: Code 0x%04x: %s\n", code, msg);
1792 aim_conn_kill(sess, &command->conn); /* this will break the main loop */
1793
1794 return 1;
1795}
1796
1797int faimtest_debugconn_connect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1798{
1799 dprintf("faimtest: connecting to an aimdebugd!\n");
1800
1801 /* convert the authorizer connection to a BOS connection */
1802 command->conn->type = AIM_CONN_TYPE_BOS;
1803
1804 aim_conn_addhandler(sess, command->conn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, faimtest_parse_incoming_im, 0);
1805
1806 /* tell the aimddebugd we're ready */
1807 aim_debugconn_sendconnect(sess, command->conn);
1808
1809 /* go right into main loop (don't open a BOS connection, etc) */
1810 return 1;
1811}
1812
1813/*
1814 * Received in response to an IM sent with the AIM_IMFLAGS_ACK option.
1815 */
1816int faimtest_parse_msgack(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1817{
1818 va_list ap;
1819 unsigned short type;
1820 char *sn = NULL;
1821
1822 va_start(ap, command);
1823 type = va_arg(ap, int);
1824 sn = va_arg(ap, char *);
1825 va_end(ap);
1826
1827 dvprintf("faimtest: msgack: 0x%04x / %s\n", type, sn);
1828
1829 return 1;
1830}
1831
1832int faimtest_getfile_filereq(struct aim_session_t *ses, struct command_rx_struct *command, ...)
1833{
1834 va_list ap;
1835 struct aim_conn_t *oftconn;
1836 struct aim_fileheader_t *fh;
1837 char *cookie;
1838
1839 va_start(ap, command);
1840 oftconn = va_arg(ap, struct aim_conn_t *);
1841 fh = va_arg(ap, struct aim_fileheader_t *);
1842 cookie = va_arg(ap, char *);
1843 va_end(ap);
1844
1845 dvprintf("faimtest: request for file %s.\n", fh->name);
1846
1847 return 1;
1848}
1849
1850
1851int faimtest_getfile_filesend(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1852{
1853 va_list ap;
1854 struct aim_conn_t *oftconn;
1855 struct aim_fileheader_t *fh;
1856 char *path, *cookie;
1857 int pos, bufpos = 0, bufsize = 2048, i;
1858 char *buf;
1859
1860 FILE *file;
1861
1862 va_start(ap, command);
1863 oftconn = va_arg(ap, struct aim_conn_t *);
1864 fh = va_arg(ap, struct aim_fileheader_t *);
1865 cookie = va_arg(ap, char *);
1866 va_end(ap);
1867
1868 dvprintf("faimtest: sending file %s(%ld).\n", fh->name, fh->size);
1869
1870 if(!(buf = malloc(2048)))
1871 return -1;
1872
1873 if( (path = (char *)calloc(1, strlen(listingpath) +strlen(fh->name)+2)) == NULL) {
1874 dperror("calloc");
1875 dprintf("faimtest: error in calloc of path\n");
1876 return 0; /* XXX: no idea what winaim expects here =) */
1877 }
1878
1879 snprintf(path, strlen(listingpath)+strlen(fh->name)+2, "%s/%s", listingpath, fh->name);
1880
1881
1882 if( (file = fopen(path, "r")) == NULL) {
1883 dvprintf("faimtest: getfile_send fopen failed for %s. damn.\n", path);
1884 return 0;
1885 }
1886
1887 /*
1888 * This is a mess. Remember that faimtest is demonstration code
1889 * only and for the sake of the gods, don't use this code in any
1890 * of your clients. --mid
1891 */
1892 for(pos = 0; pos < fh->size; pos++) {
1893 bufpos = pos % bufsize;
1894
1895 if(bufpos == 0 && pos > 0) { /* filled our buffer. spit it across the wire */
1896 if ( (i = send(oftconn->fd, buf, bufsize, 0)) != bufsize ) {
1897 dperror("faim: getfile_send: write1");
1898 dprintf("faim: getfile_send: whoopsy, didn't write it all...\n");
1899 free(buf);
1900 return -1;
1901 }
1902 }
1903 if( (buf[bufpos] = fgetc(file)) == EOF) {
1904 if(pos != fh->size) {
1905 dvprintf("faim: getfile_send: hrm... apparent early EOF at pos 0x%x of 0x%lx\n", pos, fh->size);
1906 free(buf);
1907 return -1;
1908 }
1909 }
1910 dvprintf("%c(0x%02x) ", buf[pos], buf[pos]);
1911 }
1912
1913 if( (i = send(oftconn->fd, buf, bufpos+1, 0)) != (bufpos+1)) {
1914 dperror("faim: getfile_send: write2");
1915 dprintf("faim: getfile_send cleanup: whoopsy, didn't write it all...\n");
1916 free(buf);
1917 return -1;
1918 }
1919
1920 free(buf);
1921 free(fh);
1922 return 1;
1923}
1924
1925int faimtest_getfile_complete(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1926{
1927 va_list ap;
1928 struct aim_conn_t *conn;
1929 struct aim_fileheader_t *fh;
1930
1931 va_start(ap, command);
1932 conn = va_arg(ap, struct aim_conn_t *);
1933 fh = va_arg(ap, struct aim_fileheader_t *);
1934 va_end(ap);
1935
1936 dvprintf("faimtest: completed file transfer for %s.\n", fh->name);
1937
1938 aim_conn_close(conn);
1939 aim_conn_kill(sess, &conn);
1940 return 1;
1941}
1942
1943int faimtest_getfile_disconnect(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1944{
1945 va_list ap;
1946 struct aim_conn_t *conn;
1947 char *sn;
1948
1949 va_start(ap, command);
1950 conn = va_arg(ap, struct aim_conn_t *);
1951 sn = va_arg(ap, char *);
1952 va_end(ap);
1953
1954 aim_conn_kill(sess, &conn);
1955
1956 dvprintf("faimtest: getfile: disconnected from %s\n", sn);
1957 return 1;
1958}
1959int faimtest_getfile_initiate(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1960{
1961 va_list ap;
1962 struct aim_conn_t *conn, *listenerconn;
1963 struct aim_filetransfer_priv *priv;
1964
1965 va_start(ap, command);
1966 conn = va_arg(ap, struct aim_conn_t *);
1967 listenerconn = va_arg(ap, struct aim_conn_t *);
1968 va_end(ap);
1969
1970 aim_conn_close(listenerconn);
1971 aim_conn_kill(sess, &listenerconn);
1972
1973 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILEREQ, faimtest_getfile_filereq, 0);
1974 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEFILESEND, faimtest_getfile_filesend, 0);
1975 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILECOMPLETE, faimtest_getfile_complete, 0);
1976 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILEDISCONNECT, faimtest_getfile_disconnect, 0);
1977 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTING, faimtest_getfile_listing, 0);
1978 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILELISTINGREQ, faimtest_getfile_listingreq, 0);
1979 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILERECEIVE, faimtest_getfile_receive, 0);
1980 aim_conn_addhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_GETFILESTATE4, faimtest_getfile_state4, 0);
1981
1982 priv = (struct aim_filetransfer_priv *)conn->priv;
1983
1984 dvprintf("faimtest: getfile: %s (%s) connected to us on %d\n", priv->sn, priv->ip, conn->fd);
1985 return 1;
1986}
1987
1988int faimtest_getfile_listing(struct aim_session_t *sess, struct command_rx_struct *command, ...)
1989{
1990 va_list ap;
1991 struct aim_conn_t *conn;
1992 char *listing;
1993 struct aim_filetransfer_priv *ft;
1994 char *filename, *nameend, *sizec;
1995 int filesize, namelen;
1996
1997 va_start(ap, command);
1998 conn = va_arg(ap, struct aim_conn_t *);
1999 ft = va_arg(ap, struct aim_filetransfer_priv *);
2000 listing = va_arg(ap, char *);
2001 va_end(ap);
2002
2003 dvprintf("listing on %d==================\n%s\n===========\n", conn->fd, listing);
2004
2005 nameend = strstr(listing+0x1a, "\r");
2006
2007 namelen = nameend - (listing + 0x1a);
2008
2009 filename = malloc(namelen + 1);
2010 strncpy(filename, listing+0x1a, namelen);
2011 filename[namelen] = 0x00;
2012
2013 sizec = malloc(8+1);
2014 memcpy(sizec, listing + 0x11, 8);
2015 sizec[8] = 0x00;
2016
2017 filesize = strtol(sizec, (char **)NULL, 10);
2018
2019 dvprintf("faimtest: requesting %d %s(%d long)\n", namelen, filename, filesize);
2020
2021 aim_oft_getfile_request(sess, conn, filename, filesize);
2022
2023 free(filename);
2024 free(sizec);
2025
2026 return 0;
2027}
2028
2029int faimtest_getfile_listingreq(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2030{
2031 va_list ap;
2032 struct aim_conn_t *oftconn;
2033 struct aim_fileheader_t *fh;
2034 int pos, bufpos = 0, bufsize = 2048, i;
2035 char *buf;
2036
2037 va_start(ap, command);
2038 oftconn = va_arg(ap, struct aim_conn_t *);
2039 fh = va_arg(ap, struct aim_fileheader_t *);
2040 va_end(ap);
2041
2042 dvprintf("faimtest: sending listing of size %ld\n", fh->size);
2043
2044 if(!(buf = malloc(2048)))
2045 return -1;
2046
2047 for(pos = 0; pos < fh->size; pos++) {
2048 bufpos = pos % bufsize;
2049
2050 if(bufpos == 0 && pos > 0) { /* filled our buffer. spit it across the wire */
2051 if ( (i = send(oftconn->fd, buf, bufsize, 0)) != bufsize ) {
2052 dperror("faim: getfile_send: write1");
2053 dprintf("faim: getfile_send: whoopsy, didn't write it all...\n");
2054 free(buf);
2055 return -1;
2056 }
2057 }
2058 if( (buf[bufpos] = fgetc(listingfile)) == EOF) {
2059 if(pos != fh->size) {
2060 dvprintf("faim: getfile_send: hrm... apparent early EOF at pos 0x%x of 0x%lx\n", pos, fh->size);
2061 free(buf);
2062 return -1;
2063 }
2064 }
2065 }
2066
2067 if( (i = send(oftconn->fd, buf, bufpos+1, 0)) != (bufpos+1)) {
2068 dperror("faim: getfile_send: write2");
2069 dprintf("faim: getfile_send cleanup: whoopsy, didn't write it all...\n");
2070 free(buf);
2071 return -1;
2072 }
2073
2074 dprintf("faimtest: sent listing\n");
2075 free(buf);
2076 return 0;
2077}
2078
2079int faimtest_getfile_receive(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2080{
2081 va_list ap;
2082 struct aim_conn_t *conn;
2083 struct aim_filetransfer_priv *ft;
2084 unsigned char data;
2085 int pos;
2086
2087 va_start(ap, command);
2088 conn = va_arg(ap, struct aim_conn_t *);
2089 ft = va_arg(ap, struct aim_filetransfer_priv *);
2090 va_end(ap);
2091
2092 dvprintf("faimtest: receiving %ld bytes of file data for %s:\n\t", ft->fh.size, ft->fh.name);
2093
2094 for(pos = 0; pos < ft->fh.size; pos++) {
2095 read(conn->fd, &data, 1);
2096 printf("%c(%02x) ", data, data);
2097 }
2098
2099 printf("\n");
2100
2101 aim_oft_getfile_end(sess, conn);
2102
2103 return 0;
2104}
2105
2106int faimtest_getfile_state4(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2107{
2108 va_list ap;
2109 struct aim_conn_t *conn;
2110
2111 va_start(ap, command);
2112 conn = va_arg(ap, struct aim_conn_t *);
2113 va_end(ap);
2114
2115 aim_conn_close(conn);
2116 aim_conn_kill(sess, &conn);
2117 return 0;
2118}
2119
2120
2121int faimtest_parse_ratechange(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2122{
2123 static char *codes[5] = {"invalid",
2124 "change",
2125 "warning",
2126 "limit",
2127 "limit cleared"};
2128 va_list ap;
2129 int code;
2130 unsigned long rateclass, windowsize, clear, alert, limit, disconnect;
2131 unsigned long currentavg, maxavg;
2132
2133 va_start(ap, command);
2134
2135 /* See code explanations below */
2136 code = va_arg(ap, int);
2137
2138 /*
2139 * See comments above aim_parse_ratechange_middle() in aim_rxhandlers.c.
2140 */
2141 rateclass = va_arg(ap, unsigned long);
2142
2143 /*
2144 * Not sure what this is exactly. I think its the temporal
2145 * relation factor (ie, how to make the rest of the numbers
2146 * make sense in the real world).
2147 */
2148 windowsize = va_arg(ap, unsigned long);
2149
2150 /* Explained below */
2151 clear = va_arg(ap, unsigned long);
2152 alert = va_arg(ap, unsigned long);
2153 limit = va_arg(ap, unsigned long);
2154 disconnect = va_arg(ap, unsigned long);
2155 currentavg = va_arg(ap, unsigned long);
2156 maxavg = va_arg(ap, unsigned long);
2157
2158 va_end(ap);
2159
2160
2161 dvprintf("faimtest: rate %s (rate class 0x%04lx): curavg = %ld, maxavg = %ld, alert at %ld, clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)\n",
2162 (code < 5)?codes[code]:"invalid",
2163 rateclass,
2164 currentavg, maxavg,
2165 alert, clear,
2166 limit, disconnect,
2167 windowsize);
2168
2169 if (code == AIM_RATE_CODE_CHANGE) {
2170 /*
2171 * Not real sure when these get sent.
2172 */
2173 if (currentavg >= clear)
2174 aim_conn_setlatency(command->conn, 0);
2175
2176 } else if (code == AIM_RATE_CODE_WARNING) {
2177 /*
2178 * We start getting WARNINGs the first time we go below the 'alert'
2179 * limit (currentavg < alert) and they stop when either we pause
2180 * long enough for currentavg to go above 'clear', or until we
2181 * flood it bad enough to go below 'limit' (and start getting
2182 * LIMITs instead) or even further and go below 'disconnect' and
2183 * get disconnected completely (and won't be able to login right
2184 * away either).
2185 */
2186 aim_conn_setlatency(command->conn, windowsize/4); /* XXX this is bogus! */
2187
2188 } else if (code == AIM_RATE_CODE_LIMIT) {
2189 /*
2190 * When we hit LIMIT, messages will start getting dropped.
2191 */
2192 aim_conn_setlatency(command->conn, windowsize/2); /* XXX this is bogus! */
2193
2194 } else if (code == AIM_RATE_CODE_CLEARLIMIT) {
2195 /*
2196 * The limit is cleared when curavg goes above 'clear'.
2197 */
2198 aim_conn_setlatency(command->conn, 0);
2199 }
2200
2201 return 1;
2202}
2203
2204int faimtest_parse_evilnotify(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2205{
2206 va_list ap;
2207 int newevil;
2208 struct aim_userinfo_s *userinfo;
2209
2210 va_start(ap, command);
2211 newevil = va_arg(ap, int);
2212 userinfo = va_arg(ap, struct aim_userinfo_s *);
2213 va_end(ap);
2214
2215 /*
2216 * Evil Notifications that are lacking userinfo->sn are anon-warns
2217 * if they are an evil increases, but are not warnings at all if its
2218 * a decrease (its the natural backoff happening).
2219 *
2220 * newevil is passed as an int representing the new evil value times
2221 * ten.
2222 */
2223 dvprintf("faimtest: evil level change: new value = %2.1f%% (caused by %s)\n", ((float)newevil)/10, (userinfo && strlen(userinfo->sn))?userinfo->sn:"anonymous");
2224
2225 return 1;
2226}
2227
2228int faimtest_parse_searchreply(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2229{
2230 va_list ap;
2231 char *address, *SNs;
2232 int i, num;
2233
2234 va_start(ap, command);
2235 address = va_arg(ap, char *);
2236 num = va_arg(ap, int);
2237 SNs = va_arg(ap, char *);
2238 va_end(ap);
2239
2240 dvprintf("faimtest: E-Mail Search Results for %s: ", address);
2241
2242 for(i = 0; i < num; i++)
2243 dvinlineprintf("%s, ", &SNs[i*(MAXSNLEN+1)]);
2244 dinlineprintf("\n");
2245
2246 return 1;
2247}
2248
2249int faimtest_parse_searcherror(struct aim_session_t *sess, struct command_rx_struct *command, ...)
2250{
2251 va_list ap;
2252 char *address;
2253
2254 va_start(ap, command);
2255 address = va_arg(ap, char *);
2256 va_end(ap);
2257
2258 dvprintf("faimtest: E-Mail Search Results for %s: No Results or Invalid Email\n", address);
2259
2260 return 1;
2261}
This page took 0.181399 seconds and 5 git commands to generate.