1 /*        $NetBSD: parseutils.c,v 1.7 2014/01/05 20:52:57 jakllsch Exp $        */
2 
3 /*
4  * Copyright (c) 1996, 1997
5  *        Matthias Drochner.  All rights reserved.
6  * Copyright (c) 1996, 1997
7  *        Perry E. Metzger.  All rights reserved.
8  * Copyright (c) 1997
9  *        Jason R. Thorpe.  All rights reserved
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgements:
21  *        This product includes software developed for the NetBSD Project
22  *        by Matthias Drochner.
23  *        This product includes software developed for the NetBSD Project
24  *        by Perry E. Metzger.
25  * 4. The names of the authors may not be used to endorse or promote products
26  *    derived from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
29  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
30  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
31  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
33  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
37  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 #include <lib/libkern/libkern.h>
41 #include <lib/libsa/stand.h>
42 #include <sys/boot_flag.h>
43 
44 #include "libi386.h"
45 
46 /*
47  * chops the head from the arguments and returns the arguments if any,
48  * or possibly an empty string.
49  */
50 char *
gettrailer(char * arg)51 gettrailer(char *arg)
52 {
53           char *options;
54 
55           for (options = arg; *options; options++) {
56                     switch (*options) {
57                     case ' ':
58                     case '\t':
59                               *options++ = '\0';
60                               break;
61                     default:
62                               continue;
63                     }
64                     break;
65           }
66           if (*options == '\0')
67                     return options;
68 
69           /* trim leading blanks/tabs */
70           while (*options == ' ' || *options == '\t')
71                     options++;
72 
73           return options;
74 }
75 
76 int
parseopts(const char * opts,int * howto)77 parseopts(const char *opts, int *howto)
78 {
79           int r, tmpopt = 0;
80 
81           opts++;   /* skip - */
82           while (*opts) {
83                     r = 0;
84                     BOOT_FLAG(*opts, r);
85                     if (r == 0) {
86                               printf("-%c: unknown flag\n", *opts);
87                               command_help(NULL);
88                               return 0;
89                     }
90                     tmpopt |= r;
91                     opts++;
92                     if (*opts == ' ' || *opts == '\t') {
93                               do
94                                         opts++;             /* skip whitespace */
95                               while (*opts == ' ' || *opts == '\t');
96                               if (*opts == '-')
97                                         opts++;             /* skip - */
98                               else if (*opts != '\0') {
99                                         printf("invalid arguments\n");
100                                         command_help(NULL);
101                                         return 0;
102                               }
103                     }
104           }
105 
106           *howto = tmpopt;
107           return 1;
108 }
109 
110 int
parseboot(char * arg,char ** filename,int * howto)111 parseboot(char *arg, char **filename, int *howto)
112 {
113           char *opts = NULL;
114 
115           *filename = 0;
116           *howto = 0;
117 
118           /* if there were no arguments */
119           if (!*arg)
120                     return 1;
121 
122           /* format is... */
123           /* [[xxNx:]filename] [-adqsv] */
124 
125           /* check for just args */
126           if (arg[0] == '-')
127                     opts = arg;
128           else {
129                     /* there's a file name */
130                     *filename = arg;
131 
132                     opts = gettrailer(arg);
133                     if (!*opts)
134                               opts = NULL;
135                     else if (*opts != '-') {
136                               printf("invalid arguments\n");
137                               command_help(NULL);
138                               return 0;
139                     }
140           }
141 
142           /* at this point, we have dealt with filenames. */
143 
144           /* now, deal with options */
145           if (opts) {
146                     if (parseopts(opts, howto) == 0)
147                               return 0;
148           }
149 
150           return 1;
151 }
152