X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Foptions.c;h=e7f95bf54f83d79b00370865febad357ab514c2f;hp=3d5e020338d88538d11e94f6ebd06749a7cd0ffc;hb=dee72905271845128ad26cff5cf770c433f3f4a7;hpb=257999f8445702fd2a9c4e843ed30e2dbcff528b diff --git a/pppd/options.c b/pppd/options.c index 3d5e020..e7f95bf 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.19 1995/04/27 00:20:16 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.25 1995/10/27 03:39:14 paulus Exp $"; #endif #include @@ -138,7 +138,9 @@ static int setremote __P((char **)); static int setauth __P((void)); static int readfile __P((char **)); static int setdefaultroute __P((void)); +static int setnodefaultroute __P((void)); static int setproxyarp __P((void)); +static int setnoproxyarp __P((void)); static int setpersist __P((void)); static int setdologin __P((void)); static int setusehostname __P((void)); @@ -153,6 +155,7 @@ static int setipcpconf __P((char **)); static int setipcpfails __P((char **)); static int setpaptimeout __P((char **)); static int setpapreqs __P((char **)); +static int setpapreqtime __P((char **)); static int setchaptimeout __P((char **)); static int setchapchal __P((char **)); static int setchapintv __P((char **)); @@ -165,7 +168,7 @@ static int setnobsdcomp __P((void)); static int setipparam __P((char **)); static int setpapcrypt __P((void)); -static int number_option __P((char *, long *, int)); +static int number_option __P((char *, u_int32_t *, int)); static int readable __P((int fd)); void usage(); @@ -222,7 +225,9 @@ static struct cmd { {"auth", 0, setauth}, /* Require authentication from peer */ {"file", 1, readfile}, /* Take options from a file */ {"defaultroute", 0, setdefaultroute}, /* Add default route */ + {"-defaultroute", 0, setnodefaultroute}, /* disable defaultroute option */ {"proxyarp", 0, setproxyarp}, /* Add proxy ARP entry */ + {"-proxyarp", 0, setnoproxyarp}, /* disable proxyarp option */ {"persist", 0, setpersist}, /* Keep on reopening connection after close */ {"login", 0, setdologin}, /* Use system password database for UPAP */ {"noipdefault", 0, setnoipdflt}, /* Don't use name for default IP adrs */ @@ -236,8 +241,9 @@ static struct cmd { {"ipcp-max-terminate", 1, setipcpterm}, /* Set max #xmits for term-reqs */ {"ipcp-max-configure", 1, setipcpconf}, /* Set max #xmits for conf-reqs */ {"ipcp-max-failure", 1, setipcpfails}, /* Set max #conf-naks for IPCP */ - {"pap-restart", 1, setpaptimeout}, /* Set timeout for UPAP */ + {"pap-restart", 1, setpaptimeout}, /* Set retransmit timeout for PAP */ {"pap-max-authreq", 1, setpapreqs}, /* Set max #xmits for auth-reqs */ + {"pap-timeout", 1, setpapreqtime}, /* Set time limit for peer PAP auth. */ {"chap-restart", 1, setchaptimeout}, /* Set timeout for CHAP */ {"chap-max-challenge", 1, setchapchal}, /* Set max #xmits for challenge */ {"chap-interval", 1, setchapintv}, /* Set interval for rechallenge */ @@ -495,10 +501,11 @@ readable(fd) /* * Read a word from a file. - * Words are delimited by white-space or by quotes ("). + * Words are delimited by white-space or by quotes (" or '). * Quotes, white-space and \ may be escaped with \. * \ is ignored. */ + int getword(f, word, newlinep, filename) FILE *f; @@ -507,110 +514,250 @@ getword(f, word, newlinep, filename) char *filename; { int c, len, escape; - int quoted; + int quoted, comment; + int value, digit, got, n; + +#define isoctal(c) ((c) >= '0' && (c) < '8') *newlinep = 0; len = 0; escape = 0; - quoted = 0; + comment = 0; /* - * First skip white-space and comments + * First skip white-space and comments. */ - while ((c = getc(f)) != EOF) { + 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) { /* - * \ is ignored; \ followed by anything else - * starts a word. + * This character is escaped: backslash-newline is ignored, + * various other characters indicate particular values + * as for C backslash-escapes. */ - if ((c = getc(f)) == '\n') + escape = 0; + if (c == '\n') { + c = getc(f); continue; - word[len++] = '\\'; - escape = 1; - break; + } + + 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 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; + } - if (c == '\n') - *newlinep = 1; /* next word starts a line */ - else if (c == '#') { - /* comment - ignore until EOF or \n */ - while ((c = getc(f)) != EOF && c != '\n') - ; - if (c == EOF) + + /* + * Not escaped: see if we've reached the end of the word. + */ + if (quoted) { + if (c == quoted) break; - *newlinep = 1; - } else if (!isspace(c)) - 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) + word[len] = c; + ++len; + + c = getc(f); } /* - * End of file or error - fail + * End of the word: check for errors. */ if (c == EOF) { if (ferror(f)) { + if (errno == 0) + errno = EIO; perror(filename); die(1); } - return 0; - } - - for (;;) { /* - * Is this character escaped by \ ? + * If len is zero, then we didn't find a word before the + * end of the file. */ - if (escape) { - if (c == '\n') - --len; /* ignore \ */ - else if (c == '"' || isspace(c) || c == '\\') - word[len-1] = c; /* put special char in word */ - else { - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - } - escape = 0; - } else if (c == '"') { - quoted = !quoted; - } else if (!quoted && (isspace(c) || c == '#')) { - ungetc(c, f); - break; - } else { - if (len < MAXWORDLEN-1) - word[len] = c; - ++len; - if (c == '\\') - escape = 1; - } - if ((c = getc(f)) == EOF) - break; - } - - if (ferror(f)) { - perror(filename); - die(1); + if (len == 0) + return 0; } + /* + * Warn if the word was too long, and append a terminating null. + */ if (len >= MAXWORDLEN) { - word[MAXWORDLEN-1] = 0; fprintf(stderr, "%s: warning: word in file %s too long (%.20s...)\n", progname, filename, word); - } else - word[len] = 0; + len = MAXWORDLEN - 1; + } + word[len] = 0; return 1; + +#undef isoctal + } /* - * number_option - parse a numeric parameter for an option + * number_option - parse an unsigned numeric parameter for an option. */ static int number_option(str, valp, base) char *str; - long *valp; + u_int32_t *valp; int base; { char *ptr; - *valp = strtol(str, &ptr, base); + *valp = strtoul(str, &ptr, base); if (ptr == str) { fprintf(stderr, "%s: invalid number: %s\n", progname, str); return 0; @@ -629,7 +776,7 @@ int_option(str, valp) char *str; int *valp; { - long v; + u_int32_t v; if (!number_option(str, &v, 0)) return 0; @@ -752,7 +899,7 @@ static int setmru(argv) char **argv; { - long mru; + u_int32_t mru; if (!number_option(*argv, &mru, 0)) return 0; @@ -769,7 +916,7 @@ static int setmtu(argv) char **argv; { - long mtu; + u_int32_t mtu; if (!number_option(*argv, &mtu, 0)) return 0; @@ -989,7 +1136,12 @@ static int setdomain(argv) char **argv; { - strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); + gethostname(hostname, MAXNAMELEN); + if (**argv != 0) { + if (**argv != '.') + strncat(hostname, ".", MAXNAMELEN - strlen(hostname)); + strncat(hostname, *argv, MAXNAMELEN - strlen(hostname)); + } hostname[MAXNAMELEN-1] = 0; return (1); } @@ -1002,7 +1154,7 @@ static int setasyncmap(argv) char **argv; { - long asyncmap; + u_int32_t asyncmap; if (!number_option(*argv, &asyncmap, 16)) return 0; @@ -1267,7 +1419,10 @@ setnocrtscts() static int setxonxoff() { - crtscts = 2; + lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ + lcp_wantoptions[0].neg_asyncmap = 1; + + crtscts = -2; return (1); } @@ -1345,17 +1500,41 @@ setauth() static int setdefaultroute() { + if (!ipcp_allowoptions[0].default_route) { + fprintf(stderr, "%s: defaultroute option is disabled\n", progname); + return 0; + } ipcp_wantoptions[0].default_route = 1; return 1; } +static int +setnodefaultroute() +{ + ipcp_allowoptions[0].default_route = 0; + ipcp_wantoptions[0].default_route = 0; + return 1; +} + static int setproxyarp() { + if (!ipcp_allowoptions[0].proxy_arp) { + fprintf(stderr, "%s: proxyarp option is disabled\n", progname); + return 0; + } ipcp_wantoptions[0].proxy_arp = 1; return 1; } +static int +setnoproxyarp() +{ + ipcp_wantoptions[0].proxy_arp = 0; + ipcp_allowoptions[0].proxy_arp = 0; + return 1; +} + static int setpersist() { @@ -1454,6 +1633,13 @@ setpaptimeout(argv) return int_option(*argv, &upap[0].us_timeouttime); } +static int +setpapreqtime(argv) + char **argv; +{ + return int_option(*argv, &upap[0].us_reqtimeout); +} + static int setpapreqs(argv) char **argv;