1/* cmdarg.c 2 Look up a command with arguments in a command table. 3 4 Copyright (C) 1992 Ian Lance Taylor 5 6 This file is part of the Taylor UUCP uuconf library. 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Library General Public License 10 as published by the Free Software Foundation; either version 2 of 11 the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Library General Public License for more details. 17 18 You should have received a copy of the GNU Library General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucnfi.h" 26 27#if USE_RCS_ID 28const char _uuconf_cmdarg_rcsid[] = "$Id: cmdarg.c,v 1.7 2002/03/05 19:10:42 ian Rel $"; 29#endif 30 31#include <ctype.h> 32 33#undef strcmp 34#if HAVE_STRCASECMP 35#undef strcasecmp 36#endif 37extern int strcmp (), strcasecmp (); 38 39/* Look up a command with arguments in a table and execute it. */ 40 41int 42uuconf_cmd_args (pglobal, cargs, pzargs, qtab, pinfo, pfiunknown, iflags, 43 pblock) 44 pointer pglobal; 45 int cargs; 46 char **pzargs; 47 const struct uuconf_cmdtab *qtab; 48 pointer pinfo; 49 int (*pfiunknown) P((pointer, int, char **, pointer, pointer)); 50 int iflags; 51 pointer pblock; 52{ 53 struct sglobal *qglobal = (struct sglobal *) pglobal; 54 int bfirstu, bfirstl; 55 int (*pficmp) P((const char *, const char *)); 56 register const struct uuconf_cmdtab *q; 57 int itype; 58 int callowed; 59 60 bfirstu = bfirstl = pzargs[0][0]; 61 if ((iflags & UUCONF_CMDTABFLAG_CASE) != 0) 62 pficmp = strcmp; 63 else 64 { 65 if (islower (bfirstu)) 66 bfirstu = toupper (bfirstu); 67 if (isupper (bfirstl)) 68 bfirstl = tolower (bfirstl); 69 pficmp = strcasecmp; 70 } 71 72 itype = 0; 73 74 for (q = qtab; q->uuconf_zcmd != NULL; q++) 75 { 76 int bfirst; 77 78 bfirst = q->uuconf_zcmd[0]; 79 if (bfirst != bfirstu && bfirst != bfirstl) 80 continue; 81 82 itype = UUCONF_TTYPE_CMDTABTYPE (q->uuconf_itype); 83 if (itype != UUCONF_CMDTABTYPE_PREFIX) 84 { 85 if ((*pficmp) (q->uuconf_zcmd, pzargs[0]) == 0) 86 break; 87 } 88 else 89 { 90 size_t clen; 91 92 clen = strlen (q->uuconf_zcmd); 93 if ((iflags & UUCONF_CMDTABFLAG_CASE) != 0) 94 { 95 if (strncmp (q->uuconf_zcmd, pzargs[0], clen) == 0) 96 break; 97 } 98 else 99 { 100 if (strncasecmp (q->uuconf_zcmd, pzargs[0], clen) == 0) 101 break; 102 } 103 } 104 } 105 106 if (q->uuconf_zcmd == NULL) 107 { 108 if (pfiunknown == NULL) 109 return UUCONF_CMDTABRET_CONTINUE; 110 return (*pfiunknown) (pglobal, cargs, pzargs, (pointer) NULL, pinfo); 111 } 112 113 callowed = UUCONF_CARGS_CMDTABTYPE (q->uuconf_itype); 114 if (callowed != 0 && callowed != cargs) 115 return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; 116 117 switch (itype) 118 { 119 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_STRING): 120 if (cargs == 1) 121 *(char **) q->uuconf_pvar = (char *) ""; 122 else if (cargs == 2) 123 *(char **) q->uuconf_pvar = pzargs[1]; 124 else 125 return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; 126 127 return UUCONF_CMDTABRET_KEEP; 128 129 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_INT): 130 return _uuconf_iint (qglobal, pzargs[1], q->uuconf_pvar, TRUE); 131 132 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_LONG): 133 return _uuconf_iint (qglobal, pzargs[1], q->uuconf_pvar, FALSE); 134 135 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_BOOLEAN): 136 return _uuconf_iboolean (qglobal, pzargs[1], (int *) q->uuconf_pvar); 137 138 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_FULLSTRING): 139 if (cargs == 1) 140 { 141 char ***ppz = (char ***) q->uuconf_pvar; 142 int iret; 143 144 *ppz = NULL; 145 iret = _uuconf_iadd_string (qglobal, (char *) NULL, FALSE, FALSE, 146 ppz, pblock); 147 if (iret != UUCONF_SUCCESS) 148 return iret | UUCONF_CMDTABRET_EXIT; 149 150 return UUCONF_CMDTABRET_CONTINUE; 151 } 152 else 153 { 154 char ***ppz = (char ***) q->uuconf_pvar; 155 int i; 156 157 *ppz = NULL; 158 for (i = 1; i < cargs; i++) 159 { 160 int iret; 161 162 iret = _uuconf_iadd_string (qglobal, pzargs[i], FALSE, FALSE, 163 ppz, pblock); 164 if (iret != UUCONF_SUCCESS) 165 { 166 *ppz = NULL; 167 return iret | UUCONF_CMDTABRET_EXIT; 168 } 169 } 170 171 return UUCONF_CMDTABRET_KEEP; 172 } 173 174 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_FN): 175 case UUCONF_TTYPE_CMDTABTYPE (UUCONF_CMDTABTYPE_PREFIX): 176 return (*q->uuconf_pifn) (pglobal, cargs, pzargs, q->uuconf_pvar, 177 pinfo); 178 179 default: 180 return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT; 181 } 182 183 /*NOTREACHED*/ 184} 185