📄 sessions.c
字号:
/* * Jabber AIM-Transport libfaim interface **/#include "aimtrans.h"#include "utf8.h"void *at_session_main(void *arg);static int getaimdata(char *aimbinarypath, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname){ FILE *f; static const char defaultmod[] = "aim.exe"; char *filename = NULL; struct stat st; unsigned char *buf; int invalid = 0; if(aimbinarypath == NULL) { log_error(ZONE, "Received aim.exe hash request from AOL servers but no aim.exe configured. We may get disconnected.\n"); return -1; } if (modname) { if (!(filename = malloc(strlen(aimbinarypath)+1+strlen(modname)+4+1))) { return -1; } sprintf(filename, "%s/%s.ocm", aimbinarypath, modname); } else { if (!(filename = malloc(strlen(aimbinarypath)+1+strlen(defaultmod)+1))) { return -1; } sprintf(filename, "%s/%s", aimbinarypath, defaultmod); } if (stat(filename, &st) == -1) { if (!modname) { free(filename); return -1; } invalid = 1; } if (!invalid) { if ((offset > st.st_size) || (len > st.st_size)) invalid = 1; else if ((st.st_size - offset) < len) len = st.st_size - offset; else if ((st.st_size - len) < len) len = st.st_size - len; } if (!invalid && len) len %= 4096; if (invalid) { int i; free(filename); /* not needed */ log_debug(ZONE, "memrequest: received invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname); i = 8; if (modname) i += strlen(modname); if (!(buf = malloc(i))) return -1; i = 0; if (modname) { memcpy(buf, modname, strlen(modname)); i += strlen(modname); } /* Damn endianness. This must be little (LSB first) endian. */ buf[i++] = offset & 0xff; buf[i++] = (offset >> 8) & 0xff; buf[i++] = (offset >> 16) & 0xff; buf[i++] = (offset >> 24) & 0xff; buf[i++] = len & 0xff; buf[i++] = (len >> 8) & 0xff; buf[i++] = (len >> 16) & 0xff; buf[i++] = (len >> 24) & 0xff; *bufret = buf; *buflenret = i; } else { if (!(buf = malloc(len))) { free(filename); return -1; } if (!(f = fopen(filename, "r"))) { free(filename); free(buf); return -1; } free(filename); if (fseek(f, offset, SEEK_SET) == -1) { fclose(f); free(buf); return -1; } if (fread(buf, len, 1, f) != 1) { fclose(f); free(buf); return -1; } fclose(f); *bufret = buf; *buflenret = len; } return 0; /* success! */}static int at_memrequest(aim_session_t *sess, aim_frame_t *command, ...){ va_list ap; unsigned long offset, len; unsigned char *buf; char *modname; int buflen; int j; at_session s; ati ti; s = (at_session)sess->aux_data; ti = s->ti; va_start(ap, command); offset = va_arg(ap, unsigned long); len = va_arg(ap, unsigned long); modname = va_arg(ap, char *); va_end(ap); log_debug(ZONE, "We got a memrequest\n"); if(ti->offset == offset && j_strcmp(ti->modname, modname) == 0 && ti->send_buf) { aim_sendmemblock(sess, command->conn, offset, ti->read_len, ti->send_buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST); } else { if (getaimdata(ti->aimbinarydir, &buf, &buflen, offset, len, modname) == 0) { ti->offset = offset; ti->read_len = buflen; if(ti->modname != NULL) free(ti->modname); if(modname != NULL) ti->modname = strdup(modname); if(ti->send_buf != NULL) free(ti->send_buf); if(buflen > 0) ti->send_buf = strdup(buf); else ti->send_buf = NULL; aim_sendmemblock(sess, command->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST); } else { ti->offset = offset; ti->read_len = buflen; if(ti->modname != NULL) free(ti->modname); ti->modname = NULL; if(ti->send_buf != NULL) free(ti->send_buf); ti->send_buf = NULL; aim_sendmemblock(sess, command->conn, offset, len, NULL, AIM_SENDMEMBLOCK_FLAG_ISREQUEST); } } return 1;}int at_conninitdone_bos(aim_session_t *sess, aim_frame_t *command, ...){ char *buddylist; at_session s; /* this is the new profile */ /* XXX Can we let people do this? */ char profile[] = ""; s = sess->aux_data;/* sess->snacid_next = 0x00000001; */ aim_reqpersonalinfo(sess, command->conn); aim_bos_reqlocaterights(sess, command->conn); aim_bos_setprofile(sess, command->conn, profile, NULL, AIM_CAPS_BUDDYICON | AIM_CAPS_CHAT | AIM_CAPS_GETFILE | AIM_CAPS_VOICE | AIM_CAPS_SENDFILE | AIM_CAPS_IMIMAGE); aim_bos_reqbuddyrights(sess, command->conn); /* send the buddy list and profile (required, even if empty) */ buddylist = at_buddy_buildlist(s, s->cur); log_debug(ZONE, "[AIM] Setting buddylist: %s", buddylist); if(aim_bos_setbuddylist(sess, command->conn, buddylist)<0) log_debug(ZONE, "[AIM] Error setting buddylist!"); if(buddylist != NULL) free(buddylist); /* dont really know what this does *//* aim_addicbmparam(sess, command->conn); aim_bos_reqicbmparaminfo(sess, command->conn); */ aim_reqicbmparams(sess); aim_bos_reqrights(sess, command->conn); /* set group permissions -- all user classes */ /* XXX evaluate these! */ aim_bos_setgroupperm(sess, command->conn, AIM_FLAG_ALLUSERS); aim_bos_setprivacyflags(sess, command->conn, AIM_PRIVFLAGS_ALLOWIDLE); return 1;}static int aim_icbmparaminfo(aim_session_t* sess, aim_frame_t* fr, ...){ struct aim_icbmparameters *params; va_list ap; va_start(ap, fr); params = va_arg(ap, struct aim_icbmparameters *); va_end(ap); /* * Set these to your taste, or client medium. Setting minmsginterval * higher is good for keeping yourself from getting flooded (esp * if you're on a slow connection or something where that would be * useful). */ params->maxmsglen = 8000; params->minmsginterval = 0; /* in milliseconds */ aim_seticbmparam(sess, params); return 1;}int at_conninitdone_admin(aim_session_t *sess, aim_frame_t *command, ...){ aim_clientready(sess, command->conn); log_debug(ZONE, "[AT] connected to authorization/admin service"); return 1;}int at_bosrights(aim_session_t *sess, aim_frame_t *command, ...){ unsigned short maxpermits, maxdenies; va_list ap; xmlnode x; at_session s; ati ti; s = sess->aux_data; ti = s->ti; va_start(ap, command); maxpermits = va_arg(ap, u_int); maxdenies = va_arg(ap, u_int); va_end(ap); aim_clientready(sess, command->conn); aim_icq_reqofflinemsgs(sess); log_debug(ZONE, "[AIM] officially connected to BOS, sending pres."); s->loggedin = 1; x = jutil_presnew(JPACKET__AVAILABLE, jid_full(s->cur), "Connected"); xmlnode_put_attrib(x, "from", jid_full(s->from)); at_deliver(ti,x); return 1;}int at_parse_login(aim_session_t *sess, aim_frame_t *command, ...){ struct client_info_s info = AIM_CLIENTINFO_KNOWNGOOD; unsigned char *key; va_list ap; at_session s; s = (at_session)sess->aux_data; va_start(ap, command); key = va_arg(ap, char *); va_end(ap); aim_send_login(sess,command->conn,s->screenname,s->password, &info, key); return 1;}int at_parse_authresp(aim_session_t *sess, aim_frame_t *command, ...){ va_list ap; struct aim_authresp_info *info; aim_conn_t *bosconn = NULL; at_mio am; at_session s; aim_conn_t *conn = NULL; ati ti; s = (at_session)sess->aux_data; ti = s->ti; va_start(ap, command); info = va_arg(ap, struct aim_authresp_info *); conn = command->conn; va_end(ap); log_debug(ZONE, "Auth Response for Screen name: %s\n", info->sn); /* * Check for error. */ if (info->errorcode || !info->bosip || !info->cookie) { spool sp; xmlnode x; xmlnode body; char *errorstr; x = xmlnode_new_tag("presence"); xmlnode_put_attrib(x, "to", jid_full(s->cur)); xmlnode_put_attrib(x, "from", jid_full(s->from)); xmlnode_put_attrib(x, "type", "error"); body = xmlnode_insert_tag(x, "error"); xmlnode_put_attrib(body, "code", "401"); sp = spool_new(xmlnode_pool(x)); spooler(sp, "Error Code #%04x While Logging in to AIM\n", "Error URL: %s\0", sp); errorstr = pmalloc(xmlnode_pool(x), 200); switch (info->errorcode) { case 0x05: sprintf(errorstr, "Incorrect nick/password."); break; case 0x11: sprintf(errorstr, "Your account is currently suspended."); break; case 0x18: sprintf(errorstr, "Connecting too frequently. Try again in ten minutes."); break; case 0x1c: sprintf(errorstr, "Server software is out of date."); break; default: snprintf(errorstr, 200, spool_print(sp), info->errorcode, info->errorurl); break; } xmlnode_insert_cdata(body, errorstr, strlen(errorstr)); at_deliver(ti,x); s->loggedin = 0; /* XXX End the Stuff */ aim_conn_kill(sess, &command->conn); return 1; } aim_conn_kill(sess, &command->conn); bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, info->bosip); /* XXX Handle these better so we actually return and free the threads */ if (bosconn == NULL) { fprintf(stderr, "at: could not connect to BOS: internal error\n"); } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) { fprintf(stderr, "at: could not connect to BOS\n"); aim_conn_kill(sess, &bosconn); } else { aim_conn_setlatency(bosconn, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, at_conncomplete, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, at_conninitdone_bos, 0); aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, at_bosrights, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, at_handleredirect, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, at_parse_oncoming, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, at_parse_offgoing, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, at_parse_incoming_im, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, at_parse_locerr, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, at_parse_misses, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, at_parse_ratechange, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, at_parse_evilnotify, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, at_parse_msgerr, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, at_parse_userinfo, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, at_offlinemsg, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, at_offlinemsgdone, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_SMSRESPONSE, at_icq_smsresponse, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_SIMPLEINFO, at_parse_icq_simpleinfo, 0); /* XXX Future? * aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, at_parse_msgack, 0); */ /* aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_CTN, AIM_CB_CTN_DEFAULT, aim_parse_unknown, 0); */ /* aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_DEFAULT, aim_parse_unknown, 0); */ aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, at_parse_motd, 0); aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, at_parse_connerr, 0); aim_conn_addhandler(sess, bosconn, 0x0001, 0x001f, at_memrequest, 0); aim_conn_addhandler(sess, bosconn, 0x0004, 0x0005, aim_icbmparaminfo, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -