summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Osterried <thomas@osterried.de>2009-01-15 23:18:36 +0000
committerThomas Osterried <thomas@osterried.de>2009-01-15 23:18:36 +0000
commit965640685239ef173cf8938c27e25f8e5a23a89a (patch)
treea1776a29add2b48b59a91599436ecdce7a9df81c
parent31fe82cdc9b84d7d3ddff5c23e4d56aa1cceb78a (diff)
Support for Unix98-pty's. Thanks to Christoph <dk2crn>.
Syslog logging. Bugfixes: buffer-length assurances; do never change char *foo = "bar".
-rw-r--r--kiss/net2kiss.84
-rw-r--r--kiss/net2kiss.c78
2 files changed, 63 insertions, 19 deletions
diff --git a/kiss/net2kiss.8 b/kiss/net2kiss.8
index 5ba3341..68538a0 100644
--- a/kiss/net2kiss.8
+++ b/kiss/net2kiss.8
@@ -11,7 +11,7 @@ into a KISS data stream via a pseudo-tty.
.SH PARAMETERS
.TP
.B ptyname
-specifies the path to the pseudo-tty.
+specifies the path to the pseudo-tty. If you use the special name "/dev/ptmx", then a Unix98-PTY pair is used; the pty name is written to stdout.
.SH OPTIONS
.TP
.B "\-i ifname"
@@ -24,7 +24,7 @@ master side and create a symlink named by -p to the slave side.
.TP
.B \-f
can be used in conjunction with -s to force the creation of the symlink
-even if the target file does already exist.
+even if the target file does already exist. *DANGEROUS*
.TP
.B \-v
Verbose output. Displays error messages during operation and decoded
diff --git a/kiss/net2kiss.c b/kiss/net2kiss.c
index 2532eff..f16d643 100644
--- a/kiss/net2kiss.c
+++ b/kiss/net2kiss.c
@@ -30,11 +30,13 @@
/*****************************************************************************/
+#include <stdio.h>
+#define __USE_XOPEN
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
-#include <stdio.h>
#include <errno.h>
+#include <syslog.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
@@ -46,6 +48,7 @@
#include <grp.h>
#include <string.h>
#include <termios.h>
+#include <limits.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -63,6 +66,9 @@ static int fdif, fdpty;
static struct ifreq ifr;
static char *progname;
static int verbose = 0;
+static int i_am_unix98_pty_master = 0; /* unix98 ptmx support */
+static char *namepts = NULL; /* name of the unix98 pts slave, which
+ * the client has to use */
/* --------------------------------------------------------------------- */
@@ -70,6 +76,8 @@ static void die(char *func)
{
fprintf(stderr, "%s: %s (%i)%s%s\n", progname, strerror(errno),
errno, func ? " in " : "", func ? func : "");
+ syslog(LOG_WARNING, "%s (%i)%s%s\n", strerror(errno),
+ errno, func ? " in " : "", func ? func : "");
exit(-1);
}
@@ -234,7 +242,9 @@ static void display_packet(unsigned char *bp, unsigned int len)
static int openpty(int *amaster, int *aslave, char *name,
struct termios *termp, struct winsize *winp)
{
- char line[] = "/dev/ptyXX";
+ char line[PATH_MAX];
+
+ strcpy(line, "/dev/ptyXX");
const char *cp1, *cp2;
int master, slave;
struct group *gr = getgrnam("tty");
@@ -400,7 +410,7 @@ static int doio(int fdif, int fdpty, char *ifaddr)
int i;
fd_set rmask, wmask;
struct sockaddr from;
- int from_len;
+ socklen_t from_len;
#define ADD_CHAR(c) \
obuf[ob_wpx] = c; \
@@ -528,7 +538,7 @@ int main(int argc, char *argv[])
struct sockaddr sa;
char *name_iface = "bc0";
char *name_pname = NULL;
- char slavename[32];
+ char slavename[PATH_MAX];
char *master_name;
struct termios termios;
int c;
@@ -573,6 +583,7 @@ int main(int argc, char *argv[])
"[-z] [-v] ptyname\n", progname);
exit(1);
}
+ openlog(progname, LOG_PID, LOG_DAEMON);
if (symlnk) {
int fdtty;
@@ -587,6 +598,8 @@ int main(int argc, char *argv[])
unlink(name_pname);
if (symlink(slavename, name_pname))
perror("symlink");
+ /* Users await the slave pty to be referenced in the 2nd line */
+ printf("Awaiting client connects on\n%s\n", slavename);
slavename[5] = 'p';
master_name = slavename;
} else {
@@ -596,21 +609,45 @@ int main(int argc, char *argv[])
name_pname);
exit(1);
}
+ if (!strcmp("/dev/ptmx", name_pname))
+ i_am_unix98_pty_master = 1;
master_name = name_pname;
}
if ((fdif = socket(PF_INET, SOCK_PACKET, proto)) < 0)
die("socket");
- strcpy(sa.sa_data, name_iface);
+ memset(&sa, 0, sizeof(struct sockaddr));
+ memcpy(sa.sa_data, name_iface, sizeof(sa.sa_data));
sa.sa_family = AF_INET;
if (bind(fdif, &sa, sizeof(struct sockaddr)) < 0)
die("bind");
- strcpy(ifr.ifr_name, name_iface);
+ memcpy(ifr.ifr_name, name_iface, IFNAMSIZ);
if (ioctl(fdif, SIOCGIFFLAGS, &ifr) < 0)
die("ioctl SIOCGIFFLAGS");
ifr_new = ifr;
ifr_new.ifr_flags |= if_newflags;
if (ioctl(fdif, SIOCSIFFLAGS, &ifr_new) < 0)
die("ioctl SIOCSIFFLAGS");
+ if (i_am_unix98_pty_master) {
+ /* get name of pts-device */
+ if ((namepts = ptsname(fdpty)) == NULL) {
+ fprintf(stderr, "%s: Cannot get name of pts-device.\n", progname);
+ exit (1);
+ }
+ /* unlock pts-device */
+ if (unlockpt(fdpty) == -1) {
+ fprintf(stderr, "%s: Cannot unlock pts-device %s\n", progname, namepts);
+ exit (1);
+ }
+ /* Users await the slave pty to be referenced in the 2nd line */
+ printf("Awaiting client connects on\n%s\n", namepts);
+ if (!verbose){
+ fflush(stdout);
+ fflush(stderr);
+ close(0);
+ close(1);
+ close(2);
+ }
+ }
signal(SIGHUP, restore_ifflags);
signal(SIGINT, restore_ifflags);
signal(SIGTERM, restore_ifflags);
@@ -630,17 +667,24 @@ int main(int argc, char *argv[])
die("tsgetattr");
if (doio(fdif, fdpty, name_iface))
break;
- /*
- * try to reopen master
- */
- if (verbose)
- printf("reopening master tty: %s\n", master_name);
- close(fdpty);
- if ((fdpty = open(master_name,
- O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
- fprintf(stderr, "%s: cannot reopen \"%s\"\n", progname,
- master_name);
- exit(1);
+ if (i_am_unix98_pty_master) {
+ if (verbose)
+ printf("%s: Trying to poll port ptmx (slave %s).\nWaiting 30s...\n", progname, namepts);
+ syslog(LOG_WARNING, "Trying to poll port ptmx (slave %s). Waiting 30s...\n", namepts);
+ sleep(30);
+ } else {
+ /*
+ * try to reopen master
+ */
+ if (verbose)
+ printf("reopening master tty: %s\n", master_name);
+ close(fdpty);
+
+ if ((fdpty = open(master_name, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0) {
+ fprintf(stderr, "%s: cannot reopen \"%s\"\n", progname,
+ master_name);
+ exit(1);
+ }
}
}