Beispiel #1
0
static int script_channel_get(script_var_t *retval, char *channel_name, char *setting)
{
	char s[121];
	struct chanset_t *chan;
	struct udef_struct *ul;
	int flagval;

	retval->type = SCRIPT_STRING;
	retval->len = -1;

	chan = findchan_by_dname(channel_name);
	if (!chan) return(-1);

#define CHECK(x) !strcmp(setting, x)
	if (CHECK("chanmode")) get_mode_protect(chan, s);
	else if (CHECK("aop_delay")) sprintf(s, "%d %d", chan->aop_min, chan->aop_max);
	else if (CHECK("ban_time"))  sprintf(s, "%d", chan->ban_time);
	else if (CHECK("exempt_time"))  sprintf(s, "%d", chan->exempt_time);
	else if (CHECK("invite_time"))  sprintf(s, "%d", chan->invite_time);

	else if (lookup_flag_by_name(normal_flag_map, setting, &flagval)) sprintf(s, "%d", chan->status & flagval);
	else if (lookup_flag_by_name(stupid_ircnet_flag_map, setting, &flagval)) sprintf(s, "%d", chan->ircnet_status & flagval);
	else {
		/* Hopefully it's a user-defined flag. */
		for (ul = udef; ul && ul->name; ul = ul->next) {
			if (!strcmp(setting, ul->name)) break;
		}
		if (!ul || !ul->name) {
			/* Error if it wasn't found. */
			return(-1);
		}
		if (ul->type == UDEF_STR) {
			char *value;

			/* If it's unset then give them an empty string. */
			value = (char *)getudef(ul->values, chan->dname);
			if (!value) value = "";

			retval->value = value;
			return(0);
		}
		else {
			/* Flag or int, all the same. */
			sprintf(s, "%d", getudef(ul->values, chan->dname));
		}
	}
	/* Ok, if we make it this far, the result is "s". */
	retval->value = strdup(s);
	retval->type |= SCRIPT_FREE;
	return(0);
}
Beispiel #2
0
/* Parse options for a channel.
 */
