Previous bug report on learn in error +Fix
Gary Winiger
gww at beatnix.UUCP
Sun Mar 13 06:17:16 AEST 1988
Subject: Previous bug report on learn in error +Fix
Index: learn/copy.c 4.3BSD +Fix
Description:
Previously I reported problems in learn dereferencing NULL pointers
and not clearing EOF on files before continuing to read from them.
I was over zealous in clearing EOFs. I cleared the EOF on the
lesson file. That EOF is used to determine when all the lessons
on a topic have been completed. Having cleared the EOF, learn
didn't know a topic was completed and it tried to get the next
lesson. This resulted in a division by zero and an accompanying
floating point exception.
Repeat-By:
Install my previous fix in copy.c.
Complete a topic.
Get a floating point error and accompanying core dump.
Fix:
Only clear EOF on standard in.
Attached following the corrective code for learn/copy.c is the
original bug report.
The attached code solves this problem at Elxsi.
Gary..
{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
--------- cut --------- snip --------- :.,$w diff -------------
*** /tmp/,RCSt1001436 Fri Oct 23 11:36:21 1987
--- copy.c Fri Oct 23 11:34:20 1987
***************
*** 1,5 ****
--- 1,8 ----
/*
* $Log: copy.c,v $
+ * Revision 1.3 87/10/23 11:33:42 gww
+ * Only clear eof if file is standard in.
+ *
* Revision 1.2 86/12/30 14:36:21 gww
* Stop dereferencing null pointers.
* Stop looping on EOF from user.
***************
*** 9,15 ****
*
*/
#ifndef lint
! static char *ERcsId = "$Header: copy.c,v 1.2 86/12/30 14:36:21 gww Exp $ ENIX BSD";
static char sccsid[] = "@(#)copy.c 4.3 (Berkeley) 5/15/86";
#endif not lint
--- 12,18 ----
*
*/
#ifndef lint
! static char *ERcsId = "$Header: copy.c,v 1.3 87/10/23 11:33:42 gww Exp $ ENIX BSD";
static char sccsid[] = "@(#)copy.c 4.3 (Berkeley) 5/15/86";
#endif not lint
***************
*** 251,257 ****
if (fgets(s, 100,f))
return(1);
else {
! clearerr(f);
return(0);
}
}
--- 254,261 ----
if (fgets(s, 100,f))
return(1);
else {
! if (f == stdin)
! clearerr(f);
return(0);
}
}
---------------------------------------------------------------------------
---------------------- ORIGINAL BUG REPORT --------------------------------
---------------------------------------------------------------------------
>Subject: Learn dereferences null pointers and doesn't always clear EOF. +Fix
>Index: usr.bin/learn 4.3BSD +Fix
>
>Description:
> Procedure action can return a null. This is dereferenced before it
> is checked for.
> Procedure scopy is called many places with a NULL parameter. This
> is dereferenced before it is checked.
> In both copy.c and selsub.c an EOF condition can be encountered
> and is not reset before rereading the same file.
>Repeat-By:
> Having a machine that will not accept null pointers.
> Having users type ^D at unexpected places.
>Fix:
> The attached code resolves these problems at Elxsi.
>
>Gary..
>{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
>--------- cut --------- snip --------- :.,$w diff -------------
>*** /tmp/,RCSt1001152 Tue Dec 30 14:37:13 1986
>--- copy.c Tue Dec 30 14:36:53 1986
>***************
>*** 1,11 ****
> /*
> * $Log: copy.c,v $
> * Revision 1.1 86/12/30 14:15:54 gww
> * Initial revision
> *
> */
> #ifndef lint
>! static char *ERcsId = "$Header: copy.c,v 1.1 86/12/30 14:15:54 gww Exp $ ENIX BSD";
> static char sccsid[] = "@(#)copy.c 4.3 (Berkeley) 5/15/86";
> #endif not lint
>
>--- 1,15 ----
> /*
> * $Log: copy.c,v $
>+ * Revision 1.2 86/12/30 14:36:21 gww
>+ * Stop dereferencing null pointers.
>+ * Stop looping on EOF from user.
>+ *
> * Revision 1.1 86/12/30 14:15:54 gww
> * Initial revision
> *
> */
> #ifndef lint
>! static char *ERcsId = "$Header: copy.c,v 1.2 86/12/30 14:36:21 gww Exp $ ENIX BSD";
> static char sccsid[] = "@(#)copy.c 4.3 (Berkeley) 5/15/86";
> #endif not lint
>
>***************
>*** 56,62 ****
> }
> r = wordb(s, t); /* t = first token, r = rest */
> p = action(t); /* p = token class */
>! if (*p == ONCE) { /* some actions done only once per script */
> if (wrong && !review) { /* we are on 2nd time */
> scopy(fin, NULL);
> continue;
>--- 60,67 ----
> }
> r = wordb(s, t); /* t = first token, r = rest */
> p = action(t); /* p = token class */
>! if (p != 0 && *p == ONCE) {
>! /* some actions done only once per script */
> if (wrong && !review) { /* we are on 2nd time */
> scopy(fin, NULL);
> continue;
>***************
>*** 245,252 ****
> }
> if (fgets(s, 100,f))
> return(1);
>! else
> return(0);
> }
>
> trim(s)
>--- 250,259 ----
> }
> if (fgets(s, 100,f))
> return(1);
>! else {
>! clearerr(f);
> return(0);
>+ }
> }
>
> trim(s)
>***************
>*** 272,278 ****
> if (c == '\n')
> break;
> if (c == EOF) {
>! fflush(fo);
> return;
> }
> if (fo != NULL)
>--- 279,286 ----
> if (c == '\n')
> break;
> if (c == EOF) {
>! if (fo != NULL)
>! fflush(fo);
> return;
> }
> if (fo != NULL)
>***************
>*** 288,294 ****
> }
> if (c == '#')
> ungetc(c, fi);
>! fflush(fo);
> }
>
> cmp(r) /* compare two files for status; #cmp f1 f2 [ firstnlinesonly ] */
>--- 296,303 ----
> }
> if (c == '#')
> ungetc(c, fi);
>! if (fo != NULL)
>! fflush(fo);
> }
>
> cmp(r) /* compare two files for status; #cmp f1 f2 [ firstnlinesonly ] */
>*** /tmp/,RCSt1001135 Tue Dec 30 14:34:56 1986
>--- selsub.c Tue Dec 30 14:34:31 1986
>***************
>*** 1,11 ****
> /*
> * $Log: selsub.c,v $
> * Revision 1.1 86/12/30 14:16:15 gww
> * Initial revision
> *
> */
> #ifndef lint
>! static char *ERcsId = "$Header: selsub.c,v 1.1 86/12/30 14:16:15 gww Exp $ ENIX BSD";
> static char sccsid[] = "@(#)selsub.c 4.3 (Berkeley) 5/15/86";
> #endif not lint
>
>--- 1,14 ----
> /*
> * $Log: selsub.c,v $
>+ * Revision 1.2 86/12/30 14:34:02 gww
>+ * Stop loop on EOF from user.
>+ *
> * Revision 1.1 86/12/30 14:16:15 gww
> * Initial revision
> *
> */
> #ifndef lint
>! static char *ERcsId = "$Header: selsub.c,v 1.2 86/12/30 14:34:02 gww Exp $ ENIX BSD";
> static char sccsid[] = "@(#)selsub.c 4.3 (Berkeley) 5/15/86";
> #endif not lint
>
>***************
>*** 84,89 ****
>--- 87,93 ----
> if (sname[0] == '\0') {
> list("Xinfo");
> do {
>+ clearerr(stdin);
> printf("\nWhich subject? ");
> fflush(stdout);
> gets(sname=subname);
>
>From gww Fri Oct 30 09:53:26 1987
To: /RCS/Bugs
Subject: Fortran programs can't send all kill signals +Fix
Subject: Fortran programs can't send all kill signals +Fix
Index: libU77/kill_.c 4.3BSD +Fix
Description:
A fortran program calling kill(pid,signal) cannot send
signals greater than 15 even though there are 31 defined
signals.
Repeat-By:
By examination.
Fix:
The attached code solves this problem at Elxsi.
Gary..
{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
--------- cut --------- snip --------- :.,$w diff -------------
*** /tmp/,RCSt1020143 Fri Oct 30 09:46:48 1987
--- kill_.c Fri Oct 30 09:46:35 1987
***************
*** 1,6 ****
! /* $Header: kill_.c,v 1.1 87/01/05 17:23:37 gww Exp $ ENIX BSD
*
* $Log: kill_.c,v $
* Revision 1.1 87/01/05 17:23:37 gww
* Initial revision
*
--- 1,9 ----
! /* $Header: kill_.c,v 1.2 87/10/30 09:46:09 gww Exp $ ENIX BSD
*
* $Log: kill_.c,v $
+ * Revision 1.2 87/10/30 09:46:09 gww
+ * Permit fortran programs to send all kill signals.
+ *
* Revision 1.1 87/01/05 17:23:37 gww
* Initial revision
*
***************
*** 24,35 ****
* ierror will be 0 if successful; an error code otherwise.
*/
#include "../libI77/f_errno.h"
long kill_(pid, signum)
long *pid, *signum;
{
! if (*pid < 0 || *pid > 32767L || *signum < 1 || *signum > 16)
return((long)(errno=F_ERARG));
if (kill((int)*pid, (int)*signum) != 0)
return((long)errno);
--- 27,39 ----
* ierror will be 0 if successful; an error code otherwise.
*/
+ #include <signal.h>
#include "../libI77/f_errno.h"
long kill_(pid, signum)
long *pid, *signum;
{
! if (*pid < 0 || *pid > 32767L || *signum < 1 || *signum >= NSIG)
return((long)(errno=F_ERARG));
if (kill((int)*pid, (int)*signum) != 0)
return((long)errno);
>From gww Tue Dec 15 17:02:12 1987
To: /RCS/Bugs
Subject: mt dereferences a null pointer when printing register status +Fix
Subject: mt dereferences a null pointer when printing register status +FIX
Index: bin/mt.c 4.3BSD +Fix
Description:
When the status command is used for a tape type with a null field
for dsbits or erbits, a null pointer will be dereferenced.
Repeat-By:
On a system which does not permit dereferencing a null pointer run:
mt -f /dev/<device where dsbits or erbits is null> status
Take a core dump.
Fix:
Place a guard before dereferencing the null pointer.
The attached code solves this problem at Elxsi.
Gary..
{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
--------- cut --------- snip --------- :.,$w diff -------------
*** /tmp/,RCSt1014570 Tue Dec 15 16:53:33 1987
--- /tmp/,RCSt2014570 Tue Dec 15 16:53:34 1987
***************
*** 1,5 ****
--- 1,8 ----
/*
* $Log: mt.c,v $
+ * Revision 1.2 87/12/15 16:53:02 gww
+ * Prevent dereference of null pointer.
+ *
* Revision 1.1 86/12/17 18:14:20 gww
* Initial revision
*
***************
*** 17,23 ****
#endif not lint
#ifndef lint
! static char *ERcsId = "$Header: mt.c,v 1.1 86/12/17 18:14:20 gww Exp $ ENIX BSD";
static char sccsid[] = "@(#)mt.c 5.1 (Berkeley) 4/30/85";
#endif not lint
--- 20,26 ----
#endif not lint
#ifndef lint
! static char *ERcsId = "$Header: mt.c,v 1.2 87/12/15 16:53:02 gww Exp $ ENIX BSD";
static char sccsid[] = "@(#)mt.c 5.1 (Berkeley) 4/30/85";
#endif not lint
***************
*** 179,185 ****
printf("%s=%o", s, v);
else
printf("%s=%x", s, v);
! bits++;
if (v && bits) {
putchar('<');
while (i = *bits++) {
--- 182,189 ----
printf("%s=%o", s, v);
else
printf("%s=%x", s, v);
! if (bits)
! bits++;
if (v && bits) {
putchar('<');
while (i = *bits++) {
>From gww Sat Mar 12 10:53:28 1988
To: /RCS/Bugs
Subject: Vi core dumps on SIGINT input. +Fix
Index: ucb/ex/{ex_vget.c, ex_vmain.c, ex_voper.c} 4.3BSD +Fix
Description:
As previously reported:
When vi receives the a SIGINT, it can queue it as the input character
ATTN (value -2). This character is returned by getkey() (peekkey()).
In some cases, vi asks if the character received is an xxx with
``isxxx''. The ``isxxx'' macros index the array _ctype_[] to
determine the type of the character. If _ctype_ begins on a page
boundary and the previous page is not a valid page, a segment fault
will occur.
Thanks to Keith Bostic (bostic at ucbvax) for pointing out that my
previous fix was narrow in scope and could better be done as follows.
Repeat-By:
vi foo
<user types INTERRUPT character>
When _ctype_ begins on a page boundary and the previous page is not
valid.
Fix:
Guard against checking indexing _ctype_ when the character may be
ATTN.
The attached code solves this problem at Elxsi.
Gary..
{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
--------- cut --------- snip --------- :.,$w diff -------------
Index: ucb/ex/ex_vget.c
*** /tmp/,RCSt1014232 Sat Mar 12 10:57:36 1988
--- ex_vget.c Sat Mar 12 10:56:47 1988
***************
*** 1,5 ****
--- 1,13 ----
/*
* $Log: ex_vget.c,v $
+ * Revision 1.3 88/03/12 10:55:34 gww
+ * Correct guard against non-ascii index of _ctype_[]. Thanks to
+ * Keith Bostic (bostic at ucbvax).
+ *
+ * Revision 1.2 87/05/08 17:06:28 gww
+ * Check for ATTN (-2) before using isxxxx macro so as not to negatively
+ * index _ctype_[] and possibly get a segment fault.
+ *
* Revision 1.1 86/12/23 18:16:10 gww
* Initial revision
*
***************
*** 11,17 ****
*/
#ifndef lint
! static char *ERcsId = "$Header: ex_vget.c,v 1.1 86/12/23 18:16:10 gww Exp $ ENIX BSD";
static char *sccsid = "@(#)ex_vget.c 6.8 (Berkeley) 6/7/85";
#endif not lint
--- 19,25 ----
*/
#ifndef lint
! static char *ERcsId = "$Header: ex_vget.c,v 1.3 88/03/12 10:55:34 gww Exp $ ENIX BSD";
static char *sccsid = "@(#)ex_vget.c 6.8 (Berkeley) 6/7/85";
#endif not lint
***************
*** 624,630 ****
cnt = 0;
for (;;) {
c = getkey();
! if (!isdigit(c))
break;
cnt *= 10, cnt += c - '0';
}
--- 632,638 ----
cnt = 0;
for (;;) {
c = getkey();
! if (!isascii(c) || !isdigit(c))
break;
cnt *= 10, cnt += c - '0';
}
Index: ucb/ex/ex_vmain.c
*** /tmp/,RCSt1014237 Sat Mar 12 10:57:51 1988
--- ex_vmain.c Sat Mar 12 10:56:54 1988
***************
*** 1,5 ****
--- 1,13 ----
/*
* $Log: ex_vmain.c,v $
+ * Revision 1.3 88/03/12 10:56:48 gww
+ * Correct guard against non-ascii index of _ctype_[]. Thanks to
+ * Keith Bostic (bostic at ucbvax).
+ *
+ * Revision 1.2 87/05/08 17:08:01 gww
+ * Check for ATTN (-2) before using isxxxx macro so as not to negatively
+ * index _ctype_[] and possibly get a segment fault.
+ *
* Revision 1.1 86/12/23 18:16:13 gww
* Initial revision
*
***************
*** 11,17 ****
*/
#ifndef lint
! static char *ERcsId = "$Header: ex_vmain.c,v 1.1 86/12/23 18:16:13 gww Exp $ ENIX BSD";
static char *sccsid = "@(#)ex_vmain.c 7.7 (Berkeley) 6/7/85";
#endif not lint
--- 19,25 ----
*/
#ifndef lint
! static char *ERcsId = "$Header: ex_vmain.c,v 1.3 88/03/12 10:56:48 gww Exp $ ENIX BSD";
static char *sccsid = "@(#)ex_vmain.c 7.7 (Berkeley) 6/7/85";
#endif not lint
***************
*** 112,118 ****
if (trace)
fprintf(trace, "pc=%c",peekkey());
#endif
! if (isdigit(peekkey()) && peekkey() != '0') {
hadcnt = 1;
cnt = vgetcnt();
forbid (cnt <= 0);
--- 120,128 ----
if (trace)
fprintf(trace, "pc=%c",peekkey());
#endif
! if (isascii(peekkey()) &&
! isdigit(peekkey()) &&
! peekkey() != '0') {
hadcnt = 1;
cnt = vgetcnt();
forbid (cnt <= 0);
***************
*** 126,132 ****
* an 'empty' named buffer spec in the routine
* kshift (see ex_temp.c).
*/
! forbid (c == '0' || !isalpha(c) && !isdigit(c));
vreg = c;
}
reread:
--- 136,143 ----
* an 'empty' named buffer spec in the routine
* kshift (see ex_temp.c).
*/
! forbid (c == '0' ||
! isascii(c) && !isalpha(c) && !isdigit(c));
vreg = c;
}
reread:
***************
*** 158,164 ****
* to go back to the "for" to interpret it. Likewise
* for a buffer name.
*/
! if ((isdigit(c) && c!='0') || c == '"') {
ungetkey(c);
goto looptop;
}
--- 169,175 ----
* to go back to the "for" to interpret it. Likewise
* for a buffer name.
*/
! if ((isascii(c) && isdigit(c) && c!='0') || c == '"') {
ungetkey(c);
goto looptop;
}
Index: ucb/ex/ex_voper.c
*** /tmp/,RCSt1014242 Sat Mar 12 10:58:08 1988
--- ex_voper.c Sat Mar 12 10:57:00 1988
***************
*** 1,5 ****
--- 1,13 ----
/*
* $Log: ex_voper.c,v $
+ * Revision 1.3 88/03/12 10:56:56 gww
+ * Correct guard against non-ascii index of _ctype_[]. Thanks to
+ * Keith Bostic (bostic at ucbvax).
+ *
+ * Revision 1.2 87/05/08 17:08:08 gww
+ * Check for ATTN (-2) before using isxxxx macro so as not to negatively
+ * index _ctype_[] and possibly get a segment fault.
+ *
* Revision 1.1 86/12/23 18:16:15 gww
* Initial revision
*
***************
*** 11,17 ****
*/
#ifndef lint
! static char *ERcsId = "$Header: ex_voper.c,v 1.1 86/12/23 18:16:15 gww Exp $ ENIX BSD";
static char *sccsid = "@(#)ex_voper.c 7.4 (Berkeley) 6/7/85";
#endif not lint
--- 19,25 ----
*/
#ifndef lint
! static char *ERcsId = "$Header: ex_voper.c,v 1.3 88/03/12 10:56:56 gww Exp $ ENIX BSD";
static char *sccsid = "@(#)ex_voper.c 7.4 (Berkeley) 6/7/85";
#endif not lint
***************
*** 133,139 ****
* Had an operator, so accept another count.
* Multiply counts together.
*/
! if (isdigit(peekkey()) && peekkey() != '0') {
cnt *= vgetcnt();
Xcnt = cnt;
forbid (cnt <= 0);
--- 141,147 ----
* Had an operator, so accept another count.
* Multiply counts together.
*/
! if (isascii(peekkey()) && isdigit(peekkey()) && peekkey() != '0') {
cnt *= vgetcnt();
Xcnt = cnt;
forbid (cnt <= 0);
>From gww Fri Oct 23 12:09:38 1987
To: /RCS/Bugs
Subject: Previous bug report on abort(3) in error +Fix
Subject: Previous bug report on abort(3) in error +Fix
Index: libc/gen/abort.c 4.3BSD
Description:
I previously reported that when abort was called, there were certain
cases that it would continue with the user code before core was dumped.
Keith Bostic (bostic at ucbvax) kindly pointed out that there was probably
some other error in the kernel handling of signals:
``A signal is sent as soon as the process is next scheduled to run.
The bug report assumed that there was a multiprocessor, so presumably
the process could be running on one processor while the signal was
being sent on another processor. The problem is that the process
was sending a signal to itself (that is the `abort' library routine
sends the signal to the current process). It is semantically
incorrect for a process to be running in user code and kernel code
concurrently. Therefore the process must have been stopped while
it was doing the `kill' system call. hence when it next ran in user
code it would have to get the signal. Clearly the Elxsi implementation
subtlely violates the semantics of UNIX!''
Keith is clearly correct. I have since found the problem. The kernel
was returning to the user code to allow the user to complete the
`kill' system call before taking the action of the then pending signal.
My thanks to Keith for pointing this out.
Repeat-By:
Fix:
Don't install the suggested sigpause.
Gary..
{ucbvax!sun,uunet,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
---------------------------------------------------------------------------
---------------------- ORIGINAL BUG REPORT --------------------------------
---------------------------------------------------------------------------
>Subject: abort(3) returns to user. +fix
>Index: libc/gen/abort.c 4.3BSD
>
>Description:
> When abort is called, it may return to the user and continue
> processing before core is dumped.
>Repeat-By:
> Run a program that calls abort(3) on a multiprocessor system where
> the kernel process is on a different cpu from the user process.
> Examine the core dump stack trace with adb and notice that the
> program has continued to run after abort was called.
>Fix:
> It is possible for the user process calling abort() to continue
> after the abort before the kernel process gets it stopped.
> Add code to abort to wait for the kill signal to occur.
>
> The attached code modification solves this problem at Elxsi.
>
>Gary..
>{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
>--------- cut --------- snip --------- :.,$w diff -------------
>*** /tmp/,RCSt1001187 Thu Jun 18 17:56:07 1987
>--- abort.c Thu Jun 18 17:55:11 1987
>***************
>*** 1,5 ****
>--- 1,8 ----
> /*
> * $Log: abort.c,v $
>+ * Revision 1.2 87/06/18 17:54:12 gww
>+ * Guarantee abort doesn't return to user.
>+ *
> * Revision 1.1 87/01/15 15:35:03 gww
> * Initial revision
> *
>***************
>*** 11,17 ****
> */
>
> #if defined(LIBC_SCCS) && !defined(lint)
>! static char *ERcsId = "$Header: abort.c,v 1.1 87/01/15 15:35:03 gww Exp $ ENIX BSD";
> static char sccsid[] = "@(#)abort.c 5.3 (Berkeley) 3/9/86";
> #endif LIBC_SCCS and not lint
>
>--- 14,20 ----
> */
>
> #if defined(LIBC_SCCS) && !defined(lint)
>! static char *ERcsId = "$Header: abort.c,v 1.2 87/06/18 17:54:12 gww Exp $ ENIX BSD";
> static char sccsid[] = "@(#)abort.c 5.3 (Berkeley) 3/9/86";
> #endif LIBC_SCCS and not lint
>
>***************
>*** 25,28 ****
>--- 28,32 ----
> signal(SIGILL, SIG_DFL);
> sigsetmask(~sigmask(SIGILL));
> kill(getpid(), SIGILL);
>+ sigpause(~sigmask(SIGILL));
> }
To: /RCS/Bugs
Subject: Ident(1) doesn't report SCCS what strings. +Fix
Index: new/rcs/src/ident.c 4.3BSD
Description:
Berkeley distributes most routines with SCCS what strings. Many
of us use RCS to maintain the Berkeley code. It would be nice if
we could see the original what string as well as any RCS headers
that were in our maintained code.
Repeat-By:
Run ident as distributed
Procedure to repeat the problem.
Fix:
The attached code adds this feature at Elxsi.
Description of how to fix the problem.
If you don't know the fix, don't include this section or "Fix:".
Use with pleasure....
Gary..
{ucbvax!sun,uunet,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
--------- cut --------- snip --------- :.,$w diff -------------
Index: /usr/src/new/rcs/src/ident.c
*** /tmp/,RCSt1001229 Tue Aug 4 16:49:14 1987
--- ident.c Tue Aug 4 16:19:26 1987
***************
*** 1,10 ****
/*
* $Log: ident.c,v $
* Revision 1.1 86/12/09 17:33:50 gww
* Initial revision
*
*/
! static char *ERcsId = "$Header: ident.c,v 1.1 86/12/09 17:33:50 gww Exp $ ENIX BSD";
/*
* RCS identification operation
*/
--- 1,13 ----
/*
* $Log: ident.c,v $
+ * Revision 1.2 87/08/04 16:19:10 gww
+ * Add display of sccs what strings.
+ *
* Revision 1.1 86/12/09 17:33:50 gww
* Initial revision
*
*/
! static char *ERcsId = "$Header: ident.c,v 1.2 87/08/04 16:19:10 gww Exp $ ENIX BSD";
/*
* RCS identification operation
*/
***************
*** 69,74 ****
--- 72,79 ----
while( (c=getc(fp)) != EOF) {
if ( (char)c==KDELIM)
matchcount += match(fp);
+ else if ( (char)c=='@')
+ matchcount += what(fp);
}
if (matchcount == 0)
fprintf(stderr, "ident warning: no id keywords in %s\n", *argv);
***************
*** 132,135 ****
--- 137,161 ----
if (s[j] == VDELIM)
return(true);
return(false);
+ }
+
+
+ what(fp)
+ FILE *fp;
+
+ {
+ char line[keyvallength];
+ register int c;
+ register char * tp;
+
+ if ((getc(fp) == '(') && (getc(fp) == '#') && (getc(fp) == ')') ) {
+ tp = line;
+ while(((c = getc(fp)) != '\0') && (c != '\n') && (c != '"') &&
+ (c != EOF) && (tp <= line+keyvallength-1))
+ *tp++ = c;
+ *tp='\0';
+ fprintf(stdout," %s\n",line);
+ return(1);
+ } else
+ return(0);
}
Subject: Tar(1) cannot be positioned. +Fix:
Index: bin/tar.c 4.3BSD
Index: man1/tar.1
Description:
When a tar(1) aborts for some reason, there is no way to
restart it from when it left off.
Repeat-By:
Abort a tar x and try to restart it.
Fix:
Elxsi has added a new flag to tar(1), -K. K will skip an archive
until the named file is found and then extract or list the remainder
of the archive. We found this to be quite useful when an extract from
a large archive aborted. We didn't have to reextract all the files
that had already been extracted.
Enjoy.
Gary..
{ucbvax!sun,lll-lcc!lll-tis,amdahl!altos86,bridge2}!elxsi!gww
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# tar.c.diff
# tar.1.diff
# This archive created: Thu Dec 18 18:01:33 1986
echo shar: extracting tar.c.diff '(1794 characters)'
sed 's/^XX//' << \SHAR_EOF > tar.c.diff
XX*** /tmp/,RCSt1002165 Thu Dec 18 17:47:28 1986
XX--- tar.c Thu Dec 18 17:17:38 1986
XX***************
XX*** 1,5 ****
XX--- 1,8 ----
XX /*
XX * $Log: tar.c,v $
XX+ * Revision 1.2 86/12/18 17:16:26 gww
XX+ * Add -K flag to start extracting (-x) or listing (-t) at the named file.
XX+ *
XX * Revision 1.1 86/12/17 18:14:47 gww
XX * Initial revision
XX *
XX***************
XX*** 17,23 ****
XX #endif not lint
XX
XX #ifndef lint
XX! static char *ERcsId = "$Header: tar.c,v 1.1 86/12/17 18:14:47 gww Exp $ ENIX BSD";
XX static char sccsid[] = "@(#)tar.c 5.7 (Berkeley) 4/26/86";
XX #endif not lint
XX
XX--- 20,26 ----
XX #endif not lint
XX
XX #ifndef lint
XX! static char *ERcsId = "$Header: tar.c,v 1.2 86/12/18 17:16:26 gww Exp $ ENIX BSD";
XX static char sccsid[] = "@(#)tar.c 5.7 (Berkeley) 4/26/86";
XX #endif not lint
XX
XX***************
XX*** 85,90 ****
XX--- 88,95 ----
XX int hflag;
XX int Bflag;
XX int Fflag;
XX+ int Kflag; /* Start at the Named file. Ie, skip all files up to, but */
XX+ /* not including the named file. Get all files thereafter.*/
XX
XX int mt;
XX int term;
XX***************
XX*** 244,249 ****
XX--- 249,258 ----
XX Fflag++;
XX break;
XX
XX+ case 'K':
XX+ Kflag++;
XX+ break;
XX+
XX default:
XX fprintf(stderr, "tar: %c: unknown option\n", *cp);
XX usage();
XX***************
XX*** 1052,1059 ****
XX if (*argv == 0)
XX return (1);
XX for (cp = argv; *cp; cp++)
XX! if (prefix(*cp, dblock.dbuf.name))
XX return (1);
XX passtape();
XX return (0);
XX }
XX--- 1061,1074 ----
XX if (*argv == 0)
XX return (1);
XX for (cp = argv; *cp; cp++)
XX! if (prefix(*cp, dblock.dbuf.name)) {
XX! if (Kflag)
XX! /* Kflag means 'start' at the given */
XX! /* file. Now that we've found it */
XX! /* let 'er rip! */
XX! *argv = 0;
XX return (1);
XX+ }
XX passtape();
XX return (0);
XX }
SHAR_EOF
if test 1794 -ne "`wc -c tar.c.diff`"
then
echo shar: error transmitting tar.c.diff '(should have been 1794 characters)'
fi
echo shar: extracting tar.1.diff '(990 characters)'
sed 's/^XX//' << \SHAR_EOF > tar.1.diff
XX*** /tmp/,RCSt1002158 Thu Dec 18 17:46:51 1986
XX--- tar.1 Thu Dec 18 17:46:18 1986
XX***************
XX*** 1,6 ****
XX! .\" $Header: tar.1,v 1.1 86/12/18 17:20:18 gww Exp $ ENIX BSD
XX .\"
XX .\" $Log: tar.1,v $
XX .\" Revision 1.1 86/12/18 17:20:18 gww
XX .\" Initial revision
XX .\"
XX--- 1,9 ----
XX! .\" $Header: tar.1,v 1.2 86/12/18 17:45:53 gww Exp $ ENIX BSD
XX .\"
XX .\" $Log: tar.1,v $
XX+ .\" Revision 1.2 86/12/18 17:45:53 gww
XX+ .\" Add description of -K flag.
XX+ .\"
XX .\" Revision 1.1 86/12/18 17:20:18 gww
XX .\" Initial revision
XX .\"
XX***************
XX*** 163,168 ****
XX--- 166,179 ----
XX and from /etc, one might use
XX .ti +0.5i
XX tar c -C /usr include -C / etc
XX+ .TP 10
XX+ .B K
XX+ Forces
XX+ .I tar
XX+ to skip all files up to the first file named.
XX+ This file and all the files that follow on the archive are extracted
XX+ (key letter `x') or listed (key letter `t').
XX+ This option is useful for beginning in the middle of an archive.
XX .PP
XX Previous restrictions dealing with
XX .IR tar 's
SHAR_EOF
if test 990 -ne "`wc -c tar.1.diff`"
then
echo shar: error transmitting tar.1.diff '(should have been 990 characters)'
fi
# End of shell archive
exit 0
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list