destroycommandtree((CommandTree *)ct->next[i]);
}
}
-
+
+ if(ct->cmd) {
+ if(ct->cmd->command)
+ freesstring(ct->cmd->command);
+ if(ct->cmd->ext && ct->cmd->destroyext)
+ (ct->cmd->destroyext)(ct->cmd->ext);
+ free(ct->cmd);
+ }
free(ct);
}
return sum;
}
+/* sanitisecommandname:
+ *
+ * Converts the given command name to uppercase and checks for bad chars.
+ *
+ * Returns 1 if bad chars were found
+ */
+static int sanitisecommandname(const char *cmdname, char *cmdbuf) {
+ int len,i;
+
+ strncpy(cmdbuf,cmdname,MAX_COMMAND_LEN);
+ cmdbuf[MAX_COMMAND_LEN-1]='\0';
+
+ len=strlen(cmdbuf);
+
+ /* Sanity check the string */
+ for (i=0;i<len;i++) {
+ cmdbuf[i]=toupper(cmdbuf[i]);
+ if (cmdbuf[i]<'A' || cmdbuf[i]>'Z') {
+ /* Someone tried to register an invalid command name */
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/*
- * addcommandtotree:
+ * addcommandhelptotree:
*
- * This installs a specific command in a tree.
+ * This installs a specific command in a tree, with a help paramater.
*
* This function builds the Command structure in addition to
* installing it in the tree
*/
-Command *addcommandtotree(CommandTree *ct, const char *cmdname, int level, int maxparams, CommandHandler handler) {
+Command *addcommandexttotree(CommandTree *ct, const char *cmdname, int level, int maxparams, CommandHandler handler, void *ext) {
Command *nc, *c;
- int i;
-
+ char cmdbuf[MAX_COMMAND_LEN];
+
+ if (sanitisecommandname(cmdname, cmdbuf))
+ return NULL;
+
/* Generate the struct.. */
nc=(void *)malloc(sizeof(Command));
- nc->command=getsstring(cmdname, MAX_COMMAND_LEN);
+ nc->command=getsstring(cmdbuf, MAX_COMMAND_LEN);
nc->level=level;
nc->maxparams=maxparams;
nc->handler=handler;
nc->ext=NULL;
nc->next=NULL;
-
- /* Sanity check the string */
- for (i=0;i<nc->command->length;i++) {
- nc->command->content[i]=toupper(nc->command->content[i]);
- if (nc->command->content[i]<'A' || nc->command->content[i]>'Z') {
- /* Someone tried to register an invalid command name */
- freesstring(nc->command);
- free(nc);
- return NULL;
- }
- }
+ nc->calls=0;
+ nc->destroyext=NULL;
if ((c=findcommandintree(ct,cmdname,1))!=NULL) {
/* Found something already. Append our entry to the end */
free(nc);
return NULL;
}
+
+ if (ext)
+ nc->ext=(void *)ext;
return nc;
}
insertcommand(ct->cmd,(CommandTree *)ct->next[oldcharindex],depth+1);
}
ct->cmd=c;
- ct->final=&(c->command->content[depth]);
+ /* Use a static NUL string rather than the allocated one if possible. */
+ if (c->command->length > depth)
+ ct->final=&(c->command->content[depth]);
+ else
+ ct->final="";
return 0;
} else {
if ((ct->cmd!=NULL) && (ct->final[0]!='\0')) {
int deletecommandfromtree(CommandTree *ct, const char *cmdname, CommandHandler handler) {
int i;
+ char cmdbuf[MAX_COMMAND_LEN+1];
sstring *tmpstr;
- tmpstr=getsstring(cmdname,MAX_COMMAND_LEN);
+ if (sanitisecommandname(cmdname, cmdbuf))
+ return 1;
- /* Sanity check input string */
- for (i=0;i<tmpstr->length;i++) {
- tmpstr->content[i]=toupper(tmpstr->content[i]);
- if (tmpstr->content[i]<'A' || tmpstr->content[i]>'Z') {
- /* Someone tried to delete an invalid command name */
- freesstring(tmpstr);
- return 1;
- }
- }
+ tmpstr=getsstring(cmdbuf, MAX_COMMAND_LEN);
i=deletecommand(tmpstr,ct,0,handler);
freesstring(tmpstr);
+
return i;
}
c=*ch;
(*ch)=(Command *)((*ch)->next);
freesstring(c->command);
+ if(c->ext && c->destroyext)
+ (c->destroyext)(c->ext);
free(c);
return 0;
}
c=*ch;
(*ch)=(Command *)((*ch)->next);
freesstring(c->command);
+ if(c->ext && c->destroyext)
+ (c->destroyext)(c->ext);
free(c);
+
+ /* We need to regenerate the final pointer if needed;
+ * if ct->cmd is still pointing to a command it has the same name.
+ * Otherwise we should clear it.*/
+ if (ct->cmd)
+ ct->final=&(ct->cmd->command->content[depth]);
+ else
+ ct->final="";
+
return 0;
}
}
return count;
}
+
+/* Returns the command name given a handler */
+sstring *getcommandname(CommandTree *ct, CommandHandler handler) {
+ int i;
+ sstring *s;
+
+ if(ct->cmd && ct->cmd->handler == handler) {
+ return ct->cmd->command;
+ }
+
+ for (i=0;i<26;i++) {
+ if(ct->next[i]) {
+ s=getcommandname(ct->next[i], handler);
+ if(s)
+ return s;
+ }
+ }
+
+ return NULL;
+}