static int tcl_channel_modify(Tcl_Interp * irp, struct chanset_t *chan,
			      int items, char **item)
{
  int i, x = 0, found,
      old_status = chan->status,
      old_mode_mns_prot = chan->mode_mns_prot,
      old_mode_pls_prot = chan->mode_pls_prot;
  struct udef_struct *ul = udef;
  char s[121];
  module_entry *me;

  for (i = 0; i < items; i++) {
    if (!strcmp(item[i], "chanmode")) {
      i++;
      if (i >= items) {
	if (irp)
	  Tcl_AppendResult(irp, "channel chanmode needs argument", NULL);
	return TCL_ERROR;
      }
      strlcpy(s, item[i], sizeof s);
      set_mode_protect(chan, s);
    } else if (!strcmp(item[i], "ban_time")) {
      i++;
      if (i >= items) {
        if (irp)
          Tcl_AppendResult(irp, "channel ban_time needs argument", NULL);
        return TCL_ERROR;
      }
      chan->ban_time = atoi(item[i]);
    } else if (!strcmp(item[i], "exempt_time")) {
      i++;
      if (i >= items) {
        if (irp)
          Tcl_AppendResult(irp, "channel exempt_time needs argument", NULL);
        return TCL_ERROR;
      }
      chan->exempt_time = atoi(item[i]);
    } else if (!strcmp(item[i], "invite_time")) {
      i++;
      if (i >= items) {
        if (irp)
          Tcl_AppendResult(irp, "channel invite_time needs argument", NULL);
        return TCL_ERROR;
      }
      chan->invite_time = atoi(item[i]);
    }
    else if (item[i][0] == '+' || item[i][0] == '-') {
      int flagval;

      if (lookup_flag_by_name(normal_flag_map, item[i]+1, &flagval)) {
        if (item[i][0] == '-') chan->status &= ~flagval;
        else chan->status |= flagval;
      }
      else if (lookup_flag_by_name(stupid_ircnet_flag_map, item[i]+1, &flagval)) {
        if (item[i][0] == '-') chan->ircnet_status &= ~flagval;
        else chan->ircnet_status |= flagval;
      }
      else {
        /* Hopefully it's a user-defined flag! */
        goto check_for_udef_flags;
      }
    } else if (!strncmp(item[i], "aop_delay", 9)) {
      char *p;
      i++;
      if (i >= items) {
	if (irp)
	  Tcl_AppendResult(irp, item[i - 1], " needs argument", NULL);
	return TCL_ERROR;
      }
      p = strchr(item[i], ':');
      if (p) {
	p++;
	chan->aop_min = atoi(item[i]);
	chan->aop_max = atoi(p);
      } else {
	chan->aop_min = atoi(item[i]);
	chan->aop_max = chan->aop_min;
      }
    } else {
      if (!strncmp(item[i] + 1, "udef_flag_", 10))
        initudef(UDEF_FLAG, item[i] + 11, 0);
      else if (!strncmp(item[i], "udef_int_", 9))
        initudef(UDEF_INT, item[i] + 9, 0);
	else if (!strncmp(item[i], "udef_str_", 9))
		initudef(UDEF_STR, item[i] + 9, 0);
check_for_udef_flags:
      found = 0;
      for (ul = udef; ul; ul = ul->next) {
        if (ul->type == UDEF_FLAG &&
	     /* Direct match when set during .chanset ... */
	    (!strcasecmp(item[i] + 1, ul->name) ||
	     /* ... or with prefix when set during chanfile load. */
	     (!strncmp(item[i] + 1, "udef_flag_", 10) &&
	      !strcasecmp(item[i] + 11, ul->name)))) {
          if (item[i][0] == '+')
            setudef(ul, chan->dname, 1);
          else
            setudef(ul, chan->dname, 0);
          found = 1;
	  break;
        } else if (ul->type == UDEF_INT &&
		    /* Direct match when set during .chanset ... */
		   (!strcasecmp(item[i], ul->name) ||
		    /* ... or with prefix when set during chanfile load. */
		    (!strncmp(item[i], "udef_int_", 9) &&
		     !strcasecmp(item[i] + 9, ul->name)))) {
          i++;
          if (i >= items) {
            if (irp)
              Tcl_AppendResult(irp, "this setting needs an argument", NULL);
            return TCL_ERROR;
          }
          setudef(ul, chan->dname, atoi(item[i]));
          found = 1;
	  break;
        }
	else if (ul->type == UDEF_STR && (!strcasecmp(item[i], ul->name) || (!strncmp(item[i], "udef_str_", 9) && !strcasecmp(item[i] + 9, ul->name)))) {
		char *val;
		i++;
		if (i >= items) {
			if (irp) Tcl_AppendResult(irp, "this setting needs an argument", NULL);
			return TCL_ERROR;
		}
		val = (char *)getudef(ul->values, chan->dname);
		if (val) free(val);
		/* Get extra room for new braces, etc */
		val = malloc(3 * strlen(item[i]) + 10);
		convert_element(item[i], val);
		val = realloc(val, strlen(val)+1);
		setudef(ul, chan->dname, (int)val);
		found = 1;
		break;
	}
      }
      if (!found) {
        if (irp && item[i][0]) /* ignore "" */
      	  Tcl_AppendResult(irp, "illegal channel option: ", item[i], NULL);
      	x++;
      }
    }
  }
  /* If protect_readonly == 0 and chan_hack == 0 then
   * bot is now processing the configfile, so dont do anything,
   * we've to wait the channelfile that maybe override these settings
   * (note: it may cause problems if there is no chanfile!)
   * <drummer/1999/10/21>
   */
  if (protect_readonly || chan_hack) {
    if (((old_status ^ chan->status) & CHAN_INACTIVE) &&
	module_find("irc", 0, 0)) {
      if (channel_inactive(chan) &&
	  (chan->status & (CHAN_ACTIVE | CHAN_PEND)))
	dprintf(DP_SERVER, "PART %s\n", chan->name);
      if (!channel_inactive(chan) &&
	  !(chan->status & (CHAN_ACTIVE | CHAN_PEND)))
	dprintf(DP_SERVER, "JOIN %s %s\n", (chan->name[0]) ?
					   chan->name : chan->dname,
					   chan->channel.key[0] ?
					   chan->channel.key : chan->key_prot);
    }
    if ((old_status ^ chan->status) &
	(CHAN_ENFORCEBANS | CHAN_OPONJOIN | CHAN_AUTOVOICE)) {
      if ((me = module_find("irc", 0, 0)))
	(me->funcs[IRC_RECHECK_CHANNEL])(chan, 1);
    } else if (old_mode_pls_prot != chan->mode_pls_prot ||
	       old_mode_mns_prot != chan->mode_mns_prot)
      if ((me = module_find("irc", 1, 2)))
	(me->funcs[IRC_RECHECK_CHANNEL_MODES])(chan);
  }
  if (x > 0)
    return TCL_ERROR;
  return TCL_OK;
}
Beispiel #3
0
/*
 * Note:
 *  - We write chanmode "" too, so that the bot won't use default-chanmode
 *    instead of ""
 *  - We will write empty need-xxxx too, why not? (less code + lazyness)
 */
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;
  struct udef_struct *ul;

  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, userfile_perm);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
          botnetnick, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->dname, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f,
            "channel add %s { chanmode %s idle-kick %d stopnethack-mode %d "
            "revenge-mode %d need-op %s need-invite %s need-key %s "
            "need-unban %s need-limit %s flood-chan %d:%d flood-ctcp %d:%d "
            "flood-join %d:%d flood-kick %d:%d flood-deop %d:%d "
            "flood-nick %d:%d aop-delay %d:%d ban-type %d ban-time %d "
            "exempt-time %d invite-time %d %cenforcebans %cdynamicbans "
            "%cuserbans %cautoop %cautohalfop %cbitch %cgreet %cprotectops "
            "%cprotecthalfops %cprotectfriends %cdontkickops %cstatuslog "
            "%crevenge %crevengebot %cautovoice %csecret %cshared %ccycle "
            "%cseen %cinactive %cdynamicexempts %cuserexempts %cdynamicinvites "
            "%cuserinvites %cnodesynch %cstatic }" "\n",
            name, w2, chan->idle_kick, chan->stopnethack_mode,
            chan->revenge_mode, need1, need2, need3, need4, need5,
            chan->flood_pub_thr, chan->flood_pub_time,
            chan->flood_ctcp_thr, chan->flood_ctcp_time,
            chan->flood_join_thr, chan->flood_join_time,
            chan->flood_kick_thr, chan->flood_kick_time,
            chan->flood_deop_thr, chan->flood_deop_time,
            chan->flood_nick_thr, chan->flood_nick_time,
            chan->aop_min, chan->aop_max, chan->ban_type, chan->ban_time,
            chan->exempt_time, chan->invite_time,
            PLSMNS(channel_enforcebans(chan)),
            PLSMNS(channel_dynamicbans(chan)),
            PLSMNS(!channel_nouserbans(chan)),
            PLSMNS(channel_autoop(chan)),
            PLSMNS(channel_autohalfop(chan)),
            PLSMNS(channel_bitch(chan)),
            PLSMNS(channel_greet(chan)),
            PLSMNS(channel_protectops(chan)),
            PLSMNS(channel_protecthalfops(chan)),
            PLSMNS(channel_protectfriends(chan)),
            PLSMNS(channel_dontkickops(chan)),
            PLSMNS(channel_logstatus(chan)),
            PLSMNS(channel_revenge(chan)),
            PLSMNS(channel_revengebot(chan)),
            PLSMNS(channel_autovoice(chan)),
            PLSMNS(channel_secret(chan)),
            PLSMNS(channel_shared(chan)),
            PLSMNS(channel_cycle(chan)),
            PLSMNS(channel_seen(chan)),
            PLSMNS(channel_inactive(chan)),
            PLSMNS(channel_dynamicexempts(chan)),
            PLSMNS(!channel_nouserexempts(chan)),
            PLSMNS(channel_dynamicinvites(chan)),
            PLSMNS(!channel_nouserinvites(chan)),
            PLSMNS(channel_nodesynch(chan)),
            PLSMNS(channel_static(chan)));
    for (ul = udef; ul; ul = ul->next) {
      if (ul->defined && ul->name) {
        if (ul->type == UDEF_FLAG)
          fprintf(f, "channel set %s %c%s%s\n", name, getudef(ul->values,
                  chan->dname) ? '+' : '-', "udef-flag-", ul->name);
        else if (ul->type == UDEF_INT)
          fprintf(f, "channel set %s %s%s %d\n", name, "udef-int-", ul->name,
                  (int) getudef(ul->values, chan->dname));
        else if (ul->type == UDEF_STR) {
          char *p = (char *) getudef(ul->values, chan->dname);

          if (!p)
            p = "{}";

          fprintf(f, "channel set %s udef-str-%s %s\n", name, ul->name, p);
        } else
          debug1("UDEF-ERROR: unknown type %d", ul->type);
      }
    }
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}
Beispiel #4
0
/*
 * Note:
 *  - We write chanmode "" too, so that the bot won't use default-chanmode
 *    instead of ""
 *  - We will write empty need-xxxx too, why not? (less code + lazyness)
 */
