home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / DUPDEL00.ZIP / DUPDEL.CMD next >
OS/2 REXX Batch file  |  1992-10-07  |  9KB  |  389 lines

  1. /* dupdel.cmd - Find all duplicate file names on one or multiple 
  2.                      drives, present the names to the user, and delete
  3.                      any or all based on user input.
  4.  
  5.                      Parms are path(s) with the drive letter included and
  6.                      file filters to look for.  
  7.  
  8.                        Examples: 'DUPDEL C: *.ZIP'
  9.                                  'DUPDEL C:\OS2 *.INI'
  10.                                  'DUPDEL C: D: E: *.EXE *.COM *.BAT'
  11.  
  12.  
  13.                      The user can chose which duplicate files to delete.
  14.                      The user will have the option to delete the files 
  15.                      at the end of the routine or create a temporay batch
  16.                      file to do the deletes after the file is reviewed.
  17.  
  18.                      This REXX routine requires the VREXX function package.
  19.  
  20.                      Tony Thigpen
  21.                      115 West York Court
  22.                      Longwood, FL 32779
  23.  
  24.                      Revision 0.0    10/03/92  */
  25.  
  26. trace off
  27. signal on failure name V_CLEANUP
  28. signal on halt name V_CLEANUP
  29. signal on syntax name V_CLEANUP
  30. signal on error name V_CLEANUP
  31.  
  32. parse upper source oper.system call.type cmd.file.source .
  33. if oper.system <> 'OS/2'
  34.   then call ERROR_MESSAGE '16 001 This REXX routine can only run in OS/2, not' oper.system'.'
  35. parse upper version version
  36. i = lastpos('\',cmd.file.source) + 1
  37. parse var cmd.file.source . =(i)  cmd.name '.CMD'
  38. arg args   /* args will be parsed out as drive(s) and file filter(s) */
  39.  
  40. call V_LOAD
  41. call VERIFY_PARMS
  42. call BUILD_FILE_LIST
  43. call SORT_FILES
  44. call REMOVE_NON_DUPS
  45. if file.list.0 = 0 then call ERROR_MESSAGE '6 0001 No duplicate files found'
  46. call SHOW_DUPS
  47. if del.list.0 = 0 then call ERROR_MESSAGE '6 0002 No files selected'
  48. call WHICH_WAY_SCREEN
  49. call RX_LOAD
  50. call DELETE_FILES
  51. call FINISHED_MESSAGE 
  52. exit 0
  53.  
  54. VERIFY_PARMS:
  55.  
  56. /* Break out drives and file filters from arguments */
  57. parse value ' ' with drives. filters.
  58. parse value 'C: *.*' with drives.1 filters.1
  59. parse value '1 1' with j k
  60. do i = 1 to words(args)
  61.   parm = strip(word(args,i),'B')
  62.   if substr(parm,2,1) \= ':'   /* Must be a drive or path */
  63.     then do
  64.       filters.k = parm
  65.       k = k + 1
  66.       iterate
  67.     end
  68.     drives.j = parm
  69.     if \ datatype(left(parm,1),'M')    /* Is drive letter valid */
  70.       then call ERROR_MESSAGE '16 002 Drive' parm 'is not a valid drive letter'
  71.     if right(parm,1) \= '\' then drives.j = drives.j'\'
  72.     j = j + 1
  73. end
  74. drives.0 = j - 1
  75. filters.0 = k - 1
  76.  
  77. return 0
  78.  
  79. BUILD_FILE_LIST:
  80.  
  81. file.list. = ' '
  82. file.list.0 = 0
  83.  
  84. do i = 1 to drives.0
  85.   do j = 1 to filters.0
  86.     call GET_FILES drives.i filters.j
  87.   end
  88. end
  89.  
  90. return 0
  91.  
  92. GET_FILES:
  93. arg drive filter
  94.  
  95. if RxFuncQuery(SysFileTree)
  96.   then call RxFuncAdd 'SysFileTree', 'RexxUtil', 'SysFileTree'
  97.  
  98. call SysFileTree drive||filter, 'files', 'FSO'
  99. if result \= 0
  100.   then call ERROR_MESSAGE '16 0003 Not enouth memory to get file tree'
  101.  
  102. do k = 1 to files.0
  103.    file.list.0 = file.list.0 + 1
  104.    m = file.list.0
  105.    last.slash = lastpos('\',files.k)
  106.    filename = substr(files.k,last.slash+1,length(files.k)-last.slash)
  107.    filepath = left(files.k,last.slash)
  108.    parse upper var filename file.list.name.m
  109.    file.list.path.m = filepath
  110.    file.list.full.name.m = files.k
  111. end
  112.  
  113. return 0
  114.  
  115. SORT_FILES:
  116.  
  117. done = 'NO'
  118. loops = file.list.0 - 1
  119. do until done = 'YES'
  120.   done = 'YES'
  121.   do i = 1 to loops
  122.     j = i + 1
  123.     if file.list.name.i > file.list.name.j
  124.       then parse value,
  125.            file.list.name.i'^'file.list.path.i'^'file.list.full.name.i||,
  126.         '^'file.list.name.j'^'file.list.path.j'^'file.list.full.name.j||,
  127.         '^NO' with,
  128.             file.list.name.j '^' file.list.path.j '^' file.list.full.name.j,
  129.         '^' file.list.name.i '^' file.list.path.i '^' file.list.full.name.i,
  130.         '^' done
  131.   end
  132. end
  133.  
  134. return 0
  135.  
  136. REMOVE_NON_DUPS:
  137.  
  138. loops = file.list.0 - 1
  139. file.list.dup.1 = 'NO'
  140. do i = 1 to loops
  141.   j = i + 1
  142.   file.list.dup.j = 'NO'
  143.   file.list.dup.end.i = 'YES'
  144.   if file.list.name.i = file.list.name.j
  145.     then parse value 'YES YES NO' with file.list.dup.i file.list.dup.j,
  146.       file.list.dup.end.i
  147. end
  148. i = file.list.0
  149. file.list.dup.end.i = 'YES'
  150.  
  151. j = 0
  152. do i = 1 to file.list.0
  153.   if file.list.dup.i = 'NO' then iterate
  154.   j = j + 1
  155.   if i = j then iterate
  156.   file.list.name.j = file.list.name.i
  157.   file.list.path.j = file.list.path.i
  158.   file.list.full.name.j = file.list.full.name.i
  159.   file.list.dup.j = file.list.dup.i
  160.   file.list.dup.end.j = file.list.dup.end.i
  161. end
  162. file.list.0 = j
  163.  
  164. return 0
  165.  
  166. SHOW_DUPS:
  167.  
  168. j = 0
  169. k = 0
  170. m = 0
  171. do i = 1 to file.list.0
  172.   j = j + 1
  173.   k = k + 1
  174.   files.k = file.list.path.i
  175.   if file.list.dup.end.i \= 'NO'
  176.     then do
  177.       call SELECT_SCREEN
  178.       iterate
  179.     end
  180.   if k = 10
  181.     then do
  182.       call MORE_SCREEN
  183.       call SELECT_SCREEN
  184.     end
  185. end
  186. del.list.0 = m
  187.  
  188. return 0
  189.  
  190. SELECT_SCREEN:
  191.  
  192. title = file.list.name.i
  193. files.0 = k
  194.  
  195. win.left = 00
  196. win.right = 100
  197. win.top = 90
  198. win.bottom = 60
  199. win.font = 'COUR'
  200. win.size = '10'
  201. win.forecolor = 'WHITE'
  202. win.backcolor = 'BLACK'
  203. win.id = VOpenWindow(title,win.forecolor,win)
  204. call VSetFont win.id, win
  205. call VBackColor win.id win.backcolor
  206. x = 10
  207. y = 900
  208. do n = 1 to files.0
  209.   call VSay win.id, x, y, files.n
  210.   y = y - 100
  211. end
  212.  
  213. diag.centerx = 80
  214. diag.centery = 30
  215. call VDialogPos diag.centerx, diag.centery
  216.  
  217. title = file.list.name.i
  218. files.0 = k
  219. deletes. = ' '
  220. button = ' '
  221. button = VCheckBox(title,files,deletes,3)
  222. call VCloseWindow win.id
  223.  
  224. if button = 'CANCEL'
  225.   then do
  226.     call HOW_CANCEL_SCREEN_1
  227.     k = 0
  228.     return 0
  229.   end
  230. k = 0
  231. do n = 1 to deletes.0
  232.    m = m + 1
  233.    del.list.m = deletes.n||title
  234. end  
  235.  
  236. return 0
  237.  
  238. HOW_CANCEL_SCREEN_1:
  239.  
  240. title = cmd.name '- CANCEL REQUESTED'
  241. msg.line.0 = 5
  242. msg.line.1 = 'You have have selected the CANCEL option.'
  243. msg.line.2 = ''
  244. msg.line.3 = 'If you wish to cancel the' cmd.name 'process'
  245. msg.line.4 = 'then select [YES].  If you select [NO], the'
  246. msg.line.5 = 'last screen will be redisplayed.'
  247. button = ''
  248. button = VMsgBox(title,msg.line,6)
  249. if button = 'YES'
  250.   then call ERROR_MESSAGE '8 0004' cmd.name 'Cancled By Operator'
  251. call SELECT_SCREEN
  252.  
  253. return 0
  254.  
  255. MORE_SCREEN:
  256.  
  257. title = cmd.name '- MORE'
  258. msg.line.0 = 5
  259. msg.line.1 = cmd.name 'can only display only 10 duplicate'
  260. msg.line.2 = 'files on each selection screen. When you '
  261. msg.line.3 = 'finish with the next screen, another screen'
  262. msg.line.4 = 'with additonal selections for the same file'
  263. msg.line.5 = 'name will be displayed.'
  264. button = VMsgBox(title,msg.line,1)
  265.  
  266. return 0
  267.  
  268. WHICH_WAY_SCREEN:
  269.  
  270. title = cmd.name '- Process now or later?'
  271. msg.line.0 = 7
  272. msg.line.1 = 'All selections are complete.'
  273. msg.line.2 = ' '
  274. msg.line.3 = 'Do you want the deletes to be'
  275. msg.line.4 = 'performed at this time?  If'
  276. msg.line.5 = 'you chose [NO], then a batch'
  277. msg.line.6 = 'file will be created to perform'
  278. msg.line.7 = 'the deletes at a later time.'
  279. delete.now = VMsgBox(title,msg.line,6)
  280.  
  281. return 0
  282.  
  283. RUN_IT_MSG:
  284.  
  285. title = cmd.name 
  286. msg.line.0 = 3
  287. msg.line.1 = 'To delete the selected files,'
  288. msg.line.2 = 'run the file -' delfile
  289. msg.line.3 = 'after reviewing the contents.'
  290. button = VMsgBox(title,msg.line,1)
  291.  
  292. return 0
  293.  
  294. DELETE_FILES:
  295.  
  296. if delete.now = 'NO'
  297.   then do
  298.     delfile = SysTempFileName('C:\DEL!????.CMD')
  299.     lo.rx = lineout(delfile,'/* */')
  300.     if lo.rx \= 0
  301.       then call ERROR_MESSAGE '8 0005 Can not write delete file -' delfile
  302.   end
  303.  
  304. do i = 1 to del.list.0
  305.   command = 'rc = SysFileDelete("'del.list.i'")'
  306.   if delete.now = 'YES'
  307.     then do
  308.       interpret command
  309.       if rc \= 0 
  310.         then call ERROR_MESSAGE '4 1'left(rc,3,'0') 'Delete Failed'
  311.     end
  312.     else do
  313.       lo.rx = lineout(delfile,command)
  314.       if lo.rx \= 0
  315.         then call ERROR_MESSAGE '8 0006 Can not write delete file -' delfile
  316.     end 
  317. end
  318. if delete.now = 'NO'
  319.   then call RUN_IT_MSG
  320.  
  321. return 0
  322.  
  323. RX_LOAD:
  324.  
  325. if \ RxFuncQuery('SysLoadFuncs')
  326.   then return 0
  327. call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  328. call SysLoadFuncs
  329.  
  330. return 0
  331.  
  332. V_LOAD:
  333.  
  334. if RxFuncQuery(VInit)
  335.   then call RxFuncAdd 'Vinit', 'VREXX', 'Vinit'
  336. v.initcode = VInit()
  337. if v.initcode = 'ERROR'
  338.   then call ERROR_MESSAGE '16 0007 Can Not Load Visual REXX Functions'
  339.  
  340. return 0
  341.  
  342. V_CLEANUP:
  343.  
  344. if symbol('v.initcode') = 'VAR'
  345.   then call VExit
  346. if symbol('em.rc') = 'VAR' then return
  347.  
  348. exit 9999
  349.  
  350. ERROR_MESSAGE:
  351. arg em.rc msg
  352.  
  353. if symbol('v.initcode') = 'VAR'
  354.   then call ERROR_MESSAGE_SCREEN
  355.   else say msg
  356.  
  357. if em.rc < 6 then return 0
  358.  
  359. call V_CLEANUP
  360.  
  361. exit em.rc
  362.  
  363. ERROR_MESSAGE_SCREEN:
  364.  
  365. if em.rc < 8 
  366.   then type.error = 'non-critical'
  367.   else type.error = 'critical'
  368.  
  369. title = cmd.name
  370. msg.line.0 = 3
  371. msg.line.1 = 'The following' type.error 'error has occured:'
  372. msg.line.2 = ''
  373. msg.line.3 = msg
  374. button = VMsgBox(title,msg.line,1)
  375.  
  376. return 0
  377.  
  378. FINISHED_MESSAGE:
  379.  
  380. title = cmd.name
  381. msg.line.0 = 1
  382. msg.line.1 = cmd.name 'DONE'
  383. if symbol('v.initcode') = 'VAR'
  384.   then button = VMsgBox(title,msg.line,1)
  385.   else say msg.line.1
  386.  
  387. return 0
  388.  
  389.