/* ARISA - Admin Interface - Channel Menu * Copyright (C) 2003 Carl Ritson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ static int is_chan_new(network_t *n, channel_t *c) { int i; LOCK(n); for(i = 0; i < n->no_channels; ++i) { if(n->channels[i] == c) { UNLOCK(n); return 0; } } UNLOCK(n); return 1; } /** Channel Menu Commands **/ MENU_HELPER(cmd_channels_helper) { network_t *n = (network_t *)ins->data; int i,j; LOCK(n); for(j = 0; args[no_args-1][j] != '\0'; ++j) { if(args[no_args-1][j] == '?') break; } for(i = 0; i < n->no_channels; ++i) { LOCK(n->channels[i]); if(n->channels[i]->deleted == 0 && (j == 0 || strncmp(n->channels[i]->name,args[no_args-1],j) == 0)) admin_msg(ac,"%s",n->channels[i]->name); UNLOCK(n->channels[i]); } UNLOCK(n); } MENU_HELPER(cmd_networks_helper); // pre-declaration MENU_HELPER(cmd_net_channels_helper) { network_t *n; void *ptr; if(no_args == 2) cmd_networks_helper(ins,ac,args,no_args); else if(no_args > 2) { n = irc_network_find(args[1]); if(n != NULL) { ptr = ins->data; ins->data = n; cmd_channels_helper(ins,ac,args,no_args); ins->data = ptr; } } } static const cmd_t channel_menu[]; // pre-declaration MENU_CMD(cmd_channel_save) { network_t *n = (network_t *)ins->prev->data; channel_t *c = (channel_t *)ins->data; int ret; if(is_chan_new(n,c)) { ret = irc_channel_add(n,c); if(ret == 0) { admin_msg(ac,"Successfully Saved."); ins->free = NULL; } else admin_msg(ac,"Save Failed."); } else admin_msg(ac,"Channel is already saved."); return 0; } MENU_CMD(cmd_channel_msg) { network_t *n = (network_t *)ins->prev->data; channel_t *c = (channel_t *)ins->data; char buffer[32]; char cbuffer[512]; if(ins->free != NULL) { admin_msg(ac,"This command cannot be used on unsaved channels."); return 0; } LOCK(c); xstrncpy(buffer,c->name,sizeof(buffer)); UNLOCK(c); colourise(COLOUR_IRC,cbuffer,sizeof(cbuffer),args[1]); irc_send_msg(n,buffer,cbuffer); return 0; } MENU_CMD(cmd_channel_info) { channel_t *c = (channel_t *)ins->data; int i; LOCK(c); admin_msg(ac,"-- Channel %s --",c->name); if(c->key != NULL) admin_msg(ac,"Key: %s",c->key); if(c->joined != 0) { char ctime_buf[32]; lctime_r(&c->joined,ctime_buf,sizeof(ctime_buf)); ctime_buf[strlen(ctime_buf)-1] = '\0'; admin_msg(ac,"Join at: %s",ctime_buf); } else admin_msg(ac,"Not Joined"); if(c->nolist != 0 && c->nolist > xtime()) { char ctime_buf[32]; lctime_r(&c->nolist,ctime_buf,sizeof(ctime_buf)); ctime_buf[strlen(ctime_buf)-1] = '\0'; if(c->nolist != TIME_MAX) admin_msg(ac,"nolist Enabled Till: %s",ctime_buf); else admin_msg(ac,"nolist Permenantly Enabled"); } if(c->plist != 0) { admin_msg(ac,"Pack Listing Every %d Minutes, Format: %s", c->plist,pformat_to_str(c->pformat)); if(c->last_plist != 0) { char ctime_buf[32]; lctime_r(&c->last_plist,ctime_buf,sizeof(ctime_buf)); ctime_buf[strlen(ctime_buf)-1] = '\0'; admin_msg(ac,"Last Pack Listing: %s",ctime_buf); } } if(c->mode != NULL) admin_msg(ac,"Mode: %s",c->mode); if(c->topic != NULL) { char buffer[512]; xstrncpy(buffer,c->topic,sizeof(buffer)); irc_strip_colours(buffer); admin_msg(ac,"Topic: %s",buffer); } if(c->limit != 0) admin_msg(ac,"User Limit: %d",c->limit); if(no_args >= 2 && c->no_bans > 0) { admin_msg(ac,"-- Bans --"); for(i = 0; i < c->no_bans; ++i) admin_msg(ac," %s",c->bans[i]); } UNLOCK(c); return 0; } MENU_CMD(cmd_channel_settings) { channel_t *c = (channel_t *)ins->data; if(no_args <= 1) { pqueue_t settings; pqueue_init(&settings,0); channel_read_settings(c,&settings); LOCK(c); output_settings(ac,"-- Channel Settings for %s --", c->name,&settings); UNLOCK(c); } else if(no_args >= 3) { if(channel_apply_setting(c,args[1],args[2]) == -1) admin_msg(ac,"Invalid setting: %s",args[1]); } else admin_msg(ac,"%s [ ]",args[0]); return 0; } MENU_CMD(cmd_channel_nolist) { channel_t *c = (channel_t *)ins->data; unsigned long sec; LOCK(c); if(no_args >= 2) { sec = strtol(args[1],NULL,10); if(sec == -1) c->nolist = TIME_MAX; else if(sec > 0) c->nolist = xtime() + sec; else c->nolist = 0; } if(c->nolist == 0 || c->nolist < xtime()) admin_msg(ac,"nolist not enabled"); else if(c->nolist == TIME_MAX) admin_msg(ac,"nolist permenantly enabled"); else { char buffer[32]; lctime_r(&c->nolist,buffer,sizeof(buffer)); buffer[strlen(buffer)-1] = '\0'; admin_msg(ac,"nolist enabled till: %s",buffer); } UNLOCK(c); return 0; } MENU_CMD(cmd_channel_join) { network_t *n = (network_t *)ins->prev->data; channel_t *c = (channel_t *)ins->data; char buffer[64]; if(ins->free != NULL) { // unsaved admin_msg(ac,"This command cannot be used on unsaved channels."); return 0; } buffer[0] = '\0'; LOCK(n); if(n->state == NETWORK_CONNECTED) { LOCK(c); if(c->joined == 0) { if(c->key == NULL) snprintf(buffer,sizeof(buffer), "JOIN %s",c->name); else snprintf(buffer,sizeof(buffer), "JOIN %s %s",c->name,c->key); admin_msg(ac,"Sending JOIN Command for Channel %s", c->name); } else admin_msg(ac,"Already Joined to Channel %s",c->name); UNLOCK(c); } else admin_msg(ac,"Network %s is not connected.",n->name); UNLOCK(n); if(buffer[0] != '\0') irc_send_raw(n,buffer); return 0; } MENU_CMD(cmd_channel_part) { network_t *n = (network_t *)ins->prev->data; channel_t *c = (channel_t *)ins->data; char buffer[512]; if(ins->free != NULL) { admin_msg(ac,"This command cannot be used on unsaved channels."); return 0; } buffer[0] = '\0'; LOCK(n); if(n->state == NETWORK_CONNECTED) { LOCK(c); if(c->joined != 0) { if(no_args >= 2) snprintf(buffer,sizeof(buffer),"PART %s :%s", c->name,args[1]); else snprintf(buffer,sizeof(buffer),"PART %s", c->name); admin_msg(ac,"Sending PART Command for Channel %s", c->name); } else admin_msg(ac,"Not Joined to Channel %s",c->name); UNLOCK(c); } else admin_msg(ac,"Network %s is not connected.",n->name); UNLOCK(n); if(buffer[0] != '\0') irc_send_raw(n,buffer); return 0; } MENU_CMD(cmd_channel_delete) { network_t *n = (network_t *)ins->prev->data; channel_t *c = (channel_t *)ins->data; LOCK(c); admin_msg(ac,"Deleted Channel %s.",c->name); UNLOCK(c); irc_channel_del(n,c); return RET_UP; } MENU_CMD(cmd_channel_taglines) { channel_t *c = (channel_t *)ins->data; int ret; LOCK(c); ret = cmd_strarr(ac,&c->taglines,&c->no_taglines,args,no_args); UNLOCK(c); return ret; } MENU_CMD(cmd_channel_rename) { network_t *n = (network_t *)ins->prev->data; channel_t *c = (channel_t *)ins->data; if(irc_channel_rename(n,c,args[1]) == 0) { if(ins->prompt != NULL && ins->free_prompt != 0) xfree(ins->prompt); ins->prompt = xstrdup(args[1]); ins->free_prompt = 1; admin_output_prompt(ac); } else admin_msg(ac,"Rename To %s Failed",args[1]); return 0; } MENU_CMD(cmd_channel_listen) { channel_t *c = (channel_t *)ins->data; if(ins->free == NULL) { if(strcasecmp(args[1],"on") == 0) irc_listen(NULL,c,ac->msgqueue); else irc_unlisten(NULL,c,ac->msgqueue); } else admin_msg(ac,"This command cannot be used on unsaved channels."); return 0; } static const char *mode_str(int mode) { if(mode & MODE_OWNER) return "~"; else if(mode & MODE_ANTIKICK) return "&"; else if(mode & MODE_OP) return "@"; else if(mode & MODE_HOP) return "%"; else if(mode & MODE_VOICE) return "+"; else return ""; } MENU_CMD(cmd_channel_names) { channel_t *c = (channel_t *)ins->data; network_t *n = (network_t *)ins->prev->data; nickmode_t *nms = NULL; char buffer[128]; int i,tmp,pos = 0; if(ins->free != NULL) { admin_msg(ac, "This command cannot be used on unsaved channels."); return 0; } LOCK(n); LOCK(n->info); tmp = nickhash_query_channel(n->info->nick_tracker,c,&nms); UNLOCK(n->info); for(i = 0; i < tmp; ++i) { pos += snprintf(buffer+pos,sizeof(buffer)-pos-1,"%s%s ", mode_str(nms[i].mode),nms[i].nick); if(pos > 60) { admin_msg(ac,"%s",buffer); pos = 0; } } if(nms != NULL) xfree(nms); UNLOCK(n); if(pos != 0) admin_msg(ac,"%s",buffer); return 0; } /** Channel Menu Structure **/ static const cmd_t channel_menu[] = { {"delete",cmd_channel_delete,0,0,1,0,PRIVS_EMPTY,NULL}, {"info", cmd_channel_info, 0,1,0,0,PRIVS_EMPTY,NULL}, {"join", cmd_channel_join, 0,0,1,0,PRIVS_EMPTY,NULL}, {"listen",cmd_channel_listen,1,1,0,0,PRIVS_EMPTY,NULL}, {"msg", cmd_channel_msg, 1,-2,0,0,PRIVS_EMPTY,NULL}, {"names", cmd_channel_names, 0,0,0,0,PRIVS_EMPTY,NULL}, {"nolist",cmd_channel_nolist,0,1,1,0,PRIVS_EMPTY,NULL}, {"part", cmd_channel_part, 0,-2,1,0,PRIVS_EMPTY,NULL}, {"rename",cmd_channel_rename,1,1,1,0,PRIVS_EMPTY,NULL}, {"save",cmd_channel_save,0,0,1,0,PRIVS_EMPTY,NULL}, {"settings", cmd_channel_settings, 0,3,1,0,PRIVS_EMPTY,NULL}, {"taglines",cmd_channel_taglines,0,3,1,0,PRIVS_EMPTY,NULL}, {NULL} }; /** Channel Menu Entry **/ MENU_CHECK(cmd_channel_check) { channel_t *c = (channel_t *)ins->data; int ret = 0; LOCK(c); if(c->deleted != 0) { admin_msg(ac,"Channel %s, Deleted.",c->name); ret = -1; } UNLOCK(c); return ret; } MENU_CMD(cmd_channel_entry) { network_t *n = (network_t *)ins->prev->data; channel_t *c; if(ins->prompt != NULL && ins->free_prompt) xfree(ins->prompt); ins->prompt = xstrdup(args[1]); ins->free_prompt= 1; ins->check = cmd_channel_check; c = irc_channel_find(n,args[1]); if(c == NULL) { c = alloc_channel(); c->name = xstrdup(args[1]); ins->free = (void (*)(void *)) free_channel; admin_msg(ac,"New Channel: %s",args[1]); } ins->data = c; return 0; } static void register_channel_menu(menu_t *n_menu) { menu_t *c_menu = menu_from_cmds( "channel", // name 1, // min_args 1, // max_args 1, // log 0, // hide PRIVS_EMPTY, // privs cmd_channel_entry, // func cmd_channels_helper, // helper (cmd_t *)channel_menu); menu_add(n_menu,c_menu); menu_deref(c_menu); }