static void write_channels()
{
  FILE *f;
  char s[121], w[1024], w2[1024], name[163];
  char need1[242], need2[242], need3[242], need4[242], need5[242];
  struct chanset_t *chan;
  struct udef_struct *ul;

  Context;
  if (!chanfile[0])
    return;
  sprintf(s, "%s~new", chanfile);
  f = fopen(s, "w");
  chmod(s, userfile_perm);
  if (f == NULL) {
    putlog(LOG_MISC, "*", "ERROR writing channel file.");
    return;
  }
  if (!quiet_save)
    putlog(LOG_MISC, "*", "Writing channel file ...");
  fprintf(f, "#Dynamic Channel File for %s (%s) -- written %s\n",
	  origbotname, ver, ctime(&now));
  for (chan = chanset; chan; chan = chan->next) {
    convert_element(chan->dname, name);
    get_mode_protect(chan, w);
    convert_element(w, w2);
    convert_element(chan->need_op, need1);
    convert_element(chan->need_invite, need2);
    convert_element(chan->need_key, need3);
    convert_element(chan->need_unban, need4);
    convert_element(chan->need_limit, need5);
    fprintf(f, "channel %s %s%schanmode %s idle-kick %d stopnethack-mode %d \
need-op %s need-invite %s need-key %s need-unban %s need-limit %s \
flood-chan %d:%d flood-ctcp %d:%d flood-join %d:%d \
flood-kick %d:%d flood-deop %d:%d flood-nick %d:%d \
%cclearbans %cenforcebans %cdynamicbans %cuserbans %cautoop %cbitch \
%cgreet %cprotectops %cprotectfriends %cdontkickops \
%cstatuslog %crevenge %crevengebot %cautovoice %csecret \
%cshared %ccycle %cseen %cinactive %cdynamicexempts %cuserexempts \
%cdynamicinvites %cuserinvites %cnodesynch ",
	channel_static(chan) ? "set" : "add",
	name,
	channel_static(chan) ? " " : " { ",
	w2,
	chan->idle_kick, /* idle-kick 0 is same as dont-idle-kick (less code)*/
	chan->stopnethack_mode,
	need1, need2, need3, need4, need5,
	chan->flood_pub_thr, chan->flood_pub_time,
        chan->flood_ctcp_thr, chan->flood_ctcp_time,
        chan->flood_join_thr, chan->flood_join_time,
        chan->flood_kick_thr, chan->flood_kick_time,
        chan->flood_deop_thr, chan->flood_deop_time,
	chan->flood_nick_thr, chan->flood_nick_time,
	PLSMNS(channel_clearbans(chan)),
	PLSMNS(channel_enforcebans(chan)),
	PLSMNS(channel_dynamicbans(chan)),
	PLSMNS(!channel_nouserbans(chan)),
	PLSMNS(channel_autoop(chan)),
	PLSMNS(channel_bitch(chan)),
	PLSMNS(channel_greet(chan)),
	PLSMNS(channel_protectops(chan)),
        PLSMNS(channel_protectfriends(chan)),
	PLSMNS(channel_dontkickops(chan)),
	PLSMNS(channel_logstatus(chan)),
	PLSMNS(channel_revenge(chan)),
	PLSMNS(channel_revengebot(chan)),
	PLSMNS(channel_autovoice(chan)),
	PLSMNS(channel_secret(chan)),
	PLSMNS(channel_shared(chan)),
	PLSMNS(channel_cycle(chan)),
	PLSMNS(channel_seen(chan)),
	PLSMNS(channel_inactive(chan)),
        PLSMNS(channel_dynamicexempts(chan)),
        PLSMNS(!channel_nouserexempts(chan)),
 	PLSMNS(channel_dynamicinvites(chan)),
        PLSMNS(!channel_nouserinvites(chan)),
	PLSMNS(channel_nodesynch(chan)));
    for (ul = udef; ul; ul = ul->next) {
      if (ul->defined && ul->name) {
	if (ul->type == UDEF_FLAG)
	  fprintf(f, "%c%s%s ", getudef(ul->values, chan->dname) ? '+' : '-',
		  "udef-flag-", ul->name);
	else if (ul->type == UDEF_INT)
	  fprintf(f, "%s%s %d ", "udef-int-", ul->name, getudef(ul->values,
		  chan->dname));
	else
	  debug1("UDEF-ERROR: unknown type %d", ul->type);
      }
    }
    fprintf(f, "%s\n", channel_static(chan) ? "" : "}");
    if (fflush(f)) {
      putlog(LOG_MISC, "*", "ERROR writing channel file.");
      fclose(f);
      return;
    }
  }
  fclose(f);
  unlink(chanfile);
  movefile(s, chanfile);
}