X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=pppd%2Foptions.c;h=495c29ae17c38c32591db568b0367292b223da2a;hb=971319042d43d6d079842f88622caf721a47805b;hp=c502f5b9984a53c4ec6da4fc3d07f63e71b76dcb;hpb=d4888c75a22008c21b8ca7544b1f57e3254d13c0;p=ppp.git diff --git a/pppd/options.c b/pppd/options.c index c502f5b..495c29a 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,14 +18,13 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.52 1999/03/19 01:27:43 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.59 1999/05/14 01:09:03 paulus Exp $"; #endif #include #include #include #include -#include #include #include #include @@ -66,7 +65,7 @@ int dflag = 0; /* Tell libpcap we want debugging */ int debug = 0; /* Debug flag */ int kdebugflag = 0; /* Tell kernel to print debug messages */ int default_device = 1; /* Using /dev/tty or equivalent */ -char devnam[MAXPATHLEN] = "/dev/tty"; /* Device name */ +char devnam[MAXPATHLEN]; /* Device name */ int crtscts = 0; /* Use hardware flow control */ bool modem = 1; /* Use modem control lines */ int inspeed = 0; /* Input/Output speed requested */ @@ -77,6 +76,7 @@ bool updetach = 0; /* Detach once link is up */ char *connector = NULL; /* Script to establish physical link */ char *disconnector = NULL; /* Script to disestablish physical link */ char *welcomer = NULL; /* Script to run after phys link estab. */ +char *ptycommand = NULL; /* Command to run on other side of pty */ int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ @@ -86,13 +86,21 @@ bool demand = 0; /* do dial-on-demand */ char *ipparam = NULL; /* Extra parameter for ip up/down scripts */ int idle_time_limit = 0; /* Disconnect if idle for this many seconds */ int holdoff = 30; /* # seconds to pause before reconnecting */ +bool notty = 0; /* Stdin/out is not a tty */ +char *record_file = NULL; /* File to record chars sent/received */ +int using_pty = 0; +bool sync_serial = 0; /* Device is synchronous serial device */ +int log_to_fd = 1; /* send log messages to this fd too */ extern option_t auth_options[]; +extern struct stat devstat; +extern int prepass; /* Doing pre-pass to find device name */ struct option_info connector_info; struct option_info disconnector_info; struct option_info welcomer_info; struct option_info devnam_info; +struct option_info ptycommand_info; #ifdef PPP_FILTER struct bpf_program pass_filter;/* Filter program for packets to pass */ @@ -100,10 +108,14 @@ struct bpf_program active_filter; /* Filter program for link-active pkts */ pcap_t pc; /* Fake struct pcap so we can compile expr */ #endif +char *current_option; /* the name of the option being parsed */ +int privileged_option; /* set iff the current option came from root */ +char *option_source; /* string saying where the option came from */ + /* * Prototypes */ -static int setdevname __P((char *, int)); +static int setdevname __P((char *)); static int setipaddr __P((char *)); static int setspeed __P((char *)); static int noopt __P((char **)); @@ -160,6 +172,13 @@ option_t general_options[] = { { "welcome", o_string, &welcomer, "Script to welcome client", OPT_A2INFO | OPT_PRIVFIX, &welcomer_info }, + { "pty", o_string, &ptycommand, + "Script to run on pseudo-tty master side", + OPT_A2INFO | OPT_PRIVFIX | OPT_PREPASS, &ptycommand_info }, + { "notty", o_bool, ¬ty, + "Input/output is not a tty", OPT_PREPASS | 1 }, + { "record", o_string, &record_file, + "Record characters sent/received to file" }, { "maxconnect", o_int, &maxconnect, "Set connection time limit", OPT_LLIMIT|OPT_NOINCR|OPT_ZEROINF }, { "crtscts", o_int, &crtscts, @@ -185,9 +204,9 @@ option_t general_options[] = { { "local", o_bool, &modem, "Don't use modem control lines" }, { "file", o_special, readfile, - "Take options from a file" }, + "Take options from a file", OPT_PREPASS }, { "call", o_special, callfile, - "Take options from a privileged file" }, + "Take options from a privileged file", OPT_PREPASS }, { "persist", o_bool, &persist, "Keep on reopening connection after close", 1 }, { "nopersist", o_bool, &persist, @@ -200,6 +219,13 @@ option_t general_options[] = { "Show brief listing of options" }, { "-h", o_special_noarg, showhelp, "Show brief listing of options" }, + { "sync", o_bool, &sync_serial, + "Use synchronous HDLC serial encoding", 1 }, + { "logfd", o_int, &log_to_fd, + "Send log messages to this file descriptor" }, + { "nologfd", o_int, &log_to_fd, + "Don't send log messages to any file descriptor", + OPT_NOARG | OPT_VAL(-1) }, #ifdef PPP_FILTER { "pdebug", o_int, &dflag, @@ -237,6 +263,8 @@ See pppd(8) for more options.\n\ /* * parse_args - parse a string of arguments from the command line. + * If prepass is true, we are scanning for the device name and only + * processing a few options, so error messages are suppressed. */ int parse_args(argc, argv) @@ -274,7 +302,7 @@ parse_args(argc, argv) /* * Maybe a tty name, speed or IP address? */ - if ((ret = setdevname(arg, 0)) == 0 + if ((ret = setdevname(arg)) == 0 && (ret = setspeed(arg)) == 0 && (ret = setipaddr(arg)) == 0) { option_error("unrecognized option '%s'", arg); @@ -287,9 +315,10 @@ parse_args(argc, argv) return 1; } +#if 0 /* * scan_args - scan the command line arguments to get the tty name, - * if specified. + * if specified. Also checks whether the notty or pty option was given. */ void scan_args(argc, argv) @@ -304,6 +333,9 @@ scan_args(argc, argv) arg = *argv++; --argc; + if (strcmp(arg, "notty") == 0 || strcmp(arg, "pty") == 0) + using_pty = 1; + /* Skip options and their arguments */ opt = find_option(arg); if (opt != NULL) { @@ -317,6 +349,7 @@ scan_args(argc, argv) (void) setdevname(arg, 1); } } +#endif /* * options_from_file - Read a string of options from a file, @@ -330,7 +363,7 @@ options_from_file(filename, must_exist, check_prot, priv) int priv; { FILE *f; - int i, newline, ret; + int i, newline, ret, err; option_t *opt; int oldpriv; char *oldsource; @@ -341,11 +374,13 @@ options_from_file(filename, must_exist, check_prot, priv) if (check_prot) seteuid(getuid()); f = fopen(filename, "r"); + err = errno; if (check_prot) seteuid(0); if (f == NULL) { - if (!must_exist && errno == ENOENT) + if (!must_exist && err == ENOENT) return 1; + errno = err; option_error("Can't open options file %s: %m", filename); return 0; } @@ -382,7 +417,7 @@ options_from_file(filename, must_exist, check_prot, priv) /* * Maybe a tty name, speed or IP address? */ - if ((i = setdevname(cmd, 0)) == 0 + if ((i = setdevname(cmd)) == 0 && (i = setspeed(cmd)) == 0 && (i = setipaddr(cmd)) == 0) { option_error("In file %s: unrecognized option '%s'", @@ -441,7 +476,7 @@ options_for_tty() dev = devnam; if (strncmp(dev, "/dev/", 5) == 0) dev += 5; - if (strcmp(dev, "tty") == 0) + if (dev[0] == 0 || strcmp(dev, "tty") == 0) return 1; /* don't look for /etc/ppp/options.tty */ pl = strlen(_PATH_TTYOPT) + strlen(dev) + 1; path = malloc(pl); @@ -496,6 +531,9 @@ process_option(opt, argv) char *sv; int (*parser) __P((char **)); + if (prepass && (opt->flags & OPT_PREPASS) == 0) + return 1; + if ((opt->flags & OPT_PRIV) && !privileged_option) { option_error("using the %s option requires root privilege", opt->name); return 0; @@ -677,6 +715,10 @@ option_error __V((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); if (phase == PHASE_INITIALIZE) @@ -1158,9 +1200,8 @@ setspeed(arg) * setdevname - Set the device name. */ static int -setdevname(cp, quiet) +setdevname(cp) char *cp; - int quiet; { struct stat statbuf; char dev[MAXPATHLEN]; @@ -1175,22 +1216,26 @@ setdevname(cp, quiet) } /* - * Check if there is a device by this name. + * Check if there is a character device by this name. */ if (stat(cp, &statbuf) < 0) { - if (errno == ENOENT || quiet) + if (errno == ENOENT) return 0; option_error("Couldn't stat %s: %m", cp); return -1; } + if (!S_ISCHR(statbuf.st_mode)) { + option_error("%s is not a character device", cp); + return -1; + } if (devnam_info.priv && !privileged_option) { - if (!quiet) - option_error("device name cannot be overridden"); + option_error("device name cannot be overridden"); return -1; } strlcpy(devnam, cp, sizeof(devnam)); + devstat = statbuf; default_device = 0; devnam_info.priv = privileged_option; devnam_info.source = option_source; @@ -1216,6 +1261,8 @@ setipaddr(arg) */ if ((colon = strchr(arg, ':')) == NULL) return 0; + if (prepass) + return 1; /* * If colon first character, then no local addr.