]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - linux/lib/libfreeswan/optionsfrom.c
2 * pick up more options from a file, in the middle of an option scan
3 * Copyright (C) 1998, 1999 Henry Spencer.
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Library General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 * License for more details.
15 * RCSID $Id: optionsfrom.c,v 1.1 2004/03/15 20:35:26 as Exp $
22 #define MAX 100 /* loop-detection limit */
24 /* internal work area */
32 static const char *dowork(const char *, int *, char ***, int);
33 static const char *getanarg(FILE *, struct work
*, char **);
34 static char *getline(FILE *, char *, size_t);
37 - optionsfrom - add some options, taken from a file, to argc/argv
38 * If errsto is non-NULL, does not return in event of error.
40 const char * /* NULL for success, else string literal */
41 optionsfrom(filename
, argcp
, argvp
, optind
, errsto
)
43 int *argcp
; /* pointer to argc */
44 char ***argvp
; /* pointer to argv */
45 int optind
; /* current optind, number of next argument */
46 FILE *errsto
; /* where to report errors (NULL means return) */
55 "%s: optionsfrom called %d times, looping?\n",
62 e
= dowork(filename
, argcp
, argvp
, optind
);
63 if (e
!= NULL
&& errsto
!= NULL
) {
64 fprintf(errsto
, "%s: optionsfrom failed: %s\n", (*argvp
)[0], e
);
71 - dowork - do all the real work of optionsfrom
72 * Does not alter the existing arguments, but does relocate and alter
73 * the argv pointer vector.
75 static const char * /* NULL for success, else string literal */
76 dowork(filename
, argcp
, argvp
, optind
)
78 int *argcp
; /* pointer to argc */
79 char ***argvp
; /* pointer to argv */
80 int optind
; /* current optind, number of next argument */
85 int next
; /* place for next argument */
86 int room
; /* how many more new arguments we can hold */
87 # define SOME 10 /* first guess at how many we'll need */
91 struct work wa
; /* for getanarg() */
93 f
= fopen(filename
, "r");
95 return "unable to open file";
97 newargc
= *argcp
+ SOME
;
98 newargv
= malloc((newargc
+1) * sizeof(char *));
100 return "unable to allocate memory";
101 memcpy(newargv
, *argvp
, optind
* sizeof(char *));
105 newargv
[next
] = NULL
;
107 while ((p
= getanarg(f
, &wa
, &newargv
[next
])) == NULL
) {
110 tmp
= realloc(newargv
, (newargc
+1) * sizeof(char *));
112 p
= "out of space for new argv";
113 break; /* NOTE BREAK OUT */
121 if (p
!= NULL
&& !feof(f
)) { /* error of some kind */
122 for (i
= optind
+1; i
<= next
; i
++)
123 if (newargv
[i
] != NULL
)
131 memcpy(newargv
+ next
, *argvp
+ optind
,
132 (*argcp
+1-optind
) * sizeof(char *));
133 *argcp
+= next
- optind
;
139 - getanarg - get a malloced argument from the file
141 static const char * /* NULL for success, else string literal */
142 getanarg(f
, w
, linep
)
145 char **linep
; /* where to store pointer if successful */
151 while (w
->pending
== NULL
) { /* no pending line */
152 if ((w
->line
= getline(f
, w
->buf
, sizeof(w
->buf
))) == NULL
)
153 return "error in line read"; /* caller checks EOF */
154 if (w
->line
[0] != '#' &&
155 *(w
->line
+ strspn(w
->line
, " \t")) != '\0')
156 w
->pending
= w
->line
;
159 if (w
->pending
== w
->line
&& w
->line
[0] != '-') {
160 /* fresh plain line */
163 endp
= p
+ strlen(p
);
164 if (*p
== '"' && endp
> p
+1 && *(endp
-1) == '"') {
169 if (w
->line
== w
->buf
) {
170 *linep
= malloc(endp
- p
+ 1);
172 return "out of memory for new line";
174 } else /* getline already malloced it */
179 /* chip off a piece of a pending line */
181 p
+= strspn(p
, " \t");
182 endp
= p
+ strcspn(p
, " \t");
186 endp
+= strspn(endp
, " \t");
188 /* endp now points to next real character, or to line-end NUL */
189 *linep
= malloc(len
+ 1);
190 if (*linep
== NULL
) {
191 if (w
->line
!= w
->buf
)
193 return "out of memory for new argument";
198 if (w
->line
!= w
->buf
)
206 - getline - read a line from the file, trim newline off
208 static char * /* pointer to line, NULL for eof/error */
209 getline(f
, buf
, bufsize
)
211 char *buf
; /* buffer to use, if convenient */
212 size_t bufsize
; /* size of buf */
216 if (fgets(buf
, bufsize
, f
) == NULL
)
220 if (len
< bufsize
-1 || buf
[bufsize
-1] == '\n') {
226 /* oh crud, buffer overflow */
227 /* for now, to hell with it */
237 char usage
[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ...";
238 struct option opts
[] = {
241 "builtin", 0, NULL
, 'B',
242 "optionsfrom", 1, NULL
, '+',
243 "help", 0, NULL
, 'h',
244 "version", 0, NULL
, 'v',
261 while ((opt
= getopt_long(argc
, argv
, "", opts
, NULL
)) != EOF
)
269 case '+': /* optionsfrom */
270 p
= optionsfrom(optarg
, &argc
, &argv
, optind
, errs
);
272 fprintf(stderr
, "%s: optionsfrom error: %s\n",
278 printf("%s\n", usage
);
281 case 'v': /* version */
291 fprintf(stderr
, "%s\n", usage
);
295 for (i
= 1; i
< argc
; i
++)
296 printf("%d: `%s'\n", i
, argv
[i
]);