static int script_setlaston(struct userrec *u, int when, char *chan) { if (!when) when = now; if (!chan || !findchan_by_dname(chan)) chan = "*"; set_handle_laston(chan, u, when); return(0); }
static struct chanuserrec *add_chanrec(struct userrec *u, char *chname) { struct chanuserrec *ch = NULL; if (findchan_by_dname(chname)) { ch = user_malloc(sizeof(struct chanuserrec)); ch->next = u->chanrec; u->chanrec = ch; ch->info = NULL; ch->flags = 0; ch->flags_udef = 0; ch->laston = 0; strncpy(ch->channel, chname, 81); ch->channel[80] = 0; if (!noshare && !(u->flags & USER_UNSHARED)) shareout(findchan_by_dname(chname), "+cr %s %s\n", u->handle, chname); } return ch; }
/* PUB `seen' trigger. */ static int pub_seen(char *nick, char *host, char *hand, char *channel, char *text) { char prefix[91]; /* sizeof(name) + strlen("PRIVMSG :") */ struct chanset_t *chan = findchan_by_dname(channel); if ((chan != NULL) && channel_seen(chan)) { egg_snprintf(prefix, sizeof prefix, "PRIVMSG %s :", chan->name); do_seen(DP_HELP, prefix, nick, hand, chan->dname, text); } return 0; }
static void got_sj(int idx, char *code, char *par) { struct chanset_t *chan = findchan_by_dname(newsplit(&par)); if (chan) { if (conf.bot->hub) { chan->status &= ~CHAN_INACTIVE; write_userfile(-1); } else chan->channel.jointime = ((atoi(par) + now) - server_lag); } }
/* Stick a ban/exempt/invite globally or to a chanel. */ static int script_sticksomething(void *type, char *chan_name, char *mask) { struct chanset_t *chan = NULL; if (chan_name && chan_name[0]) { chan = findchan_by_dname(chan_name); if (!chan) return(-1); } /* If type > 255, then we're unsticking. The mask type is type & 255. */ return u_setsticky_mask((int)type & 255, chan, mask, ((int)type > 255) ? 0 : 1); }
static void got_sp(int idx, char *code, char *par) { struct chanset_t *chan = findchan_by_dname(newsplit(&par)); if (chan) { if (conf.bot->hub) { remove_channel(chan); write_userfile(-1); } else chan->channel.parttime = ((atoi(par) + now) - server_lag); } }
/* PUB `seen' trigger. */ static int pub_seen(char *nick, char *host, char *hand, char *channel, char *text) { char prefix[50]; struct chanset_t *chan = findchan_by_dname(channel); Context; if ((chan != NULL) && channel_seen(chan)) { sprintf(prefix, "PRIVMSG %s :", chan->name); do_seen(DP_HELP, prefix, nick, hand, chan->dname, text); } return 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); }
static int tcl_channel(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { struct chanset_t *chan; BADARGS(2, 999, " command ?options?"); if (!strcmp(argv[1], "add")) { BADARGS(3, 4, " add channel-name ?options-list?"); if (argc == 3) return tcl_channel_add(irp, argv[2], ""); return tcl_channel_add(irp, argv[2], argv[3]); } if (!strcmp(argv[1], "set")) { BADARGS(3, 999, " set channel-name ?options?"); chan = findchan_by_dname(argv[2]); if (chan == NULL) { if (chan_hack == 1) return TCL_OK; /* Ignore channel settings for a static * channel which has been removed from * the config */ Tcl_AppendResult(irp, "no such channel record", NULL); return TCL_ERROR; } return tcl_channel_modify(irp, chan, argc - 3, &argv[3]); } if (!strcmp(argv[1], "remove")) { BADARGS(3, 3, " remove channel-name"); chan = findchan_by_dname(argv[2]); if (chan == NULL) { Tcl_AppendResult(irp, "no such channel record", NULL); return TCL_ERROR; } remove_channel(chan); return TCL_OK; } Tcl_AppendResult(irp, "unknown channel command: should be one of: ", "add, set, info, remove", NULL); return TCL_ERROR; }
static void got_down(char *botnick, char *code, char *par) { if (!par[0]) return; char *chname = newsplit(&par); struct chanset_t *chan = NULL; if (!(chan = findchan_by_dname(chname))) return; chan->channel.no_op = (now + 10); add_mode(chan, '-', 'o', botname); }
static void got_cjoin(char *botnick, char *code, char *par) { if (!par[0]) return; char *chname = newsplit(&par), *options = NULL; struct chanset_t *chan = findchan_by_dname(chname); int match = 0; if (conf.bot->hub) { newsplit(&par); /* hubs ignore the botmatch param */ options = par; } else { /* ALL hubs should add the channel, leaf should check the list for a match */ bool inactive = 0; char *bots = newsplit(&par); match = parsebots(bots, conf.bot->nick); if (strstr(par, "+inactive")) inactive = 1; if (chan && !match) return; if (!match) { size_t size = strlen(par) + 12 + 1; options = (char *) my_calloc(1, size); simple_snprintf(options, size, "%s +inactive", par); } else if (match && chan && !shouldjoin(chan)) { if (!inactive) do_chanset(NULL, chan, "-inactive", DO_LOCAL); return; } else options = par; } if (chan) return; sdprintf("OPTIONS: %s", options); char result[RESULT_LEN] = ""; if (channel_add(result, chname, options) == ERROR) /* drummer */ putlog(LOG_BOTS, "@", "Invalid channel or channel options from %s for %s: %s", botnick, chname, result); if (conf.bot->hub) write_userfile(-1); if (!match && !conf.bot->hub) free(options); }
static int pub_seennick(char *nick, char *host, char *hand, char *channel, char *text) { seendat *l; char *dest; #if EGG_IS_MIN_VER(10500) struct chanset_t *chan; #endif Context; if (seenflood()) return 0; if (nopub(channel)) return 0; putlog(LOG_CMDS, "*", "<<%s>> !%s! seennick %s", nick, hand, text); reset_global_vars(); glob_slang = slang_find(coreslangs, slang_chanlang_get(chanlangs, channel)); glob_nick = nick; #if EGG_IS_MIN_VER(10500) chan = findchan_by_dname(channel); if (chan) dest = chan->name; else dest = channel; #else dest = channel; #endif text = newsplit(&text); l = findseen(text); if (!l) { glob_query = text; if (quietseen(channel)) { set_prefix(SLNOTPREFIX); dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, SLNOTSEEN); } else { set_prefix(SLPUBPREFIX); dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, SLNOTSEEN); } return 0; } if (quietseen(channel)) { set_prefix(SLNOTPREFIX); dprintf(DP_HELP, "NOTICE %s :%s%s\n", nick, reply_prefix, do_seennick(l)); } else { set_prefix(SLPUBPREFIX); dprintf(DP_HELP, "PRIVMSG %s :%s%s\n", dest, reply_prefix, do_seennick(l)); } return 0; }
/* Should be removed when the new config system is in place. */ static int tcl_isdynamic(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { struct chanset_t *chan; BADARGS(2, 2, " channel"); chan = findchan_by_dname(argv[1]); if (chan != NULL) if (!channel_static(chan)) { Tcl_AppendResult(irp, "1", NULL); return TCL_OK; } Tcl_AppendResult(irp, "0", NULL); return TCL_OK; }
static int script_newsomething(void *type, char *chan_name, char *mask, char *creator, char *comment, char *lifetime, char *options) { time_t expire_time; struct chanset_t *chan = NULL; int sticky = 0; int r; module_entry *me; if (chan_name[0]) { chan = findchan_by_dname(chan_name); if (!chan) return(-1); } if (lifetime) { expire_time = atoi(lifetime); if (expire_time) expire_time = expire_time * 60 + now; } expire_time = now + (60 * (((int) type == 'b') ? ((chan->ban_time == 0) ? 0L : chan->ban_time) : (((int) type == 'e') ? ((chan->exempt_time == 0) ? 0L : chan->exempt_time) : ((chan->invite_time == 0) ? 0L : chan->invite_time)))); if (options && !strcasecmp(options, "sticky")) sticky = 1; r = u_addmask((int) type, chan, mask, creator, comment, expire_time, sticky); if (chan && !r) return(-1); if ((int) type == 'b') { me = module_find("irc", 0, 0); if (me) { if (chan) (me->funcs[IRC_CHECK_THIS_BAN])(chan, mask, sticky); else for (chan = chanset; chan; chan = chan->next) { (me->funcs[IRC_CHECK_THIS_BAN])(chan, mask, sticky); } } return(0); } if (chan) add_mode(chan, '+', (int) type, mask); else { for (chan = chanset; chan; chan = chan->next) { add_mode(chan, '+', (int) type, mask); } } return(0); }
void set_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname) { struct chanuserrec *cr = NULL; int oldflags = fr->match; char buffer[100]; struct chanset_t *ch; if (!u) return; if (oldflags & FR_GLOBAL) { u->flags = fr->global; u->flags_udef = fr->udef_global; if (!noshare && !(u->flags & USER_UNSHARED)) { fr->match = FR_GLOBAL; build_flags(buffer, fr, NULL); shareout(NULL, "a %s %s\n", u->handle, buffer); } } if ((oldflags & FR_BOT) && (u->flags & USER_BOT)) set_user(&USERENTRY_BOTFL, u, (void *) fr->bot); /* Don't share bot attrs */ if ((oldflags & FR_CHAN) && chname) { for (cr = u->chanrec; cr; cr = cr->next) if (!rfc_casecmp(chname, cr->channel)) break; ch = findchan_by_dname(chname); if (!cr && ch) { cr = user_malloc(sizeof(struct chanuserrec)); egg_bzero(cr, sizeof(struct chanuserrec)); cr->next = u->chanrec; u->chanrec = cr; strncpyz(cr->channel, chname, sizeof cr->channel); } if (cr && ch) { cr->flags = fr->chan; cr->flags_udef = fr->udef_chan; if (!noshare && !(u->flags & USER_UNSHARED) && channel_shared(ch)) { fr->match = FR_CHAN; build_flags(buffer, fr, NULL); shareout(ch, "a %s %s %s\n", u->handle, buffer, chname); } } } fr->match = oldflags; }
static int onchan(char *nick, char *chan) { struct chanset_t *ch; memberlist *m; ch = findchan_by_dname(chan); if (!ch) return 0; m = ismember(ch, nick); if (!m) return 0; else if (chan_issplit(m)) return 0; else return 1; }
/* Always pass the dname (display name) to this function for chname <cybah> */ void get_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname) { struct chanuserrec *cr = NULL; if (!u) { fr->global = fr->udef_global = fr->chan = fr->udef_chan = fr->bot = 0; return; } if (fr->match & FR_GLOBAL) { fr->global = u->flags; fr->udef_global = u->flags_udef; } else { fr->global = 0; fr->udef_global = 0; } if (fr->match & FR_BOT) { fr->bot = (long) get_user(&USERENTRY_BOTFL, u); } else fr->bot = 0; if (fr->match & FR_CHAN) { if (fr->match & FR_ANYWH) { fr->chan = u->flags; fr->udef_chan = u->flags_udef; for (cr = u->chanrec; cr; cr = cr->next) if (findchan_by_dname(cr->channel)) { fr->chan |= cr->flags; fr->udef_chan |= cr->flags_udef; } } else { if (chname) for (cr = u->chanrec; cr; cr = cr->next) if (!rfc_casecmp(chname, cr->channel)) break; if (cr) { fr->chan = cr->flags; fr->udef_chan = cr->flags_udef; } else { fr->chan = 0; fr->udef_chan = 0; } } } }
static void mns_chan(int idx, char *par, char *bot) { char *chname = NULL, buf2[1024] = ""; struct chanset_t *chan = NULL; int i; if (!bot) putlog(LOG_CMDS, "*", "#%s# -chan %s", dcc[idx].nick, par); if (!par[0]) { dprintf(idx, "Usage: -chan [%s]<channel>\n", CHANMETA); return; } chname = newsplit(&par); simple_snprintf(buf2, sizeof(buf2), "cpart %s %s", chname, bot ? bot : "*"); if (bot) /* bot will just set it +inactive */ putbot(bot, buf2); else putallbots(buf2); chan = findchan_by_dname(chname); if (!chan) { if ((chan = findchan(chname))) dprintf(idx, "That channel exists with a short name of %s, use that.\n", chan->dname); else dprintf(idx, "That channel doesn't exist!\n"); return; } if (!bot) { for (i = 0; i < dcc_total; i++) { if (dcc[i].type && (dcc[i].type->flags & DCT_CHAT) && !rfc_casecmp(dcc[i].u.chat->con_chan, chan->dname)) { dprintf(i, "%s is no longer a valid channel, changing your console to '*'\n", chname); strlcpy(dcc[i].u.chat->con_chan, "*", 2); console_dostore(i, 0); } } remove_channel(chan); if (conf.bot->hub) write_userfile(idx); dprintf(idx, "Channel %s removed from the botnet.\n", chname); dprintf(idx, "This includes any channel specific bans, invites, exemptions and user records that you set.\n"); } else dprintf(idx, "Channel %s removed from the bot: %s\n", chname, bot); }
static void got_jn(int idx, char *code, char *par) { char *chname = newsplit(&par); if (!chname || !chname[0]) return; struct chanset_t *chan = NULL; if (!(chan = findchan_by_dname(chname))) return; if (chan->channel.jointime && channel_inactive(chan)) { chan->status &= ~CHAN_INACTIVE; chan->channel.jointime = 0; if (!conf.bot->hub && shouldjoin(chan)) join_chan(chan); } }
void set_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname) { if (!u) return; struct chanuserrec *cr = NULL; flag_t oldflags = fr->match; char buffer[100] = ""; struct chanset_t *ch; if (oldflags & FR_GLOBAL) { u->flags = fr->global; if (!noshare) { fr->match = FR_GLOBAL; build_flags(buffer, fr, NULL); shareout("a %s %s\n", u->handle, buffer); } } if ((oldflags & FR_CHAN) && chname) { for (cr = u->chanrec; cr; cr = cr->next) if (!rfc_casecmp(chname, cr->channel)) break; ch = findchan_by_dname(chname); if (!cr && ch) { cr = (struct chanuserrec *) my_calloc(1, sizeof(struct chanuserrec)); cr->next = u->chanrec; u->chanrec = cr; strlcpy(cr->channel, chname, sizeof cr->channel); } if (cr && ch) { cr->flags = fr->chan; if (!noshare) { fr->match = FR_CHAN; build_flags(buffer, fr, NULL); shareout("a %s %s %s\n", u->handle, buffer, chname); } } } fr->match = oldflags; }
/* handonchan(): * checks if the given user is on the channel and returns its nick */ static char *handonchan(char *hand, char *chan) { struct chanset_t *ch; memberlist *m; ch = findchan_by_dname(chan); if (!ch) return 0; if (ch->channel.members > 0) { for (m = ch->channel.member; m; m = m->next) { if (m->user) { if (m->user->handle && !rfc_casecmp(m->user->handle, hand)) return m->nick; } } } return NULL; }
static int msg_bewm(char *nick, char *host, struct userrec *u, char *par) { struct chanset_t *chan = NULL; if (!homechan[0] || !(chan = findchan_by_dname(homechan))) return BIND_RET_BREAK; if (!channel_active(chan)) return BIND_RET_BREAK; if (match_my_nick(nick)) return BIND_RET_BREAK; bd::String msg; if (!u) { msg = bd::String::printf(STR("---- (%s!%s) attempted to gain secure invite, but is not a recognized user."), nick, host); privmsg(chan->name, msg.c_str(), DP_SERVER); putlog(LOG_CMDS, "*", STR("(%s!%s) !*! BEWM"), nick, host); return BIND_RET_BREAK; } if (u->bot) return BIND_RET_BREAK; struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 }; get_user_flagrec(u, &fr, chan->dname, chan); if (!chk_op(fr, chan)) { putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! !BEWM"), nick, host, u->handle); msg = bd::String::printf(STR("---- %s (%s!%s) attempted to gain secure invite, but is missing a flag."), u->handle, nick, host); privmsg(chan->name, msg.c_str(), DP_SERVER); return BIND_RET_BREAK; } msg = bd::String::printf("\001ACTION has invited \002%s\002 (%s!%s) to %s.\001", u->handle, nick, host, chan->dname); privmsg(chan->name, msg.c_str(), DP_SERVER); cache_invite(chan, nick, host, u->handle, 0, 0); putlog(LOG_CMDS, "*", STR("(%s!%s) !%s! BEWM"), nick, host, u->handle); return BIND_RET_BREAK; }
static int msg_invite(char *nick, char *host, struct userrec *u, char *par) { char *pass = NULL; struct chanset_t *chan = NULL; struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 }; if (match_my_nick(nick)) return BIND_RET_BREAK; pass = newsplit(&par); if (u_pass_match(u, pass) && !u_pass_match(u, "-")) { if (par[0] == '*') { for (chan = chanset; chan; chan = chan->next) { get_user_flagrec(u, &fr, chan->dname, chan); if (chk_op(fr, chan) && (chan->channel.mode & CHANINV)) { cache_invite(chan, nick, host, u->handle, 0, 0); } } putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE ALL", nick, host, u->handle); return BIND_RET_BREAK; } bd::String msg; if (!(chan = findchan_by_dname(par))) { msg = bd::String::printf("Usage: /MSG %s %s <pass> <channel>", botname, msginvite); notice(nick, msg.c_str(), DP_HELP); return BIND_RET_BREAK; } if (!channel_active(chan)) { msg = bd::String::printf("%s: Not on that channel right now.", par); notice(nick, msg.c_str(), DP_HELP); return BIND_RET_BREAK; } /* We need to check access here also (dw 991002) */ get_user_flagrec(u, &fr, par, chan); if (chk_op(fr, chan)) { cache_invite(chan, nick, host, u->handle, 0, 0); putlog(LOG_CMDS, "*", "(%s!%s) !%s! INVITE %s", nick, host, u->handle, par); return BIND_RET_BREAK; } } putlog(LOG_CMDS, "*", "(%s!%s) !%s! failed INVITE %s", nick, host, (u ? u->handle : "*"), par); return BIND_RET_BREAK; }
/* Kill a ban/exempt/invite either globally or from a channel. */ static int script_killsomething(void *type, char *chan_name, char *mask) { struct chanset_t *chan = NULL; if (chan_name && chan_name[0]) { chan = findchan_by_dname(chan_name); if (!chan) return(-1); } if (u_delmask((int) type, chan, mask, 1) > 0) { if (!chan) { for (chan = chanset; chan; chan = chan->next) { add_mode(chan, '-', (int) type, mask); } } else add_mode(chan, '-', (int) type, mask); } return(0); }
/* Always pass the dname (display name) to this function for chname <cybah> */ void get_user_flagrec(struct userrec *u, struct flag_record *fr, const char *chname, const struct chanset_t* chan) { fr->bot = 0; if (!u) { fr->global = fr->chan = 0; return; } if (u->bot) fr->bot = 1; fr->global = (fr->match & FR_GLOBAL) ? u->flags : 0; if (fr->match & FR_CHAN) { struct chanuserrec *cr = NULL; if ((fr->match & FR_ANYWH) || (fr->match & FR_ANYCH)) { if (fr->match & FR_ANYWH) fr->chan = u->flags; for (cr = u->chanrec; cr; cr = cr->next) { if (chan || findchan_by_dname(cr->channel)) { fr->chan |= cr->flags; } } } else { if (chname) { for (cr = u->chanrec; cr; cr = cr->next) { if (!rfc_casecmp(chname, cr->channel)) break; } } if (cr) { fr->chan = cr->flags; } else { fr->chan = 0; } } } }
static void got_cycle(char *botnick, char *code, char *par) { if (!par[0]) return; char *chname = newsplit(&par); struct chanset_t *chan = NULL; if (!(chan = findchan_by_dname(chname))) return; interval_t delay = 10; if (par[0]) delay = atoi(newsplit(&par)); do_chanset(NULL, chan, "+inactive", DO_LOCAL); dprintf(DP_SERVER, "PART %s\n", chan->name); chan->channel.jointime = ((now + delay) - server_lag); /* rejoin in 10 seconds */ }
static void schan_members_join(struct llist_header *head, char *nick, char *uhost, char *user, char *chan) { struct stats_member *m; char *host; #ifndef NO_EGG struct chanset_t *eggchan; #endif m = schan_members_create(); m->nick = nmalloc(strlen(nick) + 1); strcpy(m->nick, nick); m->uhost = nmalloc(strlen(uhost) + 1); strcpy(m->uhost, uhost); m->joined = now; if (user) { m->user = findsuser_by_name(user); if (!m->user) { m->user = addsuser(user, now, now); debug1("Stats.Mod: Created suserrec for %s.", user); } } else { host = nmalloc(strlen(nick) + 1 + strlen(uhost) + 1); sprintf(host, "%s!%s", nick, uhost); m->user = findsuser(host); nfree(host); } if (m->user) { m->user->laston = now; m->stats = findlocstats(chan, m->user->user); if (!m->stats) m->stats = initstats(chan, m->user->user); } #ifndef NO_EGG eggchan = findchan_by_dname(chan); if (chan) m->eggmember = ismember(eggchan, nick); if (!m->eggmember) debug2("Warning[stats.mod]: Couldn't find eggmember for %s in %s.", nick, chan); #endif llist_append(head, (void *) m); }
static void del_chanrec(struct userrec *u, char *chname) { struct chanuserrec *ch = u->chanrec, *lst = NULL; while (ch) { if (!rfc_casecmp(chname, ch->channel)) { if (lst == NULL) u->chanrec = ch->next; else lst->next = ch->next; if (ch->info != NULL) nfree(ch->info); nfree(ch); if (!noshare && !(u->flags & USER_UNSHARED)) shareout(findchan_by_dname(chname), "-cr %s %s\n", u->handle, chname); return; } lst = ch; ch = ch->next; } }
/* Bind this to chon and *if* the users console channel == *** * then set it to a specific channel */ static int channels_chon(char *handle, int idx) { struct flag_record fr = {FR_CHAN | FR_ANYWH | FR_GLOBAL, 0, 0, 0 }; int find; bool found = 0; struct chanset_t *chan = chanset; if (dcc[idx].type == &DCC_CHAT) { if (!findchan_by_dname(dcc[idx].u.chat->con_chan) && ((dcc[idx].u.chat->con_chan[0] != '*') || (dcc[idx].u.chat->con_chan[1] != 0))) { get_user_flagrec(dcc[idx].user, &fr, NULL); if (glob_op(fr)) found = 1; if (chan_owner(fr)) find = USER_OWNER; else if (chan_master(fr)) find = USER_MASTER; else find = USER_OP; fr.match = FR_CHAN; while (chan && !found) { get_user_flagrec(dcc[idx].user, &fr, chan->dname, chan); if (fr.chan & find) found = 1; else chan = chan->next; } if (!chan) chan = chanset; struct chat_info dummy; if (chan) strlcpy(dcc[idx].u.chat->con_chan, chan->dname, sizeof(dummy.con_chan)); else strlcpy(dcc[idx].u.chat->con_chan, "*", 2); } } return 0; }
/* Create new channel and parse commands. */ static int tcl_channel_add(Tcl_Interp *irp, char *newname, char *options) { struct chanset_t *chan; int items; int ret = TCL_OK; int join = 0; char **item; char buf[2048], buf2[256]; if (!newname || !newname[0] || (strchr(CHANMETA, newname[0]) == NULL)) { if (irp) Tcl_AppendResult(irp, "invalid channel prefix", NULL); return TCL_ERROR; } if (strchr(newname, ',') != NULL) { if (irp) Tcl_AppendResult(irp, "invalid channel name", NULL); return TCL_ERROR; } convert_element(glob_chanmode, buf2); simple_sprintf(buf, "chanmode %s ", buf2); strlcat(buf, glob_chanset, sizeof buf); strlcat(buf, options, sizeof buf); if (Tcl_SplitList(NULL, buf, &items, &item) != TCL_OK) return TCL_ERROR; if ((chan = findchan_by_dname(newname))) { /* Already existing channel, maybe a reload of the channel file */ chan->status &= ~CHAN_FLAGGED; /* don't delete me! :) */ } else { chan = calloc(1, sizeof(struct chanset_t)); chan->limit_prot = 0; chan->limit = 0; chan->ban_time = global_ban_time; chan->exempt_time = global_exempt_time; chan->invite_time = global_invite_time; chan->aop_min = global_aop_min; chan->aop_max = global_aop_max; /* We _only_ put the dname (display name) in here so as not to confuse * any code later on. chan->name gets updated with the channel name as * the server knows it, when we join the channel. <cybah> */ strlcpy(chan->dname, newname, sizeof chan->dname); /* Initialize chan->channel info */ init_channel(chan, 0); list_append((struct list_type **) &chanset, (struct list_type *) chan); join = 1; } if (setstatic) chan->status |= CHAN_STATIC; /* If chan_hack is set, we're loading the userfile. Ignore errors while * reading userfile and just return TCL_OK. This is for compatability * if a user goes back to an eggdrop that no-longer supports certain * (channel) options. */ if ((tcl_channel_modify(irp, chan, items, item) != TCL_OK) && !chan_hack) { ret = TCL_ERROR; } Tcl_Free((char *) item); if (join && !channel_inactive(chan) && module_find("irc", 0, 0)) dprintf(DP_SERVER, "JOIN %s %s\n", chan->dname, chan->key_prot); return ret; }