5. Add the necessary authentication options to your pppd
configuration (i.e. PAP/CHAP information). If you wish to
- maintain seperate configurations for different devices you may
+ maintain separate configurations for different devices you may
place configuration options in device-specific configuration
files: /etc/ppp/options.devname (devname=ttyS0, ttyS1, eth0, eth1
or any other valid device name).
void unalarm (void);
void init (void);
void set_tty_parameters (void);
-void echo_stderr (int);
+int echo_stderr (int);
void break_sequence (void);
void terminate (int status);
void do_file (char *chat_file);
int write_char (int c);
int put_char (int c);
int get_char (void);
-void chat_send (register char *s);
+int chat_send (register char *s);
char *character (int c);
void chat_expect (register char *s);
char *clean (register char *s, int sending);
/*
* process the reply string
*/
-void chat_send (register char *s)
+int chat_send (register char *s)
{
char file_data[STR_LEN];
+ int len, ret = 0;
if (say_next) {
say_next = 0;
s = clean(s, 1);
- write(2, s, strlen(s));
+ len = strlen(s);
+ ret = write(2, s, len) != len;
free(s);
- return;
+ return ret;
}
if (hup_next) {
signal(SIGHUP, SIG_IGN);
else
signal(SIGHUP, sighup);
- return;
+ return 0;
}
if (echo_next) {
echo_next = 0;
echo = (strcmp(s, "ON") == 0);
- return;
+ return 0;
}
if (abort_next) {
if (verbose)
msgf("abort on (%v)", s1);
- return;
+ return 0;
}
if (clear_abort_next) {
free(s1);
if (pack)
pack_array(abort_string,old_max);
- return;
+ return 0;
}
if (report_next) {
if (verbose)
msgf("report (%v)", s1);
- return;
+ return 0;
}
if (clear_report_next) {
if (pack)
pack_array(report_string,old_max);
- return;
+ return 0;
}
if (timeout_next) {
if (verbose)
msgf("timeout set to %d seconds", timeout);
- return;
+ return 0;
}
/*
if (!put_string(s))
fatal(1, "Failed");
+
+ return 0;
}
int get_char(void)
* When called with -1, a '\n' character is generated when
* the cursor is not at the beginning of a line.
*/
-void echo_stderr(int n)
+int echo_stderr(int n)
{
static int need_lf;
char *s;
+ int len, ret = 0;
switch (n) {
case '\r': /* ignore '\r' */
break;
/* fall through */
case '\n':
- write(2, "\n", 1);
+ ret = write(2, "\n", 1) != 1;
need_lf = 0;
break;
default:
s = character(n);
- write(2, s, strlen(s));
+ len = strlen(s);
+ ret = write(2, s, len) != len;
need_lf = 1;
break;
}
+ return ret;
}
/*
while ( ! alarmed && (c = get_char()) >= 0) {
int n, abort_len, report_len;
- if (echo)
- echo_stderr(c);
+ if (echo) {
+ if (echo_stderr(c) != 0) {
+ fatal(2, "Could not write to stderr, %m");
+ }
+ }
if (verbose && c == '\n') {
if (s == logged)
msgf(""); /* blank line */
pppd_LIBS =
if LINUX
-pppd_SOURCES += sys-linux.c
+pppd_SOURCES += sys-linux.c termios_linux.h
pppd_LIBS += $(CRYPT_LIBS) $(UTIL_LIBS)
endif
detach(void)
{
int pid;
+ int ret;
char numbuf[16];
int pipefd[2];
exit(0); /* parent dies */
}
setsid();
- chdir("/");
+ ret = chdir("/");
+ if (ret != 0) {
+ fatal("Could not change directory to '/', %m");
+ }
dup2(fd_devnull, 0);
dup2(fd_devnull, 1);
dup2(fd_devnull, 2);
/* Send the signal to the [dis]connector process(es) also */
kill_my_pg(sig);
notify(sigreceived, sig);
- if (waiting)
+ if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+ }
}
/* Send the signal to the [dis]connector process(es) also */
kill_my_pg(sig);
notify(sigreceived, sig);
- if (waiting)
+ if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+ }
}
chld(int sig)
{
got_sigchld = 1;
- if (waiting)
+ if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+ }
}
open_ccp(int sig)
{
got_sigusr2 = 1;
- if (waiting)
+ if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+ }
}
int pid;
int status = -1;
int errfd;
+ int ret;
if (log_to_fd >= 0)
errfd = log_to_fd;
}
/* here we are executing in the child */
-
- setgid(getgid());
- setuid(uid);
- if (getuid() != uid) {
- fprintf(stderr, "pppd: setuid failed\n");
- exit(1);
+ ret = setgid(getgid());
+ if (ret != 0) {
+ perror("pppd: setgid failed\n");
+ exit(1);
+ }
+ ret = setuid(uid);
+ if (ret != 0 || getuid() != uid) {
+ perror("pppd: setuid failed\n");
+ exit(1);
}
update_system_environment();
execl("/bin/sh", "sh", "-c", program, (char *)0);
pid_t
run_program(char *prog, char **args, int must_exist, void (*done)(void *), void *arg, int wait)
{
- int pid, status;
+ int pid, status, ret;
struct stat sbuf;
/*
/* Leave the current location */
(void) setsid(); /* No controlling tty. */
(void) umask (S_IRWXG|S_IRWXO);
- (void) chdir ("/"); /* no current directory. */
- setuid(0); /* set real UID = root */
- setgid(getegid());
+ ret = chdir ("/"); /* no current directory. */
+ if (ret != 0) {
+ fatal("Failed to change directory to '/', %m");
+ }
+ ret = setuid(0); /* set real UID = root */
+ if (ret != 0) {
+ fatal("Failed to set uid, %m");
+ }
+ ret = setgid(getegid());
+ if (ret != 0) {
+ fatal("failed to set gid, %m");
+ }
#ifdef BSD
/* Force the priority back to zero if pppd is running higher. */
{
int p[2];
pid_t kid;
- int readgood, wstat;
+ int readgood, wstat, ret;
ssize_t red;
if (promptprog_refused || promptprog[0] == 0 || access(promptprog, X_OK) < 0)
sys_close();
closelog();
close(p[0]);
- seteuid(getuid());
- setegid(getgid());
+ ret = seteuid(getuid());
+ if (ret != 0) {
+ warn("Couldn't set effective user id");
+ }
+ ret = setegid(getgid());
+ if (ret != 0) {
+ warn("Couldn't set effective user id");
+ }
argv[0] = promptprog;
argv[1] = user;
argv[2] = remote_name;
}
struct channel pppoa_channel = {
- options: pppoa_options,
- process_extra_options: NULL,
- check_options: NULL,
- connect: &connect_pppoatm,
- disconnect: &disconnect_pppoatm,
- establish_ppp: &generic_establish_ppp,
- disestablish_ppp: &generic_disestablish_ppp,
- send_config: NULL,
- recv_config: NULL,
- close: NULL,
- cleanup: NULL
+ .options = pppoa_options,
+ .process_extra_options = NULL,
+ .check_options = NULL,
+ .connect = &connect_pppoatm,
+ .disconnect = &disconnect_pppoatm,
+ .establish_ppp = &generic_establish_ppp,
+ .disestablish_ppp = &generic_disestablish_ppp,
+ .send_config = NULL,
+ .recv_config = NULL,
+ .close = NULL,
+ .cleanup = NULL
};
size_t elen = strlen(msg);
err.type = htons(TAG_GENERIC_ERROR);
err.length = htons(elen);
- strcpy(err.payload, msg);
+ strcpy((char*) err.payload, msg);
memcpy(cursor, &err, elen + TAG_HDR_SIZE);
cursor += elen + TAG_HDR_SIZE;
plen += elen + TAG_HDR_SIZE;
char buffer[128];
struct sockaddr pppol2tp;
} s;
- int len = sizeof(s);
+ socklen_t len = sizeof(s);
char **a;
int tmp;
- int tmp_len = sizeof(tmp);
+ socklen_t tmp_len = sizeof(tmp);
if (device_got_set)
return 0;
int on = 1;
int fd;
char reorderto[16];
- char tid[8];
- char sid[8];
+ char tid[12];
+ char sid[12];
if (pppol2tp_ifname[0]) {
struct ifreq ifr;
sprintf(&reorderto[0], "%d ", pppol2tp_reorder_timeout);
tid[0] = '\0';
if (pppol2tp_tunnel_id > 0)
- sprintf(&tid[0], "%hu ", pppol2tp_tunnel_id);
+ sprintf(&tid[0], "%u ", pppol2tp_tunnel_id);
sid[0] = '\0';
if (pppol2tp_session_id > 0)
- sprintf(&sid[0], "%hu ", pppol2tp_session_id);
+ sprintf(&sid[0], "%u ", pppol2tp_session_id);
dbglog("PPPoL2TP options: %s%s%s%s%s%s%s%s%sdebugmask %d",
pppol2tp_recv_seq ? "recvseq " : "",
}
struct channel pppol2tp_channel = {
- options: pppol2tp_options,
- process_extra_options: NULL,
- check_options: &pppol2tp_check_options,
- connect: &connect_pppol2tp,
- disconnect: &disconnect_pppol2tp,
- establish_ppp: &generic_establish_ppp,
- disestablish_ppp: &generic_disestablish_ppp,
- send_config: &send_config_pppol2tp,
- recv_config: &recv_config_pppol2tp,
- close: NULL,
- cleanup: NULL
+ .options = pppol2tp_options,
+ .process_extra_options = NULL,
+ .check_options = &pppol2tp_check_options,
+ .connect = &connect_pppol2tp,
+ .disconnect = &disconnect_pppol2tp,
+ .establish_ppp = &generic_establish_ppp,
+ .disestablish_ppp = &generic_disestablish_ppp,
+ .send_config = &send_config_pppol2tp,
+ .recv_config = &recv_config_pppol2tp,
+ .close = NULL,
+ .cleanup = NULL
};
vp->strvalue[len] = '\0';
vp->lvalue = len;
} else {
- strncpy (vp->strvalue, (char *) pval, AUTH_STRING_LEN);
+ strncpy ((char*) vp->strvalue, (char *) pval, AUTH_STRING_LEN);
vp->lvalue = strlen((char *) pval);
}
DICT_ATTR *attr;
VALUE_PAIR *vp;
VALUE_PAIR *pair;
- unsigned char hex[3]; /* For hex string conversion. */
+ char hex[3]; /* For hex string conversion. */
char buffer[512];
/*
{
case PW_TYPE_STRING:
- strcpy (pair->strvalue, valstr);
+ strcpy ((char*) pair->strvalue, valstr);
pair->lvalue = strlen(valstr);
break;
}
else
{
- strncat(value, ptr, 1);
+ strncat(value, (char*) ptr, 1);
lv--;
if (lv < 0) break;
}
{
FILE *sf;
int tries = 1;
- int seq_nbr, pos;
+ int seq_nbr, pos, ret;
char *seqfile = rc_conf_str("seqfile");
if ((sf = fopen(seqfile, "a+")) == NULL)
}
rewind(sf);
- ftruncate(fileno(sf),0);
+ ret = ftruncate(fileno(sf),0);
+ if (ret != 0) {
+ error("rc_get_seqnbr: couldn't truncate sequence file, %m");
+ }
fprintf(sf,"%d\n", (seq_nbr+1) & UCHAR_MAX);
fflush(sf); /* fflush because a process may read it between the do_unlock and fclose */
if (result == 0)
{
memset (buffer, '\0', sizeof (buffer));
- memset (secret, '\0', sizeof (secret));
error("rc_find_server: couldn't find RADIUS server %s in %s",
server_name, rc_conf_str("servers"));
return (-1);
#include "pppd.h"
#include "radiusclient.h"
#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
extern void (*radius_attributes_hook)(VALUE_PAIR *);
static void print_attributes(VALUE_PAIR *);
char name[2048];
char value[2048];
int cnt = 0;
+ mode_t old_umask;
slprintf(fname, sizeof(fname), "/var/run/radattr.%s", ifname);
+ old_umask = umask(077);
fp = fopen(fname, "w");
+ umask(old_umask);
if (!fp) {
warn("radattr plugin: Could not open %s for writing: %m", fname);
return;
* 1 -- we are ALWAYS willing to supply a secret. :-)
* %DESCRIPTION:
* Tells pppd that we will try to authenticate the peer, and not to
-* worry about looking in /etc/ppp/*-secrets
+* worry about looking in *-secrets file(s)
***********************************************************************/
static int
radius_secret_check(void)
break;
case PW_FILTER_ID:
/* packet filter, will be handled via ip-(up|down) script */
- script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1);
+ script_setenv("RADIUS_FILTER_ID", (char*) vp->strvalue, 1);
break;
case PW_FRAMED_ROUTE:
/* route, will be handled via ip-(up|down) script */
- script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1);
+ script_setenv("RADIUS_FRAMED_ROUTE", (char*) vp->strvalue, 1);
break;
case PW_IDLE_TIMEOUT:
/* idle parameter */
#ifdef CHAPMS
switch (vp->attribute) {
case PW_MS_CHAP2_SUCCESS:
- if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
+ if ((vp->lvalue != 43) || strncmp((char*) vp->strvalue + 1, "S=", 2)) {
slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet");
return -1;
}
if (message != NULL)
- strlcpy(message, vp->strvalue + 1, message_space);
+ strlcpy(message, (char*) vp->strvalue + 1, message_space);
ms_chap2_success = 1;
break;
memcpy ((char *) passbuf, vp->strvalue, (size_t) length);
secretlen = strlen (secret);
- vector = (char *)auth->vector;
+ vector = auth->vector;
for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN) {
/* Calculate the MD5 digest*/
strcpy ((char *) md5buf, secret);
AUTH_HDR *auth, *recv_auth;
UINT4 auth_ipaddr;
char *server_name; /* Name of server to query */
- int salen;
+ socklen_t salen;
int result;
int total_length;
- int length;
+ socklen_t length;
int retry_max;
int secretlen;
char secret[MAX_SECRET_LENGTH + 1];
{
if (rc_find_server (server_name, &auth_ipaddr, secret) != 0)
{
+ memset (secret, '\0', sizeof (secret));
return (ERROR_RC);
}
}
memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
secretlen = strlen (secret);
memcpy ((char *) auth + total_length, secret, secretlen);
- rc_md5_calc (vector, (char *) auth, total_length + secretlen);
+ rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
}
else
{
if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE)))
{
- strcat(msg, vp->strvalue);
+ strcat(msg, (char*) vp->strvalue);
strcat(msg, "\n");
vp = vp->next;
}
memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN);
memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
memcpy ((char *) auth + totallen, secret, secretlen);
- rc_md5_calc (calc_digest, (char *) auth, totallen + secretlen);
+ rc_md5_calc (calc_digest, (unsigned char *) auth, totallen + secretlen);
#ifdef DIGEST_DEBUG
{
snprintf(buf, sizeof(buf), "%08lX%04X%02hX",
(unsigned long int) time (NULL),
(unsigned int) getpid (),
- cnt & 0xFF);
+ (unsigned short) (cnt & 0xFF));
cnt++;
return buf;
}
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-size_t strhex_to_str(char *p, size_t len, const char *strhex)
+size_t strhex_to_str(unsigned char *p, size_t len, const char *strhex)
{
size_t i;
size_t num_chars = 0;
if (forkret == 0) {
/* child process */
uid_t uid;
+ gid_t gid;
close(child_out[0]);
close(child_in[1]);
/* run winbind as the user that invoked pppd */
- setgid(getgid());
+ gid = getgid();
+ if (setgid(gid) == -1 || getgid() != gid) {
+ fatal("pppd/winbind: could not setgid to %d: %m", gid);
+ }
uid = getuid();
- if (setuid(uid) == -1 || getuid() != uid)
+ if (setuid(uid) == -1 || getuid() != uid) {
fatal("pppd/winbind: could not setuid to %d: %m", uid);
+ }
execl("/bin/sh", "sh", "-c", ntlm_auth, NULL);
fatal("pppd/winbind: could not exec /bin/sh: %m");
}
char *domain;
char *username;
char *p;
- char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
+ unsigned char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
/* The first byte of each of these strings contains their length */
challenge_len = *challenge++;
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
-#include <termios.h>
#include <unistd.h>
/* This is in netdevice.h. However, this compile will fail miserably if
#if !defined(__GLIBC__) || __GLIBC__ >= 2
#include <asm/types.h> /* glibc 2 conflicts with linux/types.h */
-#include <asm/ioctls.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <net/route.h>
#include <sys/locks.h>
#endif
-#ifndef BOTHER
-#define BOTHER 0010000
-#endif
-struct termios2 {
- unsigned int c_iflag;
- unsigned int c_oflag;
- unsigned int c_cflag;
- unsigned int c_lflag;
- unsigned char c_line;
- unsigned char c_cc[19];
- unsigned int c_ispeed;
- unsigned int c_ospeed;
-};
+/*
+ * Instead of system header file <termios.h> use local "termios_linux.h" header
+ * file as it provides additional support for arbitrary baud rates via BOTHER.
+ */
+#include "termios_linux.h"
#ifdef INET6
#ifndef _LINUX_IN6_H
cfsetospeed (&tios, speed);
cfsetispeed (&tios, speed);
speed = cfgetospeed(&tios);
+ baud_rate = baud_rate_of(speed);
+ } else {
+#ifdef BOTHER
+ tios.c_cflag &= ~CBAUD;
+ tios.c_cflag |= BOTHER;
+ tios.c_ospeed = inspeed;
+#ifdef IBSHIFT
+ /* B0 sets input baudrate to the output baudrate */
+ tios.c_cflag &= ~(CBAUD << IBSHIFT);
+ tios.c_cflag |= B0 << IBSHIFT;
+ tios.c_ispeed = inspeed;
+#endif
+ baud_rate = inspeed;
+#else
+ baud_rate = 0;
+#endif
}
- baud_rate = baud_rate_of(speed);
}
else {
speed = cfgetospeed(&tios);
baud_rate = baud_rate_of(speed);
- }
-
- while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
- if (errno != EINTR)
- fatal("tcsetattr: %m (line %d)", __LINE__);
- restore_term = 1;
-
-/* Most Linux architectures and drivers support arbitrary baud rate values via BOTHER */
-#ifdef TCGETS2
- if (!baud_rate) {
- struct termios2 tios2;
- if (ioctl(tty_fd, TCGETS2, &tios2) == 0) {
- if (inspeed) {
- tios2.c_cflag &= ~CBAUD;
- tios2.c_cflag |= BOTHER;
- tios2.c_ispeed = inspeed;
- tios2.c_ospeed = inspeed;
-#ifdef TCSETS2
- if (ioctl(tty_fd, TCSETS2, &tios2) == 0)
- baud_rate = inspeed;
+#ifdef BOTHER
+ if (!baud_rate)
+ baud_rate = tios.c_ospeed;
#endif
- } else {
- if ((tios2.c_cflag & CBAUD) == BOTHER && tios2.c_ospeed)
- baud_rate = tios2.c_ospeed;
- }
- }
}
-#endif
/*
* We can't proceed if the serial port baud rate is unknown,
else
fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
}
+
+ while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
+ if (errno != EINTR)
+ fatal("tcsetattr: %m (line %d)", __LINE__);
+ restore_term = 1;
}
/********************************************************************
int
get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
{
- int i, mfd, sfd = -1;
+ int i, mfd, ret, sfd = -1;
char pty_name[16];
struct termios tios;
pty_name[5] = 't';
sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
if (sfd >= 0) {
- fchown(sfd, uid, -1);
- fchmod(sfd, S_IRUSR | S_IWUSR);
+ ret = fchown(sfd, uid, -1);
+ if (ret != 0) {
+ warn("Couldn't change ownership of %s, %m", pty_name);
+ }
+ ret = fchmod(sfd, S_IRUSR | S_IWUSR);
+ if (ret != 0) {
+ warn("Couldn't change permissions of %s, %m", pty_name);
+ }
break;
}
close(mfd);
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-4-Clause OR BSD-3-Clause OR BSD-2-Clause */
+/*
+ * termios fuctions to support arbitrary baudrates (on Linux)
+ *
+ * Copyright (c) 2021 Pali Rohár <pali@kernel.org>
+ * Copyright (c) 2021 Marek Behún <kabel@kernel.org>
+ */
+
+#ifndef _TERMIOS_LINUX_H_
+#define _TERMIOS_LINUX_H_
+
+/*
+ * We need to use raw TCGETS2/TCSETS2 or TCGETS/TCSETS ioctls with the BOTHER
+ * flag in struct termios2/termios, defined in Linux headers <asm/ioctls.h>
+ * and <asm/termbits.h>. Since these headers conflict with glibc's header file
+ * <termios.h>, it is not possible to use libc's termios functions and we need
+ * to reimplement them via ioctl() calls.
+ *
+ * An arbitrary baudrate is supported when the macro BOTHER is defined. The
+ * baudrate value itself is then stored into the c_ospeed and c_ispeed members.
+ * If ioctls TCGETS2/TCSETS2 are defined and supported then these fields are
+ * present in struct termios2, otherwise these fields are present in struct
+ * termios.
+ *
+ * Note that the Bnnn constants from <termios.h> need not be compatible with
+ * Bnnn constants from <asm/termbits.h>.
+ */
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(BOTHER) && defined(TCGETS2)
+#define termios termios2
+#endif
+
+static inline int tcgetattr(int fd, struct termios *t)
+{
+#if defined(BOTHER) && defined(TCGETS2)
+ return ioctl(fd, TCGETS2, t);
+#else
+ return ioctl(fd, TCGETS, t);
+#endif
+}
+
+static inline int tcsetattr(int fd, int a, const struct termios *t)
+{
+ int cmd;
+
+ switch (a) {
+#if defined(BOTHER) && defined(TCGETS2)
+ case TCSANOW:
+ cmd = TCSETS2;
+ break;
+ case TCSADRAIN:
+ cmd = TCSETSW2;
+ break;
+ case TCSAFLUSH:
+ cmd = TCSETSF2;
+ break;
+#else
+ case TCSANOW:
+ cmd = TCSETS;
+ break;
+ case TCSADRAIN:
+ cmd = TCSETSW;
+ break;
+ case TCSAFLUSH:
+ cmd = TCSETSF;
+ break;
+#endif
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ return ioctl(fd, cmd, t);
+}
+
+static inline int tcdrain(int fd)
+{
+ return ioctl(fd, TCSBRK, 1);
+}
+
+static inline int tcflush(int fd, int q)
+{
+ return ioctl(fd, TCFLSH, q);
+}
+
+static inline int tcsendbreak(int fd, int d)
+{
+#ifdef TCSBRKP
+ return ioctl(fd, TCSBRKP, d);
+#else
+ return ioctl(fd, TCSBRK, 0);
+#endif
+}
+
+static inline int tcflow(int fd, int a)
+{
+ return ioctl(fd, TCXONC, a);
+}
+
+static inline pid_t tcgetsid(int fd)
+{
+ pid_t sid;
+
+ if (ioctl(fd, TIOCGSID, &sid) < 0)
+ return (pid_t)-1;
+
+ return sid;
+}
+
+static inline speed_t cfgetospeed(const struct termios *t)
+{
+ return t->c_cflag & CBAUD;
+}
+
+static inline int cfsetospeed(struct termios *t, speed_t s)
+{
+ if (s & ~CBAUD) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ t->c_cflag &= ~CBAUD;
+ t->c_cflag |= s;
+
+ return 0;
+}
+
+#ifdef IBSHIFT
+static inline speed_t cfgetispeed(const struct termios *t)
+{
+ speed_t s = (t->c_cflag >> IBSHIFT) & CBAUD;
+
+ if (s == B0)
+ return cfgetospeed(t);
+ else
+ return s;
+}
+
+static inline int cfsetispeed(struct termios *t, speed_t s)
+{
+ if (s == 0)
+ s = B0;
+
+ if (s & ~CBAUD) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ t->c_cflag &= ~(CBAUD << IBSHIFT);
+ t->c_cflag |= s << IBSHIFT;
+
+ return 0;
+}
+#else /* !IBSHIFT */
+static inline speed_t cfgetispeed(const struct termios *t)
+{
+ return cfgetospeed(t);
+}
+
+static inline int cfsetispeed(struct termios *t, speed_t s)
+{
+ return cfsetospeed(t, s);
+}
+#endif /* !IBSHIFT */
+
+static inline int cfsetspeed(struct termios *t, speed_t s)
+{
+ if (cfsetospeed(t, s))
+ return -1;
+#ifdef IBSHIFT
+ if (cfsetispeed(t, s))
+ return -1;
+#endif
+
+ return 0;
+}
+
+static void cfmakeraw(struct termios *t)
+{
+ t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |
+ ICRNL | IXON);
+ t->c_oflag &= ~OPOST;
+ t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ t->c_cflag &= ~(CSIZE | PARENB);
+ t->c_cflag |= CS8;
+}
+
+#endif /* _TERMIOS_LINUX_H_ */
static int
start_charshunt(int ifd, int ofd)
{
- int cpid;
+ int cpid, ret;
cpid = safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2));
if (cpid == -1) {
log_to_fd = -1;
else if (log_to_fd >= 0)
log_to_fd = 2;
- setgid(getgid());
- setuid(uid);
- if (getuid() != uid)
- fatal("setuid failed");
+ ret = setgid(getgid());
+ if (ret != 0) {
+ fatal("setgid failed, %m");
+ }
+ ret = setuid(uid);
+ if (ret != 0 || getuid() != uid) {
+ fatal("setuid failed, %m");
+ }
charshunt(0, 1, record_file);
exit(0);
}
#else /* LOCKLIB */
char lock_buffer[12];
- int fd, pid, n;
+ int fd, pid, n, siz;
#ifdef SVR4
struct stat sbuf;
pid = getpid();
#ifndef LOCK_BINARY
+ siz = 11;
slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
- write (fd, lock_buffer, 11);
+ n = write (fd, lock_buffer, siz);
#else
- write(fd, &pid, sizeof (pid));
+ siz = sizeof (pid);
+ n = write(fd, &pid, siz);
#endif
+ if (n != siz) {
+ error("Could not write pid to lock file when locking");
+ }
close(fd);
return 0;
return -1;
#else /* LOCKLIB */
- int fd;
+ int fd, n, siz;
char lock_buffer[12];
if (lock_file[0] == 0)
}
#ifndef LOCK_BINARY
+ siz = 11;
slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
- write (fd, lock_buffer, 11);
+ n = write (fd, lock_buffer, siz);
#else
- write(fd, &pid, sizeof(pid));
+ siz = sizeof(pid);
+ n = write(fd, &pid, siz);
#endif /* LOCK_BINARY */
+ if (n != siz) {
+ error("Could not write pid to lock file when locking");
+ }
close(fd);
return 0;