1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 *
| 1/*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 *
|
36 * $Id: options.c,v 1.6 1995/10/09 17:56:32 joerg Exp $
| 36 * $Id: options.c,v 1.7 1996/09/01 10:21:16 peter Exp $
|
37 */ 38 39#ifndef lint 40static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; 41#endif /* not lint */ 42 43#include <signal.h> 44#include <unistd.h> 45#include <stdlib.h> 46 47#include "shell.h" 48#define DEFINE_OPTIONS 49#include "options.h" 50#undef DEFINE_OPTIONS 51#include "nodes.h" /* for other header files */ 52#include "eval.h" 53#include "jobs.h" 54#include "input.h" 55#include "output.h" 56#include "trap.h" 57#include "var.h" 58#include "memalloc.h" 59#include "error.h" 60#include "mystring.h" 61#ifndef NO_HISTORY 62#include "myhistedit.h" 63#endif 64 65char *arg0; /* value of $0 */ 66struct shparam shellparam; /* current positional parameters */ 67char **argptr; /* argument list for builtin commands */ 68char *optarg; /* set by nextopt (like getopt) */ 69char *optptr; /* used by nextopt */ 70 71char *minusc; /* argument to -c option */ 72 73 74STATIC void options __P((int)); 75STATIC void minus_o __P((char *, int)); 76STATIC void setoption __P((int, int)); 77 78 79/* 80 * Process the shell command line arguments. 81 */ 82 83void 84procargs(argc, argv) 85 int argc; 86 char **argv; 87{ 88 int i; 89 90 argptr = argv; 91 if (argc > 0) 92 argptr++; 93 for (i = 0; i < NOPTS; i++) 94 optlist[i].val = 2;
| 37 */ 38 39#ifndef lint 40static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; 41#endif /* not lint */ 42 43#include <signal.h> 44#include <unistd.h> 45#include <stdlib.h> 46 47#include "shell.h" 48#define DEFINE_OPTIONS 49#include "options.h" 50#undef DEFINE_OPTIONS 51#include "nodes.h" /* for other header files */ 52#include "eval.h" 53#include "jobs.h" 54#include "input.h" 55#include "output.h" 56#include "trap.h" 57#include "var.h" 58#include "memalloc.h" 59#include "error.h" 60#include "mystring.h" 61#ifndef NO_HISTORY 62#include "myhistedit.h" 63#endif 64 65char *arg0; /* value of $0 */ 66struct shparam shellparam; /* current positional parameters */ 67char **argptr; /* argument list for builtin commands */ 68char *optarg; /* set by nextopt (like getopt) */ 69char *optptr; /* used by nextopt */ 70 71char *minusc; /* argument to -c option */ 72 73 74STATIC void options __P((int)); 75STATIC void minus_o __P((char *, int)); 76STATIC void setoption __P((int, int)); 77 78 79/* 80 * Process the shell command line arguments. 81 */ 82 83void 84procargs(argc, argv) 85 int argc; 86 char **argv; 87{ 88 int i; 89 90 argptr = argv; 91 if (argc > 0) 92 argptr++; 93 for (i = 0; i < NOPTS; i++) 94 optlist[i].val = 2;
|
| 95 privileged = (getuid() != geteuid() || getgid() != getegid());
|
95 options(1); 96 if (*argptr == NULL && minusc == NULL) 97 sflag = 1; 98 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) 99 iflag = 1; 100 if (mflag == 2) 101 mflag = iflag; 102 for (i = 0; i < NOPTS; i++) 103 if (optlist[i].val == 2) 104 optlist[i].val = 0; 105 arg0 = argv[0]; 106 if (sflag == 0 && minusc == NULL) { 107 commandname = arg0 = *argptr++; 108 setinputfile(commandname, 0); 109 } 110 if (*argptr && minusc) 111 /* Posix.2: first arg after -c cmd is $0, remainder $1... */ 112 arg0 = *argptr++; 113 shellparam.p = argptr; 114 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */ 115 while (*argptr) { 116 shellparam.nparam++; 117 argptr++; 118 } 119 optschanged(); 120} 121 122 123void 124optschanged() 125{ 126 setinteractive(iflag); 127#ifndef NO_HISTORY 128 histedit(); 129#endif 130 setjobctl(mflag); 131} 132 133/* 134 * Process shell options. The global variable argptr contains a pointer 135 * to the argument list; we advance it past the options. 136 */ 137 138STATIC void 139options(cmdline) 140 int cmdline; 141{ 142 register char *p; 143 int val; 144 int c; 145 146 if (cmdline) 147 minusc = NULL; 148 while ((p = *argptr) != NULL) { 149 argptr++; 150 if ((c = *p++) == '-') { 151 val = 1; 152 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { 153 if (!cmdline) { 154 /* "-" means turn off -x and -v */ 155 if (p[0] == '\0') 156 xflag = vflag = 0; 157 /* "--" means reset params */ 158 else if (*argptr == NULL) 159 setparam(argptr); 160 } 161 break; /* "-" or "--" terminates options */ 162 } 163 } else if (c == '+') { 164 val = 0; 165 } else { 166 argptr--; 167 break; 168 } 169 while ((c = *p++) != '\0') { 170 if (c == 'c' && cmdline) { 171 char *q; 172#ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */ 173 if (*p == '\0') 174#endif 175 q = *argptr++; 176 if (q == NULL || minusc != NULL) 177 error("Bad -c option"); 178 minusc = q; 179#ifdef NOHACK 180 break; 181#endif 182 } else if (c == 'o') { 183 minus_o(*argptr, val); 184 if (*argptr) 185 argptr++; 186 } else {
| 96 options(1); 97 if (*argptr == NULL && minusc == NULL) 98 sflag = 1; 99 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) 100 iflag = 1; 101 if (mflag == 2) 102 mflag = iflag; 103 for (i = 0; i < NOPTS; i++) 104 if (optlist[i].val == 2) 105 optlist[i].val = 0; 106 arg0 = argv[0]; 107 if (sflag == 0 && minusc == NULL) { 108 commandname = arg0 = *argptr++; 109 setinputfile(commandname, 0); 110 } 111 if (*argptr && minusc) 112 /* Posix.2: first arg after -c cmd is $0, remainder $1... */ 113 arg0 = *argptr++; 114 shellparam.p = argptr; 115 /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */ 116 while (*argptr) { 117 shellparam.nparam++; 118 argptr++; 119 } 120 optschanged(); 121} 122 123 124void 125optschanged() 126{ 127 setinteractive(iflag); 128#ifndef NO_HISTORY 129 histedit(); 130#endif 131 setjobctl(mflag); 132} 133 134/* 135 * Process shell options. The global variable argptr contains a pointer 136 * to the argument list; we advance it past the options. 137 */ 138 139STATIC void 140options(cmdline) 141 int cmdline; 142{ 143 register char *p; 144 int val; 145 int c; 146 147 if (cmdline) 148 minusc = NULL; 149 while ((p = *argptr) != NULL) { 150 argptr++; 151 if ((c = *p++) == '-') { 152 val = 1; 153 if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { 154 if (!cmdline) { 155 /* "-" means turn off -x and -v */ 156 if (p[0] == '\0') 157 xflag = vflag = 0; 158 /* "--" means reset params */ 159 else if (*argptr == NULL) 160 setparam(argptr); 161 } 162 break; /* "-" or "--" terminates options */ 163 } 164 } else if (c == '+') { 165 val = 0; 166 } else { 167 argptr--; 168 break; 169 } 170 while ((c = *p++) != '\0') { 171 if (c == 'c' && cmdline) { 172 char *q; 173#ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */ 174 if (*p == '\0') 175#endif 176 q = *argptr++; 177 if (q == NULL || minusc != NULL) 178 error("Bad -c option"); 179 minusc = q; 180#ifdef NOHACK 181 break; 182#endif 183 } else if (c == 'o') { 184 minus_o(*argptr, val); 185 if (*argptr) 186 argptr++; 187 } else {
|
| 188 if (c == 'p' && !val && privileged) { 189 (void) setuid(getuid()); 190 (void) setgid(getgid()); 191 }
|
187 setoption(c, val); 188 } 189 } 190 } 191} 192 193STATIC void 194minus_o(name, val) 195 char *name; 196 int val; 197{ 198 int i; 199 200 if (name == NULL) { 201 out1str("Current option settings\n"); 202 for (i = 0; i < NOPTS; i++) 203 out1fmt("%-16s%s\n", optlist[i].name, 204 optlist[i].val ? "on" : "off"); 205 } else { 206 for (i = 0; i < NOPTS; i++) 207 if (equal(name, optlist[i].name)) {
| 192 setoption(c, val); 193 } 194 } 195 } 196} 197 198STATIC void 199minus_o(name, val) 200 char *name; 201 int val; 202{ 203 int i; 204 205 if (name == NULL) { 206 out1str("Current option settings\n"); 207 for (i = 0; i < NOPTS; i++) 208 out1fmt("%-16s%s\n", optlist[i].name, 209 optlist[i].val ? "on" : "off"); 210 } else { 211 for (i = 0; i < NOPTS; i++) 212 if (equal(name, optlist[i].name)) {
|
| 213 if (!val && privileged && equal(name, "privileged")) { 214 (void) setuid(getuid()); 215 (void) setgid(getgid()); 216 }
|
208 setoption(optlist[i].letter, val); 209 return; 210 } 211 error("Illegal option -o %s", name); 212 } 213} 214 215 216STATIC void 217setoption(flag, val) 218 char flag; 219 int val; 220 { 221 int i; 222 223 for (i = 0; i < NOPTS; i++) 224 if (optlist[i].letter == flag) { 225 optlist[i].val = val; 226 if (val) { 227 /* #%$ hack for ksh semantics */ 228 if (flag == 'V') 229 Eflag = 0; 230 else if (flag == 'E') 231 Vflag = 0; 232 } 233 return; 234 } 235 error("Illegal option -%c", flag); 236} 237 238 239 240#ifdef mkinit 241INCLUDE "options.h" 242 243SHELLPROC { 244 int i; 245 246 for (i = 0; i < NOPTS; i++) 247 optlist[i].val = 0; 248 optschanged(); 249 250} 251#endif 252 253 254/* 255 * Set the shell parameters. 256 */ 257 258void 259setparam(argv) 260 char **argv; 261 { 262 char **newparam; 263 char **ap; 264 int nparam; 265 266 for (nparam = 0 ; argv[nparam] ; nparam++); 267 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); 268 while (*argv) { 269 *ap++ = savestr(*argv++); 270 } 271 *ap = NULL; 272 freeparam(&shellparam); 273 shellparam.malloc = 1; 274 shellparam.nparam = nparam; 275 shellparam.p = newparam; 276 shellparam.optnext = NULL; 277} 278 279 280/* 281 * Free the list of positional parameters. 282 */ 283 284void 285freeparam(param) 286 struct shparam *param; 287 { 288 char **ap; 289 290 if (param->malloc) { 291 for (ap = param->p ; *ap ; ap++) 292 ckfree(*ap); 293 ckfree(param->p); 294 } 295} 296 297 298 299/* 300 * The shift builtin command. 301 */ 302 303int 304shiftcmd(argc, argv) 305 int argc; 306 char **argv; 307{ 308 int n; 309 char **ap1, **ap2; 310 311 n = 1; 312 if (argc > 1) 313 n = number(argv[1]); 314 if (n > shellparam.nparam) 315 error("can't shift that many"); 316 INTOFF; 317 shellparam.nparam -= n; 318 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { 319 if (shellparam.malloc) 320 ckfree(*ap1); 321 } 322 ap2 = shellparam.p; 323 while ((*ap2++ = *ap1++) != NULL); 324 shellparam.optnext = NULL; 325 INTON; 326 return 0; 327} 328 329 330 331/* 332 * The set command builtin. 333 */ 334 335int 336setcmd(argc, argv) 337 int argc; 338 char **argv; 339{ 340 if (argc == 1) 341 return showvarscmd(argc, argv); 342 INTOFF; 343 options(0); 344 optschanged(); 345 if (*argptr != NULL) { 346 setparam(argptr); 347 } 348 INTON; 349 return 0; 350} 351 352 353/* 354 * The getopts builtin. Shellparam.optnext points to the next argument 355 * to be processed. Shellparam.optptr points to the next character to 356 * be processed in the current argument. If shellparam.optnext is NULL, 357 * then it's the first time getopts has been called. 358 */ 359 360int 361getoptscmd(argc, argv) 362 int argc; 363 char **argv; 364{ 365 register char *p, *q; 366 char c; 367 char s[10]; 368 369 if (argc != 3) 370 error("Usage: getopts optstring var"); 371 if (shellparam.optnext == NULL) { 372 shellparam.optnext = shellparam.p; 373 shellparam.optptr = NULL; 374 } 375 if ((p = shellparam.optptr) == NULL || *p == '\0') { 376 p = *shellparam.optnext; 377 if (p == NULL || *p != '-' || *++p == '\0') { 378atend: 379 fmtstr(s, 10, "%d", shellparam.optnext - shellparam.p + 1); 380 setvar("OPTIND", s, 0); 381 shellparam.optnext = NULL; 382 return 1; 383 } 384 shellparam.optnext++; 385 if (p[0] == '-' && p[1] == '\0') /* check for "--" */ 386 goto atend; 387 } 388 c = *p++; 389 for (q = argv[1] ; *q != c ; ) { 390 if (*q == '\0') { 391 out1fmt("Illegal option -%c\n", c); 392 c = '?'; 393 goto out; 394 } 395 if (*++q == ':') 396 q++; 397 } 398 if (*++q == ':') { 399 if (*p == '\0' && (p = *shellparam.optnext++) == NULL) { 400 out1fmt("No arg for -%c option\n", c); 401 c = '?'; 402 goto out; 403 } 404 setvar("OPTARG", p, 0); 405 p = NULL; 406 } 407out: 408 shellparam.optptr = p; 409 s[0] = c; 410 s[1] = '\0'; 411 setvar(argv[2], s, 0); 412 return 0; 413} 414 415/* 416 * XXX - should get rid of. have all builtins use getopt(3). the 417 * library getopt must have the BSD extension static variable "optreset" 418 * otherwise it can't be used within the shell safely. 419 * 420 * Standard option processing (a la getopt) for builtin routines. The 421 * only argument that is passed to nextopt is the option string; the 422 * other arguments are unnecessary. It return the character, or '\0' on 423 * end of input. 424 */ 425 426int 427nextopt(optstring) 428 char *optstring; 429 { 430 register char *p, *q; 431 char c; 432 433 if ((p = optptr) == NULL || *p == '\0') { 434 p = *argptr; 435 if (p == NULL || *p != '-' || *++p == '\0') 436 return '\0'; 437 argptr++; 438 if (p[0] == '-' && p[1] == '\0') /* check for "--" */ 439 return '\0'; 440 } 441 c = *p++; 442 for (q = optstring ; *q != c ; ) { 443 if (*q == '\0') 444 error("Illegal option -%c", c); 445 if (*++q == ':') 446 q++; 447 } 448 if (*++q == ':') { 449 if (*p == '\0' && (p = *argptr++) == NULL) 450 error("No arg for -%c option", c); 451 optarg = p; 452 p = NULL; 453 } 454 optptr = p; 455 return c; 456}
| 217 setoption(optlist[i].letter, val); 218 return; 219 } 220 error("Illegal option -o %s", name); 221 } 222} 223 224 225STATIC void 226setoption(flag, val) 227 char flag; 228 int val; 229 { 230 int i; 231 232 for (i = 0; i < NOPTS; i++) 233 if (optlist[i].letter == flag) { 234 optlist[i].val = val; 235 if (val) { 236 /* #%$ hack for ksh semantics */ 237 if (flag == 'V') 238 Eflag = 0; 239 else if (flag == 'E') 240 Vflag = 0; 241 } 242 return; 243 } 244 error("Illegal option -%c", flag); 245} 246 247 248 249#ifdef mkinit 250INCLUDE "options.h" 251 252SHELLPROC { 253 int i; 254 255 for (i = 0; i < NOPTS; i++) 256 optlist[i].val = 0; 257 optschanged(); 258 259} 260#endif 261 262 263/* 264 * Set the shell parameters. 265 */ 266 267void 268setparam(argv) 269 char **argv; 270 { 271 char **newparam; 272 char **ap; 273 int nparam; 274 275 for (nparam = 0 ; argv[nparam] ; nparam++); 276 ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); 277 while (*argv) { 278 *ap++ = savestr(*argv++); 279 } 280 *ap = NULL; 281 freeparam(&shellparam); 282 shellparam.malloc = 1; 283 shellparam.nparam = nparam; 284 shellparam.p = newparam; 285 shellparam.optnext = NULL; 286} 287 288 289/* 290 * Free the list of positional parameters. 291 */ 292 293void 294freeparam(param) 295 struct shparam *param; 296 { 297 char **ap; 298 299 if (param->malloc) { 300 for (ap = param->p ; *ap ; ap++) 301 ckfree(*ap); 302 ckfree(param->p); 303 } 304} 305 306 307 308/* 309 * The shift builtin command. 310 */ 311 312int 313shiftcmd(argc, argv) 314 int argc; 315 char **argv; 316{ 317 int n; 318 char **ap1, **ap2; 319 320 n = 1; 321 if (argc > 1) 322 n = number(argv[1]); 323 if (n > shellparam.nparam) 324 error("can't shift that many"); 325 INTOFF; 326 shellparam.nparam -= n; 327 for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { 328 if (shellparam.malloc) 329 ckfree(*ap1); 330 } 331 ap2 = shellparam.p; 332 while ((*ap2++ = *ap1++) != NULL); 333 shellparam.optnext = NULL; 334 INTON; 335 return 0; 336} 337 338 339 340/* 341 * The set command builtin. 342 */ 343 344int 345setcmd(argc, argv) 346 int argc; 347 char **argv; 348{ 349 if (argc == 1) 350 return showvarscmd(argc, argv); 351 INTOFF; 352 options(0); 353 optschanged(); 354 if (*argptr != NULL) { 355 setparam(argptr); 356 } 357 INTON; 358 return 0; 359} 360 361 362/* 363 * The getopts builtin. Shellparam.optnext points to the next argument 364 * to be processed. Shellparam.optptr points to the next character to 365 * be processed in the current argument. If shellparam.optnext is NULL, 366 * then it's the first time getopts has been called. 367 */ 368 369int 370getoptscmd(argc, argv) 371 int argc; 372 char **argv; 373{ 374 register char *p, *q; 375 char c; 376 char s[10]; 377 378 if (argc != 3) 379 error("Usage: getopts optstring var"); 380 if (shellparam.optnext == NULL) { 381 shellparam.optnext = shellparam.p; 382 shellparam.optptr = NULL; 383 } 384 if ((p = shellparam.optptr) == NULL || *p == '\0') { 385 p = *shellparam.optnext; 386 if (p == NULL || *p != '-' || *++p == '\0') { 387atend: 388 fmtstr(s, 10, "%d", shellparam.optnext - shellparam.p + 1); 389 setvar("OPTIND", s, 0); 390 shellparam.optnext = NULL; 391 return 1; 392 } 393 shellparam.optnext++; 394 if (p[0] == '-' && p[1] == '\0') /* check for "--" */ 395 goto atend; 396 } 397 c = *p++; 398 for (q = argv[1] ; *q != c ; ) { 399 if (*q == '\0') { 400 out1fmt("Illegal option -%c\n", c); 401 c = '?'; 402 goto out; 403 } 404 if (*++q == ':') 405 q++; 406 } 407 if (*++q == ':') { 408 if (*p == '\0' && (p = *shellparam.optnext++) == NULL) { 409 out1fmt("No arg for -%c option\n", c); 410 c = '?'; 411 goto out; 412 } 413 setvar("OPTARG", p, 0); 414 p = NULL; 415 } 416out: 417 shellparam.optptr = p; 418 s[0] = c; 419 s[1] = '\0'; 420 setvar(argv[2], s, 0); 421 return 0; 422} 423 424/* 425 * XXX - should get rid of. have all builtins use getopt(3). the 426 * library getopt must have the BSD extension static variable "optreset" 427 * otherwise it can't be used within the shell safely. 428 * 429 * Standard option processing (a la getopt) for builtin routines. The 430 * only argument that is passed to nextopt is the option string; the 431 * other arguments are unnecessary. It return the character, or '\0' on 432 * end of input. 433 */ 434 435int 436nextopt(optstring) 437 char *optstring; 438 { 439 register char *p, *q; 440 char c; 441 442 if ((p = optptr) == NULL || *p == '\0') { 443 p = *argptr; 444 if (p == NULL || *p != '-' || *++p == '\0') 445 return '\0'; 446 argptr++; 447 if (p[0] == '-' && p[1] == '\0') /* check for "--" */ 448 return '\0'; 449 } 450 c = *p++; 451 for (q = optstring ; *q != c ; ) { 452 if (*q == '\0') 453 error("Illegal option -%c", c); 454 if (*++q == ':') 455 q++; 456 } 457 if (*++q == ':') { 458 if (*p == '\0' && (p = *argptr++) == NULL) 459 error("No arg for -%c option", c); 460 optarg = p; 461 p = NULL; 462 } 463 optptr = p; 464 return c; 465}
|