*/
#ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.30 1996/01/01 22:59:26 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.33 1996/05/28 00:49:10 paulus Exp $";
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include "pathnames.h"
#include "patchlevel.h"
+#if defined(SUNOS4)
+extern char *strerror();
+#endif
+
#ifdef IPX_CHANGE
#include "ipxcp.h"
#endif /* IPX_CHANGE */
char hostname[MAXNAMELEN]; /* Our hostname */
static char pidfilename[MAXPATHLEN]; /* name of pid file */
static char default_devnam[MAXPATHLEN]; /* name of default device */
-static pid_t pid; /* Our pid */
-static pid_t pgrpid; /* Process Group ID */
+static pid_t pid; /* Our pid */
static uid_t uid; /* Our real user-id */
int ttyfd = -1; /* Serial port file descriptor */
+mode_t tty_mode = -1; /* Original access permissions to tty */
int phase; /* where the link is at */
int kill_link;
int open_ccp_flag;
-static int loop_fd = -1; /* fd for loopback device */
-
u_char outpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for outgoing packet */
u_char inpacket_buf[PPP_MRU+PPP_HDRLEN]; /* buffer for incoming packet */
#define O_NONBLOCK O_NDELAY
#endif
+#ifdef PRIMITIVE_SYSLOG
+#define setlogmask(x)
+#endif
+
/*
* PPP Data Link Layer "protocol" table.
* One entry per supported protocol.
NULL
};
+int
main(argc, argv)
int argc;
char *argv[];
{
int i, nonblock, fdflags;
struct sigaction sa;
- struct cmd *cmdp;
FILE *pidfile;
char *p;
struct passwd *pw;
struct timeval timo;
sigset_t mask;
struct protent *protp;
+ struct stat statbuf;
+ phase = PHASE_INITIALIZE;
p = ttyname(0);
if (p)
strcpy(devnam, p);
strcpy(default_devnam, devnam);
+ /* Initialize syslog facilities */
+#ifdef PRIMITIVE_SYSLOG
+ openlog("pppd", LOG_PID);
+#else
+ openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
+ setlogmask(LOG_UPTO(LOG_INFO));
+#endif
+
if (gethostname(hostname, MAXNAMELEN) < 0 ) {
- perror("couldn't get hostname");
+ syslog(LOG_ERR, "couldn't get hostname: %m");
die(1);
}
hostname[MAXNAMELEN-1] = 0;
progname = *argv;
if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) ||
+ !options_for_tty() ||
!options_from_user() ||
- !parse_args(argc-1, argv+1) ||
- !options_for_tty())
+ !parse_args(argc-1, argv+1))
exit(1);
if (!ppp_available()) {
exit(1);
}
+ /*
+ * Check that the options given are valid and consistent.
+ */
sys_check_options();
auth_check_options();
for (i = 0; (protp = protocols[i]) != NULL; ++i)
if (protp->check_options != NULL)
(*protp->check_options)();
+ if (demand && connector == 0) {
+ fprintf(stderr, "%s: connect script required for demand-dialling\n",
+ progname);
+ exit(1);
+ }
/*
* If the user has specified the default device name explicitly,
*/
sys_init();
magic_init();
+ if (debug)
+ setlogmask(LOG_UPTO(LOG_DEBUG));
/*
* Detach ourselves from the terminal, if required,
SIGNAL(SIGXFSZ, bad_signal);
#endif
+ /*
+ * Apparently we can get a SIGPIPE when we call syslog, if
+ * syslogd has died and been restarted. Ignoring it seems
+ * be sufficient.
+ */
+ signal(SIGPIPE, SIG_IGN);
+
/*
* If we're doing dial-on-demand, set up the interface now.
*/
hungup = 0;
kill_link = 0;
+ /*
+ * Do the equivalent of `mesg n' to stop broadcast messages.
+ */
+ if (fstat(ttyfd, &statbuf) < 0
+ || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) {
+ syslog(LOG_WARNING,
+ "Couldn't restrict write permissions to %s: %m", devnam);
+ } else
+ tty_mode = statbuf.st_mode;
+
/* run connection script */
if (connector && connector[0]) {
MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector));
disestablish_ppp(ttyfd);
/* drop dtr to hang up */
- if (modem)
+ if (modem) {
setdtr(ttyfd, FALSE);
+ /*
+ * This sleep is in case the serial port has CLOCAL set by default,
+ * and consequently will reassert DTR when we close the device.
+ */
+ sleep(1);
+ }
restore_tty(ttyfd);
+ if (tty_mode != (mode_t) -1)
+ chmod(devnam, tty_mode);
+
close(ttyfd);
ttyfd = -1;
}
void (*func)();
caddr_t arg;
{
- struct itimerval itv;
struct callout **copp, *freep;
- int reschedule = 0;
MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg));
int sig;
{
debug = !debug;
- note_debug_level();
+ if (debug) {
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ } else {
+ setlogmask(LOG_UPTO(LOG_WARNING));
+ }
}
if (pid == 0) {
sys_close();
+ closelog();
dup2(in, 0);
dup2(out, 1);
errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644);
/* Ensure that nothing of our device environment is inherited. */
sys_close();
+ closelog();
close (0);
close (1);
close (2);
}
}
-#ifdef __STDC__
-#include <stdarg.h>
-
static void
+#if __STDC__
pr_log(void *arg, char *fmt, ...)
+#else
+pr_log(va_alist)
+ va_dcl
+#endif
{
int n;
va_list pvar;
char buf[256];
+#if __STDC__
va_start(pvar, fmt);
- vsprintf(buf, fmt, pvar);
- va_end(pvar);
-
- n = strlen(buf);
- if (linep + n + 1 > line + sizeof(line)) {
- syslog(LOG_DEBUG, "%s", line);
- linep = line;
- }
- strcpy(linep, buf);
- linep += n;
-}
-
-#else /* __STDC__ */
-#include <varargs.h>
-
-static void
-pr_log(arg, fmt, va_alist)
-void *arg;
-char *fmt;
-va_dcl
-{
- int n;
- va_list pvar;
- char buf[256];
-
+#else
+ void *arg;
+ char *fmt;
va_start(pvar);
+ arg = va_arg(pvar, void *);
+ fmt = va_arg(pvar, char *);
+#endif
+
vsprintf(buf, fmt, pvar);
va_end(pvar);
strcpy(linep, buf);
linep += n;
}
-#endif
/*
* print_string - print a readable representation of a string using
syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
die(1);
}
+
+/*
+ * fmtmsg - format a message into a buffer. Like sprintf except we
+ * also specify the length of the output buffer, and we handle
+ * %r (recursive format), %m (error message) and %I (IP address) formats.
+ * Doesn't do floating-point formats.
+ * Returns the number of chars put into buf.
+ */
+int
+fmtmsg __V((char *buf, int buflen, char *fmt, ...))
+{
+ va_list args;
+ int n;
+
+#if __STDC__
+ va_start(args, fmt);
+#else
+ char *buf;
+ int buflen;
+ char *fmt;
+ va_start(args);
+ buf = va_arg(args, char *);
+ buflen = va_arg(args, int);
+ fmt = va_arg(args, char *);
+#endif
+ n = vfmtmsg(buf, buflen, fmt, args);
+ va_end(args);
+ return n;
+}
+
+/*
+ * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
+ */
+int
+vfmtmsg(char *buf, int buflen, char *fmt, va_list args)
+{
+ int c, i, n;
+ int width, prec;
+ int base, len, neg;
+ unsigned long val;
+ char *str, *f, *buf0;
+ va_list a;
+ char num[32];
+ static char hexchars[16] = "0123456789abcdef";
+
+ buf0 = buf;
+ --buflen;
+ while (buflen > 0) {
+ for (f = fmt; *f != '%' && *f != 0; ++f)
+ ;
+ if (f > fmt) {
+ len = f - fmt;
+ if (len > buflen)
+ len = buflen;
+ memcpy(buf, fmt, len);
+ buf += len;
+ buflen -= len;
+ fmt = f;
+ }
+ if (*fmt == 0)
+ break;
+ c = *++fmt;
+ width = prec = 0;
+ while (isdigit(c)) {
+ width = width * 10 + c - '0';
+ c = *++fmt;
+ }
+ if (c == '.') {
+ c = *++fmt;
+ while (isdigit(c)) {
+ prec = prec * 10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ str = 0;
+ base = 0;
+ neg = 0;
+ ++fmt;
+ switch (c) {
+ case 'd':
+ i = va_arg(args, int);
+ if (i < 0) {
+ neg = 1;
+ val = -i;
+ } else
+ val = i;
+ base = 10;
+ break;
+ case 'o':
+ val = va_arg(args, unsigned int);
+ base = 8;
+ break;
+ case 'x':
+ val = va_arg(args, unsigned int);
+ base = 16;
+ break;
+ case 'p':
+ val = (unsigned long) va_arg(args, void *);
+ base = 16;
+ neg = 2;
+ break;
+ case 's':
+ str = va_arg(args, char *);
+ break;
+ case 'c':
+ num[0] = va_arg(args, int);
+ num[1] = 0;
+ str = num;
+ break;
+ case 'm':
+ str = strerror(errno);
+ break;
+ case 'I':
+ str = ip_ntoa(va_arg(args, u_int32_t));
+ break;
+ case 'r':
+ f = va_arg(args, char *);
+ a = va_arg(args, va_list);
+ n = vfmtmsg(buf, buflen + 1, f, a);
+ buf += n;
+ buflen -= n;
+ continue;
+ default:
+ *buf++ = '%';
+ if (c != '%')
+ --fmt; /* so %z outputs %z etc. */
+ --buflen;
+ continue;
+ }
+ if (base != 0) {
+ str = num + sizeof(num);
+ *--str = 0;
+ while (str > num + neg) {
+ *--str = hexchars[val % base];
+ val = val / base;
+ if (--prec <= 0 && val == 0)
+ break;
+ }
+ switch (neg) {
+ case 1:
+ *--str = '-';
+ break;
+ case 2:
+ *--str = 'x';
+ *--str = '0';
+ break;
+ }
+ len = num + sizeof(num) - 1 - str;
+ } else {
+ len = strlen(str);
+ if (prec > 0 && len > prec)
+ len = prec;
+ }
+ if (width > 0) {
+ if (width > buflen)
+ width = buflen;
+ if ((n = width - len) > 0) {
+ buflen -= n;
+ for (; n > 0; --n)
+ *buf++ = ' ';
+ }
+ }
+ if (len > buflen)
+ len = buflen;
+ memcpy(buf, str, len);
+ buf += len;
+ buflen -= len;
+ }
+ *buf = 0;
+ return buf - buf0;
+}