-diff -Naur conserver-8.1.16-p/configure.in conserver-8.1.16/configure.in
---- conserver-8.1.16-p/configure.in 2007-06-20 10:57:26.997646295 +0200
-+++ conserver-8.1.16/configure.in 2007-06-20 11:00:43.945111289 +0200
-@@ -16,6 +16,7 @@
- AH_TEMPLATE([HAVE_OPENSSL], [have openssl support])
- AH_TEMPLATE([HAVE_DMALLOC], [have dmalloc support])
- AH_TEMPLATE([HAVE_SA_LEN],[Defined if sa_len member exists in struct sockaddr])
-+AH_TEMPLATE([HAVE_MKSTEMP],[have mkstemp])
- AH_TEMPLATE([TRUST_REVERSE_DNS],[Defined if we trust reverse DNS])
- AH_TEMPLATE([USE_EXTENDED_MESSAGES],[Defined if we produce extended messages])
- AH_TEMPLATE([USE_UNIX_DOMAIN_SOCKETS],[Defined if we use Unix domain sockets])
-@@ -375,7 +376,13 @@
- [AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_SA_LEN)],
- [AC_MSG_RESULT(no)])
--
-+AC_MSG_CHECKING(for mkstemp)
-+AC_TRY_COMPILE([#include <stdlib.h>],
-+ [mkstemp("/tmp/XXXXXX");],
-+ [AC_MSG_RESULT(yes)
-+ AC_DEFINE(HAVE_MKSTEMP)],
-+ [AC_MSG_RESULT(no)])
-+
-
- dnl ### Host specific checks. ######################################
- AC_CANONICAL_HOST
-diff -Naur conserver-8.1.16-p/conserver/Makefile.in conserver-8.1.16/conserver/Makefile.in
---- conserver-8.1.16-p/conserver/Makefile.in 2007-06-20 10:57:27.009645531 +0200
-+++ conserver-8.1.16/conserver/Makefile.in 2007-06-20 11:00:43.949111034 +0200
-@@ -30,11 +30,11 @@
- ### Makefile rules - no user-servicable parts below
-
- CONSERVER_OBJS = access.o client.o consent.o group.o main.o master.o \
-- readcfg.o fallback.o cutil.o
-+ readcfg.o fallback.o cutil.o locks.o
- CONSERVER_HDRS = ../config.h $(top_srcdir)/compat.h $(srcdir)/access.h \
- $(srcdir)/client.h $(srcdir)/consent.h $(srcdir)/cutil.h \
- $(srcdir)/group.h $(srcdir)/main.h $(srcdir)/master.h \
-- $(srcdir)/readcfg.h $(srcdir)/version.h
-+ $(srcdir)/readcfg.h $(srcdir)/version.h $(srcdir)/locks.h
-
- ALL = conserver convert
-
-diff -Naur conserver-8.1.16-p/conserver/consent.c conserver-8.1.16/conserver/consent.c
---- conserver-8.1.16-p/conserver/consent.c 2007-06-20 10:57:27.001646040 +0200
-+++ conserver-8.1.16/conserver/consent.c 2007-06-20 11:00:43.949111034 +0200
-@@ -49,7 +49,7 @@
- #include <access.h>
- #include <readcfg.h>
- #include <main.h>
--
-+#include <locks.h>
-
- BAUD baud[] = {
- #if defined(FOR_CYCLADES_TS)
-@@ -733,6 +733,9 @@
- close(pCE->execSlaveFD);
- pCE->execSlaveFD = 0;
- }
-+ if (pCE->type == DEVICE && pCE->lock == FLAGTRUE) {
-+ rmlocks(pCE->device);
-+ }
- pCE->fup = 0;
- pCE->nolog = 0;
- pCE->autoReUp = 0;
-@@ -1013,6 +1016,21 @@
- pCE->fup = 1;
- break;
- case DEVICE:
-+ if (pCE->lock == FLAGTRUE) {
-+ if (checklock(pCE->device) != NO_LOCK) {
-+ Error("[%s] checklock(%s): device already locked",
-+ pCE->server, pCE->device);
-+ ConsDown(pCE, FLAGTRUE, FLAGTRUE);
-+ return;
-+ }
-+ if (makelock(pCE->device) == FAIL) {
-+ Error("[%s] makelock(%s): could not lock device",
-+ pCE->server, pCE->device);
-+ ConsDown(pCE, FLAGTRUE, FLAGTRUE);
-+ return;
-+ }
-+ /* now we have the lock */
-+ }
- if (-1 ==
- (cofile = open(pCE->device, O_RDWR | O_NONBLOCK, 0600))) {
-
-diff -Naur conserver-8.1.16-p/conserver/consent.h conserver-8.1.16/conserver/consent.h
---- conserver-8.1.16-p/conserver/consent.h 2007-06-20 10:57:27.001646040 +0200
-+++ conserver-8.1.16/conserver/consent.h 2007-06-20 11:02:48.352765847 +0200
-@@ -134,6 +134,7 @@
- FLAG autoreinit; /* auto-reinitialize if failed */
- FLAG unloved; /* copy "unloved" data to stdout */
- FLAG login; /* allow logins to the console */
-+ FLAG lock; /* lock the device */
-
- /*** runtime settings ***/
- CONSFILE *fdlog; /* the local log file */
-diff -Naur conserver-8.1.16-p/conserver/locks.c conserver-8.1.16/conserver/locks.c
---- conserver-8.1.16-p/conserver/locks.c 1970-01-01 01:00:00.000000000 +0100
-+++ conserver-8.1.16/conserver/locks.c 2007-06-20 11:00:43.953110779 +0200
-@@ -0,0 +1,435 @@
-+#ident "$Id$ Copyright (c) Gert Doering / Paul Sutcliffe Jr."
-+
-+/* large parts of the code in this module are taken from the
-+ * "getty kit 2.0" by Paul Sutcliffe, Jr., paul@devon.lns.pa.us,
-+ * and are used with permission here.
-+ * SVR4 style locking by Bodo Bauer, bodo@hal.nbg.sub.org.
-+ */
-+/* adopted from mgetty 1.1.30 for conserver
-+ * by Sebastian Zagrodzki, s.zagrodzki@net.icm.edu.pl */
-+
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <fcntl.h>
-+#include <signal.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <ctype.h>
-+
-+/* some OSes do include this in stdio.h, others don't... */
-+#ifndef EEXIST
-+#include <errno.h>
-+#endif
-+
-+/* SVR4 uses a different locking mechanism. This is why we need this... */
-+#ifdef SVR4
-+#include <sys/mkdev.h>
-+
-+#define LCK_NODEV -1
-+#define LCK_OPNFAIL -2
-+#endif
-+
-+#include "locks.h"
-+
-+int add_lock_to_list(char *device)
-+{
-+ s_ldev *temp_ldev, *ldev, *p_ldev = NULL;
-+
-+ Debug(2, "add_lock: %s", device);
-+ for (ldev = locked_devices; ldev && strcmp(ldev->name, device);
-+ p_ldev = ldev, ldev = ldev->next);
-+
-+ if (ldev) { /* we had it already */
-+ Msg("add_lock: That lock was already on my list");
-+ return(SUCCESS);
-+ }
-+
-+ if (!(temp_ldev = (s_ldev *) malloc(sizeof(s_ldev))))
-+ OutOfMem();
-+
-+ if (!(temp_ldev->name = (char *) malloc(strlen(device)+1)))
-+ OutOfMem();
-+
-+ strcpy(temp_ldev->name, device);
-+ temp_ldev->next = NULL;
-+ if (p_ldev)
-+ p_ldev->next = temp_ldev;
-+ else
-+ locked_devices = temp_ldev;
-+ return(SUCCESS);
-+}
-+
-+int remove_lock_from_list(char *device)
-+{
-+ s_ldev *ldev, *p_ldev = NULL;
-+
-+ Debug(2, "remove_lock: %s", device);
-+ for (ldev = locked_devices; ldev && strcmp(ldev->name, device);
-+ p_ldev = ldev, ldev = ldev->next);
-+ if (!ldev) {
-+ Msg("remove_lock: That lock wasn't on my list");
-+ return(SUCCESS);
-+ }
-+ free(ldev->name);
-+ if (p_ldev)
-+ p_ldev->next = ldev->next;
-+ else
-+ locked_devices = ldev->next;
-+ free(ldev);
-+ return(SUCCESS);
-+}
-+
-+int lock_is_on_list(char *device)
-+{
-+ s_ldev *ldev;
-+ for (ldev = locked_devices; ldev && strcmp(ldev->name, device);
-+ ldev = ldev->next);
-+ if (!ldev) {
-+ Debug(2, "lock_is_on_list: not found: %s", device);
-+ return(FALSE);
-+ } else {
-+ Debug(2, "lock_is_on_list: FOUND: %s", device);
-+ return(TRUE);
-+ }
-+}
-+
-+
-+/*
-+ * makelock() - attempt to create a lockfile
-+ *
-+ * Returns FAIL if lock could not be made (line in use).
-+ */
-+
-+int makelock(char *device)
-+{
-+ int fd, pid;
-+ char *temp, buf[MAXLINE+1];
-+ int tries = 0;
-+ char lock[MAXLINE+1];
-+
-+ s_ldev *ldev, *temp_ldev;
-+ Debug(2, "makelock: %s", device);
-+ for (ldev = locked_devices; ldev; ldev = ldev->next) {
-+ if (!strcmp(device, locked_devices->name)) {
-+ Msg("We already had a lock");
-+ return (SUCCESS);
-+ }
-+ }
-+
-+ if (get_lock_name(lock, device) == NULL) {
-+ Error("Cannot get lock filename");
-+ return (FAIL);
-+ }
-+ Debug(2, "makelock: lock='%s'", lock);
-+
-+ /* first make a temp file */
-+
-+#ifdef HAVE_MKSTEMP
-+ /* secure, but not as portable */
-+ temp=buf;
-+ sprintf(buf, LOCK, "TM.XXXXXX");
-+ if ((fd = mkstemp(temp)) == FAIL ) {
-+ Error("cannot create tempfile (%s)", temp);
-+ return(FAIL);
-+ }
-+#else
-+ /* portable, but subject to some problems on some platforms */
-+again:
-+ sprintf(buf, LOCK, "TM.XXXXXX");
-+ temp = mktemp(buf);
-+ unlink(temp);
-+ if ((fd = open(temp, O_CREAT|O_WRONLY|O_EXCL, 0644)) == FAIL) {
-+ Error("cannot create tempfile (%s)", temp);
-+ if ( errno == EEXIST && ++tries < 20 ) goto again;
-+ return(FAIL);
-+ }
-+#endif
-+
-+ /* just in case some "umask" is set (errors are ignored) */
-+ chmod( temp, 0644 );
-+
-+ /* put my pid in it */
-+ if ( lock_write_pid( fd ) == FAIL)
-+ { unlink(temp); return FAIL; }
-+
-+ /* link it to the lock file */
-+
-+ while (link(temp, lock) == FAIL)
-+ {
-+ if (errno != EEXIST )
-+ {
-+ Error("lock not made: link(temp,lock) failed" );
-+ }
-+
-+ if (errno == EEXIST) /* lock file already there */
-+ {
-+ if ((pid = readlock(lock)) == FAIL)
-+ {
-+ if ( errno == ENOENT ) /* disappeared */
-+ continue;
-+ else
-+ {
-+ Debug(2, "cannot read lockfile" );
-+ unlink(temp);
-+ return FAIL;
-+ }
-+ }
-+
-+ if (pid == getpid()) /* huh? WE locked the line!*/
-+ {
-+ Msg("we *have* the line!" );
-+ break;
-+ }
-+
-+ if ((kill(pid, 0) == FAIL) && errno == ESRCH)
-+ {
-+ /* pid that created lockfile is gone */
-+ Debug(2, "stale lockfile, created by process %d, ignoring", pid );
-+ if ( unlink(lock) < 0 &&
-+ errno != EINTR && errno != ENOENT )
-+ {
-+ Error("unlink() failed, giving up" );
-+ unlink(temp);
-+ return FAIL;
-+ }
-+ continue;
-+ }
-+
-+ Msg("lock not made: lock file exists (pid=%d)", pid);
-+ } /* if (errno == EEXIST) */
-+
-+ (void) unlink(temp);
-+ return(FAIL);
-+ }
-+
-+ Debug(2, "lock made");
-+ (void) unlink(temp);
-+
-+ Msg("Locking device");
-+ add_lock_to_list(device);
-+ return(SUCCESS);
-+}
-+
-+/*
-+ * checklock() - test for presence of valid lock file
-+ *
-+ * if lockfile found, return PID of process holding it, 0 otherwise
-+ */
-+
-+int checklock (char *device)
-+{
-+ int pid;
-+ struct stat st;
-+ char name[MAXLINE+1];
-+
-+ if ( get_lock_name( name, device ) == NULL )
-+ {
-+ Error("cannot get lock name" );
-+ return NO_LOCK;
-+ }
-+
-+ if ((stat(name, &st) == FAIL) && errno == ENOENT)
-+ {
-+ Debug(2, "checklock: stat failed, no file");
-+ return NO_LOCK;
-+ }
-+
-+ if ((pid = readlock(name)) == FAIL)
-+ {
-+ Msg("checklock: couldn't read lockfile");
-+ return NO_LOCK;
-+ }
-+
-+ if (pid == getpid())
-+ {
-+ Msg("huh? It's *our* lock file!" );
-+ return NO_LOCK;
-+ }
-+
-+ if ((kill(pid, 0) == FAIL) && errno == ESRCH)
-+ {
-+ Debug(2, "checklock: no active process has lock, will remove");
-+ (void) unlink(name);
-+ return NO_LOCK;
-+ }
-+
-+ Debug(2, "lockfile found, pid=%d", pid );
-+
-+ return pid;
-+}
-+
-+/*
-+ * readlock() - read contents of lockfile
-+ *
-+ * Returns pid read or FAIL on error.
-+ *
-+ * private function
-+ */
-+
-+int readlock (char *name)
-+{
-+ int fd, pid;
-+ char apid[20];
-+ int length;
-+
-+ if ((fd = open(name, O_RDONLY)) == FAIL)
-+ return(FAIL);
-+
-+ length = read(fd, apid, sizeof(apid)-1);
-+ apid[length]=0; /* make sscanf() happy */
-+
-+ pid = 0;
-+ if ( length == sizeof( pid ) || sscanf(apid, "%d", &pid) != 1 ||
-+ pid == 0 )
-+ {
-+ pid = * ( (int *) apid );
-+#if LOCKS_BINARY == 0
-+ Msg("compiled with ascii locks, found binary lock file (length=%d, pid=%d)!", length, pid );
-+#endif
-+ }
-+#if LOCKS_BINARY == 1
-+ else
-+ {
-+ Msg("compiled with binary locks, found ascii lock file (length=%d, pid=%d)!", length, pid );
-+ }
-+#endif
-+
-+ (void) close(fd);
-+ return(pid);
-+}
-+
-+/* lock_write_pid()
-+ *
-+ * write contents of lock file: my process ID in specified format
-+ *
-+ * private function
-+ */
-+int lock_write_pid (int fd)
-+{
-+#if LOCKS_BINARY
-+ int bpid; /* must be 4 bytes wide! */
-+ bpid = getpid();
-+ if ( write(fd, &bpid, sizeof(bpid) ) != sizeof(bpid) )
-+#else
-+ char apid[16];
-+ sprintf( apid, "%10d\n", (int) getpid() );
-+ if ( write(fd, apid, strlen(apid)) != strlen(apid) )
-+#endif
-+ {
-+ Error("cannot write PID to (temp) lock file" );
-+ close(fd);
-+ return(FAIL);
-+ }
-+ close(fd);
-+ return SUCCESS;
-+}
-+
-+/*
-+ * rmlocks() - remove lockfile
-+ * signal handler
-+ */
-+
-+void rmlocks(char *device)
-+{
-+ char lock[MAXLINE + 1];
-+ Debug(2, "rmlocks: %s", device);
-+ get_lock_name(lock, device);
-+ Debug(2, "rmlocks: lock: %s", lock);
-+ if (lock_is_on_list(device))
-+ {
-+ Msg("Removing lock file" );
-+ if (unlink(lock) == -1 )
-+ Error("error removing lock file (huh?!)" );
-+ /* mark lock file as 'not set' */
-+ remove_lock_from_list(device);
-+ }
-+}
-+
-+/* get_lock_name()
-+ *
-+ * determine full path + name of the lock file for a given device
-+ */
-+
-+#ifdef SVR4
-+
-+/*
-+ * get_lock_name() - create SVR4 lock file name (Bodo Bauer)
-+ */
-+
-+char *get_lock_name (char* lock, char* fax_tty)
-+{
-+ struct stat tbuf;
-+ char ttyname[FILENAME_MAX];
-+
-+ Debug(2, "get_lock_name(%s) called", fax_tty);
-+
-+ if ( strncmp( fax_tty, "/dev/", 5 ) == 0 )
-+ strcpy( ttyname, fax_tty );
-+ else
-+ sprintf(ttyname, "/dev/%s", fax_tty);
-+
-+ Debug(2, "-> ttyname %s", ttyname);
-+
-+ if (stat(ttyname, &tbuf) < 0) {
-+ if(errno == ENOENT) {
-+ Debug(2, "device does not exist: %s", ttyname);
-+ return(NULL);
-+ } else {
-+ Debug(2, "could not access line: %s", ttyname);
-+ return(NULL);
-+ }
-+ }
-+
-+ sprintf(lock,"%s/LK.%03u.%03u.%03u",
-+ LOCK_PATH,
-+ major(tbuf.st_dev),
-+ tbuf.st_rdev >> 18,
-+ minor(tbuf.st_rdev));
-+
-+ Debug(2, "lock file: %s", lock);
-+ return(lock);
-+}
-+
-+#else /* not SVR4 */
-+
-+char * get_lock_name (char * lock_name, char * device)
-+{
-+#ifdef LOCKS_LOWERCASE
-+ /* sco locking convention -> change all device names to lowercase */
-+
-+ char p[MAXLINE+1];
-+ int i;
-+ if ( ( i = strlen( device ) ) > sizeof(p) )
-+ {
-+ Error("get_lock_name: device name too long" );
-+ exit(5);
-+ }
-+
-+#ifdef LOCKS_ALL_LOWERCASE
-+ /* convert the full name */
-+ while ( i >= 0 )
-+ {
-+ p[i] = tolower( device[i] ); i--;
-+ }
-+#else
-+ /* convert only the last character */
-+ strcpy( p, device );
-+ i--;
-+ p[i] = tolower( p[i] );
-+#endif
-+
-+ device = p;
-+#endif /* LOCKS_LOWERCASE */
-+
-+ /* throw out all directory prefixes */
-+ if ( strchr( device, '/' ) != NULL )
-+ device = strrchr( device, '/' ) +1;
-+
-+ sprintf( lock_name, LOCK, device);
-+
-+ return lock_name;
-+}
-+
-+#endif /* !SVR4 */
-diff -Naur conserver-8.1.16-p/conserver/locks.h conserver-8.1.16/conserver/locks.h
---- conserver-8.1.16-p/conserver/locks.h 1970-01-01 01:00:00.000000000 +0100
-+++ conserver-8.1.16/conserver/locks.h 2007-06-20 11:00:43.957110525 +0200
-@@ -0,0 +1,30 @@
-+#ifndef _locks_h
-+#define _locks_h
-+#define LOCK "/tmp/LCK..%s"
-+#define MAXLINE 1024
-+#define FALSE (1==0)
-+#define TRUE (1==1)
-+#define SUCCESS 0
-+#define FAIL -1
-+#define NO_LOCK 0
-+
-+int makelock (char *device);
-+// int makelock_file ( char * lockname );
-+int checklock (char *device);
-+void rmlocks ();
-+// int steal_lock (char * device, int pid );
-+
-+
-+typedef struct _s_ldev {
-+ char *name;
-+ struct _s_ldev *next;
-+} s_ldev;
-+
-+static s_ldev *locked_devices = NULL;
-+
-+int readlock (char *name);
-+int makelock (char *name);
-+char *get_lock_name (char *lock_name, char *device);
-+int lock_write_pid (int fd);
-+
-+#endif
-diff -Naur conserver-8.1.16-p/conserver/main.c conserver-8.1.16/conserver/main.c
---- conserver-8.1.16-p/conserver/main.c 2007-06-20 10:57:27.005645786 +0200
-+++ conserver-8.1.16/conserver/main.c 2007-06-20 11:03:43.950164075 +0200
-@@ -980,6 +980,9 @@
- EMPTYSTR(pCE->motd), pCE->idletimeout,
- EMPTYSTR(pCE->idlestring),
- EMPTYSTR(pCE->replstring)));
-+ CONDDEBUG((1,
-+ "DumpDataStructures(): lock=%s",
-+ FLAGSTR(pCE->lock)));
- if (pCE->ro) {
- CONSENTUSERS *u;
- for (u = pCE->ro; u != (CONSENTUSERS *)0; u = u->next) {
-diff -Naur conserver-8.1.16-p/conserver/readcfg.c conserver-8.1.16/conserver/readcfg.c
---- conserver-8.1.16-p/conserver/readcfg.c 2007-06-20 10:57:27.009645531 +0200
-+++ conserver-8.1.16/conserver/readcfg.c 2007-06-20 11:16:56.671710166 +0200
-@@ -701,6 +701,8 @@
- c->unloved = d->unloved;
- if (d->login != FLAGUNKNOWN)
- c->login = d->login;
-+ if (d->lock != FLAGUNKNOWN)
-+ c->lock = d->lock;
- if (d->host != (char *)0) {
- if (c->host != (char *)0)
- free(c->host);
-@@ -1669,6 +1671,7 @@
- c->autoreinit = FLAGUNKNOWN;
- c->unloved = FLAGUNKNOWN;
- c->login = FLAGUNKNOWN;
-+ c->lock = FLAGUNKNOWN;
- return;
- }
-
-@@ -1706,6 +1709,8 @@
- c->unloved = negative ? FLAGFALSE : FLAGTRUE;
- else if (strcasecmp("login", token) == 0)
- c->login = negative ? FLAGFALSE : FLAGTRUE;
-+ else if (strcasecmp("lock", token) == 0)
-+ c->lock = negative ? FLAGFALSE : FLAGTRUE;
- else if (isMaster)
- Error("invalid option `%s' [%s:%d]", token, file, line);
- }
-@@ -3053,6 +3058,7 @@
- pCEmatch->autoreinit = c->autoreinit;
- pCEmatch->unloved = c->unloved;
- pCEmatch->login = c->login;
-+ pCEmatch->lock = c->lock;
- pCEmatch->inituid = c->inituid;
- pCEmatch->initgid = c->initgid;
- while (pCEmatch->aliases != (NAMES *)0) {
-@@ -3231,6 +3237,8 @@
- #endif
- if (c->ondemand == FLAGUNKNOWN)
- c->ondemand = FLAGFALSE;
-+ if (c->lock == FLAGUNKNOWN)
-+ c->lock = FLAGFALSE;
- if (c->reinitoncc == FLAGUNKNOWN)
- c->reinitoncc = FLAGFALSE;
- if (c->striphigh == FLAGUNKNOWN)
-diff -Naur conserver-8.1.16-p/conserver.cf/conserver.cf.man conserver-8.1.16/conserver.cf/conserver.cf.man
---- conserver-8.1.16-p/conserver.cf/conserver.cf.man 2007-06-20 10:57:26.997646295 +0200
-+++ conserver-8.1.16/conserver.cf/conserver.cf.man 2007-06-20 11:00:43.969109761 +0200
-@@ -846,6 +846,11 @@
- Default is
- .BR !ondemand .
- .TP
-+.B lock
-+Lock the device using UUCP-style locks.
-+Default is
-+.BR !lock .
-+.TP
- .B striphigh
- Strip the high bit off all data coming from this console and all clients
- connected to this console before processing occurs.