DELOLDER.MOD 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. MODULE DelOlder;
  2. IMPORT Diagnostics;
  3. IMPORT BigSets;
  4. IMPORT Drectory;
  5. IMPORT EnvironUtils;
  6. IMPORT ErrorManager;
  7. IMPORT HandleIO;
  8. IMPORT KbdInput;
  9. IMPORT M2Strings;
  10. IMPORT PosUtils;
  11. IMPORT StrConv;
  12. IMPORT StrEdit;
  13. IMPORT StringIO;
  14. VAR
  15. exiting, BatchMode : BOOLEAN;
  16. PrimaryFileSpec, SecondaryFileSpec, PrimaryDirName, SecondaryDirName,
  17. PrimaryFileSpecPart, SecondaryFileSpecPart: ARRAY [0..79] OF CHAR;
  18. PrimaryDrive, SecondaryDrive: CHAR;
  19. PROCEDURE Ask( question: ARRAY OF CHAR; VAR answer: ARRAY OF CHAR );
  20. VAR
  21. tmpstr: ARRAY [0..79] OF CHAR;
  22. BEGIN
  23. StringIO.WriteStr( StringIO.outp, question );
  24. IF answer[0] # 0C THEN
  25. (* There is a default. *)
  26. StringIO.WriteStr( StringIO.outp, ' <' );
  27. StringIO.WriteStr( StringIO.outp, answer );
  28. StringIO.WriteStr( StringIO.outp, '> ' );
  29. END;
  30. StringIO.ReadStr( StringIO.inp, tmpstr );
  31. IF tmpstr[0] = 0C THEN
  32. RETURN;
  33. END;
  34. IF (( CAP(tmpstr[0]) = 'Q' ) OR (tmpstr[0] = CHR(27)))
  35. AND (M2Strings.Length(tmpstr) = 1) THEN
  36. ErrorManager.StraightToDOS('');
  37. END;
  38. M2Strings.Assign( tmpstr, answer );
  39. END Ask;
  40. PROCEDURE FirstIsOlder( VAR First, Second: Drectory.FileInfoRec ): BOOLEAN;
  41. BEGIN
  42. IF First.year < Second.year THEN
  43. RETURN TRUE;
  44. ELSIF First.year > Second.year THEN
  45. RETURN FALSE;
  46. END;
  47. IF First.month < Second.month THEN
  48. RETURN TRUE;
  49. ELSIF First.month > Second.month THEN
  50. RETURN FALSE;
  51. END;
  52. IF First.day < Second.day THEN
  53. RETURN TRUE;
  54. ELSIF First.day > Second.day THEN
  55. RETURN FALSE;
  56. END;
  57. IF First.hour < Second.hour THEN
  58. RETURN TRUE;
  59. ELSIF First.hour > Second.hour THEN
  60. RETURN FALSE;
  61. END;
  62. IF First.minute < Second.minute THEN
  63. RETURN TRUE;
  64. ELSIF First.minute > Second.minute THEN
  65. RETURN FALSE;
  66. END;
  67. IF First.second < Second.second THEN
  68. RETURN TRUE;
  69. ELSE
  70. RETURN FALSE;
  71. END;
  72. END FirstIsOlder;
  73. PROCEDURE SameTimeStamp( VAR First, Second: Drectory.FileInfoRec ): BOOLEAN;
  74. BEGIN
  75. IF (First.year = Second.year) AND
  76. (First.month = Second.month) AND
  77. (First.day = Second.day) AND
  78. (First.hour = Second.hour) AND
  79. (First.minute = Second.minute) AND
  80. (First.second = Second.second) THEN
  81. RETURN TRUE;
  82. ELSE
  83. RETURN FALSE;
  84. END;
  85. END SameTimeStamp;
  86. PROCEDURE MakeInfoStr( FileInfo: Drectory.FileInfoRec; VAR TheStr: ARRAY
  87. OF CHAR );
  88. VAR
  89. dumstr: ARRAY [0..79] OF CHAR;
  90. BEGIN
  91. StrEdit.AssignStr( FileInfo.name, TheStr );
  92. WHILE M2Strings.Length(TheStr) < 12 DO
  93. StrEdit.Append( TheStr, ' ' );
  94. END;
  95. IF Drectory.SubdirectoryFile IN FileInfo.attribute THEN
  96. StrEdit.Append( TheStr, ' <DIR>' );
  97. ELSE
  98. StrConv.LongIntegerToStr( FileInfo.size, 8, dumstr );
  99. StrEdit.Append( TheStr, dumstr );
  100. END;
  101. StrConv.DateToStr( FileInfo.month, FileInfo.day, FileInfo.year,
  102. dumstr );
  103. StrEdit.Append( TheStr, ' ' );
  104. StrEdit.Append( TheStr, dumstr );
  105. StrConv.TimeToStr( FileInfo.hour, FileInfo.minute, FileInfo.second,
  106. FileInfo.second, dumstr );
  107. M2Strings.Delete( dumstr, M2Strings.Length(dumstr) - 7, 6 );
  108. StrEdit.Append( TheStr, ' ' );
  109. StrEdit.Append( TheStr, dumstr );
  110. END MakeInfoStr;
  111. PROCEDURE yes() : BOOLEAN;
  112. VAR
  113. choice : CARDINAL;
  114. BEGIN
  115. (*yes*)
  116. IF BatchMode THEN
  117. StringIO.WriteStr( StringIO.outp, 'yes');
  118. RETURN TRUE;
  119. END;
  120. choice := KbdInput.KeyHit( KbdInput.YorN );
  121. IF KbdInput.CAPkey(choice) = ORD('Y') THEN
  122. StringIO.WriteStr( StringIO.outp, 'yes');
  123. RETURN TRUE;
  124. ELSE
  125. StringIO.WriteStr( StringIO.outp, 'no');
  126. IF KbdInput.CAPkey(choice) = ORD('Q') THEN
  127. exiting := TRUE;
  128. END;
  129. RETURN FALSE;
  130. END;
  131. END yes;
  132. PROCEDURE Processor1(info : Drectory.FileInfoRec) : BOOLEAN;
  133. VAR
  134. TmpPrimaryFile, TmpSecondaryFile, PrimaryInfoStr, SecondaryInfoStr:
  135. ARRAY [0..79] OF CHAR;
  136. DirHandle: CARDINAL;
  137. tmpinfo: Drectory.FileInfoRec;
  138. BEGIN
  139. IF PosUtils.Equal( '..', info.name ) OR
  140. PosUtils.Equal( '.', info.name ) THEN
  141. RETURN TRUE;
  142. END;
  143. M2Strings.Concat( PrimaryDirName, info.name, TmpPrimaryFile );
  144. M2Strings.Concat( SecondaryDirName, info.name, TmpSecondaryFile );
  145. M2Strings.Insert( ':', TmpPrimaryFile, 0 );
  146. M2Strings.Insert( PrimaryDrive, TmpPrimaryFile, 0 );
  147. M2Strings.Insert( ':', TmpSecondaryFile, 0 );
  148. M2Strings.Insert( SecondaryDrive, TmpSecondaryFile, 0 );
  149. IF HandleIO.FileExists( TmpSecondaryFile ) THEN
  150. MakeInfoStr( info, PrimaryInfoStr );
  151. DirHandle := 0FFFFH;
  152. StringIO.PrintMessage( Drectory.FindFirstFile( TmpSecondaryFile,
  153. DirHandle, tmpinfo ) );
  154. MakeInfoStr( tmpinfo, SecondaryInfoStr );
  155. IF ((M2Strings.CompareStr( PrimaryInfoStr, SecondaryInfoStr ) = 0) OR
  156. FirstIsOlder( tmpinfo, info ) OR SameTimeStamp( tmpinfo, info) ) AND
  157. (NOT PosUtils.Present('<DIR>', PrimaryInfoStr) ) THEN
  158. M2Strings.Insert( PrimaryDirName, PrimaryInfoStr, 0 );
  159. M2Strings.Insert( ':', PrimaryInfoStr, 0 );
  160. M2Strings.Insert( PrimaryDrive, PrimaryInfoStr, 0 );
  161. M2Strings.Insert( SecondaryDirName, SecondaryInfoStr, 0 );
  162. M2Strings.Insert( ':', SecondaryInfoStr, 0 );
  163. M2Strings.Insert( SecondaryDrive, SecondaryInfoStr, 0 );
  164. StrEdit.Append( SecondaryInfoStr, ' ' );
  165. StringIO.WriteEol( StringIO.outp, '' );
  166. StringIO.WriteStr( StringIO.outp, 'Keeping ' );
  167. StringIO.WriteEol( StringIO.outp, PrimaryInfoStr );
  168. StringIO.WriteStr( StringIO.outp, 'Delete? ' );
  169. StringIO.WriteStr( StringIO.outp, SecondaryInfoStr );
  170. IF yes() THEN
  171. StringIO.PrintMessage( Drectory.DeleteFile( TmpSecondaryFile ) );
  172. END;
  173. IF exiting THEN
  174. RETURN FALSE;
  175. END;
  176. END;
  177. END;
  178. RETURN TRUE;
  179. END Processor1;
  180. BEGIN
  181. IF NOT EnvironUtils.ParsedParam( 1, PrimaryFileSpec ) THEN
  182. StringIO.WriteEol( StringIO.outp, '' );
  183. StringIO.WriteEol( StringIO.outp,
  184. 'DelOlder expects two wildcard specifications of files in different' );
  185. StringIO.WriteEol( StringIO.outp,
  186. 'directories. It deletes all files in the second directory with ' );
  187. StringIO.WriteEol( StringIO.outp,
  188. 'names that match those of files in the first directory if the ' );
  189. StringIO.WriteEol( StringIO.outp,
  190. 'secondary files are identical to or older than the primary files. A ' );
  191. StringIO.WriteEol( StringIO.outp,
  192. 'trailing /p makes it pause for confirmation before deleting each file.' );
  193. StringIO.WriteEol( StringIO.outp, '' );
  194. PrimaryFileSpec := '';
  195. Ask( 'Primary file specification? (These files will survive.) ',
  196. PrimaryFileSpec );
  197. END;
  198. IF NOT EnvironUtils.ParsedParam( 2, SecondaryFileSpec ) THEN
  199. SecondaryFileSpec := '';
  200. Ask( 'Secondary file specification? (These files may be deleted.) ',
  201. SecondaryFileSpec );
  202. END;
  203. StrEdit.CrunchBlanks( PrimaryFileSpec );
  204. StrEdit.CrunchBlanks( SecondaryFileSpec );
  205. IF SecondaryFileSpec[M2Strings.Length(SecondaryFileSpec)-2]='/' THEN
  206. IF CAP( SecondaryFileSpec[M2Strings.Length(SecondaryFileSpec)-1] ) = 'P' THEN
  207. M2Strings.Delete(SecondaryFileSpec, M2Strings.Length(SecondaryFileSpec)-2, 2);
  208. StrEdit.CutTrailingChars( ' ', SecondaryFileSpec);
  209. BatchMode := FALSE;
  210. ELSE
  211. BatchMode := TRUE;
  212. END;
  213. ELSE
  214. BatchMode := TRUE;
  215. END;
  216. BigSets.AppendSet( KbdInput.YorN, "{'q', 'Q'}" );
  217. Drectory.GetDrivePathAndName( SecondaryFileSpec, SecondaryDrive,
  218. SecondaryDirName, SecondaryFileSpecPart );
  219. Drectory.GetDrivePathAndName( PrimaryFileSpec, PrimaryDrive,
  220. PrimaryDirName, PrimaryFileSpecPart );
  221. IF PosUtils.Equal( PrimaryFileSpecPart, '.' ) THEN
  222. StringIO.PrintMessage( Drectory.GetCurrentDir( Drectory.GetDefaultDrive(),
  223. PrimaryDirName ) );
  224. END;
  225. IF PosUtils.Equal( SecondaryFileSpecPart, '.' ) THEN
  226. StringIO.PrintMessage( Drectory.GetCurrentDir( Drectory.GetDefaultDrive(),
  227. SecondaryDirName ) );
  228. END;
  229. IF PrimaryFileSpecPart[0] = 0C THEN
  230. PrimaryFileSpecPart := '*.*';
  231. END;
  232. IF SecondaryFileSpecPart[0] = 0C THEN
  233. SecondaryFileSpecPart := '*.*';
  234. END;
  235. StrEdit.CutTrailingChars( '\', PrimaryDirName );
  236. StrEdit.CutTrailingChars( '\', SecondaryDirName );
  237. StrEdit.Append( PrimaryDirName, '\' );
  238. StrEdit.Append( SecondaryDirName, '\' );
  239. exiting := FALSE;
  240. StringIO.PrintMessage(Drectory.FindFiles( PrimaryFileSpec, Processor1 ));
  241. END DelOlder.