📄 family_oservice.c
字号:
return 1;}/* Subtype 0x0008 - Add Rate Parameter */voidaim_srv_rates_addparam(OscarData *od, FlapConnection *conn){ FlapFrame *frame; aim_snacid_t snacid; GSList *tmp; frame = flap_frame_new(od, 0x02, 512); snacid = aim_cachesnac(od, 0x0001, 0x0008, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0001, 0x0008, 0x0000, snacid); for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next) { struct rateclass *rateclass; rateclass = tmp->data; byte_stream_put16(&frame->data, rateclass->classid); } flap_connection_send(conn, frame);}/* Subtype 0x0009 - Delete Rate Parameter */voidaim_srv_rates_delparam(OscarData *od, FlapConnection *conn){ FlapFrame *frame; aim_snacid_t snacid; GSList *tmp; frame = flap_frame_new(od, 0x02, 512); snacid = aim_cachesnac(od, 0x0001, 0x0009, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0001, 0x0009, 0x0000, snacid); for (tmp = conn->rateclasses; tmp != NULL; tmp = tmp->next) { struct rateclass *rateclass; rateclass = tmp->data; byte_stream_put16(&frame->data, rateclass->classid); } flap_connection_send(conn, frame);}/* Subtype 0x000a - Rate Change */static intratechange(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ int ret = 0; aim_rxcallback_t userfunc; guint16 code, classid; struct rateclass *rateclass; code = byte_stream_get16(bs); classid = byte_stream_get16(bs); rateclass = rateclass_find(conn->rateclasses, classid); if (rateclass == NULL) /* This should never really happen */ return 0; rateclass->windowsize = byte_stream_get32(bs); rateclass->clear = byte_stream_get32(bs); rateclass->alert = byte_stream_get32(bs); rateclass->limit = byte_stream_get32(bs); rateclass->disconnect = byte_stream_get32(bs); rateclass->current = byte_stream_get32(bs); rateclass->max = byte_stream_get32(bs); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, code, classid, rateclass->windowsize, rateclass->clear, rateclass->alert, rateclass->limit, rateclass->disconnect, rateclass->current, rateclass->max); return ret;}/* * How Migrations work. * * The server sends a Server Pause message, which the client should respond to * with a Server Pause Ack, which contains the families it needs on this * connection. The server will send a Migration Notice with an IP address, and * then disconnect. Next the client should open the connection and send the * cookie. Repeat the normal login process and pretend this never happened. * * The Server Pause contains no data. * *//* Subtype 0x000b - Service Pause */static intserverpause(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ int ret = 0; aim_rxcallback_t userfunc; if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame); return ret;}/* * Subtype 0x000c - Service Pause Acknowledgement * * It is rather important that aim_srv_sendpauseack() gets called for the exact * same connection that the Server Pause callback was called for, since * libfaim extracts the data for the SNAC from the connection structure. * * Of course, if you don't do that, more bad things happen than just what * libfaim can cause. * */voidaim_srv_sendpauseack(OscarData *od, FlapConnection *conn){ FlapFrame *frame; aim_snacid_t snacid; GSList *cur; frame = flap_frame_new(od, 0x02, 1024); snacid = aim_cachesnac(od, 0x0001, 0x000c, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0001, 0x000c, 0x0000, snacid); /* * This list should have all the groups that the original * Host Online / Server Ready said this host supports. And * we want them all back after the migration. */ for (cur = conn->groups; cur != NULL; cur = cur->next) byte_stream_put16(&frame->data, GPOINTER_TO_UINT(cur->data)); flap_connection_send(conn, frame);}/* Subtype 0x000d - Service Resume */static intserverresume(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ int ret = 0; aim_rxcallback_t userfunc; if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame); return ret;}/* Subtype 0x000e - Request self-info */voidaim_srv_reqpersonalinfo(OscarData *od, FlapConnection *conn){ aim_genericreq_n_snacid(od, conn, 0x0001, 0x000e);}/* Subtype 0x000f - Self User Info */static intselfinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ int ret = 0; aim_rxcallback_t userfunc; aim_userinfo_t userinfo; aim_info_extract(od, bs, &userinfo); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, &userinfo); aim_info_free(&userinfo); return ret;}/* Subtype 0x0010 - Evil Notification */static intevilnotify(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ int ret = 0; aim_rxcallback_t userfunc; guint16 newevil; aim_userinfo_t userinfo; memset(&userinfo, 0, sizeof(aim_userinfo_t)); newevil = byte_stream_get16(bs); if (byte_stream_empty(bs)) aim_info_extract(od, bs, &userinfo); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, newevil, &userinfo); aim_info_free(&userinfo); return ret;}/* * Subtype 0x0011 - Idle Notification * * Should set your current idle time in seconds. Note that this should * never be called consecutively with a non-zero idle time. That makes * OSCAR do funny things. Instead, just set it once you go idle, and then * call it again with zero when you're back. * */voidaim_srv_setidle(OscarData *od, guint32 idletime){ FlapConnection *conn; conn = flap_connection_findbygroup(od, SNAC_FAMILY_BOS); if(!conn) return; aim_genericreq_l(od, conn, 0x0001, 0x0011, &idletime);}/* * Subtype 0x0012 - Service Migrate * * This is the final SNAC sent on the original connection during a migration. * It contains the IP and cookie used to connect to the new server, and * optionally a list of the SNAC groups being migrated. * */static intmigrate(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ aim_rxcallback_t userfunc; int ret = 0; guint16 groupcount, i; GSList *tlvlist; char *ip = NULL; aim_tlv_t *cktlv; /* * Apparently there's some fun stuff that can happen right here. The * migration can actually be quite selective about what groups it * moves to the new server. When not all the groups for a connection * are migrated, or they are all migrated but some groups are moved * to a different server than others, it is called a bifurcated * migration. * * Let's play dumb and not support that. * */ groupcount = byte_stream_get16(bs); for (i = 0; i < groupcount; i++) { guint16 group; group = byte_stream_get16(bs); purple_debug_misc("oscar", "bifurcated migration unsupported -- group 0x%04x\n", group); } tlvlist = aim_tlvlist_read(bs); if (aim_tlv_gettlv(tlvlist, 0x0005, 1)) ip = aim_tlv_getstr(tlvlist, 0x0005, 1); cktlv = aim_tlv_gettlv(tlvlist, 0x0006, 1); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, ip, cktlv ? cktlv->value : NULL); aim_tlvlist_free(tlvlist); g_free(ip); return ret;}/* Subtype 0x0013 - Message of the Day */static intmotd(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs){ aim_rxcallback_t userfunc; char *msg = NULL; int ret = 0; GSList *tlvlist; guint16 id; /* * Code. * * Valid values: * 1 Mandatory upgrade * 2 Advisory upgrade * 3 System bulletin * 4 Nothing's wrong ("top o the world" -- normal) * 5 Lets-break-something. * */ id = byte_stream_get16(bs); /* * TLVs follow */ tlvlist = aim_tlvlist_read(bs); msg = aim_tlv_getstr(tlvlist, 0x000b, 1); if ((userfunc = aim_callhandler(od, snac->family, snac->subtype))) ret = userfunc(od, conn, frame, id, msg); g_free(msg); aim_tlvlist_free(tlvlist); return ret;}/* * Subtype 0x0014 - Set privacy flags * * Normally 0x03. * * Bit 1: Allows other AIM users to see how long you've been idle. * Bit 2: Allows other AIM users to see how long you've been a member. * */voidaim_srv_setprivacyflags(OscarData *od, FlapConnection *conn, guint32 flags){ aim_genericreq_l(od, conn, 0x0001, 0x0014, &flags);}/* * Subtype 0x0016 - No-op * * WinAIM sends these every 4min or so to keep the connection alive. Its not * really necessary. * * Wha? No? Since when? I think WinAIM sends an empty channel 5 * FLAP as a no-op... */voidaim_srv_nop(OscarData *od, FlapConnection *conn){ aim_genericreq_n(od, conn, 0x0001, 0x0016);}/* * Subtype 0x0017 - Set client versions * * If you've seen the clientonline/clientready SNAC you're probably * wondering what the point of this one is. And that point seems to be * that the versions in the client online SNAC are sent too late for the * server to be able to use them to change the protocol for the earlier * login packets (client versions are sent right after Host Online is * received, but client online versions aren't sent until quite a bit later). * We can see them already making use of this by changing the format of * the rate information based on what version of group 1 we advertise here. * */voidaim_srv_setversions(OscarData *od, FlapConnection *conn){ FlapFrame *frame; aim_snacid_t snacid; GSList *cur; frame = flap_frame_new(od, 0x02, 1152); snacid = aim_cachesnac(od, 0x0001, 0x0017, 0x0000, NULL, 0); aim_putsnac(&frame->data, 0x0001, 0x0017, 0x0000, snacid);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -