📄 options.c
字号:
slprintf(path, pl, "%s%s", _PATH_TTYOPT, dev); /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p) if (*p == '/') *p = '.'; ret = options_from_file(path, 0, 0, 1); free(path); return ret;}/* * options_from_list - process a string of options in a wordlist. */intoptions_from_list(w, priv) struct wordlist *w; int priv;{ char *argv[MAXARGS]; option_t *opt; int i, ret = 0; privileged_option = priv; option_source = "secrets file"; while (w != NULL) { /* * First see if it's a command. */ opt = find_option(w->word); if (opt != NULL) { int n = n_arguments(opt); struct wordlist *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; } current_option = w0->word; if (!process_option(opt, argv)) goto err; w = w->next; continue; } /* * Maybe a tty name, speed or IP address? */ if ((i = setdevname(w->word)) == 0 && (i = setspeed(w->word)) == 0 && (i = setipaddr(w->word)) == 0) { option_error("In secrets file: unrecognized option '%s'", w->word); goto err; } if (i < 0) /* error */ goto err; w = w->next; } ret = 1;err: return ret;}/* * 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) char *name;{ option_t *opt; struct option_list *list; int i; for (list = extra_options; list != NULL; list = list->next) for (opt = list->options; opt->name != NULL; ++opt) if (strcmp(name, opt->name) == 0) return opt; for (opt = general_options; opt->name != NULL; ++opt) if (strcmp(name, opt->name) == 0) return opt; for (opt = auth_options; opt->name != NULL; ++opt) if (strcmp(name, opt->name) == 0) return opt; for (i = 0; protocols[i] != NULL; ++i) if ((opt = protocols[i]->options) != NULL) for (; opt->name != NULL; ++opt) if (strcmp(name, opt->name) == 0) return opt; return NULL;}/* * process_option - process one new-style option. */static intprocess_option(opt, argv) option_t *opt; char **argv;{ u_int32_t v; int iv, a; char *sv; int (*parser) __P((char **)); if ((opt->flags & OPT_PREPASS) == 0 && prepass) return 1; if ((opt->flags & OPT_INITONLY) && pppd_phase != PHASE_INITIALIZE) { option_error("it's too late to use the %s option", opt->name); return 0; } if ((opt->flags & OPT_PRIV) && !privileged_option) { option_error("using the %s option requires root privilege", opt->name); return 0; } if ((opt->flags & OPT_ENABLE) && *(bool *)(opt->addr2) == 0) { option_error("%s option is disabled", opt->name); return 0; } if ((opt->flags & OPT_PRIVFIX) && !privileged_option) { struct option_info *ip = (struct option_info *) opt->addr2; if (ip && ip->priv) { option_error("%s option cannot be overridden", opt->name); 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; 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, 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; } 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"); if ( *(char **)(opt->addr) != NULL ) { free((void *)*(char **)(opt->addr)); *(char **)(opt->addr) = NULL; } *(char **)(opt->addr) = sv; } break; case o_special_noarg: case o_special: parser = (int (*) __P((char **))) opt->addr; if (!(*parser)(argv)) return 0; break; } if (opt->addr2) { if (opt->flags & OPT_A2INFO) { struct option_info *ip = (struct option_info *) opt->addr2; ip->priv = privileged_option; ip->source = option_source; } else if ((opt->flags & (OPT_A2COPY|OPT_ENABLE)) == 0) *(bool *)(opt->addr2) = 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;}/* * usage - print out a message telling how to use the program. */static voidusage(){ if (pppd_phase == PHASE_INITIALIZE) fprintf(stderr, usage_string, VERSION, PATCHLEVEL, IMPLEMENTATION, "rtems_pppd");}/* * option_error - print a message about an error in an option. * The message is logged, and also sent to * stderr if pppd_phase == PHASE_INITIALIZE. */voidoption_error __V((char *fmt, ...)){ va_list args; char buf[256];#if defined(__STDC__) va_start(args, fmt);#else char *fmt; va_start(args); fmt = va_arg(args, char *);#endif if (prepass) { va_end(args); return; } vslprintf(buf, sizeof(buf), fmt, args); va_end(args); fprintf(stderr, "pppd: %s\n", buf);}/* * Read a word from a file. * Words are delimited by white-space or by quotes (" or '). * Quotes, white-space and \ may be escaped with \. * \<newline> is ignored. */intgetword(f, word, newlinep, filename) FILE *f; char *word; int *newlinep; char *filename;{ int c, len, escape; int quoted, comment; int value, digit, got, n;#define isoctal(c) ((c) >= '0' && (c) < '8') *newlinep = 0; len = 0; escape = 0; comment = 0; /* * First skip white-space and comments. */ for (;;) { c = getc(f); if (c == EOF) break; /* * A newline means the end of a comment; backslash-newline * is ignored. Note that we cannot have escape && comment. */ if (c == '\n') { if (!escape) { *newlinep = 1; comment = 0; } else escape = 0; continue; } /* * Ignore characters other than newline in a comment. */ if (comment) continue; /* * If this character is escaped, we have a word start. */ if (escape) break; /* * If this is the escape character, look at the next character. */ if (c == '\\') { escape = 1; continue; } /* * If this is the start of a comment, ignore the rest of the line. */ if (c == '#') { comment = 1; continue; } /* * A non-whitespace character is the start of a word. */ if (!isspace(c)) break; } /* * Save the delimiter for quoted strings. */ if (!escape && (c == '"' || c == '\'')) { quoted = c; c = getc(f); } else quoted = 0; /* * Process characters until the end of the word. */ while (c != EOF) { if (escape) { /* * This character is escaped: backslash-newline is ignored, * various other characters indicate particular values * as for C backslash-escapes. */ escape = 0; if (c == '\n') { c = getc(f); continue; } got = 0; switch (c) { case 'a': value = '\a'; break; case 'b': value = '\b'; break; case 'f': value = '\f'; break; case 'n': value = '\n'; break; case 'r': value = '\r'; break; case 's': value = ' '; break; case 't': value = '\t'; break; default: if (isoctal(c)) { /* * \ddd octal sequence */ value = 0; for (n = 0; n < 3 && isoctal(c); ++n) { value = (value << 3) + (c & 07); c = getc(f); } got = 1; break; } if (c == 'x') { /* * \x<hex_string> sequence */ value = 0; c = getc(f); for (n = 0; n < 2 && isxdigit(c); ++n) { digit = toupper(c) - '0'; if (digit > 10) digit += '0' + 10 - 'A'; value = (value << 4) + digit; c = getc (f); } got = 1; break; } /* * Otherwise the character stands for itself. */ value = c; break; } /* * Store the resulting character for the escape sequence. */ if (len < MAXWORDLEN-1) word[len] = value; ++len; if (!got) c = getc(f); continue; } /* * Not escaped: see if we've reached the end of the word. */ if (quoted) { if (c == quoted) break; } else { if (isspace(c) || c == '#') { ungetc (c, f); break; } } /* * Backslash starts an escape sequence. */ if (c == '\\') { escape = 1; c = getc(f); continue; } /* * An ordinary character: store it in the word and get another. */ if (len < MAXWORDLEN-1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -