X-Git-Url: http://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fcmd%2Fcmd.c;h=1f418179a0b75006bcbd23e2ac559e187106419e;hp=253586972bd5240ba31cebfc4de490abb256579b;hb=e1414be76bed00d12030e2704dc6e7bcca04b6d1;hpb=36d02757fd6863a845163daf0d730bdcc0a28343 diff --git a/src/cmd/cmd.c b/src/cmd/cmd.c index 2535869..1f41817 100644 --- a/src/cmd/cmd.c +++ b/src/cmd/cmd.c @@ -1,151 +1,188 @@ /* * 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 */ -#include +#include +#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_syndesc *allSyntax=0; +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)() = 0, (*afterProc)() = 0; -static char *beforeRock, *afterRock; -static char initcmd_opcode[] = "initcmd"; /*Name of initcmd opcode*/ +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 the concatenation of the two strings */ -static char *NName(a1, a2) -char *a1, *a2; { - static char tbuffer[80]; +static char * +NName(char *a1, char *a2) +{ + static char tbuffer[300]; if (strlen(a1) == 0) { - return ""; - } - else { - strcpy(tbuffer, a1); - strcat(tbuffer, a2); - return tbuffer; + return ""; + } else { + 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(amain, asub) -register char *amain, *asub; { +static int +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 */ - for(i=0;i<=j;i++) { - if (strncmp(amain, asub, slen) == 0) return 1; + if (j < 0) + return 0; /* not a substring */ + for (i = 0; i <= j; i++) { + if (strncmp(amain, asub, slen) == 0) + return 1; amain++; } - return 0; /* didn't find it */ + return 0; /* didn't find it */ } -static int FindType(as, aname) -register struct cmd_syndesc *as; -register char *aname; { - register int i; - int cmdlen; +static int +FindType(struct cmd_syndesc *as, char *aname) +{ + 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; - for(i=0;iparms[i].type == 0) continue; /* this slot not set (seeked over) */ - if (strcmp(as->parms[i].name, aname)==0) return i; - if (strlen(as->parms[i].name) < cmdlen) continue; + for (i = 0; i < CMD_MAXPARMS; i++) { + if (as->parms[i].type == 0) + continue; /* this slot not set (seeked over) */ + if (strcmp(as->parms[i].name, aname) == 0) + return i; + 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) continue; + if (as->parms[i].flags & CMD_HIDE || !enableAbbreviation) + continue; if (strncmp(as->parms[i].name, aname, cmdlen) == 0) { - if (best != -1) ambig = 1; - else best = i; + if (best != -1) + ambig = 1; + else + best = i; } } - return (ambig? -1 : best); + return (ambig ? -1 : best); } -static struct cmd_syndesc *FindSyntax(aname, aambig) -int *aambig; -char *aname; { - register struct cmd_syndesc *ts; +static struct cmd_syndesc * +FindSyntax(char *aname, int *aambig) +{ + struct cmd_syndesc *ts; struct cmd_syndesc *best; - int cmdLen; + size_t cmdLen; int ambig; cmdLen = strlen(aname); - best = (struct cmd_syndesc *) 0; + best = (struct cmd_syndesc *)0; ambig = 0; - if (aambig) *aambig = 0; /* initialize to unambiguous */ - for(ts=allSyntax;ts;ts=ts->next) { - if (strcmp(aname, ts->name)==0) return(ts); - if (strlen(ts->name) < cmdLen) continue; /* we typed more than item has */ + if (aambig) + *aambig = 0; /* initialize to unambiguous */ + for (ts = allSyntax; ts; ts = ts->next) { + if (strcmp(aname, ts->name) == 0) + return (ts); + if (strlen(ts->name) < cmdLen) + continue; /* we typed more than item has */ /* A hidden command must be a full match (no best matches) */ - if (ts->flags & CMD_HIDDEN) continue; + if (ts->flags & CMD_HIDDEN) + continue; /* This is just an alias for *best, or *best is just an alias for us. * If we don't make this check explicitly, then an alias which is just a * short prefix of the real command's name might make things ambiguous * for no apparent reason. */ - if (best && ts->aliasOf == best->aliasOf) continue; + if (best && ts->aliasOf == best->aliasOf) + continue; if (strncmp(ts->name, aname, cmdLen) == 0) { - if (best) ambig = 1; /* ambiguous name */ + if (best) + ambig = 1; /* ambiguous name */ else best = ts; } } if (ambig) { - if(aambig) *aambig = ambig; /* if ambiguous and they care, tell them */ - return (struct cmd_syndesc *) 0; /* fails */ - } - else return best; /* otherwise its not ambiguous, and they know */ + if (aambig) + *aambig = ambig; /* if ambiguous and they care, tell them */ + return (struct cmd_syndesc *)0; /* fails */ + } else + return best; /* otherwise its not ambiguous, and they know */ } /* print the help for a single parameter */ -static void PrintParmHelp(aparm) -register struct cmd_parmdesc *aparm; { +static void +PrintParmHelp(struct cmd_parmdesc *aparm) +{ if (aparm->type == CMD_FLAG) { #ifdef notdef /* doc people don't like seeing this information */ if (aparm->help) printf(" (%s)", aparm->help); #endif - } - else if (aparm->help) { + } else if (aparm->help) { printf(" <%s>", aparm->help); - if (aparm->type == CMD_LIST) printf("+"); - } - else if (aparm->type == CMD_SINGLE) + if (aparm->type == CMD_LIST) + printf("+"); + } else if (aparm->type == CMD_SINGLE) printf(" "); else if (aparm->type == CMD_LIST) printf(" +"); } -void PrintSyntax(as) -register struct cmd_syndesc *as; { - register int i; - register struct cmd_parmdesc *tp; +extern char *AFSVersion; + +static int +VersionProc(struct cmd_syndesc *as, void *arock) +{ + printf("%s\n", AFSVersion); + return 0; +} + +void +PrintSyntax(struct cmd_syndesc *as) +{ + int i; + struct cmd_parmdesc *tp; /* now print usage, from syntax table */ if (noOpcodes) @@ -157,89 +194,103 @@ register struct cmd_syndesc *as; { printf("Usage: %s%s", NName(as->a0name, " "), as->name); } - for(i=0;iparms[i]; - if (tp->type == 0) continue; /* seeked over slot */ - if (tp->flags & CMD_HIDE) continue; /* skip hidden options */ + if (tp->type == 0) + continue; /* seeked over slot */ + if (tp->flags & CMD_HIDE) + continue; /* skip hidden options */ printf(" "); - if (tp->flags & CMD_OPTIONAL) printf("["); + if (tp->flags & CMD_OPTIONAL) + printf("["); printf("%s", tp->name); PrintParmHelp(tp); - if (tp->flags & CMD_OPTIONAL) printf("]"); + if (tp->flags & CMD_OPTIONAL) + printf("]"); } printf("\n"); } /* must print newline in any case, to terminate preceding line */ -static void PrintAliases(as) -register struct cmd_syndesc *as; { - register struct cmd_syndesc *ts; +static void +PrintAliases(struct cmd_syndesc *as) +{ + struct cmd_syndesc *ts; if (as->flags & CMD_ALIAS) { ts = as->aliasOf; printf("(alias for %s)\n", ts->name); - } - else { + } else { printf("\n"); - if (!as->nextAlias) return; /* none, print nothing */ + if (!as->nextAlias) + return; /* none, print nothing */ printf("aliases: "); - for(as=as->nextAlias;as;as=as->nextAlias) { + for (as = as->nextAlias; as; as = as->nextAlias) { printf("%s ", as->name); } printf("\n"); } } -void PrintFlagHelp(as) -register struct cmd_syndesc *as; { - register int i; - register struct cmd_parmdesc *tp; +void +PrintFlagHelp(struct cmd_syndesc *as) +{ + int i; + struct cmd_parmdesc *tp; int flag_width; char *flag_prefix; /* find flag name length */ flag_width = 0; - for(i=0;iparms[i]; - if (tp->type != CMD_FLAG) continue; - if (tp->flags & CMD_HIDE) continue; /* skip hidden options */ - if (!tp->help) continue; - - if (strlen(tp->name) > flag_width) flag_width = strlen(tp->name); + if (tp->type != CMD_FLAG) + continue; + if (tp->flags & CMD_HIDE) + continue; /* skip hidden options */ + if (!tp->help) + continue; + + if (strlen(tp->name) > flag_width) + flag_width = strlen(tp->name); } /* print flag help */ flag_prefix = "Where:"; - for(i=0;iparms[i]; - if (tp->type != CMD_FLAG) continue; - if (tp->flags & CMD_HIDE) continue; /* skip hidden options */ - if (!tp->help) continue; + if (tp->type != CMD_FLAG) + continue; + if (tp->flags & CMD_HIDE) + continue; /* skip hidden options */ + if (!tp->help) + continue; printf("%-7s%-*s %s\n", flag_prefix, flag_width, tp->name, tp->help); flag_prefix = ""; } } -static AproposProc(as, arock) -char *arock; -register struct cmd_syndesc *as; { - register struct cmd_syndesc *ts; +static int +AproposProc(struct cmd_syndesc *as, void *arock) +{ + struct cmd_syndesc *ts; char *tsub; int didAny; didAny = 0; tsub = as->parms[0].items->data; - for(ts=allSyntax;ts;ts=ts->next) { + for (ts = allSyntax; ts; ts = ts->next) { if ((ts->flags & CMD_ALIAS) || (ts->flags & CMD_HIDDEN)) - continue; + continue; if (SubString(ts->help, tsub)) { printf("%s: %s\n", ts->name, ts->help); didAny = 1; - } - else if (SubString(ts->name, tsub)) { + } else if (SubString(ts->name, tsub)) { printf("%s: %s\n", ts->name, ts->help); didAny = 1; } @@ -249,74 +300,79 @@ register struct cmd_syndesc *as; { return 0; } -static HelpProc(as, arock) -char *arock; -register struct cmd_syndesc *as; { - register struct cmd_syndesc *ts; - register struct cmd_item *ti; +static int +HelpProc(struct cmd_syndesc *as, void *arock) +{ + struct cmd_syndesc *ts; + struct cmd_item *ti; int ambig; int code = 0; if (as->parms[0].items == 0) { printf("%sCommands are:\n", NName(as->a0name, ": ")); - for(ts=allSyntax; ts; ts=ts->next) { + for (ts = allSyntax; ts; ts = ts->next) { if ((ts->flags & CMD_ALIAS) || (ts->flags & CMD_HIDDEN)) - continue; - printf("%-15s %s\n", ts->name, (ts->help?ts->help:"")); + continue; + printf("%-15s %s\n", ts->name, (ts->help ? ts->help : "")); } - } - else { + } else { /* print out individual help topics */ - for(ti = as->parms[0].items; ti; ti=ti->next) { + for (ti = as->parms[0].items; ti; ti = ti->next) { code = 0; ts = FindSyntax(ti->data, &ambig); - if (ts && (ts->flags & CMD_HIDDEN)) ts = 0; /* no hidden commands */ + if (ts && (ts->flags & CMD_HIDDEN)) + ts = 0; /* no hidden commands */ if (ts) { /* print out command name and help */ - printf("%s%s: %s ", NName(as->a0name, " "), ts->name, (ts->help?ts->help:"")); + printf("%s%s: %s ", NName(as->a0name, " "), ts->name, + (ts->help ? ts->help : "")); ts->a0name = as->a0name; PrintAliases(ts); PrintSyntax(ts); PrintFlagHelp(ts); - } - else { + } else { if (!ambig) - fprintf(stderr, "%sUnknown topic '%s'\n", NName(as->a0name, ": "), ti->data); + fprintf(stderr, "%sUnknown topic '%s'\n", + NName(as->a0name, ": "), ti->data); else { /* ambiguous, list 'em all */ - fprintf(stderr, "%sAmbiguous topic '%s'; use 'apropos' to list\n", - NName(as->a0name, ": "), ti->data); + fprintf(stderr, + "%sAmbiguous topic '%s'; use 'apropos' to list\n", + NName(as->a0name, ": "), ti->data); } code = CMD_UNKNOWNCMD; } } } - return(code); + return (code); } -cmd_SetBeforeProc(aproc, arock) -int (*aproc)(); -char *arock; { +int +cmd_SetBeforeProc(int (*aproc) (struct cmd_syndesc * ts, void *beforeRock), + void *arock) +{ beforeProc = aproc; beforeRock = arock; return 0; } -cmd_SetAfterProc(aproc, arock) -int (*aproc)(); -char *arock; { +int +cmd_SetAfterProc(int (*aproc) (struct cmd_syndesc * ts, void *afterRock), + void *arock) +{ afterProc = aproc; afterRock = arock; return 0; } /* thread on list in alphabetical order */ -static SortSyntax(as) -struct cmd_syndesc *as; { - register struct cmd_syndesc **ld, *ud; +static int +SortSyntax(struct cmd_syndesc *as) +{ + 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 */ + for (ld = &allSyntax, ud = *ld; ud; ld = &ud->next, ud = *ld) { + if (strcmp(ud->name, as->name) > 0) { /* next guy is bigger than us */ break; } } @@ -326,44 +382,44 @@ struct cmd_syndesc *as; { return 0; } -struct cmd_syndesc *cmd_CreateSyntax(aname, aproc, arock, ahelp) -int (*aproc)(); -char *ahelp; -char *arock; -char *aname; { - register struct cmd_syndesc *td; - +struct cmd_syndesc * +cmd_CreateSyntax(char *aname, + int (*aproc) (struct cmd_syndesc * ts, void *arock), + void *arock, char *ahelp) +{ + struct cmd_syndesc *td; + /* can't have two cmds in no opcode mode */ - if (noOpcodes) return (struct cmd_syndesc *) 0; + if (noOpcodes) + 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 */ - + 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 { - td->name = (char *) 0; + } else { + td->name = NULL; noOpcodes = 1; } if (ahelp) { - /* Piggy-back the hidden option onto the help string */ - if (ahelp == (char *)CMD_HIDDEN) { + /* Piggy-back the hidden option onto the help string */ + 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); } - } - else td->help = (char *) 0; + } else + td->help = NULL; td->proc = aproc; td->rock = arock; - + SortSyntax(td); cmd_Seek(td, CMD_HELPPARM); @@ -373,382 +429,439 @@ char *aname; { return td; } -int cmd_CreateAlias(as, aname) -register struct cmd_syndesc *as; -char *aname; { - register struct cmd_syndesc *td; - - td = (struct cmd_syndesc *) malloc(sizeof(struct cmd_syndesc)); +int +cmd_CreateAlias(struct cmd_syndesc *as, char *aname) +{ + struct cmd_syndesc *td; + + 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; /* if ever free things, make copy of help string, too */ - + /* thread on list */ SortSyntax(td); - + /* thread on alias lists */ td->nextAlias = as->nextAlias; as->nextAlias = td; td->aliasOf = as; - return 0; /* all done */ + return 0; /* all done */ } -int cmd_IsAdministratorCommand(as) -register struct cmd_syndesc *as; +void +cmd_DisablePositionalCommands(void) +{ + enablePositional = 0; +} + +void +cmd_DisableAbbreviations(void) +{ + enableAbbreviation = 0; +} + +int +cmd_IsAdministratorCommand(struct cmd_syndesc *as) { as->flags |= CMD_ADMIN; return 0; -} +} -int cmd_Seek(as, apos) -register struct cmd_syndesc *as; -int apos; { - if (apos >= CMD_MAXPARMS) return CMD_EXCESSPARMS; +int +cmd_Seek(struct cmd_syndesc *as, int apos) +{ + if (apos >= CMD_MAXPARMS) + return CMD_EXCESSPARMS; as->nParms = apos; return 0; } -int cmd_AddParm(as, aname, atype, aflags, ahelp) -register struct cmd_syndesc *as; -char *aname; -int atype; -char *ahelp; -afs_int32 aflags;{ - register struct cmd_parmdesc *tp; +int +cmd_AddParm(struct cmd_syndesc *as, char *aname, int atype, + afs_int32 aflags, char *ahelp) +{ + struct cmd_parmdesc *tp; - if (as->nParms >= CMD_MAXPARMS) return CMD_EXCESSPARMS; + 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 tp->help = (char *) 0; + } else + tp->help = NULL; return 0; } /* add a text item to the end of the parameter list */ -static AddItem(aparm, aval) -register struct cmd_parmdesc *aparm; -register char *aval; { - register struct cmd_item *ti, *ni; - ti = (struct cmd_item *) calloc(1, sizeof(struct cmd_item)); +static int +AddItem(struct cmd_parmdesc *aparm, char *aval) +{ + 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 */ - if (ni=aparm->items) { - for(;ni;ni=ni->next) if (ni->next == 0) break; /* skip to last one */ + if ((ni = aparm->items)) { + for (; ni; ni = ni->next) + if (ni->next == 0) + break; /* skip to last one */ ni->next = ti; - } - else aparm->items = ti; /* we're first */ + } else + aparm->items = ti; /* we're first */ return 0; } /* skip to next non-flag item, if any */ -static AdvanceType(as, aval) -register afs_int32 aval; -register struct cmd_syndesc *as; { - register afs_int32 next; - register struct cmd_parmdesc *tp; +static int +AdvanceType(struct cmd_syndesc *as, afs_int32 aval) +{ + 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) return aval; + if (as->parms[aval].flags & CMD_EXPANDS) + return aval; /* if not, find next non-flag used slot */ - for(next=aval+1;nextparms[next]; - if (tp->type != 0 && tp->type != CMD_FLAG) return next; + if (tp->type != 0 && tp->type != CMD_FLAG) + return next; } return aval; } /* discard parameters filled in by dispatch */ -static void ResetSyntax(as) -register struct cmd_syndesc *as; { +static void +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;itype) { - case CMD_SINGLE: - case CMD_LIST: - /* free whole list in both cases, just for fun */ - for(ti=tp->items;ti;ti=ni) { - ni = ti->next; - free(ti->data); - free(ti); - } - break; + for (i = 0; i < CMD_MAXPARMS; i++, tp++) { + switch (tp->type) { + case CMD_SINGLE: + case CMD_LIST: + /* free whole list in both cases, just for fun */ + for (ti = tp->items; ti; ti = ni) { + ni = ti->next; + free(ti->data); + free(ti); + } + break; - default: - break; + default: + break; } - tp->items = (struct cmd_item *)0; + tp->items = NULL; } } /* move the expands flag to the last one in the list */ -static SetupExpandsFlag(as) -register struct cmd_syndesc *as; { - register struct cmd_parmdesc *tp; - register int last, i; +static int +SetupExpandsFlag(struct cmd_syndesc *as) +{ + struct cmd_parmdesc *tp; + int last, i; last = -1; /* find last CMD_LIST type parameter, optional or not, and make it expandable - if no other dude is expandable */ - for(i=0;iparms[i]; if (tp->type == CMD_LIST) { - if (tp->flags & CMD_EXPANDS) return 0; /* done if already specified */ + if (tp->flags & CMD_EXPANDS) + return 0; /* done if already specified */ last = i; } } - if (last >= 0) as->parms[last].flags |= CMD_EXPANDS; + if (last >= 0) + as->parms[last].flags |= CMD_EXPANDS; 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.*/ -static char **InsertInitOpcode(aargc, aargv) -int *aargc; -char **aargv; -{ /*InsertInitOpcode*/ - - char **newargv; /*Ptr to new, expanded argv space*/ - char *pinitopcode; /*Ptr to space for name of init opcode*/ - int i; /*Loop counter*/ +/* 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) +{ + char **newargv; /*Ptr to new, expanded argv space */ + 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((char **)0); + 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]); - return((char **)0); + fprintf(stderr, "%s: Can't malloc initial opcode space\n", aargv[0]); + free(newargv); + return (NULL); } strcpy(pinitopcode, initcmd_opcode); - /*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]; + /* 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] = (char *)0; + newargv[*aargc] = NULL; - /*Return the happy news*/ - return(newargv); + /* Return the happy news */ + return (newargv); -} /*InsertInitOpcode*/ +} /*InsertInitOpcode */ -static NoParmsOK(as) -register struct cmd_syndesc *as; { - register int i; - register struct cmd_parmdesc *td; +static int +NoParmsOK(struct cmd_syndesc *as) +{ + int i; + struct cmd_parmdesc *td; - for(i=0;iparms[i]; if (td->type != 0 && !(td->flags & CMD_OPTIONAL)) { /* found a non-optional (e.g. required) parm, so NoParmsOK - is false (some parms are required) */ + * is false (some parms are required) */ return 0; } } 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*/ -cmd_Dispatch(argc, argv) -int argc; -char **argv; - { - char *pname; +/* 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_Parse(int argc, char **argv, struct cmd_syndesc **outsyntax) +{ + char *pname; + struct cmd_syndesc *ts = NULL; struct cmd_parmdesc *tparm; afs_int32 i, j; int curType; int positional; int ambig; - 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?*/ + 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, (char *)0); - - 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*/ + /*Remember the program name */ pname = argv[0]; if (noOpcodes) { if (argc == 1) { if (!NoParmsOK(allSyntax)) { - printf("%s: Type '%s -help' for help\n", pname, pname); - return(CMD_USAGE); + printf("%s: Type '%s -help' for help\n", pname, pname); + code = CMD_USAGE; + goto out; } } - } - else { + } 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))) { + * setup to use the initcmd below. */ + 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; } } } - + /* Find the syntax descriptor for this command, doing prefix matching properly */ if (noOpcodes) { ts = allSyntax; - } - else { - ts = (argc < 2? 0 : FindSyntax(argv[1], &ambig)); + } else { + ts = (argc < 2 ? 0 : FindSyntax(argv[1], &ambig)); if (!ts) { - /*First token doesn't match a syntax descriptor*/ + /*First token doesn't match a syntax descriptor */ if (initcmdpossible) { /*If initial command line handling hasn't been done yet, - see if there is a descriptor for the initialization opcode. - Only try this once.*/ + * 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*/ + * an error */ if (ambig) { fprintf(stderr, "%s", NName(pname, ": ")); - fprintf(stderr, "Ambiguous operation '%s'; type '%shelp' for list\n", - argv[1], NName(pname," ")); - } - else { + fprintf(stderr, + "Ambiguous operation '%s'; type '%shelp' for list\n", + argv[1], NName(pname, " ")); + } else { fprintf(stderr, "%s", NName(pname, ": ")); - fprintf(stderr, "Unrecognized operation '%s'; type '%shelp' for list\n", + fprintf(stderr, + "Unrecognized operation '%s'; type '%shelp' for list\n", argv[1], NName(pname, " ")); } - return(CMD_UNKNOWNCMD); - } - else { + code = CMD_UNKNOWNCMD; + goto out; + } else { /*Found syntax structure for an initialization opcode. Fix - up argv and argc to relect what the user - ``should have'' typed*/ + * up argv and argc to relect what the user + * ``should have'' typed */ if (!(argv = InsertInitOpcode(&argc, argv))) { - fprintf(stderr, "%sCan't insert implicit init opcode into command line\n", + 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*/ + } /*Initial opcode not yet attempted */ else { /* init cmd already run and no syntax entry found */ if (ambig) { fprintf(stderr, "%s", NName(pname, ": ")); - fprintf(stderr, "Ambiguous operation '%s'; type '%shelp' for list\n", + fprintf(stderr, + "Ambiguous operation '%s'; type '%shelp' for list\n", argv[1], NName(pname, " ")); - } - else { + } else { fprintf(stderr, "%s", NName(pname, ": ")); - fprintf(stderr, "Unrecognized operation '%s'; type '%shelp' for list\n", + fprintf(stderr, + "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 */ + } /*Argv[1] is not a valid opcode */ + } /*Opcodes are defined */ + + /* 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? */ - i = noOpcodes? 1 : 2; + * 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 = enablePositional; /* Accepting positional cmds ? */ + i = noOpcodes ? 1 : 2; SetupExpandsFlag(ts); - for(;iname); - 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); + fprintf(stderr, "%sInternal parsing error\n", + NName(pname, ": ")); + code = CMD_INTERNALERROR; + goto out; } if (ts->parms[j].type == CMD_FLAG) { - ts->parms[j].items = (struct cmd_item *) &dummy; - } - else { - positional = 0; + ts->parms[j].items = &dummy; + } else { + positional = 0; curType = j; ts->parms[j].flags |= CMD_PROCESSED; } - } - else { + } else { /* 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]; - if ((tparm->type == 0) || /* No option in this slot */ - (tparm->type == CMD_FLAG)) { /* A flag (not an argument */ + if ((tparm->type == 0) || /* No option in this slot */ + (tparm->type == CMD_FLAG)) { /* A flag (not an argument */ /* skipped parm slot */ - curType++; /* Skip this slot and reprocess this parm */ + curType++; /* Skip this slot and reprocess this parm */ i--; continue; } - + if (!(tparm->flags & CMD_PROCESSED) && (tparm->flags & CMD_HIDE)) { - curType++; /* Skip this slot and reprocess this parm */ + curType++; /* Skip this slot and reprocess this parm */ i--; continue; } @@ -757,84 +870,113 @@ 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) { - AddItem(tparm, argv[i]); /* Add to end of list */ + AddItem(tparm, argv[i]); /* Add to end of list */ + } else if (tparm->type == CMD_LIST) { + AddItem(tparm, argv[i]); /* Add to end of list */ } /* Now, if we're in positional mode, advance to the next item */ if (positional) curType = AdvanceType(ts, curType); } } - + /* 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); - ResetSyntax(ts); - return 0; + /* Display full help syntax if we don't have subcommands */ + if (noOpcodes) + PrintFlagHelp(ts); + code = CMD_USAGE; + goto out; } /* Parsing done, see if we have all of our required parameters */ - for(i=0; i < CMD_MAXPARMS; i++) { + for (i = 0; i < CMD_MAXPARMS; i++) { tparm = &ts->parms[i]; - if (tparm->type == 0) continue; /* Skipped parm slot */ + if (tparm->type == 0) + continue; /* Skipped parm slot */ 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); + if ((ts->proc == HelpProc) || (ts->proc == AproposProc)) { + 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); + code = (*beforeProc) (ts, beforeRock); + + if (code) + goto out; + + code = (*ts->proc) (ts, ts->rock); + + if (afterProc) + (*afterProc) (ts, afterRock); +out: + cmd_FreeOptions(&ts); + return code; +} + +void +cmd_FreeOptions(struct cmd_syndesc **ts) +{ + if (*ts != NULL) { + ResetSyntax(*ts); + *ts = NULL; } - i=(*ts->proc) (ts, ts->rock); - if (afterProc) (*afterProc)(ts, afterRock); - ResetSyntax(ts); /* Reset and free things */ - return(i); } /* free token list returned by parseLine */ -static FreeTokens(alist) - register struct cmd_token *alist; { - register struct cmd_token *nlist; - for(; alist; alist = nlist) { +static int +FreeTokens(struct cmd_token *alist) +{ + struct cmd_token *nlist; + for (; alist; alist = nlist) { nlist = alist->next; free(alist->key); free(alist); @@ -843,36 +985,39 @@ static FreeTokens(alist) } /* free an argv list returned by parseline */ -cmd_FreeArgv(argv) -register char **argv; { - register char *tp; - for(tp = *argv; tp; argv++, tp = *argv) +int +cmd_FreeArgv(char **argv) +{ + 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 CopyBackArgs(alist, argv, an, amaxn) -register struct cmd_token *alist; -register char **argv; -afs_int32 amaxn; -afs_int32 *an; { - register struct cmd_token *next; +static int +CopyBackArgs(struct cmd_token *alist, char **argv, + afs_int32 * an, afs_int32 amaxn) +{ + struct cmd_token *next; afs_int32 count; count = 0; - if (amaxn <= 1) return CMD_TOOMANY; - *argv = (char *) malloc(strlen(INITSTR)+1); + if (amaxn <= 1) + return CMD_TOOMANY; + *argv = (char *)malloc(strlen(INITSTR) + 1); assert(*argv); strcpy(*argv, INITSTR); amaxn--; argv++; count++; while (alist) { - if (amaxn <= 1) return CMD_TOOMANY; /* argv is too small for his many parms. */ + if (amaxn <= 1) + return CMD_TOOMANY; /* argv is too small for his many parms. */ *argv = alist->key; next = alist->next; free(alist); @@ -881,61 +1026,68 @@ afs_int32 *an; { argv++; count++; } - *(argv++) = 0; /* use last slot for terminating null */ + *(argv++) = 0; /* use last slot for terminating null */ /* don't count terminating null */ *an = count; return 0; } -static quote(x) -register int x; { - if (x == '"' || x == 39 /* single quote */) return 1; - else return 0; +static int +quote(int x) +{ + if (x == '"' || x == 39 /* single quote */ ) + return 1; + else + return 0; } -static space(x) -register int x; { - if (x == 0 || x == ' ' || x == '\t' || x== '\n') return 1; - else return 0; +static int +space(int x) +{ + if (x == 0 || x == ' ' || x == '\t' || x == '\n') + return 1; + else + return 0; } -cmd_ParseLine(aline, argv, an, amaxn) -char **argv; -afs_int32 *an; -afs_int32 amaxn; -char *aline; { +int +cmd_ParseLine(char *aline, char **argv, afs_int32 * an, afs_int32 amaxn) +{ char tbuffer[256]; - register char *tptr; + char *tptr = 0; int inToken, inQuote; struct cmd_token *first, *last; - register struct cmd_token *ttok; - register int tc; - - inToken = 0; /* not copying token chars at start */ - first = (struct cmd_token *) 0; - last = (struct cmd_token *) 0; - inQuote=0; /* not in a quoted string */ + struct cmd_token *ttok; + int tc; + + inToken = 0; /* not copying token chars at start */ + first = NULL; + last = NULL; + inQuote = 0; /* not in a quoted string */ while (1) { tc = *aline++; - if (tc == 0 || (!inQuote && space(tc))) { /* terminating null gets us in here, too */ + if (tc == 0 || (!inQuote && space(tc))) { /* terminating null gets us in here, too */ if (inToken) { - inToken = 0; /* end of this token */ - *tptr++ = 0; - ttok = (struct cmd_token *) malloc(sizeof(struct cmd_token)); + inToken = 0; /* end of this token */ + if (!tptr) + return -1; /* should never get here */ + else + *tptr++ = 0; + 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) { last->next = ttok; last = ttok; - } - else last = ttok; - if (!first) first = ttok; + } else + last = ttok; + if (!first) + first = ttok; } - } - else { + } else { /* an alpha character */ if (!inToken) { tptr = tbuffer; @@ -943,20 +1095,20 @@ char *aline; { } if (tptr - tbuffer >= sizeof(tbuffer)) { FreeTokens(first); - return CMD_TOOBIG; /* token too long */ + return CMD_TOOBIG; /* token too long */ } if (quote(tc)) { /* hit a quote, toggle inQuote flag but don't insert character */ inQuote = !inQuote; - } - else { + } else { /* insert character */ *tptr++ = tc; } } if (tc == 0) { /* last token flushed 'cause space(0) --> true */ - if (last) last->next = (struct cmd_token *) 0; + if (last) + last->next = NULL; return CopyBackArgs(first, argv, an, amaxn); } }