X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/8d74872320306bbdc8d5334746b16b7045331451..5f5fc0447463454812f1de465387cf1ca99eaf69:/parser/parser.c diff --git a/parser/parser.c b/parser/parser.c index 90111f40..2a814761 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -45,7 +45,14 @@ void destroycommandtree(CommandTree *ct) { 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); } @@ -73,6 +80,32 @@ int countcommandtree(CommandTree *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'Z') { + /* Someone tried to register an invalid command name */ + return 1; + } + } + + return 0; +} + /* * addcommandhelptotree: * @@ -82,41 +115,23 @@ int countcommandtree(CommandTree *ct) { * installing it in the tree */ -Command *addcommandhelptotree(CommandTree *ct, const char *cmdname, int level, int maxparams, CommandHandler handler, const char *help) { +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; - if (help) { - int len=strlen(help); - nc->help=(char *)malloc(len+1); - if(nc->help) { - strncpy(nc->help, help, len); - nc->help[len] = '\0'; - } - } else { - nc->help=NULL; - } - - /* Sanity check the string */ - for (i=0;icommand->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); - if(nc->help) - free(nc->help); - 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 */ @@ -126,11 +141,12 @@ Command *addcommandhelptotree(CommandTree *ct, const char *cmdname, int level, i } else if (insertcommand(nc,ct,0)) { /* Erk, that didn't work.. */ freesstring(nc->command); - if(nc->help) - free(nc->help); free(nc); return NULL; } + + if (ext) + nc->ext=(void *)ext; return nc; } @@ -160,7 +176,11 @@ int insertcommand(Command *c, CommandTree *ct, int depth) { 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')) { @@ -186,21 +206,16 @@ int insertcommand(Command *c, CommandTree *ct, int depth) { 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;ilength;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; } @@ -221,8 +236,8 @@ int deletecommand(sstring *cmdname, CommandTree *ct, int depth, CommandHandler h c=*ch; (*ch)=(Command *)((*ch)->next); freesstring(c->command); - if(c->help) - free(c->help); + if(c->ext && c->destroyext) + (c->destroyext)(c->ext); free(c); return 0; } @@ -240,9 +255,18 @@ int deletecommand(sstring *cmdname, CommandTree *ct, int depth, CommandHandler h c=*ch; (*ch)=(Command *)((*ch)->next); freesstring(c->command); - if(c->help) - free(c->help); + 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; } } @@ -334,3 +358,23 @@ int getcommandlist(CommandTree *ct, Command **commandlist, int maxcommands) { 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; +}