summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Osterried <thomas@osterried.de>2009-01-20 16:18:02 +0000
committerThomas Osterried <thomas@osterried.de>2009-01-20 16:18:02 +0000
commit6ef96412fc19133494ed0c9f0bf42a722050e07f (patch)
tree4b9dcc136bc35d1feef7dce8b3ccd48e552cf905
parent965640685239ef173cf8938c27e25f8e5a23a89a (diff)
Unix98 PTY support for mkiss and m6pack.
-rw-r--r--6pack/m6pack.85
-rw-r--r--6pack/m6pack.c128
-rw-r--r--kiss/mkiss.85
-rw-r--r--kiss/mkiss.c99
4 files changed, 188 insertions, 49 deletions
diff --git a/6pack/m6pack.8 b/6pack/m6pack.8
index cef3513..cb7c382 100644
--- a/6pack/m6pack.8
+++ b/6pack/m6pack.8
@@ -2,7 +2,7 @@
.SH NAME
m6pack \- Attach multiples 6PACK interfaces
.SH SYNOPSIS
-.B m6pack [-l] [-s speed] [-v] ttyinterface pty1 pty2...
+.B m6pack [-l] [-s speed] [-v] ttyinterface [-x <n> | pty ..]
.SH DESCRIPTION
.LP
.B m6pack
@@ -38,6 +38,9 @@ Enables system logging, the default is off.
.BI "\-s speed"
Set the speed of the serial port.
.TP 10
+.BI "\-x number"
+This option is for Unix98 PTYs. It allocates "number" ptys; their names are written to stdout.
+.TP 10
.BI \-v
Display the version.
.SH "SEE ALSO"
diff --git a/6pack/m6pack.c b/6pack/m6pack.c
index 65f85c4..0911601 100644
--- a/6pack/m6pack.c
+++ b/6pack/m6pack.c
@@ -6,18 +6,21 @@
* Fake out AX.25 code into supporting 6pack TNC rings by routing serial
* port data to/from pseudo ttys.
*
- * @(#)m6pack.c $Revision: 1.1 $ $Date: 2005/12/10 16:17:28 $
+ * @(#)m6pack.c $Revision: 1.2 $ $Date: 2009/01/20 16:18:02 $
*
* Author(s):
*
- * Iñaki Arenaza (EB2EBU) <iarenaza@escomposlinux.org>
+ * Iñaki Arenaza (EB2EBU) <iarenaza@escomposlinux.org>
*
* History:
*
* $Log: m6pack.c,v $
+ * Revision 1.2 2009/01/20 16:18:02 dl9sau
+ * Unix98 PTY support for mkiss and m6pack.
+ *
* Revision 1.1 2005/12/10 16:17:28 dl9sau
* support for 6pack tnc rings (patch found at sf.net)
- * from Iñaki Arenaza EB2EBU <iarenaza@escomposlinux.org>
+ * from Iñaki Arenaza EB2EBU <iarenaza@escomposlinux.org>
*
* Revision 0.9 2002/04/28 15:05:39 hermes-team
* Minor fixes to make it part of ax25-tools-0.0.8
@@ -53,7 +56,7 @@
* Jonathan Naylor
* Tomi Manninen
*
- * Copyright (C) 1999 Iñaki Arenaza
+ * Copyright (C) 1999 Iñaki Arenaza
* mkiss.c was GPLed, so I guess this one is GPLed too ;-)
*
*********************************************************************
@@ -68,6 +71,8 @@
*/
#include <stdio.h>
+#define __USE_XOPEN
+#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>
@@ -79,13 +84,14 @@
#include <signal.h>
#include <ctype.h>
#include <syslog.h>
+#include <limits.h>
#include <netax25/ttyutils.h>
#include <netax25/daemon.h>
#include <config.h>
-static char *version ="$Id: m6pack.c,v 1.1 2005/12/10 16:17:28 dl9sau Exp $";
+static char *version ="$Id: m6pack.c,v 1.2 2009/01/20 16:18:02 dl9sau Exp $";
typedef unsigned char __u8;
typedef enum {data, command} frame_t;
@@ -102,8 +108,7 @@ static __u8 obuf[SIZE]; /* buffer for sixpack_tx() */
static int invalid_ports = 0;
-static char *usage_string = "usage: m6pack [-l] [-s speed] [-v] "
- "ttyinterface pty ...\n";
+static char *usage_string = "usage: m6pack [-l] [-s speed] [-v] tyinterface [-x <num_ptmx_devices> | pty ..]\n";
static int dump_report = FALSE;
static int logging = FALSE;
@@ -128,6 +133,8 @@ struct iface
unsigned int txpackets; /* TX frames count */
unsigned long rxbytes; /* RX bytes count */
unsigned long txbytes; /* TX bytes count */
+ char namepts[PATH_MAX]; /* name of the unix98 pts slaves, which
+ * the client has to use */
};
#define PTY_ID_TTY (-1)
@@ -395,13 +402,11 @@ static void sigterm_handler(int sig)
}
tty_unlock(tty->name);
- for (i=0; i < numptys; i++) {
- tty_unlock(pty[i]->name);
- }
-
close(tty->fd);
free(tty);
+
for (i = 0; i < numptys; i++) {
+ tty_unlock(pty[i]->name);
close(pty[i]->fd);
free(pty[i]);
}
@@ -452,10 +457,13 @@ int main(int argc, char *argv[])
fd_set readfd;
int retval, i, size, len;
int speed = -1;
+ int ptmxdevices = 0;
+ char *npts;
+ int wrote_info = 0;
frame_t type;
head = tail = 0;
- while ((size = getopt(argc, argv, "ls:v")) != -1) {
+ while ((size = getopt(argc, argv, "ls:vx:")) != -1) {
switch (size) {
case 'l':
logging = TRUE;
@@ -463,6 +471,13 @@ int main(int argc, char *argv[])
case 's':
speed = atoi(optarg);
break;
+ case 'x':
+ ptmxdevices = atoi(optarg);
+ if (ptmxdevices < 1 || ptmxdevices > MAX_PTYS) {
+ fprintf(stderr, "m6pack: too %s devices\n", ptmxdevices < 1 ? "few" : "many");
+ return 1;
+ }
+ break;
case 'v':
printf("m6pack: %s\n", VERSION);
return 1;
@@ -473,11 +488,19 @@ int main(int argc, char *argv[])
}
}
- if ((argc - optind) < 2) {
+ if ((argc - optind) < 2 && ptmxdevices == 0) {
fprintf(stderr, usage_string);
return 1;
}
- if ((numptys = argc - optind - 1) > MAX_PTYS) {
+
+ if ((argc - optind) < 1 && ptmxdevices > 0) {
+ fprintf(stderr, usage_string);
+ return 1;
+ }
+
+ numptys = argc - optind - 1;
+
+ if (numptys + ptmxdevices > MAX_PTYS) {
fprintf(stderr, "m6pack: max %d pty interfaces allowed.\n",
MAX_PTYS);
return 1;
@@ -487,14 +510,14 @@ int main(int argc, char *argv[])
* Check for lock files before opening any TTYs
*/
if (tty_is_locked(argv[optind])) {
- fprintf(stderr, "m6pack: tty %s is locked by another "
- "process\n", argv[optind]);
+ fprintf(stderr, "m6pack: tty %s is locked by another process\n", argv[optind]);
return 1;
}
for (i = 0; i < numptys; i++) {
+ if (!strcmp("/dev/ptmx", argv[optind + i + 1]))
+ continue;
if (tty_is_locked(argv[optind + i + 1])) {
- fprintf(stderr, "m6pack: tty %s is locked by "
- "another process\n", argv[optind + i + 1]);
+ fprintf(stderr, "m6pack: pty %s is locked by another process\n", argv[optind + i + 1]);
return 1;
}
}
@@ -520,6 +543,8 @@ int main(int argc, char *argv[])
tty->pty_id = PTY_ID_TTY;
tty->optr = tty->databuf;
topfd = tty->fd;
+ tty->namepts[0] = '\0';
+
/*
* Make it block again...
*/
@@ -528,28 +553,73 @@ int main(int argc, char *argv[])
/*
* Open and configure the pty interfaces
*/
- for (i = 0; i < numptys; i++) {
+ for (i = 0; i < numptys+ptmxdevices; i++) {
+ static char name_ptmx[] = "/dev/ptmx";
+ char *pty_name = (i < numptys ? argv[optind+i+1] : name_ptmx);
+
if ((pty[i] = calloc(1, sizeof(struct iface))) == NULL) {
perror("m6pack: malloc");
return 1;
}
- if ((pty[i]->fd = open(argv[optind + i + 1], O_RDWR)) == -1) {
+ if ((pty[i]->fd = open(pty_name, O_RDWR)) == -1) {
perror("m6pack: open");
return 1;
}
- pty[i]->name = argv[optind + i + 1];
+ pty[i]->name = pty_name;
tty_raw(pty[i]->fd, FALSE);
pty[i]->pty_id = i;
pty[i]->optr = pty[i]->databuf;
topfd = (pty[i]->fd > topfd) ? pty[i]->fd : topfd;
+ pty[i]->namepts[0] = '\0';
+ if (!strcmp(pty[i]->name, "/dev/ptmx")) {
+ /* get name of pts-device */
+ if ((npts = ptsname(pty[i]->fd)) == NULL) {
+ fprintf(stderr, "m6pack: Cannot get name of pts-device.\n");
+ return 1;
+ }
+ strncpy(pty[i]->namepts, npts, PATH_MAX-1);
+ pty[i]->namepts[PATH_MAX-1] = '\0';
+
+ /* unlock pts-device */
+ if (unlockpt(pty[i]->fd) == -1) {
+ fprintf(stderr, "m6pack: Cannot unlock pts-device %s\n", pty[i]->namepts);
+ return 1;
+ }
+ if (wrote_info == 0)
+ printf("\nAwaiting client connects on:\n");
+ else
+ printf(" ");
+ printf("%s", pty[i]->namepts);
+ wrote_info = 1;
+ }
}
+ if (wrote_info > 0)
+ printf("\n");
+
+ numptys=numptys+ptmxdevices;
+
/*
* Now all the ports are open, lock them.
*/
- tty_lock(argv[optind]);
- for (i = 0; i < numptys; i++)
- tty_lock(argv[optind + i + 1]);
+ tty_lock(tty->name);
+ for (i = 0; i < numptys; i++) {
+ if (pty[i]->namepts[0] == '\0')
+ tty_lock(pty[i]->name);
+ }
+
+ if (logging) {
+ openlog("m6pack", LOG_PID, LOG_DAEMON);
+ syslog(LOG_INFO, "starting");
+ }
+
+ if (wrote_info > 0) {
+ fflush(stdout);
+ fflush(stderr);
+ close(0);
+ close(1);
+ close(2);
+ }
signal(SIGHUP, SIG_IGN);
signal(SIGUSR1, sigusr1_handler);
@@ -560,11 +630,6 @@ int main(int argc, char *argv[])
return 1;
}
- if (logging) {
- openlog("m6pack", LOG_PID, LOG_DAEMON);
- syslog(LOG_INFO, "starting");
- }
-
/*
* Loop until an error occurs on a read.
*/
@@ -651,16 +716,19 @@ int main(int argc, char *argv[])
}
}
- end:
+end:
if (logging)
closelog();
+ tty_unlock(tty->name);
close(tty->fd);
free(tty);
for (i = 0; i < numptys; i++) {
+ tty_unlock(pty[i]->name);
close(pty[i]->fd);
free(pty[i]);
}
+
return 1;
}
diff --git a/kiss/mkiss.8 b/kiss/mkiss.8
index 845eef0..0178ede 100644
--- a/kiss/mkiss.8
+++ b/kiss/mkiss.8
@@ -2,7 +2,7 @@
.SH NAME
mkiss \- Attach a multi KISS interface
.SH SYNOPSIS
-.B mkiss [-c] [-f] [-h] [-l] [-s speed] [-p pollrate] [-v] ttyinterface pty...
+.B mkiss [-c] [-f] [-h] [-l] [-s speed] [-p pollrate] [-v] ttyinterface [ -x <n> | pty ..]
.SH DESCRIPTION
.LP
.B Mkiss
@@ -58,6 +58,9 @@ Enables polling. Polled mode is used by G8BPQ KISS roms to prevent
contention on systems where multiple TNCs share the same serial line.
Pollrate is interval between polls (in 100ms units).
.TP 10
+.BI "\-x number"
+This option is for Unix98 PTYs. It allocates "number" ptys; their names are written to stdout.
+.TP 10
.BI \-v
Display the version.
.SH "SEE ALSO"
diff --git a/kiss/mkiss.c b/kiss/mkiss.c
index 329d040..169de49 100644
--- a/kiss/mkiss.c
+++ b/kiss/mkiss.c
@@ -38,6 +38,7 @@
*/
#include <stdio.h>
+#define __USE_XOPEN
#include <string.h>
#include <errno.h>
#include <stdlib.h>
@@ -51,6 +52,7 @@
#include <signal.h>
#include <ctype.h>
#include <syslog.h>
+#include <limits.h>
#include <netax25/ttyutils.h>
#include <netax25/daemon.h>
@@ -80,7 +82,7 @@ static int crc_errors = 0;
static int invalid_ports = 0;
static int return_polls = 0;
-static char *usage_string = "usage: mkiss [-p interval] [-c] [-f] [-h] [-l] [-s speed] [-v] ttyinterface pty ...\n";
+static char *usage_string = "usage: mkiss [-p interval] [-c] [-f] [-h] [-l] [-s speed] [-v] ttyinterface [-x <num_ptmx_devices> | pty ..]\n";
static int dump_report = FALSE;
@@ -108,6 +110,8 @@ struct iface
unsigned int txpackets; /* TX frames count */
unsigned long rxbytes; /* RX bytes count */
unsigned long txbytes; /* TX bytes count */
+ char namepts[PATH_MAX]; /* name of the unix98 pts slaves, which
+ * the client has to use */
};
static struct iface *tty = NULL;
@@ -421,8 +425,11 @@ int main(int argc, char *argv[])
struct timeval timeout, pollinterval;
int retval, i, size, len;
int speed = -1;
+ int ptmxdevices = 0;
+ char *npts;
+ int wrote_info = 0;
- while ((size = getopt(argc, argv, "cfhlp:s:v")) != -1) {
+ while ((size = getopt(argc, argv, "cfhlp:s:vx:")) != -1) {
switch (size) {
case 'c':
crcflag = G8BPQ_CRC;
@@ -444,6 +451,13 @@ int main(int argc, char *argv[])
case 's':
speed = atoi(optarg);
break;
+ case 'x':
+ ptmxdevices = atoi(optarg);
+ if (ptmxdevices < 1 || ptmxdevices > 16) {
+ fprintf(stderr, "mkiss: too %s devices\n", ptmxdevices < 1 ? "few" : "many");
+ return 1;
+ }
+ break;
case 'v':
printf("mkiss: %s\n", VERSION);
return 1;
@@ -454,11 +468,18 @@ int main(int argc, char *argv[])
}
}
- if ((argc - optind) < 2) {
+ if ((argc - optind) < 2 && ptmxdevices == 0) {
+ fprintf(stderr, usage_string);
+ return 1;
+ }
+
+ if ((argc - optind) < 1 && ptmxdevices > 0) {
fprintf(stderr, usage_string);
return 1;
}
- if ((numptys = argc - optind - 1) > 16) {
+
+ numptys = argc - optind - 1;
+ if ((numptys + ptmxdevices) > 16) {
fprintf(stderr, "mkiss: max 16 pty interfaces allowed.\n");
return 1;
}
@@ -471,8 +492,10 @@ int main(int argc, char *argv[])
return 1;
}
for (i = 0; i < numptys; i++) {
+ if (!strcmp("/dev/ptmx", argv[optind + i + 1]))
+ continue;
if (tty_is_locked(argv[optind + i + 1])) {
- fprintf(stderr, "mkiss: tty %s is locked by another process\n", argv[optind + i + 1]);
+ fprintf(stderr, "mkiss: pty %s is locked by another process\n", argv[optind + i + 1]);
return 1;
}
}
@@ -500,6 +523,7 @@ int main(int argc, char *argv[])
}
tty->optr = tty->obuf;
topfd = tty->fd;
+ tty->namepts[0] = '\0';
/*
* Make it block again...
@@ -509,41 +533,82 @@ int main(int argc, char *argv[])
/*
* Open and configure the pty interfaces
*/
- for (i = 0; i < numptys; i++) {
+ for (i = 0; i < numptys+ptmxdevices; i++) {
+ static char name_ptmx[] = "/dev/ptmx";
+ char *pty_name = (i < numptys ? argv[optind+i+1] : name_ptmx);
+
if ((pty[i] = calloc(1, sizeof(struct iface))) == NULL) {
perror("mkiss: malloc");
return 1;
}
- if ((pty[i]->fd = open(argv[optind + i + 1], O_RDWR)) == -1) {
+ if ((pty[i]->fd = open(pty_name, O_RDWR)) == -1) {
perror("mkiss: open");
return 1;
}
- pty[i]->name = argv[optind + i + 1];
+ pty[i]->name = pty_name;
tty_raw(pty[i]->fd, FALSE);
pty[i]->optr = pty[i]->obuf;
topfd = (pty[i]->fd > topfd) ? pty[i]->fd : topfd;
+ pty[i]->namepts[0] = '\0';
+ if (!strcmp(pty[i]->name, "/dev/ptmx")) {
+ /* get name of pts-device */
+ if ((npts = ptsname(pty[i]->fd)) == NULL) {
+ fprintf(stderr, "mkiss: Cannot get name of pts-device.\n");
+ return 1;
+ }
+ strncpy(pty[i]->namepts, npts, PATH_MAX-1);
+ pty[i]->namepts[PATH_MAX-1] = '\0';
+
+ /* unlock pts-device */
+ if (unlockpt(pty[i]->fd) == -1) {
+ fprintf(stderr, "mkiss: Cannot unlock pts-device %s\n", pty[i]->namepts);
+ return 1;
+ }
+ if (wrote_info == 0)
+ printf("\nAwaiting client connects on:\n");
+ else
+ printf(" ");
+ printf("%s", pty[i]->namepts);
+ wrote_info = 1;
+ }
}
- signal(SIGHUP, SIG_IGN);
- signal(SIGUSR1, sigusr1_handler);
- signal(SIGTERM, sigterm_handler);
+ if (wrote_info > 0)
+ printf("\n");
- if (!daemon_start(FALSE)) {
- fprintf(stderr, "mkiss: cannot become a daemon\n");
- return 1;
- }
+ numptys=numptys+ptmxdevices;
/*
* Now all the ports are open, lock them.
*/
tty_lock(tty->name);
- for (i = 0; i < numptys; i++)
- tty_lock(pty[i]->name);
+ for (i = 0; i < numptys; i++) {
+ if (pty[i]->namepts[0] == '\0')
+ tty_lock(pty[i]->name);
+ }
if (logging) {
openlog("mkiss", LOG_PID, LOG_DAEMON);
syslog(LOG_INFO, "starting");
}
+
+ if (wrote_info > 0) {
+ fflush(stdout);
+ fflush(stderr);
+ close(0);
+ close(1);
+ close(2);
+ }
+
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGUSR1, sigusr1_handler);
+ signal(SIGTERM, sigterm_handler);
+
+ if (!daemon_start(FALSE)) {
+ fprintf(stderr, "mkiss: cannot become a daemon\n");
+ return 1;
+ }
+
init_crc();
/*
* Loop until an error occurs on a read.