⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optionsfrom.c

📁 This a good VPN source
💻 C
字号:
/* * pick up more options from a file, in the middle of an option scan * Copyright (C) 1998, 1999  Henry Spencer. *  * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at your * option) any later version.  See <http://www.fsf.org/copyleft/lgpl.txt>. *  * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public * License for more details. * * RCSID $Id: optionsfrom.c,v 1.7 2004/04/09 18:00:38 mcr Exp $ */#include "internal.h"#include "openswan.h"#include <stdio.h>#define	MAX	100		/* loop-detection limit *//* internal work area */struct work {#	define	LOTS	1024	char buf[LOTS];	char *line;	char *pending;};static const char *dowork(const char *, int *, char ***, int);static const char *getanarg(FILE *, struct work *, char **);static char *getline(FILE *, char *, size_t);/* - optionsfrom - add some options, taken from a file, to argc/argv * If errsto is non-NULL, does not return in event of error. */const char *			/* NULL for success, else string literal */optionsfrom(filename, argcp, argvp, optind, errsto)const char *filename;int *argcp;			/* pointer to argc */char ***argvp;			/* pointer to argv */int optind;			/* current optind, number of next argument */FILE *errsto;			/* where to report errors (NULL means return) */{	const char *e;	static int nuses = 0;	if (errsto != NULL) {		nuses++;		if (nuses >= MAX) {			fprintf(errsto,				"%s: optionsfrom called %d times, looping?\n",				(*argvp)[0], nuses);			exit(2);		}	} else		nuses = 0;	e = dowork(filename, argcp, argvp, optind);	if (e != NULL && errsto != NULL) {		fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e);		exit(2);	}	return e;}/* - dowork - do all the real work of optionsfrom * Does not alter the existing arguments, but does relocate and alter * the argv pointer vector. */static const char *		/* NULL for success, else string literal */dowork(filename, argcp, argvp, optind)const char *filename;int *argcp;			/* pointer to argc */char ***argvp;			/* pointer to argv */int optind;			/* current optind, number of next argument */{	char **newargv;	char **tmp;	int newargc;	int next;		/* place for next argument */	int room;		/* how many more new arguments we can hold */#	define	SOME	10	/* first guess at how many we'll need */	FILE *f;	int i;	const char *p;	struct work wa;		/* for getanarg() */	f = fopen(filename, "r");	if (f == NULL)		return "unable to open file";	newargc = *argcp + SOME;	newargv = malloc((newargc+1) * sizeof(char *));	if (newargv == NULL)		return "unable to allocate memory";	memcpy(newargv, *argvp, optind * sizeof(char *));	room = SOME;	next = optind;	newargv[next] = NULL;	wa.pending = NULL;	while ((p = getanarg(f, &wa, &newargv[next])) == NULL) {		if (room == 0) {			newargc += SOME;			tmp = realloc(newargv, (newargc+1) * sizeof(char *));			if (tmp == NULL) {				p = "out of space for new argv";				break;		/* NOTE BREAK OUT */			}			newargv = tmp;			room += SOME;		}		next++;		room--;	}	if (p != NULL && !feof(f)) {	/* error of some kind */		for (i = optind+1; i <= next; i++)			if (newargv[i] != NULL)				free(newargv[i]);		free(newargv);		fclose(f);		return p;	}	fclose(f);	memcpy(newargv + next, *argvp + optind,					(*argcp+1-optind) * sizeof(char *));	*argcp += next - optind;	*argvp = newargv;	return NULL;}/* - getanarg - get a malloced argument from the file */static const char *		/* NULL for success, else string literal */getanarg(f, w, linep)FILE *f;struct work *w;char **linep;			/* where to store pointer if successful */{	size_t len;	char *p;	char *endp;	while (w->pending == NULL) {	/* no pending line */		if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL)			return "error in line read";	/* caller checks EOF */		if (w->line[0] != '#' &&				*(w->line + strspn(w->line, " \t")) != '\0')			w->pending = w->line;	}	if (w->pending == w->line && w->line[0] != '-') {		/* fresh plain line */		w->pending = NULL;		p = w->line;		endp = p + strlen(p);		if (*p == '"' && endp > p+1 && *(endp-1) == '"') {			p++;			endp--;			*endp = '\0';		}		if (w->line == w->buf) {			*linep = malloc(endp - p + 1);			if (*linep == NULL)				return "out of memory for new line";			strcpy(*linep, p);		} else			/* getline already malloced it */			*linep = p;		return NULL;	}	/* chip off a piece of a pending line */	p = w->pending;	p += strspn(p, " \t");	endp = p + strcspn(p, " \t");	len = endp - p;	if (*endp != '\0') {		*endp++ = '\0';		endp += strspn(endp, " \t");	}	/* endp now points to next real character, or to line-end NUL */	*linep = malloc(len + 1);	if (*linep == NULL) {		if (w->line != w->buf)			free(w->line);		return "out of memory for new argument";	}	strcpy(*linep, p);	if (*endp == '\0') {		w->pending = NULL;		if (w->line != w->buf)			free(w->line);	} else		w->pending = endp;	return NULL;}/* - getline - read a line from the file, trim newline off */static char *			/* pointer to line, NULL for eof/error */getline(f, buf, bufsize)FILE *f;char *buf;			/* buffer to use, if convenient */size_t bufsize;			/* size of buf */{	size_t len;	if (fgets(buf, bufsize, f) == NULL)		return NULL;	len = strlen(buf);	if (len < bufsize-1 || buf[bufsize-1] == '\n') {		/* it fit */		buf[len-1] = '\0';		return buf;	}	/* oh crud, buffer overflow */	/* for now, to hell with it */	return NULL;}#ifdef TEST#include <getopt.h>char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ...";struct option opts[] = {	"foo",		0,	NULL,	'f',	"bar",		0,	NULL,	'b',	"builtin",	0,	NULL,	'B',	"optionsfrom",	1,	NULL,	'+',	"help",		0,	NULL,	'h',	"version",	0,	NULL,	'v',	0,		0,	NULL,	0,};intmain(argc, argv)int argc;char *argv[];{	int opt;	extern char *optarg;	extern int optind;	int errflg = 0;	const char *p;	int i;	FILE *errs = NULL;	while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)		switch (opt) {		case 'f':		case 'b':			break;		case 'B':			errs = stderr;			break;		case '+':	/* optionsfrom */			p = optionsfrom(optarg, &argc, &argv, optind, errs);			if (p != NULL) {				fprintf(stderr, "%s: optionsfrom error: %s\n",								argv[0], p);				exit(1);			}			break;		case 'h':	/* help */			printf("%s\n", usage);			exit(0);			break;		case 'v':	/* version */			printf("1\n");			exit(0);			break;		case '?':		default:			errflg = 1;			break;		}	if (errflg) {		fprintf(stderr, "%s\n", usage);		exit(2);	}	for (i = 1; i < argc; i++)		printf("%d: `%s'\n", i, argv[i]);	exit(0);}#endif /* TEST */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -