X-Git-Url: http://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fcmd%2Fcmd.c;h=1f418179a0b75006bcbd23e2ac559e187106419e;hp=456d66b640a401fce6727f089312deca3ffd445d;hb=e1414be76bed00d12030e2704dc6e7bcca04b6d1;hpb=61cf9fa731654b943a271dcf585b95062fbe7a4c diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c index 456d66b..1f41817 100644 --- a/src/cmd/cmd.c +++ b/src/cmd/cmd.c @@ -1,7 +1,7 @@ /* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. - * + * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html @@ -10,29 +10,27 @@ #include #include -RCSID - ("$Header$"); +#include -#include #include -#include "cmd.h" -#include -#include -#include #include +#include "cmd.h" + /* declaration of private token type */ struct cmd_token { struct cmd_token *next; char *key; }; -static int dummy; /* non-null ptr used for flag existence */ +static struct cmd_item dummy; /* non-null ptr used for flag existence */ static struct cmd_syndesc *allSyntax = 0; static int noOpcodes = 0; -static int (*beforeProc) (struct cmd_syndesc * ts, char *beforeRock) = - 0, (*afterProc) (struct cmd_syndesc * ts, char *afterRock) = 0; -static char *beforeRock, *afterRock; +static int (*beforeProc) (struct cmd_syndesc * ts, void *beforeRock) = NULL; +static int (*afterProc) (struct cmd_syndesc * ts, void *afterRock) = NULL; +static int enablePositional = 1; +static int enableAbbreviation = 1; +static void *beforeRock, *afterRock; static char initcmd_opcode[] = "initcmd"; /*Name of initcmd opcode */ /* take name and string, and return null string if name is empty, otherwise return @@ -40,24 +38,25 @@ static char initcmd_opcode[] = "initcmd"; /*Name of initcmd opcode */ static char * NName(char *a1, char *a2) { - static char tbuffer[80]; + static char tbuffer[300]; if (strlen(a1) == 0) { - return ""; + return ""; } else { - strcpy(tbuffer, a1); - strcat(tbuffer, a2); - return tbuffer; + strncpy(tbuffer, a1, sizeof(tbuffer)); + strncat(tbuffer, a2, sizeof(tbuffer)); + tbuffer[sizeof(tbuffer)-1]='\0'; + return tbuffer; } } /* return true if asub is a substring of amain */ static int -SubString(register char *amain, register char *asub) +SubString(char *amain, char *asub) { int mlen, slen; - register int i, j; - mlen = strlen(amain); - slen = strlen(asub); + int i, j; + mlen = (int) strlen(amain); + slen = (int) strlen(asub); j = mlen - slen; if (j < 0) return 0; /* not a substring */ @@ -70,13 +69,18 @@ SubString(register char *amain, register char *asub) } static int -FindType(register struct cmd_syndesc *as, register char *aname) +FindType(struct cmd_syndesc *as, char *aname) { - register int i; + int i; size_t cmdlen; int ambig; int best; + /* Allow --long-style options. */ + if (aname[0] == '-' && aname[1] == '-' && aname[2] && aname[3]) { + aname++; + } + cmdlen = strlen(aname); ambig = 0; best = -1; @@ -88,7 +92,7 @@ FindType(register struct cmd_syndesc *as, register char *aname) if (strlen(as->parms[i].name) < cmdlen) continue; /* A hidden option must be a full match (no best matches) */ - if (as->parms[i].flags & CMD_HIDE) + if (as->parms[i].flags & CMD_HIDE || !enableAbbreviation) continue; if (strncmp(as->parms[i].name, aname, cmdlen) == 0) { @@ -104,7 +108,7 @@ FindType(register struct cmd_syndesc *as, register char *aname) static struct cmd_syndesc * FindSyntax(char *aname, int *aambig) { - register struct cmd_syndesc *ts; + struct cmd_syndesc *ts; struct cmd_syndesc *best; size_t cmdLen; int ambig; @@ -147,7 +151,7 @@ FindSyntax(char *aname, int *aambig) /* print the help for a single parameter */ static void -PrintParmHelp(register struct cmd_parmdesc *aparm) +PrintParmHelp(struct cmd_parmdesc *aparm) { if (aparm->type == CMD_FLAG) { #ifdef notdef @@ -165,11 +169,20 @@ PrintParmHelp(register struct cmd_parmdesc *aparm) printf(" +"); } +extern char *AFSVersion; + +static int +VersionProc(struct cmd_syndesc *as, void *arock) +{ + printf("%s\n", AFSVersion); + return 0; +} + void -PrintSyntax(register struct cmd_syndesc *as) +PrintSyntax(struct cmd_syndesc *as) { - register int i; - register struct cmd_parmdesc *tp; + int i; + struct cmd_parmdesc *tp; /* now print usage, from syntax table */ if (noOpcodes) @@ -200,9 +213,9 @@ PrintSyntax(register struct cmd_syndesc *as) /* must print newline in any case, to terminate preceding line */ static void -PrintAliases(register struct cmd_syndesc *as) +PrintAliases(struct cmd_syndesc *as) { - register struct cmd_syndesc *ts; + struct cmd_syndesc *ts; if (as->flags & CMD_ALIAS) { ts = as->aliasOf; @@ -220,11 +233,11 @@ PrintAliases(register struct cmd_syndesc *as) } void -PrintFlagHelp(register struct cmd_syndesc *as) +PrintFlagHelp(struct cmd_syndesc *as) { - register int i; - register struct cmd_parmdesc *tp; - size_t flag_width; + int i; + struct cmd_parmdesc *tp; + int flag_width; char *flag_prefix; /* find flag name length */ @@ -263,9 +276,9 @@ PrintFlagHelp(register struct cmd_syndesc *as) } static int -AproposProc(register struct cmd_syndesc *as, char *arock) +AproposProc(struct cmd_syndesc *as, void *arock) { - register struct cmd_syndesc *ts; + struct cmd_syndesc *ts; char *tsub; int didAny; @@ -288,10 +301,10 @@ AproposProc(register struct cmd_syndesc *as, char *arock) } static int -HelpProc(register struct cmd_syndesc *as, char *arock) +HelpProc(struct cmd_syndesc *as, void *arock) { - register struct cmd_syndesc *ts; - register struct cmd_item *ti; + struct cmd_syndesc *ts; + struct cmd_item *ti; int ambig; int code = 0; @@ -335,8 +348,8 @@ HelpProc(register struct cmd_syndesc *as, char *arock) } int -cmd_SetBeforeProc(int (*aproc) (struct cmd_syndesc * ts, char *beforeRock), - char *arock) +cmd_SetBeforeProc(int (*aproc) (struct cmd_syndesc * ts, void *beforeRock), + void *arock) { beforeProc = aproc; beforeRock = arock; @@ -344,8 +357,8 @@ cmd_SetBeforeProc(int (*aproc) (struct cmd_syndesc * ts, char *beforeRock), } int -cmd_SetAfterProc(int (*aproc) (struct cmd_syndesc * ts, char *afterRock), - char *arock) +cmd_SetAfterProc(int (*aproc) (struct cmd_syndesc * ts, void *afterRock), + void *arock) { afterProc = aproc; afterRock = arock; @@ -356,7 +369,7 @@ cmd_SetAfterProc(int (*aproc) (struct cmd_syndesc * ts, char *afterRock), static int SortSyntax(struct cmd_syndesc *as) { - register struct cmd_syndesc **ld, *ud; + struct cmd_syndesc **ld, *ud; for (ld = &allSyntax, ud = *ld; ud; ld = &ud->next, ud = *ld) { if (strcmp(ud->name, as->name) > 0) { /* next guy is bigger than us */ @@ -371,22 +384,22 @@ SortSyntax(struct cmd_syndesc *as) struct cmd_syndesc * cmd_CreateSyntax(char *aname, - int (*aproc) (struct cmd_syndesc * ts, char *arock), - char *arock, char *ahelp) + int (*aproc) (struct cmd_syndesc * ts, void *arock), + void *arock, char *ahelp) { - register struct cmd_syndesc *td; + struct cmd_syndesc *td; /* can't have two cmds in no opcode mode */ if (noOpcodes) - return (struct cmd_syndesc *)0; + return NULL; - td = (struct cmd_syndesc *)calloc(1, sizeof(struct cmd_syndesc)); + td = calloc(1, sizeof(struct cmd_syndesc)); assert(td); td->aliasOf = td; /* treat aliasOf as pointer to real command, no matter what */ /* copy in name, etc */ if (aname) { - td->name = (char *)malloc(strlen(aname) + 1); + td->name = malloc(strlen(aname) + 1); assert(td->name); strcpy(td->name, aname); } else { @@ -398,7 +411,7 @@ cmd_CreateSyntax(char *aname, if (ahelp == (char *)CMD_HIDDEN) { td->flags |= CMD_HIDDEN; } else { - td->help = (char *)malloc(strlen(ahelp) + 1); + td->help = malloc(strlen(ahelp) + 1); assert(td->help); strcpy(td->help, ahelp); } @@ -417,14 +430,14 @@ cmd_CreateSyntax(char *aname, } int -cmd_CreateAlias(register struct cmd_syndesc *as, char *aname) +cmd_CreateAlias(struct cmd_syndesc *as, char *aname) { - register struct cmd_syndesc *td; + struct cmd_syndesc *td; - td = (struct cmd_syndesc *)malloc(sizeof(struct cmd_syndesc)); + td = malloc(sizeof(struct cmd_syndesc)); assert(td); memcpy(td, as, sizeof(struct cmd_syndesc)); - td->name = (char *)malloc(strlen(aname) + 1); + td->name = malloc(strlen(aname) + 1); assert(td->name); strcpy(td->name, aname); td->flags |= CMD_ALIAS; @@ -441,15 +454,27 @@ cmd_CreateAlias(register struct cmd_syndesc *as, char *aname) return 0; /* all done */ } +void +cmd_DisablePositionalCommands(void) +{ + enablePositional = 0; +} + +void +cmd_DisableAbbreviations(void) +{ + enableAbbreviation = 0; +} + int -cmd_IsAdministratorCommand(register struct cmd_syndesc *as) +cmd_IsAdministratorCommand(struct cmd_syndesc *as) { as->flags |= CMD_ADMIN; return 0; } int -cmd_Seek(register struct cmd_syndesc *as, int apos) +cmd_Seek(struct cmd_syndesc *as, int apos) { if (apos >= CMD_MAXPARMS) return CMD_EXCESSPARMS; @@ -458,23 +483,23 @@ cmd_Seek(register struct cmd_syndesc *as, int apos) } int -cmd_AddParm(register struct cmd_syndesc *as, char *aname, int atype, +cmd_AddParm(struct cmd_syndesc *as, char *aname, int atype, afs_int32 aflags, char *ahelp) { - register struct cmd_parmdesc *tp; + struct cmd_parmdesc *tp; if (as->nParms >= CMD_MAXPARMS) return CMD_EXCESSPARMS; tp = &as->parms[as->nParms++]; - tp->name = (char *)malloc(strlen(aname) + 1); + tp->name = malloc(strlen(aname) + 1); assert(tp->name); strcpy(tp->name, aname); tp->type = atype; tp->flags = aflags; - tp->items = (struct cmd_item *)0; + tp->items = NULL; if (ahelp) { - tp->help = (char *)malloc(strlen(ahelp) + 1); + tp->help = malloc(strlen(ahelp) + 1); assert(tp->help); strcpy(tp->help, ahelp); } else @@ -484,12 +509,12 @@ cmd_AddParm(register struct cmd_syndesc *as, char *aname, int atype, /* add a text item to the end of the parameter list */ static int -AddItem(register struct cmd_parmdesc *aparm, register char *aval) +AddItem(struct cmd_parmdesc *aparm, char *aval) { - register struct cmd_item *ti, *ni; - ti = (struct cmd_item *)calloc(1, sizeof(struct cmd_item)); + struct cmd_item *ti, *ni; + ti = calloc(1, sizeof(struct cmd_item)); assert(ti); - ti->data = (char *)malloc(strlen(aval) + 1); + ti->data = malloc(strlen(aval) + 1); assert(ti->data); strcpy(ti->data, aval); /* now put ti at the *end* of the list */ @@ -505,10 +530,10 @@ AddItem(register struct cmd_parmdesc *aparm, register char *aval) /* skip to next non-flag item, if any */ static int -AdvanceType(register struct cmd_syndesc *as, register afs_int32 aval) +AdvanceType(struct cmd_syndesc *as, afs_int32 aval) { - register afs_int32 next; - register struct cmd_parmdesc *tp; + afs_int32 next; + struct cmd_parmdesc *tp; /* first see if we should try to grab rest of line for this dude */ if (as->parms[aval].flags & CMD_EXPANDS) @@ -525,11 +550,11 @@ AdvanceType(register struct cmd_syndesc *as, register afs_int32 aval) /* discard parameters filled in by dispatch */ static void -ResetSyntax(register struct cmd_syndesc *as) +ResetSyntax(struct cmd_syndesc *as) { int i; - register struct cmd_parmdesc *tp; - register struct cmd_item *ti, *ni; + struct cmd_parmdesc *tp; + struct cmd_item *ti, *ni; tp = as->parms; for (i = 0; i < CMD_MAXPARMS; i++, tp++) { @@ -547,16 +572,16 @@ ResetSyntax(register struct cmd_syndesc *as) default: break; } - tp->items = (struct cmd_item *)0; + tp->items = NULL; } } /* move the expands flag to the last one in the list */ static int -SetupExpandsFlag(register struct cmd_syndesc *as) +SetupExpandsFlag(struct cmd_syndesc *as) { - register struct cmd_parmdesc *tp; - register int last, i; + struct cmd_parmdesc *tp; + int last, i; last = -1; /* find last CMD_LIST type parameter, optional or not, and make it expandable @@ -574,7 +599,9 @@ SetupExpandsFlag(register struct cmd_syndesc *as) return 0; } -/*Take the current argv & argc and alter them so that the initialization opcode is made to appear. This is used in cases where the initialization opcode is implicitly invoked.*/ +/* Take the current argv & argc and alter them so that the initialization + * opcode is made to appear. This is used in cases where the initialization + * opcode is implicitly invoked.*/ static char ** InsertInitOpcode(int *aargc, char **aargv) { @@ -582,16 +609,17 @@ InsertInitOpcode(int *aargc, char **aargv) char *pinitopcode; /*Ptr to space for name of init opcode */ int i; /*Loop counter */ - /*Allocate the new argv array, plus one for the new opcode, plus one more for the trailing null pointer */ - newargv = (char **)malloc(((*aargc) + 2) * sizeof(char *)); + /* Allocate the new argv array, plus one for the new opcode, plus one + * more for the trailing null pointer */ + newargv = malloc(((*aargc) + 2) * sizeof(char *)); if (!newargv) { fprintf(stderr, "%s: Can't create new argv array with %d+2 slots\n", aargv[0], *aargc); return (NULL); } - /*Create space for the initial opcode & fill it in */ - pinitopcode = (char *)malloc(sizeof(initcmd_opcode)); + /* Create space for the initial opcode & fill it in */ + pinitopcode = malloc(sizeof(initcmd_opcode)); if (!pinitopcode) { fprintf(stderr, "%s: Can't malloc initial opcode space\n", aargv[0]); free(newargv); @@ -599,26 +627,28 @@ InsertInitOpcode(int *aargc, char **aargv) } strcpy(pinitopcode, initcmd_opcode); - /*Move all the items in the old argv into the new argv, in their proper places */ + /* Move all the items in the old argv into the new argv, in their + * proper places */ for (i = *aargc; i > 1; i--) newargv[i] = aargv[i - 1]; - /*Slip in the opcode and the trailing null pointer, and bump the argument count up by one for the new opcode */ + /* Slip in the opcode and the trailing null pointer, and bump the + * argument count up by one for the new opcode */ newargv[0] = aargv[0]; newargv[1] = pinitopcode; (*aargc)++; newargv[*aargc] = NULL; - /*Return the happy news */ + /* Return the happy news */ return (newargv); } /*InsertInitOpcode */ static int -NoParmsOK(register struct cmd_syndesc *as) +NoParmsOK(struct cmd_syndesc *as) { - register int i; - register struct cmd_parmdesc *td; + int i; + struct cmd_parmdesc *td; for (i = 0; i < CMD_MAXPARMS; i++) { td = &as->parms[i]; @@ -631,34 +661,57 @@ NoParmsOK(register struct cmd_syndesc *as) return 1; } -/* Call the appropriate function, or return syntax error code. Note: if no opcode is specified, an initialization routine exists, and it has NOT been called before, we invoke the special initialization opcode*/ +/* Add help, apropos commands once */ +static void +initSyntax(void) +{ + struct cmd_syndesc *ts; + + if (!noOpcodes) { + ts = cmd_CreateSyntax("help", HelpProc, NULL, + "get help on commands"); + cmd_AddParm(ts, "-topic", CMD_LIST, CMD_OPTIONAL, "help string"); + cmd_AddParm(ts, "-admin", CMD_FLAG, CMD_OPTIONAL, NULL); + + ts = cmd_CreateSyntax("apropos", AproposProc, NULL, + "search by help text"); + cmd_AddParm(ts, "-topic", CMD_SINGLE, CMD_REQUIRED, "help string"); + ts = cmd_CreateSyntax("version", VersionProc, NULL, + (char *)CMD_HIDDEN); + ts = cmd_CreateSyntax("-version", VersionProc, NULL, + (char *)CMD_HIDDEN); + ts = cmd_CreateSyntax("-help", HelpProc, NULL, + (char *)CMD_HIDDEN); + ts = cmd_CreateSyntax("--version", VersionProc, NULL, + (char *)CMD_HIDDEN); + ts = cmd_CreateSyntax("--help", HelpProc, NULL, + (char *)CMD_HIDDEN); + } +} + +/* Call the appropriate function, or return syntax error code. Note: if + * no opcode is specified, an initialization routine exists, and it has + * NOT been called before, we invoke the special initialization opcode + */ int -cmd_Dispatch(int argc, char **argv) +cmd_Parse(int argc, char **argv, struct cmd_syndesc **outsyntax) { char *pname; - struct cmd_syndesc *ts; + struct cmd_syndesc *ts = NULL; struct cmd_parmdesc *tparm; afs_int32 i, j; int curType; int positional; int ambig; + int code = 0; static int initd = 0; /*Is this the first time this routine has been called? */ static int initcmdpossible = 1; /*Should be consider parsing the initial command? */ + *outsyntax = NULL; + if (!initd) { initd = 1; - /* Add help, apropos commands once */ - if (!noOpcodes) { - ts = cmd_CreateSyntax("help", HelpProc, (char *)0, - "get help on commands"); - cmd_AddParm(ts, "-topic", CMD_LIST, CMD_OPTIONAL, "help string"); - cmd_AddParm(ts, "-admin", CMD_FLAG, CMD_OPTIONAL, NULL); - - ts = cmd_CreateSyntax("apropos", AproposProc, (char *)0, - "search by help text"); - cmd_AddParm(ts, "-topic", CMD_SINGLE, CMD_REQUIRED, - "help string"); - } + initSyntax(); } /*Remember the program name */ @@ -668,17 +721,19 @@ cmd_Dispatch(int argc, char **argv) if (argc == 1) { if (!NoParmsOK(allSyntax)) { printf("%s: Type '%s -help' for help\n", pname, pname); - return (CMD_USAGE); + code = CMD_USAGE; + goto out; } } } else { if (argc < 2) { /* if there is an initcmd, don't print an error message, just * setup to use the initcmd below. */ - if (!(initcmdpossible && FindSyntax(initcmd_opcode, (int *)0))) { + if (!(initcmdpossible && FindSyntax(initcmd_opcode, NULL))) { printf("%s: Type '%s help' or '%s help ' for help\n", pname, pname, pname); - return (CMD_USAGE); + code = CMD_USAGE; + goto out; } } } @@ -695,7 +750,7 @@ cmd_Dispatch(int argc, char **argv) * see if there is a descriptor for the initialization opcode. * Only try this once. */ initcmdpossible = 0; - ts = FindSyntax(initcmd_opcode, (int *)0); + ts = FindSyntax(initcmd_opcode, NULL); if (!ts) { /*There is no initialization opcode available, so we declare * an error */ @@ -710,7 +765,8 @@ cmd_Dispatch(int argc, char **argv) "Unrecognized operation '%s'; type '%shelp' for list\n", argv[1], NName(pname, " ")); } - return (CMD_UNKNOWNCMD); + code = CMD_UNKNOWNCMD; + goto out; } else { /*Found syntax structure for an initialization opcode. Fix * up argv and argc to relect what the user @@ -719,7 +775,8 @@ cmd_Dispatch(int argc, char **argv) fprintf(stderr, "%sCan't insert implicit init opcode into command line\n", NName(pname, ": ")); - return (CMD_INTERNALERROR); + code = CMD_INTERNALERROR; + goto out; } } } /*Initial opcode not yet attempted */ @@ -736,19 +793,22 @@ cmd_Dispatch(int argc, char **argv) "Unrecognized operation '%s'; type '%shelp' for list\n", argv[1], NName(pname, " ")); } - return CMD_UNKNOWNCMD; + code = CMD_UNKNOWNCMD; + goto out; } } /*Argv[1] is not a valid opcode */ } /*Opcodes are defined */ - /* Found the descriptor; start parsing. curType is the type we're trying to parse */ + /* Found the descriptor; start parsing. curType is the type we're + * trying to parse */ curType = 0; /* We start off parsing in "positional" mode, where tokens are put in * slots positionally. If we find a name that takes args, we go * out of positional mode, and from that point on, expect a switch * before any particular token. */ - positional = 1; /* Are we still in the positional region of the cmd line? */ + + positional = enablePositional; /* Accepting positional cmds ? */ i = noOpcodes ? 1 : 2; SetupExpandsFlag(ts); for (; i < argc; i++) { @@ -767,17 +827,17 @@ cmd_Dispatch(int argc, char **argv) else fprintf(stderr, "'%shelp %s' for detailed help\n", NName(argv[0], " "), ts->name); - ResetSyntax(ts); - return (CMD_UNKNOWNSWITCH); + code = CMD_UNKNOWNSWITCH; + goto out; } if (j >= CMD_MAXPARMS) { fprintf(stderr, "%sInternal parsing error\n", NName(pname, ": ")); - ResetSyntax(ts); - return (CMD_INTERNALERROR); + code = CMD_INTERNALERROR; + goto out; } if (ts->parms[j].type == CMD_FLAG) { - ts->parms[j].items = (struct cmd_item *)&dummy; + ts->parms[j].items = &dummy; } else { positional = 0; curType = j; @@ -787,8 +847,8 @@ cmd_Dispatch(int argc, char **argv) /* Try to fit in this descr */ if (curType >= CMD_MAXPARMS) { fprintf(stderr, "%sToo many arguments\n", NName(pname, ": ")); - ResetSyntax(ts); - return (CMD_TOOMANY); + code = CMD_TOOMANY; + goto out; } tparm = &ts->parms[curType]; @@ -810,8 +870,8 @@ cmd_Dispatch(int argc, char **argv) if (tparm->items) { fprintf(stderr, "%sToo many values after switch %s\n", NName(pname, ": "), tparm->name); - ResetSyntax(ts); - return (CMD_NOTLIST); + code = CMD_NOTLIST; + goto out; } AddItem(tparm, argv[i]); /* Add to end of list */ } else if (tparm->type == CMD_LIST) { @@ -826,16 +886,16 @@ cmd_Dispatch(int argc, char **argv) /* keep track of this for messages */ ts->a0name = argv[0]; - /* If we make it here, all the parameters are filled in. Check to see if this - * is a -help version. Must do this before checking for all required parms, - * otherwise it is a real nuisance */ + /* If we make it here, all the parameters are filled in. Check to see if + * this is a -help version. Must do this before checking for all + * required parms, otherwise it is a real nuisance */ if (ts->parms[CMD_HELPPARM].items) { PrintSyntax(ts); /* Display full help syntax if we don't have subcommands */ if (noOpcodes) PrintFlagHelp(ts); - ResetSyntax(ts); - return 0; + code = CMD_USAGE; + goto out; } /* Parsing done, see if we have all of our required parameters */ @@ -846,51 +906,76 @@ cmd_Dispatch(int argc, char **argv) if ((tparm->flags & CMD_PROCESSED) && tparm->items == 0) { fprintf(stderr, "%s The field '%s' isn't completed properly\n", NName(pname, ": "), tparm->name); - ResetSyntax(ts); - tparm->flags &= ~CMD_PROCESSED; - return (CMD_TOOFEW); + code = CMD_TOOFEW; + goto out; } if (!(tparm->flags & CMD_OPTIONAL) && tparm->items == 0) { fprintf(stderr, "%sMissing required parameter '%s'\n", NName(pname, ": "), tparm->name); - ResetSyntax(ts); - tparm->flags &= ~CMD_PROCESSED; - return (CMD_TOOFEW); + code = CMD_TOOFEW; + goto out; } tparm->flags &= ~CMD_PROCESSED; } + *outsyntax = ts; + +out: + if (code && ts != NULL) + ResetSyntax(ts); + + return code; +} + +int +cmd_Dispatch(int argc, char **argv) +{ + struct cmd_syndesc *ts = NULL; + int code; + + code = cmd_Parse(argc, argv, &ts); + if (code) + return code; /* - * Before calling the beforeProc and afterProc and all the implications - * from those calls, check if the help procedure was called and call it now. + * Before calling the beforeProc and afterProc and all the implications + * from those calls, check if the help procedure was called and call it + * now. */ if ((ts->proc == HelpProc) || (ts->proc == AproposProc)) { - i = (*ts->proc) (ts, ts->rock); - ResetSyntax(ts); - return (i); + code = (*ts->proc) (ts, ts->rock); + goto out; } /* Now, we just call the procedure and return */ if (beforeProc) - i = (*beforeProc) (ts, beforeRock); - else - i = 0; - if (i) { - ResetSyntax(ts); - return (i); - } - i = (*ts->proc) (ts, ts->rock); + code = (*beforeProc) (ts, beforeRock); + + if (code) + goto out; + + code = (*ts->proc) (ts, ts->rock); + if (afterProc) (*afterProc) (ts, afterRock); - ResetSyntax(ts); /* Reset and free things */ - return (i); +out: + cmd_FreeOptions(&ts); + return code; +} + +void +cmd_FreeOptions(struct cmd_syndesc **ts) +{ + if (*ts != NULL) { + ResetSyntax(*ts); + *ts = NULL; + } } /* free token list returned by parseLine */ static int -FreeTokens(register struct cmd_token *alist) +FreeTokens(struct cmd_token *alist) { - register struct cmd_token *nlist; + struct cmd_token *nlist; for (; alist; alist = nlist) { nlist = alist->next; free(alist->key); @@ -901,23 +986,24 @@ FreeTokens(register struct cmd_token *alist) /* free an argv list returned by parseline */ int -cmd_FreeArgv(register char **argv) +cmd_FreeArgv(char **argv) { - register char *tp; + char *tp; for (tp = *argv; tp; argv++, tp = *argv) free(tp); return 0; } -/* copy back the arg list to the argv array, freeing the cmd_tokens as you go; the actual - data is still malloc'd, and will be freed when the caller calls cmd_FreeArgv - later on */ +/* copy back the arg list to the argv array, freeing the cmd_tokens as you go; + * the actual data is still malloc'd, and will be freed when the caller calls + * cmd_FreeArgv later on + */ #define INITSTR "" static int -CopyBackArgs(register struct cmd_token *alist, register char **argv, +CopyBackArgs(struct cmd_token *alist, char **argv, afs_int32 * an, afs_int32 amaxn) { - register struct cmd_token *next; + struct cmd_token *next; afs_int32 count; count = 0; @@ -947,7 +1033,7 @@ CopyBackArgs(register struct cmd_token *alist, register char **argv, } static int -quote(register int x) +quote(int x) { if (x == '"' || x == 39 /* single quote */ ) return 1; @@ -956,7 +1042,7 @@ quote(register int x) } static int -space(register int x) +space(int x) { if (x == 0 || x == ' ' || x == '\t' || x == '\n') return 1; @@ -968,15 +1054,15 @@ int cmd_ParseLine(char *aline, char **argv, afs_int32 * an, afs_int32 amaxn) { char tbuffer[256]; - register char *tptr = 0; + char *tptr = 0; int inToken, inQuote; struct cmd_token *first, *last; - register struct cmd_token *ttok; - register int tc; + struct cmd_token *ttok; + int tc; inToken = 0; /* not copying token chars at start */ - first = (struct cmd_token *)0; - last = (struct cmd_token *)0; + first = NULL; + last = NULL; inQuote = 0; /* not in a quoted string */ while (1) { tc = *aline++; @@ -987,10 +1073,10 @@ cmd_ParseLine(char *aline, char **argv, afs_int32 * an, afs_int32 amaxn) return -1; /* should never get here */ else *tptr++ = 0; - ttok = (struct cmd_token *)malloc(sizeof(struct cmd_token)); + ttok = malloc(sizeof(struct cmd_token)); assert(ttok); - ttok->next = (struct cmd_token *)0; - ttok->key = (char *)malloc(strlen(tbuffer) + 1); + ttok->next = NULL; + ttok->key = malloc(strlen(tbuffer) + 1); assert(ttok->key); strcpy(ttok->key, tbuffer); if (last) { @@ -1022,7 +1108,7 @@ cmd_ParseLine(char *aline, char **argv, afs_int32 * an, afs_int32 amaxn) if (tc == 0) { /* last token flushed 'cause space(0) --> true */ if (last) - last->next = (struct cmd_token *)0; + last->next = NULL; return CopyBackArgs(first, argv, an, amaxn); } }