!* -*-TECO-*-! !~FILENAME~:! !Directory Editor Subsystem! DIRED !& DIRED Delete File:! !S Delete current file.! 0l "L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! < .-z; !* Iterate |arg| times, stop at end! "l b-.; -l ' 1a-32"e fD 1@v ' !* Mark one file as deleted.! "g l ' > 0 !* Changes have already been reported to ^R.! !& DIRED Delete Through:! !S Delete file which link points to.! 0l .-z"e fg 1 ' !* Barf at end of buffer.! 3f=__L"n fg 1 ' !* Must be a link, and not T'd or D'd.! f[d file e[ fn e] !* Push filenames and channel.! [1 .+6,.+12x1 !* Extract FN1 of link.! [2 .+13,.+19x2 !* Extract FN2 of link.! et1_2 !* Get around ITS bug! 1:"n fg 1 ' !* Barf if file linked to doesn't exist.! fs i fileu2 !* See what file it links to.! .,( diT :l !_2). (l)  !* Put names linked to at end, and a "T" at front.! !& DIRED Next Undumped:! !S Move to the next file not dumped on tape.! [.5[.6 u.6 q.6"l -1u.5 -q.6u.6'"# 1u.5' q.6< < q.5l b-.; .-z; 19c 1:fb!:; > > 0l 1  !& DIRED Help:! !S Type our help msg.! m(m.mdescribe)&_DIRED  !& DIRED Next Hog:! !S Move to the next file of which there are more than two (or arg) copies.! [5[6[7[8 .[9 !* Q7 will point after last file in grp! 0l 6:cw 6x5 !* Skip current file and all with same FN1.! < l .-z; 6c 6f=5:@;> < 0l .u8 .-z; 6c 6x5 0l !* FN1 to Q5, line location to Q8! -(ff"n ' "# 2' fo..q File_Versions_Kept)u6 < l .u7 .-z; 6c !* Look at files following this one! 6f=5:@; !* Count files with matching FN1! 7c\"E 1;' %6w > !* And numeric second file name! q6; > !* Stop if saw more than 2 (QFile Versions Kept) copies.! q8-z"E q9j fg 1  ' !* Beep and exit if nothing found! !* Q8 points at first file of group, q7 at last. Both point at beginning of file's line.! !* Now make sure, if possible, that entire group is on screen.! 10f[%center fswindow"l :f' !* If window unknown, choose one putting point near top! f[^rvpos q7j L 1f[reread 0@v !* Find out vpos of where Q7 points.! f]rereadw fs ^r vpos-(FSLINESF"EW FSHEIGHT-(FSECHOLINES)-1' "#-(FS TOPLIN)')( f]^r vpos )"G q8j 1:F' !* Won't fit in existing window => start on line 1.! q8j 0 !& DIRED Automatic Delete:! !S Put D's next to versions of the current file that need it. With an argument, the entire directory is processed, not just the current file. Obeys the following flags: File Versions Kept Temp File FN2 List! FF"E :m( m.m &_DIRED_Automatic_One_File ) ' !* With no argument, use routine below! BJ < .-z; !* Otherwise, iterate over the whole directory! m( m.m &_DIRED_Automatic_One_File ) R > BJ  !* Go to front of directory and redisplay all! !& DIRED Automatic One File:! !S Put D's next to deletable versions of one file.! !*** must return entire range of this fn1 as two values, *! !*** with point at the beginning of the range, *! !*** so that an R command on the values will move to the next file. *! 0L [0 2fo..Q File_Versions_Kept[2 !* Q2 gets number of versions to keep! .-z"E fg 1  ' !* Barf if at end (no file)! .f[VB .+6,.+12x0 !* Set buffer boundaries around files with this name! < L .-z; .+6,.+12f=0:@; > !* This puts . at start of first different line! 0[3 fsz-.f[VZ !* Put Z after last file with this FN1.! j 7a-_"e !* If this FN1 indicates temp files,! < .-z; fD l>j h' !* mark them ALL for deletion.! < .-z; 13c 6@f0123456789_-6"n 0l 0;' !* Find first non-numeric FN2.! %3w l > !* Count number of numeric fn2s.! -q2l !* Move back over those we want to keep.! < b-.; -l !* Mark all previous numeric FN2s for deletion.! 31A-$"N fD' > !* But don't mark delete-protected ones.! QTemp_File_FN2_Listu0 !* Mark all "temp" fn2s for deletion.! J<.-z; .+13,.+19:FB0"L 0l FD' L> J H  !* Exit with point at first file in group! !& DIRED Undelete:! !S Undo the effect of a previous D command.! 0l [0 !* Save arg in q0 so we can change it! ff"E 0,1af DT "L !* If no args, and this line doesn't have a D or T! .-b"g !* and previous line does have one! -l 1af DT :"L -1u0' !* then make the argument be -1! l''' !* then back up one line.! q0"L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! q0< !* Iterate |arg| times.! q0"l b-.; -l ' .-z; !* If going forward, stop if at end.! 1af DT +1"g !* If this file is marked deleted,! f_ 1f 19c !* remove the mark,! !_"n fkc:k 0@v' !* and remove names of linked-to file to delete, if any.! 0l' q0"g l'> 0 !* Changes already reported to ^R.! !& DIRED Reverse Undelete:! !S Move up one line and undo a D.! -:m(m.m &_DIRED_Undelete) !& DIRED Primary File:! !S Move current file onto FIRST:.! m(M.M &_DIRED_Move_File)DSK:  !* FIRST: isn't implemented yet.! !& DIRED Secondary File:! !S Move current file onto SECOND:.! m(M.M &_DIRED_Move_File)SECOND:  !& DIRED Tertiary File:! !S Move current file onto THIRD:.! m(M.M &_DIRED_Move_File)THIRD:  !& DIRED Quaternary File:! !S Move current file onto FOURTH:.! m(M.M &_DIRED_Move_File)FOURTH:  !& DIRED Move File:! !S Move current file onto specified device! 0l "L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! [1 [2 [3 f[D File !* Save! FsMachine !* Find out machine for device->pack mappings.! et*_* 5,f Move_to[4 !* Get device (or directory) to move onto! f[b bind gDIRED_Top_Lines f]b bind < .-z; !* Iterate |arg| times, stop at end! "L b-.; -L ' 2c 1a-L"N !* Ignore links! 4c 6x1 7c 6x2 !* Q1, Q2 get file names! et1_2 f[D File !* Defaults get current file! :E_4: !* Copy file, preserve date, set defaults to where it went! !* This assumes user typed only a device name! 17c F_ !* Clear do-not-reap bit on display.! 0l f_ !* Undelete the file.! fs D Dev :f6 u3 f]D File !* Q3 gets device written to, restore file defaults! 2c f0_ !* Assume pack 0! f=3SECOND"E !* Kludgily change displayed pack number! F6AI-QH"E f2' !* QH has the machine name.! "# f13'' !* Traditional! f=3THIRD"E f14' !* On MC, THIRD: is pack 14 or 15! f=3FOURTH"E f16' !* On MC, FOURTH: is pack 16! ' !* This quote matches IGNORE LINKS.! "G L' >  !* Then do full redisplay! !& DIRED SRCCOM File:! !S Valret a :SRCCOM of current file! 0l "L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! 0fo..qSRCCOM_switchesf"ew :i*/e/y'[2 !* get switches! [1 < .-z; !* Iterate |arg| times, stop at end! "L b-.; -L ' 6c 6x1 f61fs D Fn1 !* Put this file into default file name! 7c 6x1 f61fs D Fn2 fs D Fileu1 !* Get default file name back to go into srccom command! _:vkî:srccom_12 !* Valret! "G L' >  !* Then do full redisplay! !& DIRED Complement Reap-Bit:! !S Complement don't-reap bit of current file! 0l "L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! [1 [2 [3 f[D File !* Save! < .-z; !* Iterate |arg| times, stop at end! "L b-.; -L ' 2c 1a-L"N !* Ignore links! 4c 6x1 7c 6x2 !* Q1, Q2 get file names! et1_2 !* Get around ITS bug! 1,ER !* Open file, do not set ref date.! FS IF Reap U3 !* Q3 gets dont-reap bit! 1-Q3 FS IF Reap W EC !* Change it in the file system! 17c Q3"E F$ '"# F_' ' !* Change it on the display! 0L "G L' >  !* Then do full redisplay! !& DIRED View File:! !S Enter View File on the current file! [1 [2 f[D File !* Get out of magic dired environment! @fn|0[DIRED_Old_Refresh m(m.m &_DIRED_Refresh) | qDIRED_Old_Refreshf[Refresh qDIRED_Old_Topf[Top qDIRED_Old_Linesf[Lines 0l "L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! < .-z; !* Iterate |arg| times, stop at end! "L b-.; -L ' 6c 6x1 7c 6x2 ET1_2 !* Get file name,! m(m.m View_File) !* view file.! "G L ' > "G -L '  !* Leave cursor on last file processed, full redisp! !& DIRED Examine File:! !S Enter recursive ^R on the current file! [1 [2 f[D File 0[..F !* Get out of magic dired environment! @fn|0[DIRED_Old_Refresh m(m.m &_DIRED_Refresh) | qDIRED_Old_Refreshf[Refresh qDIRED_Old_Topf[Top qDIRED_Old_Linesf[Lines 0l "L .-b'"#.-z' "e fg 1 ' !* Barf at end of buffer.! < .-z; !* Iterate |arg| times, stop at end! "L b-.; -L ' 6c 6x1 7c 6x2 et1_2 !* The ET is to get around an ITS bug! 1,ER !* Get file name, open (dont set ref date)! 0L f[Window f[B Bind !* Get buffer! fsD Fn2f6 !* Check out second file name! J @f0123456789k z"E !f6 fsD Fn2 ' !* If all numeric, use greater than! @y !* But read in file the guy said! 1FS Read Only :I* [DIRED_Examine_Mode:__1_2_][..J FR !* Fix mode line!  !* Enter ^R on it! ]..J f]B Bind f]Window "G L ' > "G -L '  !* Leave cursor on last file processed, full redisp! !& DIRED ..F:! !S ..F macro to make ^R understand DIRED commands. It reads DIRED commands and executes them. When a control- or meta- character is typed, it is left for ^R to execute.! FS ^R MODE"E ' !* Don't be confused if called when exiting DIRED ^R! !* because DIRED was called from outside all ^R's.! [0 [1 [2 0 @V < 2,M.I @:FI:FCU0 !* Read input with no prompting.! Q0F _XQUNT!?DKSEÐCH$MV1234U1 !* Is it a DIRED command that isn't a control-char?! Q0-200. F aaaaaaaaDK F"G U1' !* Is it ^D or ^K? They are equivalent to D and K.! Q1+1"G FI !* Yes => run it.! FS ^R ARGP&2"N FS ^R ARG' "# 1' U2 !* Compute the arg like ^R.! FS ^R ARGP&4"N -Q2U2' FS ^R EXPT< Q2*4U2> FS ^R ARGP"N Q2' @M:DIRED_Dispatch(Q1) !* Run the command. ! ( 0 FS ^R ARGPW 0 FS ^R ARGW 0 FS ^R EXPTW -1FS ^R PREVW !* Flush the ^R arg we gave it.! 0FS ECHO ACT"N :I*CFS ECHO DIS' ) @V !' !* Hand its values back to ^R.! @:FIFS^R INDIRU0 !* Is it a ^R command? Get 9-bit uppercase.! AFS^R INIT-Q0"E !* Flush self inserting characters.! FIW FG !' 0;> 0 !* Any other ^R command => return so ^R can gobble it.! !& DIRED ^R Enter:! !S FS ^R ENTER for DIRED. Puts & DIRED ..F into ..F so that this ^R becomes a DIRED command loop.! 0 F[ ^R ENTER !* Don't screw any recursive ^R's (eg minibuffer).! M.M &_DIRED_..F [..F 1F[ ^R MDLY W 0F[ ^R MCNT m.m &_DIRED_Help F[HELP MAC M.V DIRED_Dispatch !* Make sure variable exists.! [ DIRED_Dispatch 23*5 FS Q VECTOR[0 Q0 U DIRED_Dispatch !* Create the dispatch table for DIRED commands.! !* Note that the 19 slots correspond to the characters! !* XQUNTDKSEPCH$MV ! !* via the F in & DIRED ..F.! -1[1 !* So fill the slots with appropriate macros.!  FS ^R INIT U:0(%1) !* Space moves down a line.! M.M ^R_Extended_CommandU:0(%1) !* X executes an MM command.! 27 FS ^R INIT U:0(%1) !* Q exits the DIRED ^R.! M.M &_DIRED_Undelete U:0(%1) !* U takes away a delete-mark.! M.M &_DIRED_Next_Hog U:0(%1) !* N finds next file with >2 versions.! M.M &_DIRED_Delete_Through U:0(%1) !* T deletes through a link.! M.M &_DIRED_Next_Undumped U:0(%1) !* Excl finds next undumped file.! M.M &_DIRED_Help U:0(%1) !* ? prints documentation.! M.M &_DIRED_Delete_File U:0(%1) !* D deletes this file.! Q:0(Q1) U:0(%1) !* So does K.! M.M &_DIRED_Secondary_File U:0(%1) !* S puts on secondary pack! M.M &_DIRED_Examine_File U:0(%1) !* E edits! M.M &_DIRED_Reverse_Undelete U:0(%1) !* Rubout undeletes backwards.! M.M &_DIRED_Primary_File U:0(%1) !* P puts on primary pack! M.M &_DIRED_SRCCOM_File U:0(%1) !* C calls SRCCOM! M.M &_DIRED_Automatic_Delete U:0(%1) !* H puts in D's appropriately! M.M &_DIRED_Complement_Reap-Bit U:0(%1) !* $ complements don't reap bit! M.M &_DIRED_Move_File U:0(%1) !* M moves file! M.M &_DIRED_View_File U:0(%1) !* V views file.! M.M &_DIRED_Primary_File U:0(%1) !* 1 moves file to primary.! M.M &_DIRED_Secondary_File U:0(%1) !* 2 moves file to second:.! M.M &_DIRED_Tertiary_File U:0(%1) !* 3 moves file to third:.! M.M &_DIRED_Quaternary_File U:0(%1) !* 4 moves file to fourth:.! 0[DIRED_Old_Refresh !* Don't do full redisplay! m(m.m &_DIRED_Refresh) !* Display top two lines.! ]DIRED_Old_Refresh ]1 ]0 0_ !* No  so don't pop qDIRED Dispatch! !:! !& DIRED:! !& DIRED Enter:! !C Edit a directory. The string argument may contain device colon, directory semicolon, and a file name. If the string contains a file name, or there is a numeric argument, only files with the specified or defaulted first name appear. Enters ^R mode with the directory in the buffer. D deletes the file which is on the current line. (also K,^D,^K) U undeletes the current line file. Rubout undeletes the previous line file. H puts D's by files that seem to need them. ^UH does whole dir. Space is like ^N - moves down a line. N moves to the next file of which there are more than 2 copies. (n M.VFile Versions Kept to find more than n copies). T deletes Through a link, ie. what the link points to. The file shown in the deletion list, will be the file pointed to.  finds the next "" (not backed up) file. 1 moves the file onto a primary pack. 2 moves the file onto SECOND:. 3 moves the file onto THIRD:. 4 moves the file onto FOURTH:. M asks you for a device and/or directory and moves the file there. If you specify a different directory the old copy is left behind. C valrets a :SRCCOM, you must hit yourself. E read-only recursive edit on current file. V View File on current file. $ complements the don't-reap bit ? types this cruft. Q lists files to be deleted and asks for confirmation: Typing YES deletes them; X or Q aborts; N resumes DIRED. The D,U,,P,S,M,C,E,V commands repeat if given an argument, backwards if negative.! f[ B Bindw f[ D Filew f[ S Stringw 1f[ Fnam Syntax [0 :fo..q DIRED_Top_Lines "L !* Check some variables.! m.v DIRED_Top_Lines !* If they don't exist,! m.v DIRED_Old_Lines !* make them.! m.v DIRED_Old_Refresh m.v DIRED_Old_Top @fn|m.m Kill_Variable [K !* Set up to kill them later.! mK DIRED_Top_Lines mK DIRED_Old_Lines mK DIRED_Old_Refresh mK DIRED_Old_Top ]K|' '# [DIRED_Top_Lines !* Else if they exist,! [DIRED_Old_Lines !* just push them! [DIRED_Old_Refresh [DIRED_Old_Top' fsLinesuDIRED_Old_Lines !* Save fs-flags! fsRefreshuDIRED_Old_Refresh fsTopuDIRED_Old_Top m.m &_DIRED_^R_Enterf[ ^R enter !* Make our next ^R be a DIRED-command loop.! QBuffer_Filenamesf"N u0 ET0 ' !* Default file name is buffer file name! [1 f6__NULLf[DFn1 fsDFn1:f6u1 !* Discover whether a filename is in arg! 5,f Directory:_u0 et0 !* Default file name from string arg! fs D Fn1:f6u0 f=01f"nwq0' u1 !* Q1 gets given file name or 0! f] D Fn1w FF"G fs D Fn1:f6u1 ' !* If a num arg given, set Q1 to default file name! 1:< QDIRED_use_DIR_deviceu0 >"N !* If DIR device option not specified! :i* NAME1_UPu0 !* Then use the default! q0m.C DIRED_use_DIR_device *0_to_not_use_DIR:,_or_DIR_device_file_names ' Q0"E EZ ' !* Read in the directory, optionally using DIR device! "# f[ D File fs D Dev:f6[2 FQ2-3"G :I*WTD__Device_name_2_too_long_for_DIR_device FS ERR' ER DIR2:0 @y ]2 f] D File ' j 2l b,.fxDIRED_Top_Lines !* Save directory name and info! ET GAZONK_.DEL !* Make sure writing it out doesn't clobber anything.! Q1"N !* If specified, edit the dir down to one file group! :i11_ fq1+6u0 < .-Z; .+6,.+q0f=1"n K'"# L'> BJ Z-."E I______No_files_with_ g1 ias_FN1 '' [..J :I..J DIRED [1[2[3[4 F[WINDOW 10F[% Center 0FS MODIF f !* Flush all blank lines from end.! -1u3 :i1î !* flag greatest than files! ji  !* Put a CRLF at front.! <.-z; 3a-L"N .+6,.+12f=1"E !* If file not a link and same fn1 as previous! 13c.(\u4)-."L q4-q2"G q4u2 !* Then maybe update mobiest numeric fn2 in Q2.! 0l.(q3jf_)j19c\wc.u3!''' !* take .gt. off prev and put on this! "# :i1î !* different fn1, start new group of files! 13c.(\u2)-."L 0l.+6,.+12x1 20c\wc.u3!''' l> jl <.-z; !* Now flush all lines not indicating some deletion.! 1a f _*"l l' "# k'> !_î _L; !* Move all links and T hair to the front! 0l fx1 .( q2j g1 .u2 )+fq1j 2r > q2j <.-z; 6d14c :i1___ !* display the rest in compressed format! .u3 1:fb!"N 1:f1! q3j' !* Preserving the excl and greater than flags! !<"N 0:f1> q3j' 1:fb$"N 2:f1$ q3j' !* And the dollar flag! :k 0l g1 l > q2j <.-z; :l fswidth-(fshpos)-18"g i_k '"# l '> 0a-12."N i  ''' ' !* Here ends the stuff conditional on DIRED Long Format! jk z"e  ' !* nothing to delete => return.! f f]bbindw !* Here if answer is N - pop to DIRED-loop level! > !* and go back and edit directory again.! !*** Here after exiting DIRED-loop: delete the files! 0u..h !* Unless something goes wrong, let ^R redisplay immediately.! [1[2 bj !* There used to be a 2L after this, to compensate for the two! !* lines of disk info at the top, but they aren't there anymore.! < .-z; 1f=D"e .(6c 6x1 7c 6x2)j 1:"N FT_Delete_of_1_2_failed '' 1f=T"e .(!_ :x1)j 1:"n FT_Delete_of_1_failed '' l >  !& DIRED Refresh:! !S Redisplay the screen in DIRED! qDIRED_Old_Refresh f"n [1 m(q1 (]1))' !* Call previous refresh.! fs QPPtr( !* Save for later pop.! 0f[Refresh f[Window qDIRED_Old_Topfs Topw 2fs Linesw !* Only refresh top two lines.! qDIRED_Top_Lines[0 :ft0 0u..H !* Do the refresh.! fs Top+2fs Top !* Hide these lines from EMACS.! qDIRED_Old_Linesf"n-2'"#w 0'fsLinesw )fs QPUnwindw !* Pop all the pushes.! !Compare Directories:! !C Compare directories on different ITS machines. Takes string argument that should contain the name of the directory to compare, the name of the foreign machine (as a device name), and (optionally) a switch: /W, /S, /D or /L. /W (the default) means show Whole dir (all files). /S means show all files that are the Same in the two dirs. /D means show all files that Differ. /L means show only Last file for given FN1-machine pair. Example: MM Compare Directories MC:LISP;/S.! [0[1[2[3[4[5[6[7[8[9 F[ B BIND F[ S STRING 1F[FNAM SYNTAX F[ D FILE [..J :I..J Directory_Comparison FR ET !* Read arg containing dir name and other machine name.! FS D SNAME :F6 U0 !* Get sname as string in Q0.! FS D DEVICE :F6 U2 !* Get device name in Q2 as string.! F=2AI"N F=2ML"N F=2DM"N F=2MC"N f=2KL"n f=2MX"n f=2MD"n f=2KS"n f=2DSK"n :I*NSM No_Such_Machine_as_2 FS ERR''''''''' !* If "FN1" given has the form of a switch (eg, /W) then obey it.! !* Switches we know are W, S, L and D for Whole, Same, Different and Last.! FS D FN1&7700000000./100000000.+40.:I6 !* Get 2nd char of FN1, which is the switch name (maybe).! FS D FN1 :F6 U3 !* Get whole FN1 in Q3.! F=3/6"N :I6 W' !* Has the FN1 the form /? If not, assume W switch.! 6 U6 !* Get switch name as ascii char code.! Q6F WSDL"L WU6' !* Only W, S, D, L allowed; default is W.! :I4 !* Q4 gets the header lines (AI FOO )! @:I7` !* GROVEL OVER A DIRECTORY.! !* ASSUME IT LIES BETWEEN POINT AND Z.! !* NUMERIC ARG SHOULD BE MACHINE NAME, AS STRING.! !* Q4 ACCUMULATES A HEADER LINE FOR EACH DIR.! :L 2FWK I  0L @FX4 !* Q4 gets line with Machine, sname and free disk space.! !* If showing only last file of each FN1, delete the others.! !* LAST goes by biggest numeric value of second file name.! Q6-L"E .( < L .-Z; .+6,.+12X5 13C \U9 1A-32"N !' -L .+6,.+12F=5"E 13C\-Q9"L 0LK ' "# LK-L ' ' "# L'> )J' <.-Z; 2D G() !* Insert Machine name on each line.! 1F=L"N F____ !* If not a link: flush pack #,! 18C 4,\(-FWK)\ !* Flush extra space before file size.! .,(S_ R .)K I__ !* And the same after it.! 1F=!"N I_'"# C' !* Move over excl, or put in space, so dates are aligned.! 1F=$"N I_'"# C' !* Do the same for the dont-reap flag.! 9+.-(S_ .)F"G,32I' !* Align the times too,! :L -3D' !* and flush the seconds.! L> ` FT Reading_local_directory.  EZDSK: J 2X1 !* Q1 gets name of local machine.! Q1M7 !* Grovel over this directory.! FT Reading_foreign_directory.  ZJ .U3 EZ2: !* NOW HAVE LOCAL DIR, THEN FOREIGN DIR, IN BUFFER *! !* Q1 HAS LOCAL NAME, Q2 HAS FOREIGN NAME, Q3 MIDPOINT *! !* ALSO, Q6 HAS SWITCH (WSDL), AND Q4 HAS FREE BLOCKS ON LOCAL MACHINE.! Q3J Q2M7 !* Grovel over this directory.! !* NOW SORT FILE NAMES - Q4 HAS HEADER LINES *! FT Sorting_and_merging_them.   6C  13C  L  ZJ I__Q___THISIS_A-FAKE_42_CHAR_FILE_NAME_LINE  J G4 !* DECIDE WHICH FILE SPECS TO MERGE *! !* DISPLAY THE WHOLE MESS, OR LEAVE IN BUFFER *! ZJ -K J 0U..H 0[..F  !* Let user look at the comparison.!  !Reap File:! !C Delete old versions of a file. Takes filename as string argument (FN2 is ignored). Offers to delete all matching files with numeric FN2 except for the most recent few. Files with the don't-reap bit are exempt unless Reap File is given a nonzero pre-comma argument. The number of versions kept is the numeric argument, or QFile Versions Kept if no argument (usually 2). In addition, if there is a file with FN2 = XGP, @XGP, MEMO, etc. you are given the chance to delete it too.! [6 [7 [8 [9 -F[FNAM SYN F[B BIND F[S STRING 0F[CASE U6 FF&1"E 2FO..Q File_Versions_Kept U6 !* Q6 gets numeric arg, or File Versions Kept, or 2.! Q6:"G @FEAOR FS ERR'' !* Keeping 0 versions illegal unless explicit! Q6"L @FEAOR FS ERR' !* Negative # versions to keep is illegal,! 0FO..Q Buffer_FilenamesF"E W' F[ D File' 5,F File_to_deleteu7 ET7 !* Set default to spec'd filename.! F[D FILE !* Read in list of files with that FN1.! FS D DEVICE:F6 U8 FQ8-3"G :I*WTD__Device_name_8_too_long_for_DIR_device FS ERR' ERDIR8:FIRSTX_ !* Read dir from DIRfoo, sorted with numeric FN2s first! YKK EC F]D FILE FS D FN1 :F6 U8 !* Q8 gts just the FN1, as a string.! Z"E :I*No_files_with_first_name_8 FS ERR' !*By convention, the DIR device returns all files with numeric fn2 at the beginning of the directory listing.! "n 2,'Q6M(M.M &_Reap_File_List) !* Now process the dir listing, maybe delete files.! 30:W !* Give user a chance to read "Deleted".! 0U..H  !& Reap File List:! !S Delete some of the files listed in the buffer. The buffer should contain a part of a directory listing, containing all the files with a given FN1. The number of versions to keep should be given as a numeric argument. This subroutine figures out which files ought to be deleted, asks the user about them, and then deletes them after confirmation. The buffer contents are all killed. The virtual boundaries are respected. "1," as argument causes these files not to be mentioned at all if there are no files to delete (nothing is typed out). "2," means delete even files with the don't reap bit set.! F[D FILE [1 [2 [3 [5 :i2 !* Q2 gets list of files we have decided to save! QTemp_File_FN2_List[4 FN HK !* On exit, kill the lines we were thinking about.! !* Starting at the end of the buffer, this next loop exits if the second file name is numeric! ZJ < 0L B-.; -L 13C 6@F_0123456789-6"E 0L 0;' !* Exit this loop if we get up to a numeric FN2.! 0L &2"'n+(31a-$"'n)"n !* If don't reap bit set, save the file.! 7a-_"e ofoo' !* Does this file's fn1 start with "_"?! .+13,.+19:FB 4 "L !* Is this file's FN2 on the temporary list?! !foo! FT Delete:_ 0l 6c T FT(Y_or_N):  FSFLUSH"N F+ L !' !* If not all output made it, try printing again.! FIU5 Q5- "E !* ^L means redisplay screen and ask again.! F+ L !' FT5  Q5FYy+1"G !* Y means delete it.! 13X5 1: FT Deleted.  0LK !''' > L .,Z@FX2 !* State: Q2 contains files with non-numeric fn2 which will be saved, Buffer contains only files with numeric fn2. ^Y has number of those to keep.! &1"N J L .-Z"E '' !* If have 2nd arg, and no files to delete,! !* just return - don't mention this FN1.! !* always save last names.! ZJ -L !* Maybe save some earlier ones, due to don't reap bit. Collect them in Q3, unreversed.! :I3 &2"e < B-.; -L !* Save them by taking them out of bfr! 31A-$"E FX5 :I353' !* and putting them in Q3.! >' ZJ -L !* Get all saved files in buffer, with point! .( G2 G3)J !* before em! .U2 &1"N .-B"E '' !* If have 2nd arg, and no files to delete, just exit.! !Redisp! !* Q2 holds dividing line between deleted and saved files.! Q2J 0FSFLUSHEDU3 Q3"N :FT' FTSaving_these_files:  < .-Z; 6C T L> !* Type names of saved files.! Q2-B"E FT ...and_no_other_files_to_delete.  ' FT Delete_these_files?  Q2J < B-.; -L 6C T 0L> FT (Y_or_N)? Q3"E FSFLUSHED"N FIW F+ O Redisp'' !* If flushed once, redisplay.! !* Flushed twice => no use to redisplay. We started at screen top this time.! FIU1 Q1- "E F+ O Redisp' !* ^L means "ask me again".! FT1 FT  Q2,ZK !* Once user answers, flush names of saved files.! Q1:FC-Y"N !* Don't delete any of these files unless user says "Y"! FT Not_deleted  ' !* delete the files! J <.-Z; 6C 13X1 1:W L> FT Deleted.   !Clean Directory:! !C Try to reap the specified directory. Takes the directory name as a string argument; default is visited one. Does (essentially) MM Reap File on each FN1 in the directory, which finds the excess versions and offers to delete them. A numeric arg specifies the number of versions to keep. We also offer to delete any file whose first name starts with "_". Files with the don't-reap bit are never deleted unless Clean Directory is given a nonzero pre-comma argument.! 0FO..Q Buffer_FilenamesF"EW' F[D FILE F[B BIND F[S STRING 5,F Directory:_ [0 ET0 !* Read name of directory to clean.! [1 [3 [6 F[B BIND U3 "E 2FO..Q File_Versions_KeptU3' !* Q3 has # versions to keep.! Q3:"G @FEAOR FSERR' !* Must be positive.! Q3:\U1 !* Q1 has that number as a string.! FS D SNAME :F6 U6 !* Q6 has dir being reaped, as string.! [..J :I..JChecking_6_directory_for_files_with_>1_versions... FR FS D DEVICE:F6 U1 FQ1-3"G :I*WTD__Device_name_1_too_long_for_DIR_device FS ERR' F[D FILE ERDIR1:NAME1_UP !* Read dir from DIRfoo, sorted with numeric FN2s first! F]D FILE @Y JKK < .-Z; !* Loop over FN1's.! 6C 6X1 !* Q1 gets this FN1.! < L .-Z; !* Find all files with this FN1.! 6C 6F=1"N 0L 0;'> !* Stop after the last one.! FSZ-.FS VZ !* Set bounds around files with same FN1.! "N 2+'1,Q3M(M.M&_Reap_File_List) !* Ask about deleting some, if appropriate.! HK 0FS VZ > !* Flush these files. Open bounds to Consider next FN1.! 0U..H  !* Return no value, so screen will redisplay! !List Files:! !C Brief directory listing. Lists directory N entries to a line, with the following special characters to the left of the filenames: : this is a link  this file has not been backed up to tape yet * this file has really been deleted but not yet closed, or is otherwise locked. (blank) this is a plain normal file Also the top line contains in order, the device being listed from, the directory, Free: followed by the number of free blocks on the device, Used: followed by the number of blocks this directory is taking up. ! f[ B Bind f[s string 1,f Dir:_[1 !* Put dir name in qreg 1! EZ1; JL 0U1 !* get directory listing, go to 2nd line! 0[4 0[2 -1[3 !* q2 pri blks free, q3 sec blks or -1 if no sec pack.! :<:FB#; %4w \-13"E c\u3 ' !* q4 non-zero if disk ! "# c\+q2u2 ' >w q4"E :ftNon-Directory_Device   ' !* check for real non-dir device! J:FT :T FT__Free:_ Q2:= !* Print device name and primary free blocks.! Q3:"L FT+ Q3:=' !* Print secondary free blocks if appropriate.! J2K 0U2 0U3 !* Use Q2 now to count used blocks, Q3 for used sec blocks! < .-z+2; !* Give up after processing all files.! fswidth/16< .-z+2; !* This many columns ! 40.U1 !* Q1 file type ! 1A-*"E *u1 ' !* locked ! 3A-L"E :u1 ' !* a link ! .( q1-:"N !* if it is not a link, accumulate total blocks ! 2c 2F~13"e 4+14C\+q3U3' "# 4+14C\+q2U2' !* Into appropriate counter, based on pack number.! 2A-!"E !* and mark file as not-backed-up if so no other marker.! q1-40."E !U1 ' ' ' )j 6d q1I !* get to front of file name, put tag ! 14C K I_ > !* delete garbage after file name ! -@f_K I  > j i,_Used:_ g2 I+ G3 I !* Put used blocks count in at front of buffer.!  ht :FV 0 !* print rest of listing ! !List Directories:! !C List names of all file directories.! f[D File f[B Bind erDSK:M.F.D._(FILE) @Y  :LL !* Get and sort the MFD ! JD < fswidth/9< !* Put this many columns ! .-z; D :LK I___ > -@f_k I  .-z; > HT :FV  !* Local Modes: Compile Command: M(M.M Generate Library)EMACS;[DIRE] >EMACS1;DIRED > End: *!