commands.c

Go to the documentation of this file.
00001 /* Routines for looking up commands in a *Serv command list.
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church. 
00010  * 
00011  *
00012  */
00013 
00014 #include "services.h"
00015 #include "commands.h"
00016 #include "language.h"
00017 
00018 /*************************************************************************/
00019 
00027 Command *lookup_cmd(Command * list, char *cmd)
00028 {
00029     Command *c;
00030 
00031     for (c = list; c->name; c++) {
00032         if (stricmp(c->name, cmd) == 0) {
00033             return c;
00034         }
00035     }
00036     return NULL;
00037 }
00038 
00039 /*************************************************************************/
00040 
00050 void run_cmd(char *service, User * u, Command * list, char *cmd)
00051 {
00052     Command *c = lookup_cmd(list, cmd);
00053     do_run_cmd(service, u, c, cmd);
00054 }
00055 
00056 /*************************************************************************/
00057 
00067 void mod_run_cmd(char *service, User * u, CommandHash * cmdTable[],
00068                  const char *cmd)
00069 {
00070     Command *c = findCommand(cmdTable, cmd);
00071     do_run_cmd(service, u, c, cmd);
00072 }
00073 
00074 
00075 /*************************************************************************/
00076 
00085 void do_run_cmd(char *service, User * u, Command * c, const char *cmd)
00086 {
00087     int retVal = 0;
00088     Command *current;
00089 
00090     if (c && c->routine) {
00091         if ((checkDefCon(DEFCON_OPER_ONLY)
00092              || checkDefCon(DEFCON_SILENT_OPER_ONLY)) && !is_oper(u)) {
00093             if (!checkDefCon(DEFCON_SILENT_OPER_ONLY)) {
00094                 notice_lang(service, u, OPER_DEFCON_DENIED);
00095             }
00096         } else {
00097             char *mod_current_module_name_save = mod_current_module_name;
00098             Module *mod_current_module_save = mod_current_module;
00099             mod_current_module_name = c->mod_name;
00100             mod_current_module = findModule(c->mod_name);
00101             if ((c->has_priv == NULL) || c->has_priv(u)) {
00102                 retVal = c->routine(u);
00103                 if (retVal == MOD_CONT) {
00104                     current = c->next;
00105                     while (current && retVal == MOD_CONT) {
00106                         mod_current_module_name = current->mod_name;
00107                         mod_current_module = findModule(current->mod_name);
00108                         if (current->routine)
00109                             retVal = current->routine(u);
00110                         current = current->next;
00111                     }
00112                 }
00113             } else {
00114                 notice_lang(service, u, ACCESS_DENIED);
00115                 alog("Access denied for %s with service %s and command %s",
00116                      u->nick, service, cmd);
00117             }
00118             mod_current_module_name = mod_current_module_name_save;
00119             mod_current_module = mod_current_module_save;
00120         }
00121     } else {
00122         if ((!checkDefCon(DEFCON_SILENT_OPER_ONLY)) || is_oper(u)) {
00123             notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service);
00124         }
00125     }
00126 }
00127 
00128 /*************************************************************************/
00129 
00137 void do_help_limited(char *service, User * u, Command * c)
00138 {
00139     if (c->has_priv == is_services_oper)
00140         notice_lang(service, u, HELP_LIMIT_SERV_OPER);
00141     else if (c->has_priv == is_services_admin)
00142         notice_lang(service, u, HELP_LIMIT_SERV_ADMIN);
00143     else if (c->has_priv == is_services_root)
00144         notice_lang(service, u, HELP_LIMIT_SERV_ROOT);
00145     else if (c->has_priv == is_oper)
00146         notice_lang(service, u, HELP_LIMIT_IRC_OPER);
00147     else if (c->has_priv == is_host_setter)
00148         notice_lang(service, u, HELP_LIMIT_HOST_SETTER);
00149     else if (c->has_priv == is_host_remover)
00150         notice_lang(service, u, HELP_LIMIT_HOST_REMOVER);
00151 }
00152 
00153 /*************************************************************************/
00154 
00163 void do_help_cmd(char *service, User * u, Command * c, const char *cmd)
00164 {
00165     Command *current;
00166     int has_had_help = 0;
00167     int cont = MOD_CONT;
00168     const char *p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
00169     Module *calling_module = mod_current_module;
00170     char *calling_module_name = mod_current_module_name;
00171     int help_message;
00172     int (*help_message_ptr)(User *u) = NULL;
00173 
00174     for (current = c; (current) && (cont == MOD_CONT);
00175          current = current->next) {
00176         mod_current_module_name = current->mod_name;
00177         if (mod_current_module_name)
00178             mod_current_module = findModule(mod_current_module_name);
00179         else
00180             mod_current_module = NULL;
00181 
00182         p1 = current->help_param1;
00183         p2 = current->help_param2;
00184         p3 = current->help_param3;
00185         p4 = current->help_param4;
00186 
00187         help_message = 0;
00188         help_message_ptr = NULL;
00189 
00190         if (current->helpmsg_all >= 0) {
00191             notice_help(service, u, current->helpmsg_all, p1, p2, p3, p4);
00192             has_had_help = 1;
00193         } else if (current->all_help) {
00194             cont = current->all_help(u);
00195             has_had_help = 1;
00196         }
00197 
00198         if (is_services_root(u) && (current->helpmsg_root >= 0 || current->root_help)) {
00199             if (current->helpmsg_root >= 0)
00200                 help_message = current->helpmsg_root;
00201             else if (current->root_help)
00202                 help_message_ptr = current->root_help;
00203         } else if (is_services_admin(u) && (current->helpmsg_admin >= 0 || current->admin_help)) {
00204             if (current->helpmsg_admin >= 0)
00205                 help_message = current->helpmsg_admin;
00206             else if (current->admin_help)
00207                 help_message_ptr = current->admin_help;
00208         } else if (is_services_oper(u) && (current->helpmsg_oper >= 0 || current->oper_help)) {
00209             if (current->helpmsg_oper >= 0)
00210                 help_message = current->helpmsg_oper;
00211             else if (current->oper_help)
00212                 help_message_ptr = current->oper_help;
00213         } else {
00214             /* Shouldn't we check for the user to be identified? */
00215             if (current->helpmsg_reg >= 0)
00216                 help_message = current->helpmsg_reg;
00217             else if (current->regular_help)
00218                 help_message_ptr = current->regular_help;
00219         }
00220 
00221         if (help_message) {
00222             notice_help(service, u, help_message, p1, p2, p3, p4);
00223             has_had_help = 1;
00224         } else if (help_message_ptr) {
00225             cont = help_message_ptr(u);
00226             has_had_help = 1;
00227         }
00228 
00229     }
00230     if (has_had_help == 0) {
00231         notice_lang(service, u, NO_HELP_AVAILABLE, cmd);
00232     } else {
00233         do_help_limited(service, u, c);
00234     }
00235 
00236     mod_current_module = calling_module;
00237     mod_current_module_name = calling_module_name;
00238 }
00239 
00240 /*************************************************************************/
00241 
00250 void help_cmd(char *service, User * u, Command * list, char *cmd)
00251 {
00252     Command *c = lookup_cmd(list, cmd);
00253     do_help_cmd(service, u, c, cmd);
00254 }
00255 
00256 /*************************************************************************/
00257 
00266 void mod_help_cmd(char *service, User * u, CommandHash * cmdTable[],
00267                   const char *cmd)
00268 {
00269     Command *c = findCommand(cmdTable, cmd);
00270     do_help_cmd(service, u, c, cmd);
00271 }
00272 
00273 /*************************************************************************/