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

📄 options.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 3 页
字号:
    while (w != NULL) {	opt = find_option(w->word);	if (opt == NULL) {	    option_error("In secrets file: unrecognized option '%s'",			 w->word);	    goto err;	}	n = n_arguments(opt);	w0 = w;	for (i = 0; i < n; ++i) {	    w = w->next;	    if (w == NULL) {		option_error(			"In secrets file: too few parameters for option '%s'",			w0->word);		goto err;	    }	    argv[i] = w->word;	}	if (!process_option(opt, w0->word, argv))	    goto err;	w = w->next;    }    ret = 1;err:    return ret;}/* * match_option - see if this option matches an option_t structure. */static intmatch_option(name, opt, dowild)    char *name;    option_t *opt;    int dowild;{	int (*match) __P((char *, char **, int));	if (dowild != (opt->type == o_wild))		return 0;	if (!dowild)		return strcmp(name, opt->name) == 0;	match = (int (*) __P((char *, char **, int))) opt->addr;	return (*match)(name, NULL, 0);}/* * find_option - scan the option lists for the various protocols * looking for an entry with the given name. * This could be optimized by using a hash table. */static option_t *find_option(name)    const char *name;{	option_t *opt;	struct option_list *list;	int i, dowild;	for (dowild = 0; dowild <= 1; ++dowild) {		for (opt = general_options; opt->name != NULL; ++opt)			if (match_option(name, opt, dowild))				return opt;		for (opt = auth_options; opt->name != NULL; ++opt)			if (match_option(name, opt, dowild))				return opt;		for (list = extra_options; list != NULL; list = list->next)			for (opt = list->options; opt->name != NULL; ++opt)				if (match_option(name, opt, dowild))					return opt;		for (opt = the_channel->options; opt->name != NULL; ++opt)			if (match_option(name, opt, dowild))				return opt;		for (i = 0; protocols[i] != NULL; ++i)			if ((opt = protocols[i]->options) != NULL)				for (; opt->name != NULL; ++opt)					if (match_option(name, opt, dowild))						return opt;	}	return NULL;}/* * process_option - process one new-style option. */static intprocess_option(opt, cmd, argv)    option_t *opt;    char *cmd;    char **argv;{    u_int32_t v;    int iv, a;    char *sv;    int (*parser) __P((char **));    int (*wildp) __P((char *, char **, int));    char *optopt = (opt->type == o_wild)? "": " option";    int prio = option_priority;    option_t *mainopt = opt;    current_option = opt->name;    if ((opt->flags & OPT_PRIVFIX) && privileged_option)	prio += OPRIO_ROOT;    while (mainopt->flags & OPT_PRIOSUB)	--mainopt;    if (mainopt->flags & OPT_PRIO) {	if (prio < mainopt->priority) {	    /* new value doesn't override old */	    if (prio == OPRIO_CMDLINE && mainopt->priority > OPRIO_ROOT) {		option_error("%s%s set in %s cannot be overridden\n",			     opt->name, optopt, mainopt->source);		return 0;	    }	    return 1;	}	if (prio > OPRIO_ROOT && mainopt->priority == OPRIO_CMDLINE)	    warn("%s%s from %s overrides command line",		 opt->name, optopt, option_source);    }    if ((opt->flags & OPT_INITONLY) && phase != PHASE_INITIALIZE) {	option_error("%s%s cannot be changed after initialization",		     opt->name, optopt);	return 0;    }    if ((opt->flags & OPT_PRIV) && !privileged_option) {	option_error("using the %s%s requires root privilege",		     opt->name, optopt);	return 0;    }    if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) {	option_error("%s%s is disabled", opt->name, optopt);	return 0;    }    if ((opt->flags & OPT_DEVEQUIV) && devnam_fixed) {	option_error("the %s%s may not be changed in %s",		     opt->name, optopt, option_source);	return 0;    }    switch (opt->type) {    case o_bool:	v = opt->flags & OPT_VALUE;	*(bool *)(opt->addr) = v;	if (opt->addr2 && (opt->flags & OPT_A2COPY))	    *(bool *)(opt->addr2) = v;	else if (opt->addr2 && (opt->flags & OPT_A2CLR))	    *(bool *)(opt->addr2) = 0;	else if (opt->addr2 && (opt->flags & OPT_A2CLRB))	    *(u_char *)(opt->addr2) &= ~v;	else if (opt->addr2 && (opt->flags & OPT_A2OR))	    *(u_char *)(opt->addr2) |= v;	break;    case o_int:	iv = 0;	if ((opt->flags & OPT_NOARG) == 0) {	    if (!int_option(*argv, &iv))		return 0;	    if ((((opt->flags & OPT_LLIMIT) && iv < opt->lower_limit)		 || ((opt->flags & OPT_ULIMIT) && iv > opt->upper_limit))		&& !((opt->flags & OPT_ZEROOK && iv == 0))) {		char *zok = (opt->flags & OPT_ZEROOK)? " zero or": "";		switch (opt->flags & OPT_LIMITS) {		case OPT_LLIMIT:		    option_error("%s value must be%s >= %d",				 opt->name, zok, opt->lower_limit);		    break;		case OPT_ULIMIT:		    option_error("%s value must be%s <= %d",				 opt->name, zok, opt->upper_limit);		    break;		case OPT_LIMITS:		    option_error("%s value must be%s between %d and %d",				opt->name, zok, opt->lower_limit, opt->upper_limit);		    break;		}		return 0;	    }	}	a = opt->flags & OPT_VALUE;	if (a >= 128)	    a -= 256;		/* sign extend */	iv += a;	if (opt->flags & OPT_INC)	    iv += *(int *)(opt->addr);	if ((opt->flags & OPT_NOINCR) && !privileged_option) {	    int oldv = *(int *)(opt->addr);	    if ((opt->flags & OPT_ZEROINF) ?		(oldv != 0 && (iv == 0 || iv > oldv)) : (iv > oldv)) {		option_error("%s value cannot be increased", opt->name);		return 0;	    }	}	*(int *)(opt->addr) = iv;	if (opt->addr2 && (opt->flags & OPT_A2COPY))	    *(int *)(opt->addr2) = iv;	break;    case o_uint32:	if (opt->flags & OPT_NOARG) {	    v = opt->flags & OPT_VALUE;	    if (v & 0x80)		    v |= 0xffffff00U;	} else if (!number_option(*argv, &v, 16))	    return 0;	if (opt->flags & OPT_OR)	    v |= *(u_int32_t *)(opt->addr);	*(u_int32_t *)(opt->addr) = v;	if (opt->addr2 && (opt->flags & OPT_A2COPY))	    *(u_int32_t *)(opt->addr2) = v;	break;    case o_string:	if (opt->flags & OPT_STATIC) {	    strlcpy((char *)(opt->addr), *argv, opt->upper_limit);	} else {	    sv = strdup(*argv);	    if (sv == NULL)		novm("option argument");	    *(char **)(opt->addr) = sv;	}	break;    case o_special_noarg:    case o_special:	parser = (int (*) __P((char **))) opt->addr;	if (!(*parser)(argv))	    return 0;	if (opt->flags & OPT_A2LIST) {	    struct option_value *ovp, **pp;	    ovp = malloc(sizeof(*ovp) + strlen(*argv));	    if (ovp != 0) {		strcpy(ovp->value, *argv);		ovp->source = option_source;		ovp->next = NULL;		pp = (struct option_value **) &opt->addr2;		while (*pp != 0)		    pp = &(*pp)->next;		*pp = ovp;	    }	}	break;    case o_wild:	wildp = (int (*) __P((char *, char **, int))) opt->addr;	if (!(*wildp)(cmd, argv, 1))	    return 0;	break;    }    if (opt->addr2 && (opt->flags & (OPT_A2COPY|OPT_ENABLE		|OPT_A2PRINTER|OPT_A2STRVAL|OPT_A2LIST|OPT_A2OR)) == 0)	*(bool *)(opt->addr2) = !(opt->flags & OPT_A2CLR);    mainopt->source = option_source;    mainopt->priority = prio;    mainopt->winner = opt - mainopt;    return 1;}/* * override_value - if the option priorities would permit us to * override the value of option, return 1 and update the priority * and source of the option value.  Otherwise returns 0. */intoverride_value(option, priority, source)    const char *option;    int priority;    const char *source;{	option_t *opt;	opt = find_option(option);	if (opt == NULL)		return 0;	while (opt->flags & OPT_PRIOSUB)		--opt;	if ((opt->flags & OPT_PRIO) && priority < opt->priority)		return 0;	opt->priority = priority;	opt->source = source;	opt->winner = -1;	return 1;}/* * n_arguments - tell how many arguments an option takes */static intn_arguments(opt)    option_t *opt;{	return (opt->type == o_bool || opt->type == o_special_noarg		|| (opt->flags & OPT_NOARG))? 0: 1;}/* * add_options - add a list of options to the set we grok. */voidadd_options(opt)    option_t *opt;{    struct option_list *list;    list = malloc(sizeof(*list));    if (list == 0)	novm("option list entry");    list->options = opt;    list->next = extra_options;    extra_options = list;}/* * check_options - check that options are valid and consistent. */voidcheck_options(){	if (logfile_fd >= 0 && logfile_fd != log_to_fd)		close(logfile_fd);}/* * print_option - print out an option and its value */static voidprint_option(opt, mainopt, printer, arg)    option_t *opt, *mainopt;    void (*printer) __P((void *, char *, ...));    void *arg;{	int i, v;	char *p;	if (opt->flags & OPT_NOPRINT)		return;	switch (opt->type) {	case o_bool:		v = opt->flags & OPT_VALUE;		if (*(bool *)opt->addr != v)			/* this can happen legitimately, e.g. lock			   option turned off for default device */			break;		printer(arg, "%s", opt->name);		break;	case o_int:		v = opt->flags & OPT_VALUE;		if (v >= 128)			v -= 256;		i = *(int *)opt->addr;		if (opt->flags & OPT_NOARG) {			printer(arg, "%s", opt->name);			if (i != v) {				if (opt->flags & OPT_INC) {					for (; i > v; i -= v)						printer(arg, " %s", opt->name);				} else					printer(arg, " # oops: %d not %d\n",						i, v);			}		} else {			printer(arg, "%s %d", opt->name, i);		}		break;	case o_uint32:		printer(arg, "%s", opt->name);		if ((opt->flags & OPT_NOARG) == 0)			printer(arg, " %x", *(u_int32_t *)opt->addr);		break;	case o_string:		if (opt->flags & OPT_HIDE) {			p = "??????";		} else {			p = (char *) opt->addr;			if ((opt->flags & OPT_STATIC) == 0)				p = *(char **)p;		}		printer(arg, "%s %q", opt->name, p);		break;	case o_special:	case o_special_noarg:	case o_wild:		if (opt->type != o_wild) {			printer(arg, "%s", opt->name);			if (n_arguments(opt) == 0)				break;			printer(arg, " ");		}		if (opt->flags & OPT_A2PRINTER) {			void (*oprt) __P((option_t *,					  void ((*)__P((void *, char *, ...))),					  void *));			oprt = (void (*) __P((option_t *,					 void ((*)__P((void *, char *, ...))),					 void *)))opt->addr2;			(*oprt)(opt, printer, arg);		} else if (opt->flags & OPT_A2STRVAL) {			p = (char *) opt->addr2;			if ((opt->flags & OPT_STATIC) == 0)				p = *(char **)p;			printer("%q", p);		} else if (opt->flags & OPT_A2LIST) {			struct option_value *ovp;			ovp = (struct option_value *) opt->addr2;			for (;;) {				printer(arg, "%q", ovp->value);				if ((ovp = ovp->next) == NULL)					break;				printer(arg, "\t\t# (from %s)\n%s ",					ovp->source, opt->name);			}		} else {			printer(arg, "xxx # [don't know how to print value]");		}		break;	default:		printer(arg, "# %s value (type %d\?\?)", opt->name, opt->type);		break;	}	printer(arg, "\t\t# (from %s)\n", mainopt->source);}/* * print_option_list - print out options in effect from an * array of options. */static voidprint_option_list(opt, printer, arg)    option_t *opt;    void (*printer) __P((void *, char *, ...));    void *arg;{	while (opt->name != NULL) {		if (opt->priority != OPRIO_DEFAULT		    && opt->winner != (short int) -1)			print_option(opt + opt->winner, opt, printer, arg);		do {			++opt;		} while (opt->flags & OPT_PRIOSUB);	}}/* * print_options - print out what options are in effect. */voidprint_options(printer, arg)    void (*printer) __P((void *, char *, ...));    void *arg;{	struct option_list *list;	int i;	printer(arg, "pppd options in effect:\n");	print_option_list(general_options, printer, arg);	print_option_list(auth_options, printer, arg);	for (list = extra_options; list != NULL; list = list->next)		print_option_list(list->options, printer, arg);	print_option_list(the_channel->options, printer, arg);	for (i = 0; protocols[i] != NULL; ++i)		print_option_list(protocols[i]->options, printer, arg);}/* * usage - print out a message telling how to use the program. */static voidusage(){    if (phase == PHASE_INITIALIZE)	fprintf(stderr, usage_string, VERSION, progname);}/* * showhelp - print out usage message and exit. */static intshowhelp(argv)    char **argv;{    if (phase == PHASE_INITIALIZE) {	usage();	exit(0);    }    return 0;}/* * showversion - print out the version number and exit. */static intshowversion(argv)    char **argv;{    if (phase == PHASE_INITIALIZE) {	fprintf(stderr, "pppd version %s\n", VERSION);	exit(0);    }    return 0;}/* * option_error - print a message about an error in an option. * The message is logged, and also sent to * stderr if phase == PHASE_INITIALIZE. */voidoption_error __V((char *fmt, ...)){    va_list args;    char buf[1024];#if defined(__STDC__)    va_start(args, fmt);#else    char *fmt;    va_start(args);    fmt = va_arg(args, char *);#endif    vslprintf(buf, sizeof(buf), fmt, args);    va_end(args);    if (phase == PHASE_INITIALIZE)	fprintf(stderr, "%s: %s\n", progname, buf);    syslog(LOG_ERR, "%s", buf);}#if 0/*

⌨️ 快捷键说明

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