Пример #1
0
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);  
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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);
  }
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
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;
}
Пример #9
0
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, &section);
  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;
}
Пример #10
0
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);
  }
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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, &section);
  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;
}