static void LOGIN_REDIRECT_get(struct mwGetBuffer *b, struct mwMsgLoginRedirect *msg) { if(mwGetBuffer_error(b)) return; mwString_get(b, &msg->host); mwString_get(b, &msg->server_id); }
static void WELCOME_recv(struct mwServiceConference *srvc, struct mwConference *conf, struct mwGetBuffer *b) { struct mwConferenceHandler *h; guint16 tmp16; guint32 tmp32; guint32 count; GList *l = NULL; /* re-read name and title */ g_free(conf->name); g_free(conf->title); conf->name = NULL; conf->title = NULL; mwString_get(b, &conf->name); mwString_get(b, &conf->title); /* some numbers we don't care about, then a count of members */ guint16_get(b, &tmp16); guint32_get(b, &tmp32); guint32_get(b, &count); if(mwGetBuffer_error(b)) { g_warning("error parsing welcome message for conference"); mwConference_destroy(conf, ERR_FAILURE, NULL); return; } while(count--) { guint16 member_id; struct mwLoginInfo *member = g_new0(struct mwLoginInfo, 1); guint16_get(b, &member_id); mwLoginInfo_get(b, member); if(mwGetBuffer_error(b)) { login_free(member); break; } MEMBER_ADD(conf, member_id, member); l = g_list_append(l, member); } conf_state(conf, mwConference_OPEN); h = srvc->handler; if(h->conf_opened) h->conf_opened(conf, l); /* get rid of the GList, but not its contents */ g_list_free(l); }
static void recv_channelCreate(struct mwServiceFileTransfer *srvc, struct mwChannel *chan, struct mwMsgChannelCreate *msg) { struct mwFileTransferHandler *handler; struct mwGetBuffer *b; char *fnm, *txt; guint32 size, junk; gboolean b_err; g_return_if_fail(srvc->handler != NULL); handler = srvc->handler; b = mwGetBuffer_wrap(&msg->addtl); guint32_get(b, &junk); /* unknown */ mwString_get(b, &fnm); /* offered filename */ mwString_get(b, &txt); /* offering message */ guint32_get(b, &size); /* size of offered file */ /// Miranda NG adaptation - start - http://www.lilotux.net/~mikael/pub/meanwhile/ft_fix.diff /* guint32_get(b, &junk); */ /* unknown */ /// Miranda NG adaptation - end /* and we just skip an unknown guint16 at the end */ b_err = mwGetBuffer_error(b); mwGetBuffer_free(b); if(b_err) { g_warning("bad/malformed addtl in File Transfer service"); mwChannel_destroy(chan, ERR_FAILURE, NULL); } else { struct mwIdBlock idb; struct mwFileTransfer *ft; login_into_id(&idb, mwChannel_getUser(chan)); ft = mwFileTransfer_new(srvc, &idb, txt, fnm, size); ft->channel = chan; ft_state(ft, mwFileTransfer_PENDING); mwChannel_setServiceData(chan, ft, NULL); if(handler->ft_offered) handler->ft_offered(ft); } g_free(fnm); g_free(txt); }
static void recv_list(struct mwServiceDirectory *srvc, struct mwOpaque *data) { struct mwGetBuffer *b; guint32 request, code, count; gboolean foo_1; guint16 foo_2; b = mwGetBuffer_wrap(data); guint32_get(b, &request); guint32_get(b, &code); guint32_get(b, &count); gboolean_get(b, &foo_1); guint16_get(b, &foo_2); if(foo_1 || foo_2) { mw_mailme_opaque(data, "received strange address book list"); mwGetBuffer_free(b); return; } while(!mwGetBuffer_error(b) && count--) { guint32 id; char *name = NULL; guint32_get(b, &id); mwString_get(b, &name); book_new(srvc, name, id); g_free(name); } }
static void text_recv(struct mwServiceConference *srvc, struct mwConference *conf, struct mwLoginInfo *m, struct mwGetBuffer *b) { /* this function acts a lot like receiving an IM Text message. The text message contains only a string */ char *text = NULL; struct mwConferenceHandler *h; mwString_get(b, &text); if(mwGetBuffer_error(b)) { g_warning("failed to parse text message in conference"); g_free(text); return; } h = srvc->handler; if(text && h->on_text) { h->on_text(conf, m, text); } g_free(text); }
static void LOGIN_get(struct mwGetBuffer *b, struct mwMsgLogin *msg) { if(mwGetBuffer_error(b)) return; guint16_get(b, &msg->login_type); mwString_get(b, &msg->name); mwOpaque_get(b, &msg->auth_data); guint16_get(b, &msg->auth_type); }
static void recv_channelCreate(struct mwService *srvc, struct mwChannel *chan, struct mwMsgChannelCreate *msg) { /* - this is how we really receive invitations - create a conference and associate it with the channel - obtain the invite data from the msg addtl info - mark the conference as INVITED - trigger the got_invite event */ struct mwServiceConference *srvc_conf = (struct mwServiceConference *) srvc; struct mwConference *conf; struct mwGetBuffer *b; char *invite = NULL; guint tmp; conf = conf_new(srvc_conf); conf->channel = chan; b = mwGetBuffer_wrap(&msg->addtl); guint32_get(b, &tmp); mwString_get(b, &conf->name); mwString_get(b, &conf->title); guint32_get(b, &tmp); mwLoginInfo_get(b, &conf->owner); guint32_get(b, &tmp); mwString_get(b, &invite); if(mwGetBuffer_error(b)) { g_warning("failure parsing addtl for conference invite"); mwConference_destroy(conf, ERR_FAILURE, NULL); } else { struct mwConferenceHandler *h = srvc_conf->handler; conf_state(conf, mwConference_INVITED); if(h->on_invited) h->on_invited(conf, &conf->owner, invite); } mwGetBuffer_free(b); g_free(invite); }
static int recv_SECTION_LIST(struct mwPlace *place, struct mwGetBuffer *b) { int ret = 0; guint32 sec, count; mwGetBuffer_advance(b, 4); guint32_get(b, &sec); g_return_val_if_fail(sec == place->section, -1); mwGetBuffer_advance(b, 8); guint32_get(b, &count); mwGetBuffer_advance(b, 8); while(count--) { struct place_member *m; m = g_new0(struct place_member, 1); mwGetBuffer_advance(b, 4); guint32_get(b, &m->place_id); guint16_get(b, &m->member_type); mwIdBlock_get(b, &m->idb); mwString_get(b, &m->login_id); mwString_get(b, &m->name); guint16_get(b, &m->login_type); guint32_get(b, &m->unknown_a); guint32_get(b, &m->unknown_b); PUT_MEMBER(place, m); } if(place->state != mwPlace_OPEN) place_opened(place); return ret; }
static int recv_SECTION_PEER_JOIN(struct mwPlace *place, struct mwGetBuffer *b) { struct mwServicePlace *srvc; struct place_member *pm; guint32 section; int ret = 0; srvc = place->service; guint32_get(b, §ion); if(! section) { g_info("SECTION_PEER_JOIN with section 0x00"); return 0; } mwGetBuffer_advance(b, 4); pm = g_new0(struct place_member, 1); guint32_get(b, &pm->place_id); guint16_get(b, &pm->member_type); mwIdBlock_get(b, &pm->idb); mwString_get(b, &pm->login_id); mwString_get(b, &pm->name); guint16_get(b, &pm->login_type); guint32_get(b, &pm->unknown_a); guint32_get(b, &pm->unknown_b); PUT_MEMBER(place, pm); if(srvc->handler && srvc->handler->peerJoined) srvc->handler->peerJoined(place, &pm->idb); if(pm->place_id == place->our_id) place_opened(place); return ret; }
static void HANDSHAKE_get(struct mwGetBuffer *b, struct mwMsgHandshake *msg) { if(mwGetBuffer_error(b)) return; guint16_get(b, &msg->major); guint16_get(b, &msg->minor); guint32_get(b, &msg->head.channel); guint32_get(b, &msg->srvrcalc_addr); guint16_get(b, &msg->login_type); guint32_get(b, &msg->loclcalc_addr); if(msg->major >= 0x001e && msg->minor >= 0x001d) { guint16_get(b, &msg->unknown_a); guint32_get(b, &msg->unknown_b); mwString_get(b, &msg->local_host); } }
char *mwStorageUnit_asString(struct mwStorageUnit *item) { struct mwGetBuffer *b; char *c = NULL; g_return_val_if_fail(item != NULL, NULL); b = mwGetBuffer_wrap(&item->data); mwString_get(b, &c); if(mwGetBuffer_error(b)) g_debug("error obtaining string value from opaque"); mwGetBuffer_free(b); return c; }
static int recv_MESSAGE(struct mwPlace *place, struct mwGetBuffer *b) { struct mwServicePlace *srvc; guint32 pm_id; guint32 unkn_a, unkn_b, ign; struct place_member *pm; char *msg = NULL; int ret = 0; srvc = place->service; /* no messages before becoming fully open, please */ g_return_val_if_fail(place->state == mwPlace_OPEN, -1); /* regarding unkn_a and unkn_b: they're probably a section indicator and a message count, I'm just not sure which is which. Until this implementation supports place sections in the API, it really doesn't matter. */ guint32_get(b, &pm_id); pm = GET_MEMBER(place, pm_id); g_return_val_if_fail(pm != NULL, -1); guint32_get(b, &unkn_a); guint32_get(b, &ign); /* actually an opaque length */ if(! ign) return ret; guint32_get(b, &unkn_b); mwString_get(b, &msg); if(srvc->handler && srvc->handler->message) srvc->handler->message(place, &pm->idb, msg); g_free(msg); return ret; }
static int recv_INFO(struct mwPlace *place, struct mwGetBuffer *b) { int ret = 0; guint32 skip = 0; guint32 section = 0; guint32_get(b, &skip); guint32_get(b, §ion); mwGetBuffer_advance(b, skip); if(! section) { /* this is a place info rather than member info */ if(place->title) g_free(place->title); mwGetBuffer_advance(b, 2); mwString_get(b, &place->title); place_state(place, mwPlace_JOINED); ret = send_SECTION_LIST(place, place->section); } return ret; }