/* ARISA - Admin Interface - Pool 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_pool_new(interface_t *intf, pool_t *p) { int i; LOCK(intf); for(i = 0; i < intf->send.no_pools; ++i) { if(intf->send.pools[i] == p) { UNLOCK(intf); return 0; } } UNLOCK(intf); return 1; } /** Pool Menu Commands **/ MENU_HELPER(cmd_pools_helper) { interface_t *intf = (interface_t *)ins->data; int i,j; LOCK(intf); if(intf->type != INTERFACE_SEND) { UNLOCK(intf); return; } for(j = 0; args[no_args-1][j] != '\0'; ++j) { if(args[no_args-1][j] == '?') break; } for(i = 0; i < intf->send.no_pools; ++i) { LOCK(intf->send.pools[i]); if(intf->send.pools[i]->deleted == 0 && (j == 0 || strncmp(intf->send.pools[i]->name,args[no_args-1],j) == 0)) admin_msg(ac,"%s",intf->send.pools[i]->name); UNLOCK(intf->send.pools[i]); } UNLOCK(intf); } MENU_HELPER(cmd_interfaces_helper); // pre-declaration MENU_HELPER(cmd_int_pools_helper) { interface_t *intf; void *ptr; int i,j; if(no_args == 2) { for(j = 0; args[1][j] != '\0'; ++j) { if(args[1][j] == '?') break; } LOCK(global); for(i = 0; i < global->no_interfaces; ++i) { LOCK(global->interfaces[i]); if(global->interfaces[i]->deleted == 0 && global->interfaces[i]->type == INTERFACE_SEND && (j == 0 || strncmp(global->interfaces[i]->name,args[1],j) == 0)) admin_msg(ac,"%s",global->interfaces[i]->name); UNLOCK(global->interfaces[i]); } UNLOCK(global); } else if(no_args > 2) { intf = interface_find(args[1]); if(intf != NULL) { ptr = ins->data; ins->data = intf; cmd_pools_helper(ins,ac,args,no_args); ins->data = ptr; } } } MENU_CMD(cmd_pool_delete) { interface_t *intf = (interface_t *)ins->prev->data; pool_t *p = (pool_t *)ins->data; int done = 1; if(!is_pool_new(intf,p)) { pool_del(intf,p); LOCK(p); if(p->deleted != 0) admin_msg(ac,"Pool %s Deleted",p->name); else { done = 0; admin_msg(ac,"Pool %s Deletion not possible",p->name); } UNLOCK(p); } if(done) return RET_UP; else return 0; } MENU_CMD(cmd_pool_rename) { interface_t *intf = (interface_t *)ins->prev->data; pool_t *p = (pool_t *)ins->data; if(pool_rename(intf,p,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,"Failed Renamed to %s",args[1]); return 0; } MENU_CMD(cmd_pool_save) { interface_t *intf = (interface_t *)ins->prev->data; pool_t *p = (pool_t *)ins->data; int ret; if(is_pool_new(intf,p)) { ret = pool_add(intf,p); if(ret == 0) { admin_msg(ac,"Successfully Saved"); ins->free = NULL; } else admin_msg(ac,"Save Failed."); } else admin_msg(ac,"Pool is already saved."); return 0; } static void cmd_pool_show_info(acontext_t *ac, pool_t *p) { char btmp[16]; float f; int i; LOCK(p); admin_msg(ac,"-- Pool %s --",p->name); admin_msg(ac,"Sends: %d/%d",p->no_csends,p->sends); for(i = 0,f = 0.0; i < AVGSPEED; ++i) f += (float)p->avgspeed[i]; f /= ((float)AVGSPEED) * 1024.0; if(p->bandwidth != 0) admin_msg(ac,"Current Rate: %.2f KiB/sec (Limit %ld, Samples: %d)", f,p->bandwidth,AVGSPEED); else admin_msg(ac,"Current Rate: %.2f KiB/sec (Samples: %d)", f,AVGSPEED); admin_msg(ac,"Record Rate: %.2f KiB/sec", ((float)p->record_rate)/1024.0); admin_msg(ac,"Record Send: %.2f KiB/sec", ((float)p->record_send)/1024.0); admin_msg(ac,"Total Transfered: %s", format_bytes(btmp,sizeof(btmp), ((unsigned long long)p->stat_mib)*1024*1024 + (unsigned long long)p->stat_carry,1)); UNLOCK(p); } MENU_CMD(cmd_pool_info) { pool_t *p = (pool_t *)ins->data; cmd_pool_show_info(ac,p); return 0; } static int cmd_pool_settings_p(pool_t *p, acontext_t *ac, char **args, int no_args) { if(no_args == 1) { pqueue_t settings; pqueue_init(&settings,0); pool_read_settings(p,&settings); LOCK(p); output_settings(ac,"-- Pool Settings for %s --", p->name,&settings); UNLOCK(p); } else if(no_args >= 3) { if(pool_apply_setting(p,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_pool_settings) { pool_t *p = (pool_t *)ins->data; return cmd_pool_settings_p(p,ac,args,no_args); } static const char *send_state_text(state_t s); // pre-declaration static void cmd_pool_display_send(acontext_t *ac, send_t *s, time_t now) { char buffer1[256],buffer2[16],buffer3[16]; float f; int i; LOCK(s); RLOCK(s->pack); for(i = 0, f = 0.0; i < AVGSPEED; ++i) f += (float)s->avgspeed[i]; f /= ((float)AVGSPEED) * 1024.0; if(s->network != NULL) LOCK(s->network); admin_cmsg(ac,"%%r-%%n To: [%%9%s:%s%%n] (%s)", s->network != NULL ? s->network->name : "Unknown", s->nick != NULL ? s->nick : "Unknown",s->host); if(s->network != NULL) UNLOCK(s->network); admin_cmsg(ac," Rate: %%9%.1f KiB/sec%%n, State: %s, Elp:%s Rem:%s (%ds), Retries: %d", f,send_state_text(s->state), s->connected == 0 ? "-" : etimestr(now - s->connected,buffer2,sizeof(buffer2)), f > 0.0 && s->pos != s->pack->size ? etimestr( (s->pack->size - s->pos) / (off_t)((f*1024.0) >= 1.0 ? (f*1024.0) : 1.0), buffer3,sizeof(buffer3)) : "-", s->last_contact != 0 ? now - s->last_contact : 0, s->retries); pathtofn(s->pack->file,buffer1,sizeof(buffer1)); admin_cmsg(ac," File: %%9%s%%n (%lldKiB/%lldKiB)", buffer1, s->pos/1024ULL,s->pack->size/1024ULL); RUNLOCK(s->pack); UNLOCK(s); } static int cmd_pool_sends_p(pool_t *p, acontext_t *ac, char **args, int no_args) { int i; if(no_args == 1) { time_t now = xtime(); LOCK(p); admin_msg(ac,"-- Sends on Pool %s --",p->name); for(i = 0; i < p->no_csends; ++i) cmd_pool_display_send(ac,p->csends[i],now); if(i == 0) admin_msg(ac,"None"); UNLOCK(p); } else if((tolower(args[1][0]) == 'c' || tolower(args[1][0]) == 'd') && no_args >= 3) { if(no_args >= 4) { i = pool_send_close(p,args[2],NULL,args[3],NULL,NULL,no_args >= 5 ? args[4] : NULL); i += pool_send_close(p,args[2],NULL,NULL,args[3],NULL,no_args >= 5 ? args[4] : NULL); } else i = pool_send_close(p,args[2],NULL,NULL,NULL,NULL,NULL); admin_msg(ac,"Closed %d Matching Sends",i); } else admin_msg(ac,"%s [close [ ]]",args[0]); return 0; } MENU_CMD(cmd_pool_sends) { pool_t *p = (pool_t *)ins->data; return cmd_pool_sends_p(p,ac,args,no_args); } /** Pool Menu Structure **/ static const cmd_t pool_menu[] = { {"delete", cmd_pool_delete, 0,0,1,0,PRIVS_EMPTY,NULL}, {"info", cmd_pool_info, 0,0,0,0,PRIVS_EMPTY,NULL}, {"rename", cmd_pool_rename, 1,1,1,0,PRIVS_EMPTY,NULL}, {"save", cmd_pool_save, 0,0,1,0,PRIVS_EMPTY,NULL}, {"sends", cmd_pool_sends, 0,4,1,0,PRIVS_EMPTY,NULL}, {"settings", cmd_pool_settings, 0,2,1,0,PRIVS_EMPTY,NULL}, {NULL} }; /** Pool Menu Entry **/ MENU_CHECK(cmd_pool_check) { pool_t *p = (pool_t *)ins->data; int ret = 0; LOCK(p); if(p->deleted != 0) { admin_msg(ac,"Pool %s, Deleted.",p->name); ret = -1; } UNLOCK(p); return ret; } MENU_CMD(cmd_pool_entry) { interface_t *intf = (interface_t *)ins->prev->data; pool_t *p; LOCK(intf); if(intf->type != INTERFACE_SEND) { UNLOCK(intf); admin_msg(ac,"Only available on %s type interfaces.", interfacetype_to_str(INTERFACE_SEND)); return -1; } else UNLOCK(intf); if(ins->prompt != NULL && ins->free_prompt) xfree(ins->prompt); ins->prompt = xstrdup(args[1]); ins->free_prompt= 1; ins->check = cmd_pool_check; p = pool_find(intf,args[1]); if(p == NULL) { p = alloc_pool(); p->name = xstrdup(args[1]); ins->free = (void (*)(void *)) free_pool; admin_msg(ac,"New Pool: %s",args[1]); } ins->data = p; return 0; } static void register_pool_menu(menu_t *intf_menu) { menu_t *p_menu = menu_from_cmds( "pool", // name 1, // min_args 1, // max_args 1, // log 0, // hide PRIV_TO_MASK(PRIV_POOLS), // privs cmd_pool_entry, // func cmd_pools_helper, // helper (cmd_t *)pool_menu); menu_add(intf_menu,p_menu); menu_deref(p_menu); }