1 diff -Naur conserver-8.1.9/configure.in conserver-8.1.9-p/configure.in
2 --- conserver-8.1.9/configure.in Sun May 30 18:50:32 2004
3 +++ conserver-8.1.9-p/configure.in Fri Aug 6 23:23:02 2004
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.9/conserver/Makefile.in conserver-8.1.9-p/conserver/Makefile.in
28 --- conserver-8.1.9/conserver/Makefile.in Tue Feb 10 01:32:28 2004
29 +++ conserver-8.1.9-p/conserver/Makefile.in Fri Aug 6 22:11:26 2004
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.9/conserver/consent.c conserver-8.1.9-p/conserver/consent.c
45 --- conserver-8.1.9/conserver/consent.c Thu Jun 3 23:53:59 2004
46 +++ conserver-8.1.9-p/conserver/consent.c Sat Aug 7 00:20:34 2004
57 close(pCE->execSlaveFD);
60 + if (pCE->type == DEVICE && pCE->lock == FLAGTRUE) {
61 + rmlocks(pCE->device);
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.9/conserver/consent.h conserver-8.1.9-p/conserver/consent.h
89 --- conserver-8.1.9/conserver/consent.h Wed Jun 2 01:45:47 2004
90 +++ conserver-8.1.9-p/conserver/consent.h Fri Aug 6 22:41:11 2004
92 FLAG striphigh; /* strip high-bit of console data */
93 FLAG autoreinit; /* auto-reinitialize if failed */
94 FLAG unloved; /* copy "unloved" data to stdout */
95 + FLAG lock; /* lock the device */
97 /*** runtime settings ***/
98 CONSFILE *fdlog; /* the local log file */
99 diff -Naur conserver-8.1.9/conserver/locks.c conserver-8.1.9-p/conserver/locks.c
100 --- conserver-8.1.9/conserver/locks.c Thu Jan 1 01:00:00 1970
101 +++ conserver-8.1.9-p/conserver/locks.c Sat Aug 7 00:21:23 2004
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.9/conserver/locks.h conserver-8.1.9-p/conserver/locks.h
539 --- conserver-8.1.9/conserver/locks.h Thu Jan 1 01:00:00 1970
540 +++ conserver-8.1.9-p/conserver/locks.h Fri Aug 6 23:12:48 2004
543 +#define LOCK "/var/lock/LCK..%s"
544 +#define MAXLINE 1024
545 +#define FALSE (1==0)
550 +typedef void RETSIGTYPE;
552 +int makelock (char *device);
553 +// int makelock_file ( char * lockname );
554 +int checklock (char *device);
555 +RETSIGTYPE rmlocks ();
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.9/conserver/main.c conserver-8.1.9-p/conserver/main.c
573 --- conserver-8.1.9/conserver/main.c Wed Jul 14 07:28:42 2004
574 +++ conserver-8.1.9-p/conserver/main.c Fri Aug 6 22:38:37 2004
576 "DumpDataStructures(): motd=%s, idletimeout=%d, idlestring=%s",
577 EMPTYSTR(pCE->motd), pCE->idletimeout,
578 EMPTYSTR(pCE->idlestring)));
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.9/conserver/readcfg.c conserver-8.1.9-p/conserver/readcfg.c
586 --- conserver-8.1.9/conserver/readcfg.c Wed Jul 14 07:28:42 2004
587 +++ conserver-8.1.9-p/conserver/readcfg.c Fri Aug 6 22:42:11 2004
588 @@ -1401,6 +1401,7 @@
589 c->reinitoncc = FLAGUNKNOWN;
590 c->autoreinit = FLAGUNKNOWN;
591 c->unloved = FLAGUNKNOWN;
592 + c->lock = FLAGUNKNOWN;
596 @@ -1436,6 +1437,8 @@
597 c->autoreinit = negative ? FLAGFALSE : FLAGTRUE;
598 else if (strcasecmp("unloved", token) == 0)
599 c->unloved = negative ? FLAGFALSE : FLAGTRUE;
600 + else if (strcasecmp("lock", token) == 0)
601 + c->lock = negative ? FLAGFALSE : FLAGTRUE;
603 Error("invalid option `%s' [%s:%d]", token, file, line);
605 @@ -2711,6 +2714,7 @@
606 pCEmatch->reinitoncc = c->reinitoncc;
607 pCEmatch->autoreinit = c->autoreinit;
608 pCEmatch->unloved = c->unloved;
609 + pCEmatch->lock = c->lock;
610 while (pCEmatch->aliases != (NAMES *)0) {
612 name = pCEmatch->aliases->next;
613 @@ -2881,6 +2885,8 @@
615 if (c->ondemand == FLAGUNKNOWN)
616 c->ondemand = FLAGFALSE;
617 + if (c->lock == FLAGUNKNOWN)
618 + c->lock = FLAGFALSE;
619 if (c->reinitoncc == FLAGUNKNOWN)
620 c->reinitoncc = FLAGFALSE;
621 if (c->striphigh == FLAGUNKNOWN)