Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!lll-winken!uunet!portal!cup.portal.com!thad From: thad@cup.portal.com (Thad P Floryan) Newsgroups: comp.sys.amiga Subject: Re: ARP1.3 bug Message-ID: <17528@cup.portal.com> Date: 23 Apr 89 10:56:19 GMT References: <8589@polya.Stanford.EDU> <6585@medusa.cs.purdue.edu> <509@cpsc6b.cpsc6a.att.com> Distribution: na Organization: The Portal System (TM) Lines: 340 Since it appears so many are having the same problem for which I developed a solution several months ago, enclosed is a shar containing my "purge" program. Since it's small, distribution via the "text" newsgroup seems the expedient solution. In conversation with Bob Page over dinner last week, he's still getting the { sources | binaries } set up "here"; Bob is now in N.California. Makefile, source code, and uuencoded executable (for those without a C compiler) are included. Hope this prevents teeth-gnashing, hair-pulling, etc. :-) Thad Floryan [ thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad ] # 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: # Makefile # purge.c # purge.uue # This archive created: Sun Apr 23 03:51:29 1989 echo shar: extracting Makefile sed 's/^X//' << \SHAR_EOF > Makefile X# Makefile for purge command X# X Xpurge: purge.o X ln -M +Q purge -lc X Xpurge.o: purge.c X cc purge SHAR_EOF if test 98 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 98 characters)' fi echo shar: extracting purge.c sed 's/^X//' << \SHAR_EOF > purge.c X/* P U R G E X * X * Deletes files in the current directory whose names match the pattern "*~". X * Such filenames are typically (GNU and MG) EMACS' and PATCH's backup files. X * Execution errors return silently with the exit status set = 20 and without X * deleting any files. X * X * USAGE: X * X * CLI> PURGE X * X * X * HISTORY: X * X * V1.0 8-Jan-1989, Initial Release, Thad Floryan X * Copyright (c) 1989 by Thad Floryan X * X * DISTRIBUTION: X * X * Although copyrighted, this program is freely redistributable. Feel X * welcome to use this program for your personal learning. X * X * NOTES: X * X * 1. The deleting of a file within an ExNext() loop perturbs the "order" of X * ExNext() in RAM: under 1.2. To get around this OS bug, PURGE collects X * all the qualifying filenames in one pass and deletes them en masse; this X * is the reason for the DeleteNames structure and its support routines. X * X * If the bug is fixed in later OS releases, then the following program X * suffices (assuming the presence of Manx' scdir() or equivalent): X * X * extern char *scdir(); X * main() { X * char *ptr; X * while ((ptr=scdir("*~")) != 0) unlink(ptr); X * } X * _wb_parse(){} X * _cli_parse(){} X * X * The above program does work fine under 1.2 *IF* the current directory X * is a disk (either floppy or HD). X * X * 2. At the end of this file are stubs for _cli_parse() and _wb_parse() to X * reduce the size of the executable because no arguments are parsed nor X * does PURGE run from the Workbench. X * X * 3. The "equivalent" shell script I use on my UNIXPC/3B1 is: X * X * # @(#) purge - removes Emacs' and patch's "*~" files (including .*~ files) X * # X * # Usage: X * # X * # $ purge purges current directory [ rm ./*~ ] X * # $ purge . purges current directory [ rm ./*~ ] X * # $ purge foo purges named directory [ rm foo/*~ ] X * # $ purge /foo/bar purges named directory [ rm /foo/bar/*~ ] X * # X * # Thad Floryan, 3-Dec-1988 X * X * if [ -z "$1" ]; then X * rm -f ./*~ ./.*~ X * else X * rm -f $1/*~ $1/.*~ X * fi X * exit 0 X * X * BUILDING: X * X * A Makefile is supplied to perform the following using Manx 3.6a: X * X * cc purge X * ln -M +Q purge -lc X */ X X#include X#include X#include X#include X X#define MAXFILENAME 30 /* max length of a file name */ X Xextern char *rindex(); Xextern int strlen(); X Xvoid ACCUMULATE_NAME(); Xvoid DO_DELETE(); Xvoid FREE_NAMESPACE(); X Xstatic char *version = "purge V1.0 8-Jan-1989; Copyright (c) 1989 Thad Floryan"; X Xstatic struct FileInfoBlock *fibptr; X Xstruct DeleteNames { X struct DeleteNames *DN_Next; X struct DeleteNames *DN_Prev; X char DN_Name[MAXFILENAME + 1]; X}; X Xstatic struct DeleteNames *delbase; Xstatic struct DeleteNames *dellast; Xstatic struct DeleteNames *deltemp; Xstatic int delcnt = 0; X X/*****************************************************************************/ Xmain() X{ X struct FileLock *lockptr; X long errcod = 0; X X/* X * Allocate memory for structure(s) of interest X */ X fibptr = (struct FileInfoBlock *) X AllocMem((long)sizeof(struct FileInfoBlock), (long)MEMF_CLEAR); X/* X * Get Lock on current directory X */ X lockptr = Lock("", ACCESS_READ); X/* X * Check for file(s) X */ X if (Examine(lockptr, fibptr) == 0) X { X errcod = -1L; X } X X if (errcod == 0L) X { X ACCUMULATE_NAME(); X X for (;;) X { X if (ExNext(lockptr, fibptr) == 0L) X { X if ((errcod = IoErr()) == ERROR_NO_MORE_ENTRIES) X { X errcod = 0L; X } X break; /* gets out of "for" loop */ X } X ACCUMULATE_NAME(); X } X } X if (delcnt != 0) X { X if (errcod == 0) X { X DO_DELETE(); X } X FREE_NAMESPACE(); X } X/* X * Free up everything we got from the system X */ X UnLock(lockptr); X FreeMem(fibptr, (long)sizeof(struct FileInfoBlock)); X X (errcod == 0L) ? exit(0) : exit(20); X} X X/***************************************************************************** X * Qualifies a file whose last filename character is a '~' X * X */ Xvoid ACCUMULATE_NAME() X{ X register char *stringptr; X register char *indexptr; X int status; X/* X * Assure this is a FILE and not a DIRECTORY X */ X if (fibptr->fib_DirEntryType < 0) X { X stringptr = fibptr->fib_FileName; X indexptr = rindex(stringptr, '~'); X X if (indexptr == 0) X { X return; X } X if((long)strlen(stringptr) == (indexptr - stringptr + 1L)) X { X if (delcnt == 0) /* check if 1st name */ X { X delbase = (struct DeleteNames *) X AllocMem((long)sizeof(struct DeleteNames), X (long)MEMF_CLEAR); X dellast = delbase; X strcpy(dellast->DN_Name, stringptr); X delcnt++; X } X else /* subsequent entries */ X { X deltemp = (struct DeleteNames *) X AllocMem((long)sizeof(struct DeleteNames), X (long)MEMF_CLEAR); X deltemp->DN_Prev = dellast; X dellast->DN_Next = deltemp; X strcpy(deltemp->DN_Name, stringptr); X dellast = deltemp; X delcnt++; X } X } X } X} X Xvoid DO_DELETE() X{ X deltemp = delbase; X while (deltemp != 0) X { X/* X * unlink(deltemp->DN_Name) could be used, too. X */ X DeleteFile(deltemp->DN_Name); X deltemp = deltemp->DN_Next; X } X} X X/***************************************************************************** X * Frees up the filename space in the reverse order it was allocated; X * this seems best to help the system coalesce the free memory chunks. X */ Xvoid FREE_NAMESPACE() X{ X while (dellast != 0) X { X deltemp = dellast->DN_Prev; X FreeMem(dellast, (long)sizeof(struct DeleteNames)); X dellast = deltemp; X } X} X X/***************************************************************************** X * The following two stubs are here to prevent linking in the library X * routines of the same name since we don't run from Workbench and X * there are no CLI arguments to parse. X */ X_wb_parse(){} X_cli_parse(){} SHAR_EOF if test 5769 -ne "`wc -c purge.c`" then echo shar: error transmitting purge.c '(should have been 5769 characters)' fi echo shar: extracting purge.uue sed 's/^X//' << \SHAR_EOF > purge.uue Xbegin 777 purge XM```#\P`````````#``````````(```&M````&@````$```/I```!K4[Z`F)PZ XM=7)G92!6,2XP(#@M2F%N+3$Y.#D@*&,I5&AA9"!&;&]R>6%N`$Y5__A"K?_XN XM2'D``0``2'@!!$ZZ!A903RE`@!)(>/_^2'H`I$ZZ!:A03RM`__PO+(`2+RW_J XM_$ZZ!6)03TI`9@@K?/______^$JM__AF+F%X+RR`$B\M__Q.N@524$]*0&86_ XM3KH%7BM`__BPO````.AF!$*M__A@!&%.8-1*;(`&9PY*K?_X9@1.N@$$3KH!7 XM+"\M__Q.N@5@6$](>`$$+RR`$DZZ!:Q03TJM__AF"D)G3KH#.E1/8`H_/``4) XM3KH#+E1/3EU.=0``3E7__DCG`#`@;(`22J@`!&P``+`D;(`24(H_/`!^+PI.U XMN@$.7$\F0"`+9@A,WPP`3EU.=2!+D(&R`'B%L@!H`!"!L@!H@K(`>( XM+PH@;(`>4(@O"$ZZ`)Q03REL@!Z`&E)L@`9@`/]H3E4``"EL@!:`'DJL@!YGT XM&"!L@!Y0B"\(3KH#XEA/(&R`'BE0@!Y@XDY=3G5.50``2JR`&F<@(&R`&BEH' XM``2`'DAX`"@O+(`:3KH$>%!/*6R`'H`:8-I.74YU3E4``$Y=3G5.50``3EU.$ XM=2!O``0B2$H89OQ3B!`O``FSR&<(L"!F^"`(3G5P`$YU(&\`!"`((F\`"!#9, XM9OQ.=2!O``0@"$H89OR1P"`(4X!.=6%P0^R`$D7L@!*UR68.,CP`%6L(=``B& XMPE')__PI3X`B+'@`!"E.@"9(YX"`""X`!`$I9Q!+^@`(3J[_XF`&0J?S7TYS, XM0_H`($ZN_F@I0(`J9@PN/``#@`=.KO^48`1.N@`:4$].=61O@`J3KH"'"!L@"XA0``,4$\O+(`\/RR`0$ZZ_"9"9TZZ``Q03R1?I XM3EU.=2H`3E4``$JL@$)G!B!L@$).D#\M``A.N@`(5$].74YU3E7__"\$,"T`/ XM"$C`*T#__$JL@"YG*'@`8`H_!$ZZ`/Y43U)$N&R`"&WP,"R`",'\``8O`"\L' XM@"Y.N@(04$]*K(!&9P8@;(!&3I!*K(`.9PHO+(`.3KH!EEA/2JR`2F<((&R`? XM2B"L@$Y*K(!29PHO+(!23KH!H%A/2JR`5F<*+RR`5DZZ`9!83TJL@%IG"B\LD XM@%I.N@&`6$]*K(!>9PHO+(!>3KH!<%A/+'@`!`@N``0!*6<4+PU+^@`*3J[_U XMXBI?8`9"I_-?3G-*K(`X9C!*K(!B9R@P+(!F2,`O`"\L@&).N@%H,"R`0%)`- XM2,#E@"\`+RR`/$ZZ`51/[P`08`Y.N@$^+RR`.$ZZ`5Y83R`M__PN;(`B3G4HC XM'TY=3G5.50``2.<.(#@M``@P!,'\``8D0-7L@"Y*1&T*N&R`"&P$2I)F$#E\L XM``*`:'#_3-\$<$Y=3G4(*@`'``1F""\23KH`"EA/0I)P`&#B(B\`!"QL@"I.V XM[O_<(B\`!"QL@"I.[O^"3OH``B(O``0L;(`J3N[_N$[Z``),[P`&``0L;(`J" XM3N[_FDSO``8`!"QL@"I.[O^4+&R`*D[N_\I.^@`"+&R`*D[N_WQ.^@`"3.\`Z XM!@`$+&R`*D[N_ZQ,[P`&``0L;(`J3N[_XBQL@"I.[O_$3OH``B(O``0L;(`JY XM3N[_IDCG`01,[R"```PL;(`F3J[_E$S?((!.=2)O``0L;(`F3N[^8D[Z``),< XM[P`#``0L;(`F3N[_.B)O``0L;(`F3N[^VBQL@"9.[O]\3OH``B)O``0@+P`([ XM+&R`)D[N_RX@;P`$+&R`)D[N_HPB;P`$+&R`)D[N_H8@;P`$+&R`)D[N_H``< XM`````^P````!`````0```M@````````#\@```^H````$````!````!0`````) XH`````````^P````!```````````````````#\@```^L````!```#\A0`= X`` Xend SHAR_EOF if test 2602 -ne "`wc -c purge.uue`" then echo shar: error transmitting purge.uue '(should have been 2602 characters)' fi # End of shell archive exit 0