Example #1
0
MsnSlpCall *
msn_slp_sip_recv(MsnSlpLink *slplink, const char *body)
{
	MsnSlpCall *slpcall;

	if (body == NULL)
	{
		pecan_warning ("received bogus message");
		return NULL;
	}

	if (!strncmp(body, "INVITE", strlen("INVITE")))
	{
		char *branch;
		char *content;
		char *content_type;

		slpcall = msn_slp_call_new(slplink);

		/* From: <msnmsgr:[email protected]> */
#if 0
		slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");
#endif

		branch = get_token(body, ";branch={", "}");

		slpcall->id = get_token(body, "Call-ID: {", "}");

#if 0
		long content_len = -1;

		temp = get_token(body, "Content-Length: ", "\r\n");
		if (temp != NULL)
			content_len = atoi(temp);
		g_free(temp);
#endif
		content_type = get_token(body, "Content-Type: ", "\r\n");

		content = get_token(body, "\r\n\r\n", NULL);

		got_invite(slpcall, branch, content_type, content);

		g_free(branch);
		g_free(content_type);
		g_free(content);
	}
	else if (!strncmp(body, "MSNSLP/1.0 ", strlen("MSNSLP/1.0 ")))
	{
		char *content;
		char *content_type;
		/* Make sure this is "OK" */
		const char *status = body + strlen("MSNSLP/1.0 ");
		char *call_id;

		call_id = get_token(body, "Call-ID: {", "}");
		slpcall = msn_slplink_find_slp_call(slplink, call_id);
		g_free(call_id);

		g_return_val_if_fail(slpcall != NULL, NULL);

		if (strncmp(status, "200 OK", 6))
		{
			/* It's not valid. Kill this off. */
			char temp[32];
			const char *c;

			/* Eww */
			if ((c = strchr(status, '\r')) || (c = strchr(status, '\n')) ||
				(c = strchr(status, '\0')))
			{
				size_t offset =  c - status;
				if (offset >= sizeof(temp))
					offset = sizeof(temp) - 1;

				strncpy(temp, status, offset);
				temp[offset] = '\0';
			}

			pecan_error ("received non-OK result: %s", temp);

			slpcall->wasted = TRUE;

			/* msn_slp_call_destroy(slpcall); */
			return slpcall;
		}

		content_type = get_token(body, "Content-Type: ", "\r\n");

		content = get_token(body, "\r\n\r\n", NULL);

		got_ok(slpcall, content_type, content);

		g_free(content_type);
		g_free(content);
	}
	else if (!strncmp(body, "BYE", strlen("BYE")))
	{
		char *call_id;

		call_id = get_token(body, "Call-ID: {", "}");
		slpcall = msn_slplink_find_slp_call(slplink, call_id);
		g_free(call_id);

		if (slpcall != NULL)
			slpcall->wasted = TRUE;

		/* msn_slp_call_destroy(slpcall); */
	}
	else
		slpcall = NULL;

	return slpcall;
}
Example #2
0
static int gotmode(char *from, char *origmsg)
{
  char *nick, *ch, *op, *chg, *msg;
  char s[UHOSTLEN], buf[511];
  char ms2[3];
  int z;
  struct userrec *u;
  memberlist *m;
  struct chanset_t *chan;

  strncpy(buf, origmsg, 510);
  buf[510] = 0;
  msg = buf;
  /* Usermode changes? */
  if (msg[0] && (strchr(CHANMETA, msg[0]) != NULL)) {
    ch = newsplit(&msg);
    chg = newsplit(&msg);
    reversing = 0;
    chan = findchan(ch);
    if (!chan) {
      putlog(LOG_MISC, "*", CHAN_FORCEJOIN, ch);
      dprintf(DP_SERVER, "PART %s\n", ch);
    } else if (channel_active(chan) || channel_pending(chan)) {
      z = strlen(msg);
      if (msg[--z] == ' ')      /* I hate cosmetic bugs :P -poptix */
        msg[z] = 0;
      putlog(LOG_MODES, chan->dname, "%s: mode change '%s %s' by %s", ch, chg,
             msg, from);
      u = get_user_by_host(from);
      get_user_flagrec(u, &user, ch);
      nick = splitnick(&from);
      m = ismember(chan, nick);
      if (m)
        m->last = now;
      if (m && channel_active(chan) && (me_op(chan) || (me_halfop(chan) &&
          !chan_hasop(m))) && !(glob_friend(user) || chan_friend(user) ||
          (channel_dontkickops(chan) && (chan_op(user) || (glob_op(user) &&
          !chan_deop(user))))) && !match_my_nick(nick)) {
        if (chan_fakeop(m) || chan_fakehalfop(m)) {
          putlog(LOG_MODES, ch, CHAN_FAKEMODE, ch);
          dprintf(DP_MODE, "KICK %s %s :%s\n", ch, nick, CHAN_FAKEMODE_KICK);
          m->flags |= SENTKICK;
          reversing = 1;
        } else if (!chan_hasop(m) && !chan_hashalfop(m) &&
                 !channel_nodesynch(chan)) {
          putlog(LOG_MODES, ch, CHAN_DESYNCMODE, ch);
          dprintf(DP_MODE, "KICK %s %s :%s\n", ch, nick, CHAN_DESYNCMODE_KICK);
          m->flags |= SENTKICK;
          reversing = 1;
        }
      }
      ms2[0] = '+';
      ms2[2] = 0;
      while ((ms2[1] = *chg)) {
        int todo = 0;

        switch (*chg) {
        case '+':
          ms2[0] = '+';
          break;
        case '-':
          ms2[0] = '-';
          break;
        case 'i':
          todo = CHANINV;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'p':
          todo = CHANPRIV;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 's':
          todo = CHANSEC;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'm':
          todo = CHANMODER;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'c':
          todo = CHANNOCLR;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'C':
          todo = CHANNOCTCP;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'R':
          todo = CHANREGON;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'M':
          todo = CHANMODREG;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'r':
          todo = CHANLONLY;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'D':
          todo = CHANDELJN;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'u':
          todo = CHANSTRIP;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'N':
          todo = CHANNONOTC;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'T':
          todo = CHANNOAMSG;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'd':
          todo = CHANINVIS;
          break;
        case 't':
          todo = CHANTOPIC;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'n':
          todo = CHANNOMSG;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'a':
          todo = CHANANON;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'q':
          todo = CHANQUIET;
          if (!nick[0] && bounce_modes)
            reversing = 1;
          break;
        case 'l':
          if (!nick[0] && bounce_modes)
            reversing = 1;
          if (ms2[0] == '-') {
            check_tcl_mode(nick, from, u, chan->dname, ms2, "");
            /* The Tcl proc might have modified/removed the chan or user */
            if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
              return 0;
            if (channel_active(chan)) {
              if (reversing && (chan->channel.maxmembers != 0)) {
                simple_sprintf(s, "%d", chan->channel.maxmembers);
                add_mode(chan, '+', 'l', s);
              } else if ((chan->limit_prot != 0) && !glob_master(user) &&
                         !chan_master(user) && !match_my_nick(nick)) {
                simple_sprintf(s, "%d", chan->limit_prot);
                add_mode(chan, '+', 'l', s);
              }
            }
            chan->channel.maxmembers = 0;
          } else {
            op = newsplit(&msg);
            fixcolon(op);
            if (op == '\0')
              break;
            chan->channel.maxmembers = atoi(op);
            check_tcl_mode(nick, from, u, chan->dname, ms2,
                           int_to_base10(chan->channel.maxmembers));
            /* The Tcl proc might have modified/removed the chan or user */
            if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
              return 0;
            if (channel_pending(chan))
              break;
            if ((reversing && !(chan->mode_pls_prot & CHANLIMIT)) ||
                ((chan->mode_mns_prot & CHANLIMIT) && !glob_master(user) &&
                !chan_master(user)))
              add_mode(chan, '-', 'l', "");
            if ((chan->limit_prot != chan->channel.maxmembers) &&
                (chan->mode_pls_prot & CHANLIMIT) && (chan->limit_prot != 0) &&
                !glob_master(user) && !chan_master(user)) {
              simple_sprintf(s, "%d", chan->limit_prot);
              add_mode(chan, '+', 'l', s);
            }
          }
          break;
        case 'k':
          if (ms2[0] == '+')
            chan->channel.mode |= CHANKEY;
          else
            chan->channel.mode &= ~CHANKEY;
          op = newsplit(&msg);
          fixcolon(op);
          if (op == '\0') {
            break;
          }
          check_tcl_mode(nick, from, u, chan->dname, ms2, op);
          /* The Tcl proc might have modified/removed the chan or user */
          if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
            return 0;
          if (ms2[0] == '+') {
            set_key(chan, op);
            if (channel_active(chan))
              got_key(chan, nick, from, op);
          } else {
            if (channel_active(chan)) {
              if (reversing && chan->channel.key[0])
                add_mode(chan, '+', 'k', chan->channel.key);
              else if (chan->key_prot[0] && !glob_master(user) &&
                       !chan_master(user) && !match_my_nick(nick))
                add_mode(chan, '+', 'k', chan->key_prot);
            }
            set_key(chan, NULL);
          }
          break;
        case 'o':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_op(chan, nick, from, op, u, &user);
          else
            got_deop(chan, nick, from, op, u);
          break;
        case 'h':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_halfop(chan, nick, from, op, u, &user);
          else
            got_dehalfop(chan, nick, from, op, u);
          break;
        case 'v':
          op = newsplit(&msg);
          fixcolon(op);
          m = ismember(chan, op);
          if (!m) {
            if (channel_pending(chan))
              break;
            putlog(LOG_MISC, chan->dname, CHAN_BADCHANMODE, chan->dname, op);
            chan->status |= CHAN_PEND;
            refresh_who_chan(chan->name);
          } else {
            simple_sprintf(s, "%s!%s", m->nick, m->userhost);
            get_user_flagrec(m->user ? m->user : get_user_by_host(s),
                             &victim, chan->dname);
            if (ms2[0] == '+') {
              m->flags &= ~SENTVOICE;
              m->flags |= CHANVOICE;
              check_tcl_mode(nick, from, u, chan->dname, ms2, op);
              if (!(chan = modebind_refresh(ch, from, &user, s, &victim)))
                return 0;
              if (channel_active(chan) && !glob_master(user) &&
                  !chan_master(user) && !match_my_nick(nick)) {
                if (chan_quiet(victim) ||
                    (glob_quiet(victim) && !chan_voice(victim)))
                  add_mode(chan, '-', 'v', op);
                else if (reversing)
                  add_mode(chan, '-', 'v', op);
              }
            } else {
              m->flags &= ~SENTDEVOICE;
              m->flags &= ~CHANVOICE;
              check_tcl_mode(nick, from, u, chan->dname, ms2, op);
              if (!(chan = modebind_refresh(ch, from, &user, s, &victim)))
                return 0;
              if (channel_active(chan) && !glob_master(user) &&
                  !chan_master(user) && !match_my_nick(nick)) {
                if ((channel_autovoice(chan) && !chan_quiet(victim) &&
                    (chan_voice(victim) || glob_voice(victim))) ||
                    (!chan_quiet(victim) && (glob_gvoice(victim) ||
                    chan_gvoice(victim))))
                  add_mode(chan, '+', 'v', op);
                else if (reversing)
                  add_mode(chan, '+', 'v', op);
              }
            }
          }
          break;
        case 'b':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_ban(chan, nick, from, op, ch, u);
          else
            got_unban(chan, nick, from, op, ch, u);
          break;
        case 'e':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_exempt(chan, nick, from, op, ch, u);
          else
            got_unexempt(chan, nick, from, op, ch, u);
          break;
        case 'I':
          op = newsplit(&msg);
          fixcolon(op);
          if (ms2[0] == '+')
            got_invite(chan, nick, from, op, ch, u);
          else
            got_uninvite(chan, nick, from, op, ch, u);
          break;
        }
        if (todo) {
          check_tcl_mode(nick, from, u, chan->dname, ms2, "");
          if (!(chan = modebind_refresh(ch, from, &user, NULL, NULL)))
            return 0;
          if (ms2[0] == '+')
            chan->channel.mode |= todo;
          else
            chan->channel.mode &= ~todo;
          if (channel_active(chan)) {
            if ((((ms2[0] == '+') && (chan->mode_mns_prot & todo)) ||
                ((ms2[0] == '-') && (chan->mode_pls_prot & todo))) &&
                !glob_master(user) && !chan_master(user) &&
                !match_my_nick(nick))
              add_mode(chan, ms2[0] == '+' ? '-' : '+', *chg, "");
            else if (reversing && ((ms2[0] == '+') ||
                     (chan->mode_pls_prot & todo)) && ((ms2[0] == '-') ||
                     (chan->mode_mns_prot & todo)))
              add_mode(chan, ms2[0] == '+' ? '-' : '+', *chg, "");
          }
        }
        chg++;
      }
      if (!me_op(chan) && !nick[0])
        chan->status |= CHAN_ASKEDMODES;
    }
  }
  return 0;
}
Example #3
0
// Specific MUC message handling (for example invitation processing)
void got_muc_message(const char *from, LmMessageNode *x, time_t timestamp)
{
  LmMessageNode *node;
  // invitation
  node = lm_message_node_get_child(x, "invite");
  if (node) {
    const char *invite_from;
    const char *reason = NULL;
    const char *password = NULL;

    invite_from = lm_message_node_get_attribute(node, "from");
    reason = lm_message_node_get_child_value(node, "reason");
    password = lm_message_node_get_child_value(node, "password");
    if (invite_from)
      got_invite(invite_from, from, reason, password, TRUE);
  }

  // declined invitation
  node = lm_message_node_get_child(x, "decline");
  if (node) {
    const char *decline_from = lm_message_node_get_attribute(node, "from");
    const char *reason = lm_message_node_get_child_value(node, "reason");
    if (decline_from) {
      if (reason && reason[0])
        scr_LogPrint(LPRINT_LOGNORM, "<%s> declined your invitation: %s.",
                     from, reason);
      else
        scr_LogPrint(LPRINT_LOGNORM, "<%s> declined your invitation.", from);
    }
  }

  // status codes
  for (node = x -> children; node; node = node -> next) {
    if (!g_strcmp0(node -> name, "status")) {
      const char *codestr = lm_message_node_get_attribute(node, "code");
      if (codestr) {
        const char *mesg = NULL;
        switch (atoi(codestr)) {
          // initial
          case 100:
                  mesg = "The room is not anonymous.";
                  break;
          case 101:
                  mesg = "Your affilation has changed while absent.";
                  break;
          case 102:
                  mesg = "The room shows unavailable members.";
                  break;
          case 103:
                  mesg = "The room does not show unavailable members.";
                  break;
          case 104:
                  mesg = "The room configuration has changed.";
                  break;
          case 170:
                  mesg = "The room is logged.";
                  break;
          case 171:
                  mesg = "The room is not logged.";
                  break;
          case 172:
                  mesg = "The room is not anonymous.";
                  break;
          case 173:
                  mesg = "The room is semi-anonymous.";
                  break;
          case 174:
                  mesg = "The room is anonymous.";
                  break;
          default:
                  scr_LogPrint(LPRINT_DEBUG,
                               "got_muc_message: Unknown MUC status code: %s.",
                               codestr);
                  break;
        }
        if (mesg) {
          scr_WriteIncomingMessage(from, mesg, timestamp,
                                   HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
        if (settings_opt_get_int("log_muc_conf"))
            hlog_write_message(from, 0, -1, mesg);
        }
      }
    }
  }
}