*/
#ifndef lint
-static char rcsid[] = "$Id: main.c,v 1.57 1999/03/08 05:34:43 paulus Exp $";
+static char rcsid[] = "$Id: main.c,v 1.60 1999/03/16 03:14:50 paulus Exp $";
#endif
#include <stdio.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <netinet/in.h>
#include "pppd.h"
#include "magic.h"
int privileged; /* we're running as real uid root */
int need_holdoff; /* need holdoff period before restarting */
int detached; /* have detached from terminal */
+int log_to_stderr; /* send log messages to stderr too */
+
+static int fd_ppp; /* fd for talking PPP */
+static int fd_loop; /* fd for getting demand-dial packets */
int phase; /* where the link is at */
int kill_link;
int open_ccp_flag;
static int waiting;
-static jmp_buf sigjmp;
+static sigjmp_buf sigjmp;
char **script_env; /* Env. variable values for scripts */
int s_env_nalloc; /* # words avail at script_env */
char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n";
+GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */
+int ngroups; /* How many groups valid in groups */
+
/* Prototypes for procedures local to this file. */
static void create_pidfile __P((void));
static int device_script __P((char *, int, int));
static void reap_kids __P((void));
static void pr_log __P((void *, char *, ...));
+static void logit __P((int, char *, va_list));
+static void vslp_printer __P((void *, char *, ...));
extern char *ttyname __P((int));
extern char *getlogin __P((void));
phase = PHASE_INITIALIZE;
p = ttyname(0);
if (p)
- strcpy(devnam, p);
- strcpy(default_devnam, devnam);
+ strlcpy(devnam, sizeof(devnam), p);
+ strlcpy(default_devnam, sizeof(default_devnam), devnam);
script_env = NULL;
uid = getuid();
privileged = uid == 0;
- sprintf(numbuf, "%d", uid);
+ slprintf(numbuf, sizeof(numbuf), "%d", uid);
script_setenv("ORIG_UID", numbuf);
+ ngroups = getgroups(NGROUPS_MAX, groups);
+
/*
* Initialize to the standard option set, then parse, in order,
* the system options file, the user's options file,
}
script_setenv("DEVICE", devnam);
- sprintf(numbuf, "%d", baud_rate);
+ slprintf(numbuf, sizeof(numbuf), "%d", baud_rate);
script_setenv("SPEED", numbuf);
/*
default_device = 1;
if (default_device)
nodetach = 1;
+ log_to_stderr = !default_device;
/*
* Initialize system-dependent stuff and magic number package.
sigaddset(&mask, SIGCHLD);
sigaddset(&mask, SIGUSR2);
-#define SIGNAL(s, handler) { \
+#define SIGNAL(s, handler) do { \
sa.sa_handler = handler; \
- if (sigaction(s, &sa, NULL) < 0) { \
- syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \
- exit(1); \
- } \
- }
+ if (sigaction(s, &sa, NULL) < 0) \
+ fatal("Couldn't establish signal handler (%d): %m", s); \
+ } while (0)
sa.sa_mask = mask;
sa.sa_flags = 0;
signal(SIGPIPE, SIG_IGN);
waiting = 0;
- sigprocmask(SIG_BLOCK, &mask, NULL);
/*
* If we're doing dial-on-demand, set up the interface now.
/*
* Open the loopback channel and set it up to be the ppp interface.
*/
- open_ppp_loopback();
+ fd_loop = open_ppp_loopback();
syslog(LOG_INFO, "Using interface ppp%d", ifunit);
- (void) sprintf(ifname, "ppp%d", ifunit);
+ slprintf(ifname, sizeof(ifname), "ppp%d", ifunit);
script_setenv("IFNAME", ifname);
create_pidfile(); /* write pid to file */
/*
* Don't do anything until we see some activity.
*/
- phase = PHASE_DORMANT;
kill_link = 0;
+ phase = PHASE_DORMANT;
demand_unblock();
+ add_fd(fd_loop);
for (;;) {
- if (setjmp(sigjmp) == 0) {
- waiting = 1;
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
- wait_loop_output(timeleft(&timo));
+ if (sigsetjmp(sigjmp, 1) == 0) {
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+ if (kill_link) {
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ } else {
+ waiting = 1;
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ wait_input(timeleft(&timo));
+ }
}
- sigprocmask(SIG_BLOCK, &mask, NULL);
waiting = 0;
calltimeout();
if (kill_link) {
break;
reap_kids();
}
- if (kill_link)
+ remove_fd(fd_loop);
+ if (kill_link && !persist)
break;
/*
* Now we want to bring up the link.
*/
demand_block();
- syslog(LOG_INFO, "Starting link");
+ info("Starting link");
}
/*
*/
hungup = 0;
kill_link = 0;
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
for (;;) {
/* If the user specified the device name, become the
user before opening it. */
if (ttyfd >= 0)
break;
if (errno != EINTR)
- syslog(LOG_ERR, "Failed to open %s: %m", devnam);
+ error("Failed to open %s: %m", devnam);
if (!persist || errno != EINTR)
goto fail;
}
- sigprocmask(SIG_BLOCK, &mask, NULL);
if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1
|| fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0)
- syslog(LOG_WARNING,
- "Couldn't reset non-blocking mode on device: %m");
+ warn("Couldn't reset non-blocking mode on device: %m");
/*
* 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);
+ warn("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));
+ MAINDEBUG(("Connecting with <%s>", connector));
if (!default_device && modem) {
hangup_modem(ttyfd); /* in case modem is off hook */
set_up_tty(ttyfd, 1);
if (device_script(connector, ttyfd, ttyfd) < 0) {
- syslog(LOG_ERR, "Connect script failed");
+ error("Connect script failed");
goto fail;
}
- syslog(LOG_INFO, "Serial connection established.");
+ info("Serial connection established.");
sleep(1); /* give it time to set up its terminal */
}
/* reopen tty if necessary to wait for carrier */
if (connector == NULL && modem) {
for (;;) {
- if (!devnam_info.priv)
- seteuid(uid);
- i = open(devnam, O_RDWR);
- if (!devnam_info.priv)
- seteuid(0);
- if (i >= 0)
+ if ((i = open(devnam, O_RDWR)) >= 0)
break;
if (errno != EINTR)
- syslog(LOG_ERR, "Failed to reopen %s: %m", devnam);
+ error("Failed to reopen %s: %m", devnam);
if (!persist || errno != EINTR || hungup || kill_link)
goto fail;
}
/* run welcome script, if any */
if (welcomer && welcomer[0]) {
if (device_script(welcomer, ttyfd, ttyfd) < 0)
- syslog(LOG_WARNING, "Welcome script failed");
+ warn("Welcome script failed");
}
/* set up the serial device as a ppp interface */
- establish_ppp(ttyfd);
+ fd_ppp = establish_ppp(ttyfd);
if (!demand) {
- syslog(LOG_INFO, "Using interface ppp%d", ifunit);
- (void) sprintf(ifname, "ppp%d", ifunit);
+ info("Using interface ppp%d", ifunit);
+ slprintf(ifname, sizeof(ifname), "ppp%d", ifunit);
script_setenv("IFNAME", ifname);
create_pidfile(); /* write pid to file */
* Start opening the connection and wait for
* incoming events (reply, timeout, etc.).
*/
- syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam);
+ notice("Connect: %s <--> %s", ifname, devnam);
lcp_lowerup(0);
lcp_open(0); /* Start protocol */
open_ccp_flag = 0;
+ add_fd(fd_ppp);
for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) {
- if (setjmp(sigjmp) == 0) {
- waiting = 1;
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
- wait_input(timeleft(&timo));
+ if (sigsetjmp(sigjmp, 1) == 0) {
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+ if (kill_link || open_ccp_flag) {
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ } else {
+ waiting = 1;
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ wait_input(timeleft(&timo));
+ }
}
- sigprocmask(SIG_BLOCK, &mask, NULL);
waiting = 0;
calltimeout();
if (kill_link) {
* the ppp unit back to the loopback. Set the
* real serial device back to its normal mode of operation.
*/
+ remove_fd(fd_ppp);
clean_check();
if (demand)
restore_loop();
if (disconnector && !hungup) {
set_up_tty(ttyfd, 1);
if (device_script(disconnector, ttyfd, ttyfd) < 0) {
- syslog(LOG_WARNING, "disconnect script failed");
+ warn("disconnect script failed");
} else {
- syslog(LOG_INFO, "Serial link disconnected.");
+ info("Serial link disconnected.");
}
}
if (!demand) {
if (pidfilename[0] != 0
&& unlink(pidfilename) < 0 && errno != ENOENT)
- syslog(LOG_WARNING, "unable to delete pid file: %m");
+ warn("unable to delete pid file: %m");
pidfilename[0] = 0;
}
if (!persist)
break;
+ kill_link = 0;
if (demand)
demand_discard();
if (holdoff > 0 && need_holdoff) {
phase = PHASE_HOLDOFF;
TIMEOUT(holdoff_end, NULL, holdoff);
do {
- if (setjmp(sigjmp) == 0) {
- waiting = 1;
- sigprocmask(SIG_UNBLOCK, &mask, NULL);
- wait_time(timeleft(&timo));
+ if (sigsetjmp(sigjmp, 1) == 0) {
+ sigprocmask(SIG_BLOCK, &mask, NULL);
+ if (kill_link) {
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ } else {
+ waiting = 1;
+ sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ wait_input(timeleft(&timo));
+ }
}
- sigprocmask(SIG_BLOCK, &mask, NULL);
waiting = 0;
calltimeout();
if (kill_link) {
die(1);
}
detached = 1;
+ log_to_stderr = 0;
pid = getpid();
/* update pid file if it has been written already */
if (pidfilename[0])
FILE *pidfile;
char numbuf[16];
- (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
+ slprintf(pidfilename, sizeof(pidfilename), "%s%s.pid",
+ _PATH_VARRUN, ifname);
if ((pidfile = fopen(pidfilename, "w")) != NULL) {
fprintf(pidfile, "%d\n", pid);
(void) fclose(pidfile);
} else {
- syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename);
+ error("Failed to create pid file %s: %m", pidfilename);
pidfilename[0] = 0;
}
- sprintf(numbuf, "%d", pid);
+ slprintf(numbuf, sizeof(numbuf), "%d", pid);
script_setenv("PPPD_PID", numbuf);
}
return;
if (len == 0) {
- syslog(LOG_NOTICE, "Modem hangup");
+ notice("Modem hangup");
hungup = 1;
lcp_lowerdown(0); /* serial link is no longer available */
link_terminated(0);
}
if (debug /*&& (debugflags & DBG_INPACKET)*/)
- log_packet(p, len, "rcvd ", LOG_DEBUG);
+ dbglog("rcvd %P", p, len);
if (len < PPP_HDRLEN) {
- MAINDEBUG((LOG_INFO, "io(): Received short packet."));
+ MAINDEBUG(("io(): Received short packet."));
return;
}
* Toss all non-LCP packets unless LCP is OPEN.
*/
if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
- MAINDEBUG((LOG_INFO,
- "get_input: Received non-LCP packet when LCP not open."));
+ MAINDEBUG(("get_input: Received non-LCP packet when LCP not open."));
return;
}
if (phase <= PHASE_AUTHENTICATE
&& !(protocol == PPP_LCP || protocol == PPP_LQR
|| protocol == PPP_PAP || protocol == PPP_CHAP)) {
- MAINDEBUG((LOG_INFO, "get_input: discarding proto 0x%x in phase %d",
+ MAINDEBUG(("get_input: discarding proto 0x%x in phase %d",
protocol, phase));
return;
}
}
if (debug)
- syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol);
+ warn("Unsupported protocol (0x%x) received", protocol);
lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
}
close_tty();
if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT)
- syslog(LOG_WARNING, "unable to delete pid file: %m");
+ warn("unable to delete pid file: %m");
pidfilename[0] = 0;
if (locked)
{
struct callout *newp, *p, **pp;
- MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.",
- (long) func, (long) arg, time));
+ MAINDEBUG(("Timeout %p:%p in %d seconds.", func, arg, time));
/*
* Allocate timeout.
*/
- if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) {
- syslog(LOG_ERR, "Out of memory in timeout()!");
- die(1);
- }
+ if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL)
+ fatal("Out of memory in timeout()!");
newp->c_arg = arg;
newp->c_func = func;
gettimeofday(&timenow, NULL);
{
struct callout **copp, *freep;
- MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg));
+ MAINDEBUG(("Untimeout %p:%p.", func, arg));
/*
* Find first matching timeout and remove it from the list.
while (callout != NULL) {
p = callout;
- if (gettimeofday(&timenow, NULL) < 0) {
- syslog(LOG_ERR, "Failed to get time of day: %m");
- die(1);
- }
+ if (gettimeofday(&timenow, NULL) < 0)
+ fatal("Failed to get time of day: %m");
if (!(p->c_time.tv_sec < timenow.tv_sec
|| (p->c_time.tv_sec == timenow.tv_sec
&& p->c_time.tv_usec <= timenow.tv_usec)))
hup(sig)
int sig;
{
- syslog(LOG_INFO, "Hangup (SIGHUP)");
+ info("Hangup (SIGHUP)");
kill_link = 1;
if (conn_running)
/* Send the signal to the [dis]connector process(es) also */
kill_my_pg(sig);
if (waiting)
- longjmp(sigjmp, 1);
+ siglongjmp(sigjmp, 1);
}
term(sig)
int sig;
{
- syslog(LOG_INFO, "Terminating on signal %d.", sig);
+ info("Terminating on signal %d.", sig);
persist = 0; /* don't try to restart */
kill_link = 1;
if (conn_running)
/* Send the signal to the [dis]connector process(es) also */
kill_my_pg(sig);
if (waiting)
- longjmp(sigjmp, 1);
+ siglongjmp(sigjmp, 1);
}
int sig;
{
if (waiting)
- longjmp(sigjmp, 1);
+ siglongjmp(sigjmp, 1);
}
{
open_ccp_flag = 1;
if (waiting)
- longjmp(sigjmp, 1);
+ siglongjmp(sigjmp, 1);
}
if (crashed)
_exit(127);
crashed = 1;
- syslog(LOG_ERR, "Fatal signal %d", sig);
+ error("Fatal signal %d", sig);
if (conn_running)
kill_my_pg(SIGTERM);
die(1);
if (pid < 0) {
conn_running = 0;
- syslog(LOG_ERR, "Failed to create child process: %m");
- die(1);
+ fatal("Failed to create child process: %m");
}
if (pid == 0) {
}
}
setuid(uid);
+ if (getuid() != uid) {
+ error("setuid failed");
+ exit(1);
+ }
setgid(getgid());
execl("/bin/sh", "sh", "-c", program, (char *)0);
- syslog(LOG_ERR, "could not exec /bin/sh: %m");
- _exit(99);
+ error("could not exec /bin/sh: %m");
+ exit(99);
/* NOTREACHED */
}
while (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
continue;
- syslog(LOG_ERR, "error waiting for (dis)connection process: %m");
- die(1);
+ fatal("error waiting for (dis)connection process: %m");
}
conn_running = 0;
if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode)
|| (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) {
if (must_exist || errno != ENOENT)
- syslog(LOG_WARNING, "Can't execute %s: %m", prog);
+ warn("Can't execute %s: %m", prog);
return 0;
}
pid = fork();
- if (pid == -1) {
- syslog(LOG_ERR, "Failed to create child process for %s: %m", prog);
- die(1);
- }
+ if (pid == -1)
+ fatal("Failed to create child process for %s: %m", prog);
if (pid == 0) {
int new_fd;
#ifdef BSD
/* Force the priority back to zero if pppd is running higher. */
if (setpriority (PRIO_PROCESS, 0, 0) < 0)
- syslog (LOG_WARNING, "can't reset priority to 0: %m");
+ warn("can't reset priority to 0: %m");
#endif
/* SysV recommends a second fork at this point. */
/* run the program */
execve(prog, args, script_env);
- if (must_exist || errno != ENOENT) {
- int i;
- syslog(LOG_WARNING, "Can't execute %s: %m", prog);
- for (i = 0; args[i]; ++i)
- syslog(LOG_DEBUG, "args[%d] = '%s'", i, args[i]);
- for (i = 0; script_env[i]; ++i)
- syslog(LOG_DEBUG, "env[%d] = '%s'", i, script_env[i]);
- }
+ if (must_exist || errno != ENOENT)
+ warn("Can't execute %s: %m", prog);
_exit(-1);
}
if (debug)
- syslog(LOG_DEBUG, "Script %s started; pid = %d", prog, pid);
+ dbglog("Script %s started; pid = %d", prog, pid);
++n_children;
chp = (struct subprocess *) malloc(sizeof(struct subprocess));
if (chp == NULL) {
- syslog(LOG_WARNING, "losing track of %s process", prog);
+ warn("losing track of %s process", prog);
} else {
chp->pid = pid;
chp->prog = prog;
if (chp->pid == pid)
break;
if (debug)
- syslog(LOG_DEBUG, "process %d (%s) finished, status = 0x%x",
+ dbglog("process %d (%s) finished, status = 0x%x",
pid, (chp? chp->prog: "??"), status);
if (WIFSIGNALED(status)) {
- syslog(LOG_WARNING,
- "Child process %s (pid %d) terminated with signal %d",
- (chp? chp->prog: "??"), pid, WTERMSIG(status));
+ warn("Child process %s (pid %d) terminated with signal %d",
+ (chp? chp->prog: "??"), pid, WTERMSIG(status));
}
if (chp && chp->done)
(*chp->done)(chp->arg);
}
if (pid == -1 && errno != ECHILD)
- syslog(LOG_ERR, "Error waiting for child process: %m");
+ error("Error waiting for child process: %m");
}
char *prefix;
int level;
{
- strcpy(line, prefix);
+ strlcpy(line, sizeof(line), prefix);
linep = line + strlen(line);
format_packet(p, len, pr_log, NULL);
if (linep != line)
fmt = va_arg(pvar, char *);
#endif
- n = vfmtmsg(buf, sizeof(buf), fmt, pvar);
+ n = vslprintf(buf, sizeof(buf), fmt, pvar);
va_end(pvar);
if (linep + n + 1 > line + sizeof(line)) {
syslog(LOG_DEBUG, "%s", line);
linep = line;
}
- strcpy(linep, buf);
+ strlcpy(linep, line + sizeof(line) - linep, buf);
linep += n;
}
+/*
+ * vslp_printer - used in processing a %P format
+ */
+struct buffer_info {
+ char *ptr;
+ int len;
+};
+
+static void
+vslp_printer __V((void *arg, char *fmt, ...))
+{
+ int n;
+ va_list pvar;
+ struct buffer_info *bi;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ void *arg;
+ char *fmt;
+ va_start(pvar);
+ arg = va_arg(pvar, void *);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ bi = (struct buffer_info *) arg;
+ n = vslprintf(bi->ptr, bi->len, fmt, pvar);
+ va_end(pvar);
+
+ bi->ptr += n;
+ bi->len -= n;
+}
+
/*
* print_string - print a readable representation of a string using
* printer.
novm(msg)
char *msg;
{
- syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
- die(1);
+ fatal("Virtual memory exhausted allocating %s\n", msg);
}
/*
- * fmtmsg - format a message into a buffer. Like sprintf except we
+ * slprintf - 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.
+ * %r (recursive format), %m (error message), %v (visible string),
+ * %q (quoted string), %t (current time) 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, ...))
+slprintf __V((char *buf, int buflen, char *fmt, ...))
{
va_list args;
int n;
buflen = va_arg(args, int);
fmt = va_arg(args, char *);
#endif
- n = vfmtmsg(buf, buflen, fmt, args);
+ n = vslprintf(buf, buflen, fmt, args);
va_end(args);
return n;
}
/*
- * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
+ * vslprintf - like slprintf, takes a va_list instead of a list of args.
*/
#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)
int
-vfmtmsg(buf, buflen, fmt, args)
+vslprintf(buf, buflen, fmt, args)
char *buf;
int buflen;
char *fmt;
unsigned char *p;
char num[32];
time_t t;
+ u_int32_t ip;
static char hexchars[] = "0123456789abcdef";
+ struct buffer_info bufinfo;
buf0 = buf;
--buflen;
base = 8;
break;
case 'x':
+ case 'X':
val = va_arg(args, unsigned int);
base = 16;
break;
str = strerror(errno);
break;
case 'I':
- str = ip_ntoa(va_arg(args, u_int32_t));
+ ip = va_arg(args, u_int32_t);
+ ip = ntohl(ip);
+ slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff,
+ (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
+ str = num;
break;
case 'r':
f = va_arg(args, char *);
#ifndef __powerpc__
- n = vfmtmsg(buf, buflen + 1, f, va_arg(args, va_list));
+ n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list));
#else
/* On the powerpc, a va_list is an array of 1 structure */
- n = vfmtmsg(buf, buflen + 1, f, va_arg(args, void *));
+ n = vslprintf(buf, buflen + 1, f, va_arg(args, void *));
#endif
buf += n;
buflen -= n;
OUTCHAR(c);
}
continue;
+ case 'P': /* print PPP packet */
+ bufinfo.ptr = buf;
+ bufinfo.len = buflen + 1;
+ p = va_arg(args, unsigned char *);
+ n = va_arg(args, int);
+ format_packet(p, n, vslp_printer, &bufinfo);
+ buf = bufinfo.ptr;
+ buflen = bufinfo.len - 1;
+ continue;
+ case 'B':
+ p = va_arg(args, unsigned char *);
+ for (n = prec; n > 0; --n) {
+ c = *p++;
+ if (fillch == ' ')
+ OUTCHAR(' ');
+ OUTCHAR(hexchars[(c >> 4) & 0xf]);
+ OUTCHAR(hexchars[c & 0xf]);
+ }
+ continue;
default:
*buf++ = '%';
if (c != '%')
script_setenv(var, value)
char *var, *value;
{
- int vl = strlen(var);
+ size_t vl = strlen(var) + strlen(value) + 2;
int i;
char *p, *newstring;
- newstring = (char *) malloc(vl + strlen(value) + 2);
+ newstring = (char *) malloc(vl);
if (newstring == 0)
return;
- strcpy(newstring, var);
- newstring[vl] = '=';
- strcpy(newstring+vl+1, value);
+ slprintf(newstring, vl, "%s=%s", var, value);
/* check if this variable is already set */
if (script_env != 0) {
}
}
}
+
+/*
+ * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+void
+strlcpy(char *dest, size_t len, const char *src)
+{
+ if (len == 0)
+ return;
+ if (strlen(src) < len)
+ strcpy(dest, src);
+ else {
+ strncpy(dest, src, len - 1);
+ dest[len-1] = 0;
+ }
+}
+
+/*
+ * strlcat - like strcat/strncat, doesn't overflow destination buffer,
+ * always leaves destination null-terminated (for len > 0).
+ */
+void
+strlcat(char *dest, size_t len, const char *src)
+{
+ size_t dlen;
+
+ if (len == 0)
+ return;
+ dlen = strlen(dest);
+ if (dlen < len - 1)
+ strlcpy(dest + dlen, len - dlen, src);
+}
+
+/*
+ * logit - does the hard work for fatal et al.
+ */
+static void
+logit(level, fmt, args)
+ int level;
+ char *fmt;
+ va_list args;
+{
+ int n;
+ char buf[256];
+ static char nl = '\n';
+
+ n = vslprintf(buf, sizeof(buf), fmt, args);
+ syslog(level, "%s", buf);
+ if (log_to_stderr && (level != LOG_DEBUG || debug)) {
+ if (write(2, buf, n) != n
+ || (buf[n-1] != '\n' && write(2, &nl, 1) != 1))
+ log_to_stderr = 0;
+ }
+}
+
+/*
+ * fatal - log an error message and die horribly.
+ */
+void
+fatal __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_ERR, fmt, pvar);
+ va_end(pvar);
+
+ die(1); /* as promised */
+}
+
+/*
+ * error - log an error message.
+ */
+void
+error __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_ERR, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * warn - log a warning message.
+ */
+void
+warn __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_WARNING, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * notice - log a notice-level message.
+ */
+void
+notice __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_NOTICE, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * info - log an informational message.
+ */
+void
+info __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_INFO, fmt, pvar);
+ va_end(pvar);
+}
+
+/*
+ * dbglog - log a debug message.
+ */
+void
+dbglog __V((char *fmt, ...))
+{
+ va_list pvar;
+
+#if __STDC__
+ va_start(pvar, fmt);
+#else
+ char *fmt;
+ va_start(pvar);
+ fmt = va_arg(pvar, char *);
+#endif
+
+ logit(LOG_DEBUG, fmt, pvar);
+ va_end(pvar);
+}