The definitive fix for tips' lock file problem
David Herron, NPR Lover
david at ukma.UUCP
Mon Jul 8 10:49:05 AEST 1985
Index: /usr/src/usr.bin/tip/{cu.c,tip.c,tip.h,uucplock.c}
Unix-Version: BRL-Unix Release 3 (but not very different from 4.2BSD tip)
Date: 7-July-1985
Summary: The definitive fix for the tip lock file problem.
Problem: As distributed, tip doesn't work. There are two specific
problems. One is that it doesn't remove lock files. Examining
the comments in the RCS logs shows that y'all were heading that
direction but had never made it. The other problem is that
it doesn't do wls at astrovax's dialin and out stuff.
I'm sending the revisions I made which finished the stuff y'all were
doing for the lock files. I am assuming you have wls's code and
will put it in yourselves. (If not, I *can* forward it).
Explanation: This is being posted to net.bugs.4bsd because the fix
is needed, and should easily slide into place. The only
problem is that in 4.2BSD tip, finish() calls delock().
The BRL people had deleted this call in preparation
for code like this but had never installed the rest of it.
Description: I put a trap in tip (by calling a routine called "Parent()")
at the point just before it setuid()'s. Parent() fork()'s and
the child returns immediately to continue on with setuid()'s
and all the rest. In the meantime, the parent is setting up
two things. One is a SIGALRM every 10 minutes which will
touch the lock file (I'm using ultouch() from uucp). (I'm doing
this for people who sit in tip for days at a time :-)). The other
is a loop which is doing wait3()'s looking for stopped/dead/dying
children. For dead children the parent deletes the lock file
and exits. For stopped children it stops itself then when it
wakes up sends a SIGCONT to the children.
Something-I-Am-Thinking-About: There was a suggestion the Will Sebok
posted about a month ago. It was for tip to have a set of
variables which identified the commands to run for file
transfers. For instance. One variable is "sendfile_here"
(more thought will come up with a better name) which would
be defined as "kermit -l /dev/ttyxx -b 1200 -s %s". The
%s is substituted to be the name of the file to send. There's
a corresponding variable to use as the command string for the
other side. Ckermit will have to be modified to have an
"override the lock file" switch is the biggest problem.
But, I think you get the idea.
David Herron
cbosgd!ukma!david
RCS file: RCS/cu.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** /tmp/,RCSt1002886 Sun Jul 7 20:04:30 1985
--- /tmp/,RCSt2002886 Sun Jul 7 20:04:32 1985
***************
*** 1,7
/*
* C U . C
*
! * $Revision: 1.2 $
*
* $Log: cu.c,v $
* Revision 1.2 83/12/13 23:51:47 dpk
--- 1,7 -----
/*
* C U . C
*
! * $Revision: 1.3 $
*
* $Log: cu.c,v $
* Revision 1.3 85/07/07 14:06:21 root
***************
*** 4,9
* $Revision: 1.2 $
*
* $Log: cu.c,v $
* Revision 1.2 83/12/13 23:51:47 dpk
* Added distinctive RCS header
*
--- 4,20 -----
* $Revision: 1.3 $
*
* $Log: cu.c,v $
+ * Revision 1.3 85/07/07 14:06:21 root
+ * New method to solve the lock file problem. We keep a process around who
+ * is still setuid. This is done by fork()ing before the setuid. The
+ * parent goes into a loop waiting for children to die. (Also watches
+ * for children SIGSTOP so it can STOP itself, also touches the lock
+ * file (using ultouch() from uucp) every TOUCHTIME seconds.)
+ *
+ * Look at Parent().
+ *
+ * ukma!david
+ *
* Revision 1.2 83/12/13 23:51:47 dpk
* Added distinctive RCS header
*
***************
*** 9,15
*
*/
#ifndef lint
! static char RCSid[] = "@(#)$Header: cu.c,v 1.2 83/12/13 23:51:47 dpk BRL $";
#endif
#ifndef lint
--- 20,26 -----
*
*/
#ifndef lint
! static char RCSid[] = "@(#)$Header: cu.c,v 1.3 85/07/07 14:06:21 root Exp $";
#endif
#ifndef lint
***************
*** 20,25
int cleanup();
int timeout();
/*
* Botch the interface to look like cu's
--- 31,37 -----
int cleanup();
int timeout();
+ int touchlock();
/*
* Botch the interface to look like cu's
***************
*** 29,34
{
register int i;
static char sbuf[12];
if (argc < 2) {
printf("usage: cu telno [-t] [-s speed] [-a acu] [-l line] [-#]\n");
--- 41,47 -----
{
register int i;
static char sbuf[12];
+ extern int Parent();
if (argc < 2) {
printf("usage: cu telno [-t] [-s speed] [-a acu] [-l line] [-#]\n");
***************
*** 95,100
}
setbuf(stdout, NULL);
loginit();
setuid(getuid());
setgid(getgid());
vinit();
--- 108,114 -----
}
setbuf(stdout, NULL);
loginit();
+ Parent(); /* child returns, parent never returns */
setuid(getuid());
setgid(getgid());
vinit();
RCS file: RCS/tip.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** /tmp/,RCSt1002932 Sun Jul 7 20:06:11 1985
--- /tmp/,RCSt2002932 Sun Jul 7 20:06:17 1985
***************
*** 1,7
/*
* T I P . C
*
! * $Revision: 1.2 $
*
* $Log: tip.c,v $
* Revision 1.2 83/12/13 23:52:37 dpk
--- 1,7 -----
/*
* T I P . C
*
! * $Revision: 1.3 $
*
* $Log: tip.c,v $
* Revision 1.3 85/07/07 13:57:25 root
***************
*** 4,9
* $Revision: 1.2 $
*
* $Log: tip.c,v $
* Revision 1.2 83/12/13 23:52:37 dpk
* Added distinctive RCS header
*
--- 4,20 -----
* $Revision: 1.3 $
*
* $Log: tip.c,v $
+ * Revision 1.3 85/07/07 13:57:25 root
+ * New method to solve the lock file problem. We keep a process around who
+ * is still setuid. This is done by fork()ing before the setuid. The
+ * parent goes into a loop waiting for children to die. (Also watches
+ * for children SIGSTOP so it can STOP itself, also touches the lock
+ * file (using ultouch() from uucp) every TOUCHTIME seconds.)
+ *
+ * Look at Parent().
+ *
+ * ukma!david
+ *
* Revision 1.2 83/12/13 23:52:37 dpk
* Added distinctive RCS header
*
***************
*** 9,15
*
*/
#ifndef lint
! static char RCSid[] = "@(#)$Header: tip.c,v 1.2 83/12/13 23:52:37 dpk BRL $";
#endif
#ifndef lint
--- 20,26 -----
*
*/
#ifndef lint
! static char RCSid[] = "@(#)$Header: tip.c,v 1.3 85/07/07 13:57:25 root Exp $";
#endif
#ifndef lint
***************
*** 22,27
* or
* cu phone-number [-s speed] [-l line] [-a acu]
*/
#include "tip.h"
/*
--- 33,41 -----
* or
* cu phone-number [-s speed] [-l line] [-a acu]
*/
+ #include <sys/time.h>
+ #include <sys/resource.h>
+ #include <sys/wait.h>
#include "tip.h"
/*
***************
*** 33,38
};
int disc = OTTYDISC; /* tip normally runs this way */
int intprompt();
int timeout();
int cleanup();
--- 47,53 -----
};
int disc = OTTYDISC; /* tip normally runs this way */
+ int touchlock();
int intprompt();
int timeout();
int cleanup();
***************
*** 47,52
register char *p;
char sbuf[12];
if (equal(sname(argv[0]), "cu")) {
cumain(argc, argv);
cumode = 1;
--- 62,71 -----
register char *p;
char sbuf[12];
+ ioctl(0, TIOCGETP, (char *)&defarg);
+ ioctl(0, TIOCGETC, (char *)&defchars);
+ ioctl(0, TIOCGLTC, (char *)&deflchars);
+ ioctl(0, TIOCGETD, (char *)&odisc);
if (equal(sname(argv[0]), "cu")) {
cumain(argc, argv);
cumode = 1;
***************
*** 107,112
}
setbuf(stdout, NULL);
loginit();
/*
* Now that we have the logfile and the ACU open
* return to the real uid and gid. These things will
--- 126,132 -----
}
setbuf(stdout, NULL);
loginit();
+ Parent(); /* It is the CHILD that returns from this ... */
/*
* Now that we have the logfile and the ACU open
* return to the real uid and gid. These things will
***************
*** 150,159
* From here down the code is shared with
* the "cu" version of tip.
*/
- ioctl(0, TIOCGETP, (char *)&defarg);
- ioctl(0, TIOCGETC, (char *)&defchars);
- ioctl(0, TIOCGLTC, (char *)&deflchars);
- ioctl(0, TIOCGETD, (char *)&odisc);
arg = defarg;
arg.sg_flags = ANYP | CBREAK;
tchars = defchars;
--- 170,175 -----
* From here down the code is shared with
* the "cu" version of tip.
*/
arg = defarg;
arg.sg_flags = ANYP | CBREAK;
tchars = defchars;
***************
*** 508,511
}
fprintf(stderr, "%s: unknown parity value\n", PA);
fflush(stderr);
}
--- 524,579 -----
}
fprintf(stderr, "%s: unknown parity value\n", PA);
fflush(stderr);
+ }
+
+ /*
+ * code for the parent to touch the lock file.
+ */
+ touchlock()
+ {
+ ultouch();
+ printf("touchlock()\r\n"); /* DEBUG */
+ signal(SIGALRM, touchlock);
+ alarm(TOUCHTIME);
+ }
+
+ /*
+ * Parent() -- Be a big daddy and watch for the children to die off.
+ *
+ * fork() off so the child can change user id's. The parent
+ * will be up here watching for the child to exit, and when
+ * it does it will remove the lock file and reenable the modem
+ * (if necessary). It will also touch the lock file from
+ * time to time.
+ */
+ Parent()
+ {
+ union wait chstatus;
+ struct rusage rusage;
+ int child;
+
+ if ((child = fork()) != 0) {
+ /* parent */
+ touchlock();
+ /* STRUCTURE ALERT!!! */
+ loop:
+ while (wait3(&chstatus, WUNTRACED, &rusage) != child)
+ printf("waiting ...\r\n");
+ if (chstatus.w_stopval == WSTOPPED) {
+ /*
+ * Child has stopped because of ~^Z command
+ */
+ kill(0, SIGTSTP);
+ goto loop;
+ }
+ /* else */
+ kill(child, SIGTERM);
+ delock(uucplock);
+ printf("done\r\n");
+ /* make sure ... */
+ unraw();
+ exit(chstatus);
+ }
+ else
+ return;
}
RCS file: RCS/tip.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -r1.2 -r1.3
*** /tmp/,RCSt1002940 Sun Jul 7 20:06:53 1985
--- /tmp/,RCSt2002940 Sun Jul 7 20:06:54 1985
***************
*** 1,7
/*
* T I P . H
*
! * $Revision: 1.2 $
*
* $Log: tip.h,v $
* Revision 1.2 83/12/13 23:53:25 dpk
--- 1,7 -----
/*
* T I P . H
*
! * $Revision: 1.3 $
*
* $Log: tip.h,v $
* Revision 1.3 85/07/07 14:06:25 root
***************
*** 4,9
* $Revision: 1.2 $
*
* $Log: tip.h,v $
* Revision 1.2 83/12/13 23:53:25 dpk
* Added distinctive RCS header
*
--- 4,20 -----
* $Revision: 1.3 $
*
* $Log: tip.h,v $
+ * Revision 1.3 85/07/07 14:06:25 root
+ * New method to solve the lock file problem. We keep a process around who
+ * is still setuid. This is done by fork()ing before the setuid. The
+ * parent goes into a loop waiting for children to die. (Also watches
+ * for children SIGSTOP so it can STOP itself, also touches the lock
+ * file (using ultouch() from uucp) every TOUCHTIME seconds.)
+ *
+ * Look at Parent().
+ *
+ * ukma!david
+ *
* Revision 1.2 83/12/13 23:53:25 dpk
* Added distinctive RCS header
*
***************
*** 245,247
extern char *index();
extern char *malloc();
extern char *connect();
--- 256,260 -----
extern char *index();
extern char *malloc();
extern char *connect();
+ #define TOUCHTIME 600
+ extern int ultouch();
RCS file: RCS/uucplock.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -c -r1.3 -r1.4
*** /tmp/,RCSt1002955 Sun Jul 7 20:07:29 1985
--- /tmp/,RCSt2002955 Sun Jul 7 20:07:35 1985
***************
*** 1,7
/*
* U U C P L O C K . C
*
! * $Revision: 1.3 $
*
* $Log: uucplock.c,v $
* Revision 1.3 84/10/12 17:05:18 dpk
--- 1,7 -----
/*
* U U C P L O C K . C
*
! * $Revision: 1.4 $
*
* $Log: uucplock.c,v $
* Revision 1.4 85/07/07 14:06:32 root
***************
*** 4,9
* $Revision: 1.3 $
*
* $Log: uucplock.c,v $
* Revision 1.3 84/10/12 17:05:18 dpk
* Increased sizeof lockfile name array.
* Size is now 64.
--- 4,20 -----
* $Revision: 1.4 $
*
* $Log: uucplock.c,v $
+ * Revision 1.4 85/07/07 14:06:32 root
+ * New method to solve the lock file problem. We keep a process around who
+ * is still setuid. This is done by fork()ing before the setuid. The
+ * parent goes into a loop waiting for children to die. (Also watches
+ * for children SIGSTOP so it can STOP itself, also touches the lock
+ * file (using ultouch() from uucp) every TOUCHTIME seconds.)
+ *
+ * Look at Parent().
+ *
+ * ukma!david
+ *
* Revision 1.3 84/10/12 17:05:18 dpk
* Increased sizeof lockfile name array.
* Size is now 64.
***************
*** 13,19
*
*/
#ifndef lint
! static char RCSid[] = "@(#)$Header: uucplock.c,v 1.3 84/10/12 17:05:18 dpk Exp $";
#endif
#ifndef lint
--- 24,30 -----
*
*/
#ifndef lint
! static char RCSid[] = "@(#)$Header: uucplock.c,v 1.4 85/07/07 14:06:32 root Exp $";
#endif
#ifndef lint
***************
*** 33,38
}
#define LOCKPRE "/usr/spool/uucp/LCK."
/*
* This code is taken almost directly from uucp and follows the same
--- 44,50 -----
}
#define LOCKPRE "/usr/spool/uucp/LCK."
+ #define LCKMODE 0664
/*
* This code is taken almost directly from uucp and follows the same
***************
*** 184,190
{
int fd;
! fd = creat(tempfile, 0444);
if (fd < 0)
return (-1);
write(fd,(char *)&pid, sizeof(int));
--- 196,202 -----
{
int fd;
! fd = creat(tempfile, LCKMODE);
if (fd < 0)
return (-1);
write(fd,(char *)&pid, sizeof(int));
***************
*** 226,229
char lname[30];
sprintf(lname, "%s.%s", LOCKPRE, sys);
return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0);
}
--- 238,281 -----
char lname[30];
sprintf(lname, "%s.%s", LOCKPRE, sys);
return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0);
+ }
+
+ /***
+ * ultouch() update 'change' time for lock files
+ *
+ * -- mod by rti!trt --
+ * Only update ctime, not mtime or atime.
+ * The 'chmod' method permits cu(I)-like programs
+ * to determine how long uucp has been on the line.
+ * The old "change access, mod, and change time" method
+ * can be had by defining OLDTOUCH
+ *
+ * return code - none
+ */
+ ultouch()
+ {
+ time_t time();
+ static time_t lasttouch = 0;
+ register int i;
+ struct ut {
+ time_t actime;
+ time_t modtime;
+ } ut;
+
+ ut.actime = time(&ut.modtime);
+ /* Do not waste time touching locking files too often */
+ /* (But, defend against backward time changes) */
+ if (ut.actime >= lasttouch && ut.actime < lasttouch+60)
+ return;
+ lasttouch = ut.actime;
+
+ for (i = 0; i < Nlocks; i++) {
+ if (Lockfile[i] == NULL)
+ continue;
+ #ifdef OLDTOUCH
+ utime(Lockfile[i], &ut);
+ #else
+ chmod(Lockfile[i], LCKMODE);
+ #endif
+ }
}
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list