*/
#ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.9 1994/05/09 02:40:21 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.13 1994/05/27 01:02:14 paulus Exp $";
#endif
#define SETSID
#include <stdio.h>
+#include <string.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <netdb.h>
#include <utmp.h>
+#include <pwd.h>
#include <sys/wait.h>
/*
* /etc/ppp/options exists.
*/
#ifndef REQ_SYSOPTIONS
-#define REQ_SYSOPTIONS 0
-#endif
-
-#ifdef STREAMS
-#undef SGTTY
+#define REQ_SYSOPTIONS 1
#endif
#ifdef SGTTY
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
-
-#include "callout.h"
-
#include <net/if.h>
-#include <net/if_ppp.h>
-
-#include <string.h>
-
-#ifndef BSD
-#define BSD 43
-#endif /*BSD*/
+#include "callout.h"
#include "ppp.h"
#include "magic.h"
#include "fsm.h"
char hostname[MAXNAMELEN]; /* Our hostname */
char our_name[MAXNAMELEN];
char remote_name[MAXNAMELEN];
+static char pidfilename[MAXPATHLEN];
static pid_t pid; /* Our pid */
static pid_t pgrpid; /* Process Group ID */
-static char pidfilename[MAXPATHLEN];
+uid_t uid; /* Our real user-id */
char devname[MAXPATHLEN] = "/dev/tty"; /* Device name */
int default_device = TRUE; /* use default device (stdin/out) */
/* prototypes */
-static void hup __ARGS((int, int, struct sigcontext *, char *));
-static void intr __ARGS((int, int, struct sigcontext *, char *));
-static void term __ARGS((int, int, struct sigcontext *, char *));
-static void alrm __ARGS((int, int, struct sigcontext *, char *));
-static void io __ARGS((int, int, struct sigcontext *, char *));
+static void hup __ARGS((int));
+static void intr __ARGS((int));
+static void term __ARGS((int));
+static void alrm __ARGS((int));
+static void io __ARGS((int));
+static void chld __ARGS((int));
static void incdebug __ARGS((int));
static void nodebug __ARGS((int));
void establish_ppp __ARGS((void));
void (*) (void *, char *, ...), void *));
void pr_log __ARGS((void *, char *, ...));
-#ifdef STREAMS
extern char *ttyname __ARGS((int));
-#endif
extern char *getlogin __ARGS((void));
/*
char *argv[];
{
int mask, i;
- struct sigvec sv;
+ struct sigaction sa;
struct cmd *cmdp;
FILE *pidfile;
char *p;
+ struct passwd *pw;
-#ifdef STREAMS
- p = ttyname(fileno(stdin));
+ p = ttyname(0);
if (p)
strcpy(devname, p);
-#endif
if (gethostname(hostname, MAXNAMELEN) < 0 ) {
perror("couldn't get hostname");
hostname[MAXNAMELEN-1] = 0;
pid = getpid();
+ uid = getuid();
if (!ppp_available()) {
fprintf(stderr, "Sorry - PPP is not available on this system\n");
progname = *argv;
- if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS) ||
+ if (!options_from_file(_PATH_SYSOPTIONS, REQ_SYSOPTIONS, 0) ||
!options_from_user() ||
- !parse_args(argc-1, argv+1))
+ !parse_args(argc-1, argv+1) ||
+ !options_for_tty())
die(1);
check_auth_options();
setipdefault();
- if (lockflag && !default_device)
- if (lock(devname) < 0)
- die(1);
-
/*
* Initialize syslog system and magic number package.
*/
-#if (BSD >= 43 || defined(sun)) && !defined(ultrix)
+#if !defined(ultrix)
openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP);
setlogmask(LOG_UPTO(LOG_INFO));
#else
magic_init();
p = getlogin();
- if (p == NULL)
- p = "(unknown)";
+ if (p == NULL) {
+ pw = getpwuid(uid);
+ if (pw != NULL && pw->pw_name != NULL)
+ p = pw->pw_name;
+ else
+ p = "(unknown)";
+ }
syslog(LOG_NOTICE, "pppd %s.%d started by %s, uid %d",
- VERSION, PATCHLEVEL, p, getuid());
+ VERSION, PATCHLEVEL, p, uid);
#ifdef SETSID
/*
}
#endif
+ if (lockflag && !default_device)
+ if (lock(devname) < 0)
+ die(1);
+
/* Get an internet socket for doing socket ioctl's on. */
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "socket : %m");
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGALRM);
sigaddset(&mask, SIGIO);
+ sigaddset(&mask, SIGCHLD);
#ifdef STREAMS
sigaddset(&mask, SIGPOLL);
#endif
#define SIGNAL(s, handler) { \
- sv.sv_handler = handler; \
- if (sigvec(s, &sv, NULL) < 0) { \
- syslog(LOG_ERR, "sigvec(%d): %m", s); \
+ sa.sa_handler = handler; \
+ if (sigaction(s, &sa, NULL) < 0) { \
+ syslog(LOG_ERR, "sigaction(%d): %m", s); \
die(1); \
} \
}
- sv.sv_mask = mask;
- sv.sv_flags = 0;
+ sa.sa_mask = mask;
+ sa.sa_flags = 0;
SIGNAL(SIGHUP, hup); /* Hangup */
SIGNAL(SIGINT, intr); /* Interrupt */
SIGNAL(SIGTERM, term); /* Terminate */
SIGNAL(SIGALRM, alrm); /* Timeout */
SIGNAL(SIGIO, io); /* Input available */
+ SIGNAL(SIGCHLD, chld); /* Death of child process */
#ifdef STREAMS
SIGNAL(SIGPOLL, io); /* Input available */
#endif
syslog(LOG_ERR, "fcntl(F_GETFL): %m");
die(1);
}
+
+#ifdef _linux_ /* This is a kludge for Linux. FIXME !!! -- later. */
+#undef FASYNC
+#define FASYNC 0
+#endif
+
if (fcntl(fd, F_SETFL, FNDELAY | FASYNC) == -1) {
syslog(LOG_ERR, "fcntl(F_SETFL, FNDELAY | FASYNC): %m");
die(1);
sigprocmask(SIG_BLOCK, &mask, NULL); /* Block signals now */
lcp_lowerup(0); /* XXX Well, sort of... */
lcp_open(0); /* Start protocol */
- for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
+ for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; )
sigpause(0); /* Wait for next signal */
- reap_kids(); /* Don't leave dead kids lying around */
- }
/*
* Run disconnector script, if requested
#ifdef CRTSCTS
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL | CRTSCTS);
- if (crtscts)
+ if (crtscts == 1)
tios.c_cflag |= CRTSCTS;
#else
tios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CLOCAL);
tios.c_lflag = 0;
tios.c_cc[VMIN] = 1;
tios.c_cc[VTIME] = 0;
+
+ if (crtscts == 2) {
+ tios.c_iflag |= IXOFF;
+ tios.c_cc[VSTOP] = 0x13; /* DC3 = XOFF = ^S */
+ tios.c_cc[VSTART] = 0x11; /* DC1 = XON = ^Q */
+ }
+
speed = translate_speed(inspeed);
if (speed) {
cfsetospeed(&tios, speed);
if (initfdflags != -1 && fcntl(fd, F_SETFL, initfdflags) < 0)
syslog(LOG_WARNING, "fcntl(F_SETFL, fdflags): %m");
+ initfdflags = -1;
disestablish_ppp();
}
close(fd);
- fd = 0;
+ fd = -1;
}
if (pidfilename[0] != 0 && unlink(pidfilename) < 0)
*
* Indicates that the physical layer has been disconnected.
*/
-/*ARGSUSED*/
static void
-hup(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
+hup(sig)
+ int sig;
{
syslog(LOG_INFO, "Hangup (SIGHUP)");
*
* Indicates that we should initiate a graceful disconnect and exit.
*/
-/*ARGSUSED*/
static void
-term(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
+term(sig)
+ int sig;
{
syslog(LOG_INFO, "Terminating link.");
persist = 0; /* don't try to restart */
*
* Indicates that we should initiate a graceful disconnect and exit.
*/
-/*ARGSUSED*/
static void
-intr(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
+intr(sig)
+ int sig;
{
syslog(LOG_INFO, "Interrupt received: terminating link");
persist = 0; /* don't try to restart */
*
* Indicates a timeout.
*/
-/*ARGSUSED*/
static void
-alrm(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
+alrm(sig)
+ int sig;
{
struct itimerval itv;
struct callout *freep, *list, *last;
}
+/*
+ * chld - Catch SIGCHLD signal.
+ * Calls reap_kids to get status for any dead kids.
+ */
+static void
+chld(sig)
+ int sig;
+{
+ reap_kids();
+}
+
+
/*
* io - Catch SIGIO signal.
*
* Indicates that incoming data is available.
*/
-/*ARGSUSED*/
static void
-io(sig, code, scp, addr)
- int sig, code;
- struct sigcontext *scp;
- char *addr;
+io(sig)
+ int sig;
{
int len, i;
u_char *p;
MAINDEBUG((LOG_DEBUG, "IO signal received"));
adjtimeout(); /* Adjust timeouts */
- /* we do this to see if the SIGIO handler is being invoked for input */
- /* ready, or for the socket buffer hitting the low-water mark. */
-
- notime.tv_sec = 0;
- notime.tv_usec = 0;
- FD_ZERO(&fdset);
- FD_SET(fd, &fdset);
-
- if ((ready = select(32, &fdset, (fd_set *) NULL, (fd_set *) NULL,
- ¬ime)) == -1) {
- syslog(LOG_ERR, "Error in io() select: %m");
- die(1);
- }
-
- if (ready == 0) {
- MAINDEBUG((LOG_DEBUG, "IO non-input ready SIGIO occured."));
- return;
- }
-
/* Yup, this is for real */
for (;;) { /* Read all available packets */
p = inpacket_buf; /* point to beginning of packet buffer */
return;
if (len == 0) {
- syslog(LOG_WARNING, "End of file on fd!");
- die(1);
+ MAINDEBUG((LOG_DEBUG, "End of file on fd!"));
+ lcp_lowerdown(0);
+ return;
}
if (debug /*&& (debugflags & DBG_INPACKET)*/)