1 diff -Naur conserver-8.1.16-p/configure.in conserver-8.1.16/configure.in
2 --- conserver-8.1.16-p/configure.in 2007-06-20 10:57:26.997646295 +0200
3 +++ conserver-8.1.16/configure.in 2007-06-20 11:00:43.945111289 +0200
5 AH_TEMPLATE([HAVE_OPENSSL], [have openssl support])
6 AH_TEMPLATE([HAVE_DMALLOC], [have dmalloc support])
7 AH_TEMPLATE([HAVE_SA_LEN],[Defined if sa_len member exists in struct sockaddr])
8 +AH_TEMPLATE([HAVE_MKSTEMP],[have mkstemp])
9 AH_TEMPLATE([TRUST_REVERSE_DNS],[Defined if we trust reverse DNS])
10 AH_TEMPLATE([USE_EXTENDED_MESSAGES],[Defined if we produce extended messages])
11 AH_TEMPLATE([USE_UNIX_DOMAIN_SOCKETS],[Defined if we use Unix domain sockets])
14 AC_DEFINE(HAVE_SA_LEN)],
17 +AC_MSG_CHECKING(for mkstemp)
18 +AC_TRY_COMPILE([#include <stdlib.h>],
19 + [mkstemp("/tmp/XXXXXX");],
21 + AC_DEFINE(HAVE_MKSTEMP)],
22 + [AC_MSG_RESULT(no)])
25 dnl ### Host specific checks. ######################################
27 diff -Naur conserver-8.1.16-p/conserver/Makefile.in conserver-8.1.16/conserver/Makefile.in
28 --- conserver-8.1.16-p/conserver/Makefile.in 2007-06-20 10:57:27.009645531 +0200
29 +++ conserver-8.1.16/conserver/Makefile.in 2007-06-20 11:00:43.949111034 +0200
31 ### Makefile rules - no user-servicable parts below
33 CONSERVER_OBJS = access.o client.o consent.o group.o main.o master.o \
34 - readcfg.o fallback.o cutil.o
35 + readcfg.o fallback.o cutil.o locks.o
36 CONSERVER_HDRS = ../config.h $(top_srcdir)/compat.h $(srcdir)/access.h \
37 $(srcdir)/client.h $(srcdir)/consent.h $(srcdir)/cutil.h \
38 $(srcdir)/group.h $(srcdir)/main.h $(srcdir)/master.h \
39 - $(srcdir)/readcfg.h $(srcdir)/version.h
40 + $(srcdir)/readcfg.h $(srcdir)/version.h $(srcdir)/locks.h
42 ALL = conserver convert
44 diff -Naur conserver-8.1.16-p/conserver/consent.c conserver-8.1.16/conserver/consent.c
45 --- conserver-8.1.16-p/conserver/consent.c 2007-06-20 10:57:27.001646040 +0200
46 +++ conserver-8.1.16/conserver/consent.c 2007-06-20 11:00:43.949111034 +0200
55 #if defined(FOR_CYCLADES_TS)
57 close(pCE->execSlaveFD);
60 + if (pCE->type == DEVICE && pCE->lock == FLAGTRUE) {
61 + rmlocks(pCE->device);
66 @@ -1013,6 +1016,21 @@
70 + if (pCE->lock == FLAGTRUE) {
71 + if (checklock(pCE->device) != NO_LOCK) {
72 + Error("[%s] checklock(%s): device already locked",
73 + pCE->server, pCE->device);
74 + ConsDown(pCE, FLAGTRUE, FLAGTRUE);
77 + if (makelock(pCE->device) == FAIL) {
78 + Error("[%s] makelock(%s): could not lock device",
79 + pCE->server, pCE->device);
80 + ConsDown(pCE, FLAGTRUE, FLAGTRUE);
83 + /* now we have the lock */
86 (cofile = open(pCE->device, O_RDWR | O_NONBLOCK, 0600))) {
88 diff -Naur conserver-8.1.16-p/conserver/consent.h conserver-8.1.16/conserver/consent.h
89 --- conserver-8.1.16-p/conserver/consent.h 2007-06-20 10:57:27.001646040 +0200
90 +++ conserver-8.1.16/conserver/consent.h 2007-06-20 11:02:48.352765847 +0200
92 FLAG autoreinit; /* auto-reinitialize if failed */
93 FLAG unloved; /* copy "unloved" data to stdout */
94 FLAG login; /* allow logins to the console */
95 + FLAG lock; /* lock the device */
97 /*** runtime settings ***/
98 CONSFILE *fdlog; /* the local log file */
99 diff -Naur conserver-8.1.16-p/conserver/locks.c conserver-8.1.16/conserver/locks.c
100 --- conserver-8.1.16-p/conserver/locks.c 1970-01-01 01:00:00.000000000 +0100
101 +++ conserver-8.1.16/conserver/locks.c 2007-06-20 11:00:43.953110779 +0200
103 +#ident "$Id$ Copyright (c) Gert Doering / Paul Sutcliffe Jr."
105 +/* large parts of the code in this module are taken from the
106 + * "getty kit 2.0" by Paul Sutcliffe, Jr., paul@devon.lns.pa.us,
107 + * and are used with permission here.
108 + * SVR4 style locking by Bodo Bauer, bodo@hal.nbg.sub.org.
110 +/* adopted from mgetty 1.1.30 for conserver
111 + * by Sebastian Zagrodzki, s.zagrodzki@net.icm.edu.pl */
119 +#include <sys/types.h>
120 +#include <sys/stat.h>
123 +/* some OSes do include this in stdio.h, others don't... */
128 +/* SVR4 uses a different locking mechanism. This is why we need this... */
130 +#include <sys/mkdev.h>
132 +#define LCK_NODEV -1
133 +#define LCK_OPNFAIL -2
138 +int add_lock_to_list(char *device)
140 + s_ldev *temp_ldev, *ldev, *p_ldev = NULL;
142 + Debug(2, "add_lock: %s", device);
143 + for (ldev = locked_devices; ldev && strcmp(ldev->name, device);
144 + p_ldev = ldev, ldev = ldev->next);
146 + if (ldev) { /* we had it already */
147 + Msg("add_lock: That lock was already on my list");
151 + if (!(temp_ldev = (s_ldev *) malloc(sizeof(s_ldev))))
154 + if (!(temp_ldev->name = (char *) malloc(strlen(device)+1)))
157 + strcpy(temp_ldev->name, device);
158 + temp_ldev->next = NULL;
160 + p_ldev->next = temp_ldev;
162 + locked_devices = temp_ldev;
166 +int remove_lock_from_list(char *device)
168 + s_ldev *ldev, *p_ldev = NULL;
170 + Debug(2, "remove_lock: %s", device);
171 + for (ldev = locked_devices; ldev && strcmp(ldev->name, device);
172 + p_ldev = ldev, ldev = ldev->next);
174 + Msg("remove_lock: That lock wasn't on my list");
179 + p_ldev->next = ldev->next;
181 + locked_devices = ldev->next;
186 +int lock_is_on_list(char *device)
189 + for (ldev = locked_devices; ldev && strcmp(ldev->name, device);
190 + ldev = ldev->next);
192 + Debug(2, "lock_is_on_list: not found: %s", device);
195 + Debug(2, "lock_is_on_list: FOUND: %s", device);
202 + * makelock() - attempt to create a lockfile
204 + * Returns FAIL if lock could not be made (line in use).
207 +int makelock(char *device)
210 + char *temp, buf[MAXLINE+1];
212 + char lock[MAXLINE+1];
214 + s_ldev *ldev, *temp_ldev;
215 + Debug(2, "makelock: %s", device);
216 + for (ldev = locked_devices; ldev; ldev = ldev->next) {
217 + if (!strcmp(device, locked_devices->name)) {
218 + Msg("We already had a lock");
223 + if (get_lock_name(lock, device) == NULL) {
224 + Error("Cannot get lock filename");
227 + Debug(2, "makelock: lock='%s'", lock);
229 + /* first make a temp file */
232 + /* secure, but not as portable */
234 + sprintf(buf, LOCK, "TM.XXXXXX");
235 + if ((fd = mkstemp(temp)) == FAIL ) {
236 + Error("cannot create tempfile (%s)", temp);
240 + /* portable, but subject to some problems on some platforms */
242 + sprintf(buf, LOCK, "TM.XXXXXX");
243 + temp = mktemp(buf);
245 + if ((fd = open(temp, O_CREAT|O_WRONLY|O_EXCL, 0644)) == FAIL) {
246 + Error("cannot create tempfile (%s)", temp);
247 + if ( errno == EEXIST && ++tries < 20 ) goto again;
252 + /* just in case some "umask" is set (errors are ignored) */
253 + chmod( temp, 0644 );
255 + /* put my pid in it */
256 + if ( lock_write_pid( fd ) == FAIL)
257 + { unlink(temp); return FAIL; }
259 + /* link it to the lock file */
261 + while (link(temp, lock) == FAIL)
263 + if (errno != EEXIST )
265 + Error("lock not made: link(temp,lock) failed" );
268 + if (errno == EEXIST) /* lock file already there */
270 + if ((pid = readlock(lock)) == FAIL)
272 + if ( errno == ENOENT ) /* disappeared */
276 + Debug(2, "cannot read lockfile" );
282 + if (pid == getpid()) /* huh? WE locked the line!*/
284 + Msg("we *have* the line!" );
288 + if ((kill(pid, 0) == FAIL) && errno == ESRCH)
290 + /* pid that created lockfile is gone */
291 + Debug(2, "stale lockfile, created by process %d, ignoring", pid );
292 + if ( unlink(lock) < 0 &&
293 + errno != EINTR && errno != ENOENT )
295 + Error("unlink() failed, giving up" );
302 + Msg("lock not made: lock file exists (pid=%d)", pid);
303 + } /* if (errno == EEXIST) */
305 + (void) unlink(temp);
309 + Debug(2, "lock made");
310 + (void) unlink(temp);
312 + Msg("Locking device");
313 + add_lock_to_list(device);
318 + * checklock() - test for presence of valid lock file
320 + * if lockfile found, return PID of process holding it, 0 otherwise
323 +int checklock (char *device)
327 + char name[MAXLINE+1];
329 + if ( get_lock_name( name, device ) == NULL )
331 + Error("cannot get lock name" );
335 + if ((stat(name, &st) == FAIL) && errno == ENOENT)
337 + Debug(2, "checklock: stat failed, no file");
341 + if ((pid = readlock(name)) == FAIL)
343 + Msg("checklock: couldn't read lockfile");
347 + if (pid == getpid())
349 + Msg("huh? It's *our* lock file!" );
353 + if ((kill(pid, 0) == FAIL) && errno == ESRCH)
355 + Debug(2, "checklock: no active process has lock, will remove");
356 + (void) unlink(name);
360 + Debug(2, "lockfile found, pid=%d", pid );
366 + * readlock() - read contents of lockfile
368 + * Returns pid read or FAIL on error.
373 +int readlock (char *name)
379 + if ((fd = open(name, O_RDONLY)) == FAIL)
382 + length = read(fd, apid, sizeof(apid)-1);
383 + apid[length]=0; /* make sscanf() happy */
386 + if ( length == sizeof( pid ) || sscanf(apid, "%d", &pid) != 1 ||
389 + pid = * ( (int *) apid );
390 +#if LOCKS_BINARY == 0
391 + Msg("compiled with ascii locks, found binary lock file (length=%d, pid=%d)!", length, pid );
394 +#if LOCKS_BINARY == 1
397 + Msg("compiled with binary locks, found ascii lock file (length=%d, pid=%d)!", length, pid );
407 + * write contents of lock file: my process ID in specified format
411 +int lock_write_pid (int fd)
414 + int bpid; /* must be 4 bytes wide! */
416 + if ( write(fd, &bpid, sizeof(bpid) ) != sizeof(bpid) )
419 + sprintf( apid, "%10d\n", (int) getpid() );
420 + if ( write(fd, apid, strlen(apid)) != strlen(apid) )
423 + Error("cannot write PID to (temp) lock file" );
432 + * rmlocks() - remove lockfile
436 +void rmlocks(char *device)
438 + char lock[MAXLINE + 1];
439 + Debug(2, "rmlocks: %s", device);
440 + get_lock_name(lock, device);
441 + Debug(2, "rmlocks: lock: %s", lock);
442 + if (lock_is_on_list(device))
444 + Msg("Removing lock file" );
445 + if (unlink(lock) == -1 )
446 + Error("error removing lock file (huh?!)" );
447 + /* mark lock file as 'not set' */
448 + remove_lock_from_list(device);
454 + * determine full path + name of the lock file for a given device
460 + * get_lock_name() - create SVR4 lock file name (Bodo Bauer)
463 +char *get_lock_name (char* lock, char* fax_tty)
466 + char ttyname[FILENAME_MAX];
468 + Debug(2, "get_lock_name(%s) called", fax_tty);
470 + if ( strncmp( fax_tty, "/dev/", 5 ) == 0 )
471 + strcpy( ttyname, fax_tty );
473 + sprintf(ttyname, "/dev/%s", fax_tty);
475 + Debug(2, "-> ttyname %s", ttyname);
477 + if (stat(ttyname, &tbuf) < 0) {
478 + if(errno == ENOENT) {
479 + Debug(2, "device does not exist: %s", ttyname);
482 + Debug(2, "could not access line: %s", ttyname);
487 + sprintf(lock,"%s/LK.%03u.%03u.%03u",
489 + major(tbuf.st_dev),
490 + tbuf.st_rdev >> 18,
491 + minor(tbuf.st_rdev));
493 + Debug(2, "lock file: %s", lock);
497 +#else /* not SVR4 */
499 +char * get_lock_name (char * lock_name, char * device)
501 +#ifdef LOCKS_LOWERCASE
502 + /* sco locking convention -> change all device names to lowercase */
506 + if ( ( i = strlen( device ) ) > sizeof(p) )
508 + Error("get_lock_name: device name too long" );
512 +#ifdef LOCKS_ALL_LOWERCASE
513 + /* convert the full name */
516 + p[i] = tolower( device[i] ); i--;
519 + /* convert only the last character */
520 + strcpy( p, device );
522 + p[i] = tolower( p[i] );
526 +#endif /* LOCKS_LOWERCASE */
528 + /* throw out all directory prefixes */
529 + if ( strchr( device, '/' ) != NULL )
530 + device = strrchr( device, '/' ) +1;
532 + sprintf( lock_name, LOCK, device);
538 diff -Naur conserver-8.1.16-p/conserver/locks.h conserver-8.1.16/conserver/locks.h
539 --- conserver-8.1.16-p/conserver/locks.h 1970-01-01 01:00:00.000000000 +0100
540 +++ conserver-8.1.16/conserver/locks.h 2007-06-20 11:00:43.957110525 +0200
544 +#define LOCK "/tmp/LCK..%s"
545 +#define MAXLINE 1024
546 +#define FALSE (1==0)
552 +int makelock (char *device);
553 +// int makelock_file ( char * lockname );
554 +int checklock (char *device);
556 +// int steal_lock (char * device, int pid );
559 +typedef struct _s_ldev {
561 + struct _s_ldev *next;
564 +static s_ldev *locked_devices = NULL;
566 +int readlock (char *name);
567 +int makelock (char *name);
568 +char *get_lock_name (char *lock_name, char *device);
569 +int lock_write_pid (int fd);
572 diff -Naur conserver-8.1.16-p/conserver/main.c conserver-8.1.16/conserver/main.c
573 --- conserver-8.1.16-p/conserver/main.c 2007-06-20 10:57:27.005645786 +0200
574 +++ conserver-8.1.16/conserver/main.c 2007-06-20 11:03:43.950164075 +0200
576 EMPTYSTR(pCE->motd), pCE->idletimeout,
577 EMPTYSTR(pCE->idlestring),
578 EMPTYSTR(pCE->replstring)));
580 + "DumpDataStructures(): lock=%s",
581 + FLAGSTR(pCE->lock)));
584 for (u = pCE->ro; u != (CONSENTUSERS *)0; u = u->next) {
585 diff -Naur conserver-8.1.16-p/conserver/readcfg.c conserver-8.1.16/conserver/readcfg.c
586 --- conserver-8.1.16-p/conserver/readcfg.c 2007-06-20 10:57:27.009645531 +0200
587 +++ conserver-8.1.16/conserver/readcfg.c 2007-06-20 11:16:56.671710166 +0200
589 c->unloved = d->unloved;
590 if (d->login != FLAGUNKNOWN)
592 + if (d->lock != FLAGUNKNOWN)
594 if (d->host != (char *)0) {
595 if (c->host != (char *)0)
597 @@ -1669,6 +1671,7 @@
598 c->autoreinit = FLAGUNKNOWN;
599 c->unloved = FLAGUNKNOWN;
600 c->login = FLAGUNKNOWN;
601 + c->lock = FLAGUNKNOWN;
605 @@ -1706,6 +1709,8 @@
606 c->unloved = negative ? FLAGFALSE : FLAGTRUE;
607 else if (strcasecmp("login", token) == 0)
608 c->login = negative ? FLAGFALSE : FLAGTRUE;
609 + else if (strcasecmp("lock", token) == 0)
610 + c->lock = negative ? FLAGFALSE : FLAGTRUE;
612 Error("invalid option `%s' [%s:%d]", token, file, line);
614 @@ -3053,6 +3058,7 @@
615 pCEmatch->autoreinit = c->autoreinit;
616 pCEmatch->unloved = c->unloved;
617 pCEmatch->login = c->login;
618 + pCEmatch->lock = c->lock;
619 pCEmatch->inituid = c->inituid;
620 pCEmatch->initgid = c->initgid;
621 while (pCEmatch->aliases != (NAMES *)0) {
622 @@ -3231,6 +3237,8 @@
624 if (c->ondemand == FLAGUNKNOWN)
625 c->ondemand = FLAGFALSE;
626 + if (c->lock == FLAGUNKNOWN)
627 + c->lock = FLAGFALSE;
628 if (c->reinitoncc == FLAGUNKNOWN)
629 c->reinitoncc = FLAGFALSE;
630 if (c->striphigh == FLAGUNKNOWN)
631 diff -Naur conserver-8.1.16-p/conserver.cf/conserver.cf.man conserver-8.1.16/conserver.cf/conserver.cf.man
632 --- conserver-8.1.16-p/conserver.cf/conserver.cf.man 2007-06-20 10:57:26.997646295 +0200
633 +++ conserver-8.1.16/conserver.cf/conserver.cf.man 2007-06-20 11:00:43.969109761 +0200
639 +Lock the device using UUCP-style locks.
644 Strip the high bit off all data coming from this console and all clients
645 connected to this console before processing occurs.