* * DeluxeDirectory * * written by Gerson Kurz * ; Puh! Extensive documentation done on Sept.6,1991 due to popular demand ; if you have better comments (or you find bugs etc) feel free to remove em ; as long as you send me a copy !! ;OVERSCAN = 1 version MACRO dc.b "3.4" ENDM MAX_PATHSIZE equ 1024 incdir 'include:' macfile 'lvo/exec.i' _LVOxxx for exec.library macfile 'lvo/dos.i' _LVOxxx for dos.library macfile 'lvo/utility.i' macfile 'macro.i' several macros macfile 'dos/rdargs.i' argument parsing macfile 'dos/dosasl.i' file matching macfile 'dos/datetime.i' date comparison macfile 'dos/dosextens.i' filehandler structure macfile 'exec/libraries.i' for OS2.0 check macfile 'utility/utility.i' ; => \1:STRING TO PRINT, [\2:VALUES FOR STRING] printf MACRO printf for blank messages only IFGT NARG-1 MOVE.L #\2,D2 = arguments ELSE MOVEQ #0,D2 no arguments needed ENDC MOVE.L #\1,D1 = string PUSHR a5 since a5 seems to be trashed by this function CALL VPrintf print string to default output PULLR a5 restore a5 ENDM printfc MACRO printf for colored/blank messages mixed IFGT NARG-1 MOVE.L #\2,D2 = arguments ELSE MOVEQ #0,D2 no arguments needed ENDC MOVE.L #\1,D1 = string TST.L (arg.nocolor) test if colored message available BNE.B .PRINTF_\@ no, it ain't MOVE.L #C_\1,D1 set color message .PRINTF_\@ PUSHR a5 store a5 again CALL VPrintf print string to default output PULLR a5 restore a5 ENDM bra.b _start enter program ** Insert Version-String so that the CLI-Version-Command can always get it dc.b 0,'$VER: MDIR v' version string !! version dc.b ' by Gerson Kurz (Sept.6,1991)',10,0 cnop 0,4 _start CLEARBSS clear BSS section ** Open DOS.LIBRARY for OS2.0 V36 or higher lea (dos.name,pc),a1 open dos.library V36++ moveq #0,d0 no version number on first try CALL OpenLibrary,exec.base open library move.l d0,(dos.base) save base tst.l d0 failure ? beq no.kick.2.0 yes, send message & quit move.l d0,a0 get dos.base cmp.w #36,(LIB_VERSION,a0) test for OS2.0 version blo no.kick.2.0 no, quit lea (utility.name,pc),a1 open dos.library V36++ moveq #0,d0 no version number on first try CALL OpenLibrary,exec.base open library move.l d0,(utility.base) save base tst.l d0 failure ? beq no.kick.2.0 yes, send message & quit ** Read and parse the arguments from the input stream move.l #arg.template,d1 template string for arguments move.l #arg.dirs,d2 first of the flags in a row [see definition] moveq #0,d3 no optional rdargs CALL ReadArgs,dos.base read & parse arguments tst.l d0 error ? beq dos.error yes, display error move.l d0,(arg.rdargs) save adress to free memory tst.l (arg.help) help selected ? bne help yes, show help ** Check arguments for collisions & init argument defaults bsr setupargs enter subroutine ** Setup NEWER/OLDER options if appropriate tst.l (arg.newer) NEWER-keyword there ? beq.b not.newer no, cancel move.l (arg.newer),a0 get filename bsr open.cmpfile open file and get date-string cmp.l #FALSE,d0 failure ? beq dos.error yes, show dos-error not.newer tst.l (arg.older) OLDER-keyword there ? beq.b not.older no, cancel move.l (arg.older),a0 get filename bsr open.cmpfile open file and get date-string cmp.l #FALSE,d0 failure ? beq dos.error yes, show dos-error not.older ** Get current date [for head-display] lea (datetime),a4 datetime buffer (from datetime.i) move.b #FORMAT_DOS,(dat_Format,a4) format type = standard DOS move.l #StrDay.msg,(dat_StrDay,a4) init day-msg move.l #StrDate.msg,(dat_StrDate,a4) init date-msg move.l #StrTime.msg,(dat_StrTime,a4) init time-msg clr.b (dat_Flags,a4) no substitute allowed move.l a4,d1 get copy to d1 CALL DateStamp get current date move.l a4,d1 get another copy CALL DateToStr get string from datestamp tst.l d0 error ? beq dos.error yes, quit bsr norm.dates check for 'DATES/NODATES' options ** Check SINCE/UPTO options tst.l (arg.since) test SINCE keyword beq.b not.since not valid move.l (arg.since),a1 date-string bsr get.cmpdate get date value tst.l d0 error ? beq date.error yes, quit not.since tst.l (arg.upto) test UPTO keyword beq.b not.upto not valid move.l (arg.upto),a1 date-string bsr get.cmpdate get date value tst.l d0 error ? beq date.error yes, quit not.upto ** Handle the multiple-directory strings move.l (arg.dirs),a4 multiple DIR-strings lea.l (a4),a0 get current string bsr show.volume show directory tst.l (a4) are there any more ? beq.b done no, done tst.l (4,a4) are there really no more ?> beq.b done no, done addq.l #4,a4 next string .loop lea.l (a4),a0 get string bsr show.volume show directory addq.l #4,a4 next string tst.l (a4) done ? bne.b .loop no loop ** Return to CLI/Shell environment done bsr.b close.args close parse arguments moveq #RETURN_OK,d0 return value = OK rts done !! ** Close arguments ( the routine basically frees all allocated memory ) close.args move.l (arg.rdargs),d1 arguments tst.l d1 any valid ? beq.b 1$ no, don't free them CALL FreeArgs,dos.base free arguments 1$ tst.l (utility.base) beq.b 2$ move.l (utility.base),a1 CALL CloseLibrary,exec.base 2$ rts return ** Display error if running below OS2.0 no.kick.2.0 move.l #falsekick.msg,d2 message moveq #falsekick.size,d3 size of message CALL Output,dos.base old printf for compatibility CALL Write send to standard output moveq #RETURN_FAIL,d0 return = error rts done ** Display error if some date i/o failed date.error printf dateerror.msg special error message bsr close.args close arguments moveq #RETURN_FAIL,d0 return = error rts done ** Display DOS-error dos.error CALL IoErr,dos.base get io error move.l d0,d1 copy error value move.l #err.head,d2 error header = 'ERROR:' CALL PrintFault print errorstring bsr close.args close arguments moveq #RETURN_FAIL,d0 return = error rts done help printf help.msg show help message bsr close.args close arguments moveq #RETURN_OK,d0 return = ok rts done ** Show directory => a0: name of directory/file/pattern show.volume PUSHALL save all registers clr.l (NROF_dirs) clear directory counter clr.l (NROF_files) clear file counter clr.l (NROF_bytes) clear byte counter clr.l (NROF_blocks) clear block counter lea (anchorpath),a1 anchor path lea (volname),a1 name of thee volume move.l (a0),a0 get name 1$ move.b (a0)+,d0 get next char move.b d0,(a1)+ copy char tst.b d0 tst if end of string bne.b 1$ no, loop move.l #volname,d1 name of thee volume move.l #SHARED_LOCK,d2 lock = shared (we're humble) CALL Lock,dos.base lock volume tst.l d0 chk for error beq .nodirlock yes, quit move.l d0,d6 copy lock move.l d0,d1 get lock move.l #fileinfoblock,d2 fileinfoblock CALL Examine examine file move.l d6,d1 get lock CALL UnLock free lock ** This next part will be a little confusing if you read it, basically I try to ** see if the user specified a PATTERN (e.g. c:a*) or a DIRECTORY (c:). If it ** Is a directory, I have to AddPart a '/#?' to get all entrys of the directory, ** because MatchFirst/MatchNext() will think it has already done its job when it ** finds C:. Got that ?? lea (fileinfoblock),a0 fileinfoblock move.l (fib_DirEntryType,a0),d0 get type (dir/file) btst #31,d0 =negative ? beq 3$ yep, is a directory .nodirlock lea (anchorpath),a0 anchor path move.l a0,d2 get it move.l #SIGBREAKF_CTRL_C,(ap_BreakBits,a0) set breakbit = CTRL-C move.l #volname,d1 name of volume CALL MatchFirst,dos.base get first match tst.l d0 test if error bne vol.matcherror yes, quit lea (anchorpath+ap_Info+fib_FileName),a0 get filename (rather volumename) tst.b (a0) is it there ? bne.b 2$ yo! continue move.l #anchorpath,d1 else get path CALL MatchEnd and free it 3$ move.l #volname,d1 volumename move.l #addpart.msg,d2 '/#?',0 move.l #MAX_PATHSIZE,d3 maximum path = 1024 CALL AddPart here it is ! cmp.l #DOSFALSE,d0 error ? beq vol.doserror yep, quit lea (anchorpath),a0 anchorpath move.l a0,d2 get a copy move.l #SIGBREAKF_CTRL_C,(ap_BreakBits,a0) set break = CTRL_C move.l #volname,d1 name of volume CALL MatchFirst,dos.base find first match tst.l d0 error ? bne vol.matcherror yo once again quit 2$ lea (volname),a0 name of volume move.l #MAX_PATHSIZE-1,d0 size = 1024 .clearpath clr.b (a0)+ clear string dbra d0,.clearpath continue looping ** Now, we get the full pathname of the volume lea (anchorpath),a0 Path move.l (ap_Current,a0),a0 ptr to current item move.l (an_Lock,a0),d1 lock move.l #volname,d2 name which will contain the path move.l #MAX_PATHSIZE,d3 maximum = 1024 CALL NameFromLock get name from lock tst.l d0 error ? beq vol.doserror yes, done jsr GETDISKINFO get INFO-like stuff ** Finally we start displaying ! (Yipee!) move.b #-1,(rowcount) rowcount = 1..3 etc showdirectory lea (anchorpath),a4 anchorpath ** Check if HIDDEN-bit is set move.l (ap_Info+fib_Protection,a4),d0 get protection btst #7,d0 check if hidden beq.b .not.hidden no, continue tst.l (arg.nohidden) dow have to ch bne continue no,continue .not.hidden ** Check if it is a Directory move.l (ap_Info+fib_DirEntryType,a4),d0 get entry type clr.b (dirflag) not a directory [=default] btst #31,d0 is negative ? bne.b 1$ yo, it's no directory move.b #1,(dirflag) else set flag 1$ ** Now for several time-checks ! timecheck tst.l (arg.today) TODAY keyword beq.b .not_today not specified bsr checkdates compare dates bne continue not equal => abort .not_today tst.l (arg.since) SINCE keyword beq.b .not_since not specified bsr checkdates2 compare dates blo continue less => abort .not_since tst.l (arg.upto) UPTO keyword beq.b .not_upto not specified bsr checkdates2 compare dates bhi continue higher => abort .not_upto tst.l (arg.newer) NEWER keyword beq.b .not_newer not specified bsr checkdates2 compare dates blo continue less => abort .not_newer tst.l (arg.older) OLDER keyword beq.b .not_older not specified bsr checkdates2 compare dates bhi continue higher => abort .not_older ** Now for some thing which could be placed somewhere else,too but well, ** it's here and who cares anyway ?! setreturn lea (anchorpath),a4 anchorpath lea (ap_Info+fib_FileName,a4),a1 get filename move.l a1,(filename) save if !! tst.l (arg.all) test if argument = all beq nextfile no, continue examination ** Yo, and here is the ALL-section, which needs some treatment with MatchNext().. tst.b (dirflag) is it a dir ? beq nextfile no, well done! bsr getfull.fname get full pathname ** Handle DIDDIR (directory has just been done, returning to parent level) move.b (ap_Flags,a4),d0 get anchorpath flags btst #APB_DIDDIR,d0 DIR just DONE beq.b 1$ no, continue PUSHR d0 save flags tst.l (arg.fullpath) fullpath ? bne.b .not1 yep, no need for [>(path)] tst.l (arg.list) list option ? bne.b .l1 no, display normal type bsr checkdir.return check for return printfc diddir.msg2,filename print norm-style message bra.b .not1 continue .l1 printfc diddir.msg,filename else print list-style .not1 PULLR d0 restore flags bra 2$ continue ** DODIR says that we want to examine this directory (some strange guys will ** want to include a possible 'ASK' option here, but well it's YOUR problem really.. 1$ bset #APB_DODIR,d0 set flag = DODIR PUSHR d0 save flags addq.l #1,(NROF_dirs) more of those dirs tst.l (arg.fullpath) fullpath ? bne.b .show2 yes, show it ! tst.l (arg.list) list ? bne.b .l2 yes, show it bsr checkdir.return else (possible) return printfc dodir.msg2,filename print [>(path)] bra.b .not2 continue .show2 printfc fndir.msg,filename special for 'fullpath all' mode bra.b .not2 continue .l2 printf dodir.msg,filename print list-type .not2 PULLR d0 restore flags 2$ bclr #APB_DIDDIR,d0 set flag [ so no errors ] move.b d0,(ap_Flags,a4) save flags bra nofileinfo continue ** Analyze Flags nextfile ** Handle FILES/DIRS options tst.l (arg.filesonly) FILES option ? beq.b 1$ no, continue tst.b (dirflag) chk if we have a directory bne continue yes, continue 1$ tst.l (arg.dirsonly) DIRS option ? beq.b 2$ no, continue tst.b (dirflag) chk if we have a directory beq continue no, continue 2$ ** Handle the LARGER/SMALLER options move.l (ap_Info+fib_Size,a4),d0 get size of file tst.l (arg.larger) LARGER option ? beq.b not.larger no continue move.l (arg.larger),a0 get argument move.l (a0),d1 get argument size cmp.l d1,d0 compare with current size bls continue quit if LARGER not.larger tst.l (arg.smaller) SMALLER option ? beq.b not.smaller no continue move.l (arg.smaller),a0 get argument move.l (a0),d1 get argument size cmp.l d1,d0 compare with current size bhs continue quit if SMALLER not.smaller ** Display HEAD-message if appropriate tst.b (anyentry.flag) already HEADed ? bne.b head.is.there yo, continue printfc head.msg,headname print HEAD-msg move.b #-1,(anyentry.flag) set HEADed flag head.is.there ** Display [RETURN] if needed tst.l (arg.fullpath) FULLPATH ? bne.b .noreturn yo, we don't need RETURNs addq.b #1,(rowcount) next row move.b (maxrows),d0 maxrows cmp.b (rowcount),d0 compare ? bne.b .noreturn not yet clr.b (rowcount) reset printf return.msg print RETURN .noreturn ** Update counters for files,dirs,blocks and bytes (what's missing ? yes, BLEEPS! are missing) move.l (ap_Info+fib_NumBlocks,a4),d0 nr of blocks add.l d0,(NROF_blocks) shit I only got damn 68000 move.l (ap_Info+fib_Size,a4),d0 size of the entry add.l d0,(NROF_bytes) add to total bytes tst.b (dirflag) is it a dir ? bne.b .is.a.dir yo addq.l #1,(NROF_files) add nr of files bra.b .is.nothing continue .is.a.dir addq.l #1,(NROF_dirs) else add nr of dirs .is.nothing ** Do according to the type-flags (VERBOSE,SHORT,LIST or 'NORMAL') tst.l (arg.verbose) verbose ? bne verbose.display yes -> display verbose action tst.l (arg.short) short ? bne short.display yes -> display short action tst.l (arg.list) list ? bne list.display yes -> display list action ** 'NORMAL' display (not supplied as keyword really, this is the default choice ** (Note that the code may look a little bit confusing but a) you should know that ** by now, and b) I did it step after step so there are some -eh- inconsistencys ** (Hey, be glad that I commented this one! Just a few years ago I used not only ** to reduce my comments to lyrics from the songs I listend to while coding, I ** also used labels like 'OIUsXOJ' and 'shitFUCK' (case sensitive, of course) ** [and of course didn't use INCLUDEs but absolute hex offsets...] haha) ** (This is a nested IF-THEN-ELSE construct anyway) move.l (ap_Info+fib_Size,a4),(filesize) get size of thee file tst.l (arg.fullpath) is it full-path type ? bne.b .fullpath.norm yes, the show it tst.b (dirflag) directory ? bne.b 1$ yes, show it printf nfile.msg,filename display file bra continue done 1$ printfc ndir.msg,filename display directory bra continue done .fullpath.norm bsr getfull.fname get full pathname tst.b (dirflag) directory ? bne.b 2$ yes, show it printf fnfile.msg,filename display file bra continue done 2$ printfc fndir.msg,filename display directory bra continue done ** SHORT display short.display tst.b (dirflag) directory ? bne.b 1$ yes, show it printf sfile.msg,filename display file bra continue done 1$ printfc sdir.msg,filename display directory bra continue done ** LIST-lookalike display list.display bsr getextinfo.1 get list-info tst.l (arg.fullpath) FULLPATH ? bne.b .fullpath.list yo, bring the noise tst.b (dirflag) directory ? bne.b 1$ yes, show it printf lfile.msg,filename display file bra .continue.list done 1$ printfc ldir.msg,filename display directory bra .continue.list done .fullpath.list bsr getfull.fname get full pathname tst.b (dirflag) directory ? bne.b 2$ yes, show it printf flfile.msg,filename display file bra.b .continue.list2 continue 2$ printfc fldir.msg,filename display directory [this construct isn't 'clean' but it works] .continue.list2 printfc flinfo.msg,protstring print info message tst.l (comment) comment ? beq continue no continue printfc fcomment.msg,comment print comment bra continue continue .continue.list printfc linfo.msg,protstring protection ? tst.l (comment) comment ? beq continue no continue printfc comment.msg,comment print comment bra continue continue ** VERBOSE-type display verbose.display bsr getextinfo.1 get extended information lea (anchorpath),a4 anchorpath move.l (ap_Info+fib_EntryType,a4),(v_entrytype) type of entry move.l (ap_Info+fib_DiskKey,a4),(v_diskkey) blockheader for entry bsr getfull.fname get fullpath [default for VERBOSE] tst.b (dirflag) directory ? bne.b 2$ yes, show it printf flfile.msg,filename display file bra.b 1$ done 2$ printfc fldir.msg,filename display directory 1$ printfc fvinfo.msg,protstring2 print x-tended information tst.l (comment) comment ? beq continue no continue printfc fcomment.msg,comment print comment bra continue continue continue ** Get next file nofileinfo move.l #anchorpath,d1 get match-anchor CALL MatchNext next file tst.l d0 error ? beq showdirectory no continue [this seems a strange returncode but it's true!] PUSHR d0 save error code tst.l (arg.fullpath) FULLPATH ? bne.b .noreturn no, continue tst.b (anyentry.flag) any entry displayed ? beq.b .noreturn no, continue printf return.msg RETURN! .noreturn PULLR d0 get error code cmp.l #ERROR_NO_MORE_ENTRIES,d0 is it 'end of directory' bne.b vol.matcherror no, error ! ** Quit subroutine move.l #anchorpath,d1 match-anchor CALL MatchEnd close it [freemem] tst.b (anyentry.flag) have there been any entrys ? beq.b 1$ no, continue printfc volinfo.msg,NROF_files display info message bra.b 2$ continue 1$ printf vol_noentry.msg,headname print fault message 2$ PULLALL restore registers rts return ** Display DOS-Errormsg vol.doserror CALL IoErr get IOerror vol.matcherror move.l d0,d1 copy move.l #err.head,d2 header ='ERROR:' CALL PrintFault print error message PULLALL restore registers rts return ** Get ExtendedInformation #1 getextinfo.1 PUSHALL store registers move.l (ap_Info+fib_Size,a4),(filesize) size of file move.l (ap_Info+fib_NumBlocks,a4),(nrofblocks) nr of blocks move.l (ap_Info+fib_NumBlocks,a4),(nrofblocks2) copy #2 move.l (ap_Info+fib_Protection,a4),d0 protection bsr get.protstring => protection string lea (datetime),a0 date/time struct move.l a0,d1 copy lea (ap_Info+fib_DateStamp,a4),a1 date of current entry move.l (a1)+,(a0)+ copy days move.l (a1)+,(a0)+ copy minutes move.l (a1)+,(a0)+ copy tickx bsr norm.dates normative dates CALL DateToStr get date/time string clr.l (comment) no comment [default] lea (ap_Info+fib_Comment,a4),a1 get comment string tst.b (a1) is there any ? beq .nocomment no,continue move.l a1,(comment) save comment .nocomment PULLALL restore registers rts return ** Set norm dates [handle DATES/NODATES option] norm.dates PUSHR a0 save a0 lea (datetime),a0 get date/time struct move.b #DTB_SUBST|DTB_FUTURE,(dat_Flags,a0) normal = substitute tst.l (arg.dates) test DATES beq.b 1$ not selected clr.b (dat_Flags,a0) no substitution 1$ PULLR a0 restore a0 rts return * This section deals with the argument conflict resolving. I don't comment * it because a) I'm bored, b) it's 1.00 AM and c) you know it anyway ; argument hierarchy : ; ~~~~~~~~~~~~~~~~~~~~ ; 1. fullpath ; 2. all ; 3. verbose x ; 4. list x (all three mutual exclusive) ; 5. short x ; 6. normal x ; 7. all comparison flags, dont conflict with any of the above ; further collisions : ; ~~~~~~~~~~~~~~~~~~~~ ; ALL<>(SHORT,NORMAL) ; FULLPATH<>(SHORT,NORMAL) ; HIDDEN<>NOHIDDEN ; COLOR<>NOCOLOR ; DATES<>NODATES setupargs tst.l (arg.fullpath) beq .not.fullpath clr.l (arg.short) .not.fullpath tst.l (arg.all) beq .not.all clr.l (arg.short) .not.all tst.l (arg.verbose) beq.b .not.verbose move.l #1,(arg.list) move.l #1,(arg.fullpath) clr.l (arg.short) bra.b setuprows .not.verbose tst.l (arg.list) beq.b setuprows clr.l (arg.short) setuprows move.b #3,(maxrows) tst.l (arg.short) beq.b 1$ move.b #4,(maxrows) 1$ tst.l (arg.list) beq.b 2$ move.b #1,(maxrows) 2$ tst.l (arg.fullpath) beq.b 4$ move.b #1,(maxrows) 4$ tst.l (arg.since) beq.b 5$ clr.l (arg.upto) 5$ tst.l (arg.smaller) beq.b 6$ clr.l (arg.larger) move.l #1,(arg.filesonly) 6$ tst.l (arg.larger) beq.b 7$ move.l #1,(arg.filesonly) 7$ tst.l (arg.nohidden) beq.b 8$ clr.l (arg.hidden) 8$ tst.l (arg.nodates) beq.b 9$ clr.l (arg.dates) 9$ tst.l (arg.nocolor) beq.b 10$ clr.l (arg.color) 10$ rts ** This subroutine analyzes the packet protection and copies it to thee protection string get.protstring PUSHALL lea (protstring.data),a0 movem.l a0/d0,-(sp) moveq #8-1,d0 .clear move.b #'-',(a0)+ dbra d0,.clear clr.b (a0)+ movem.l (sp)+,a0/d0 btst #7,d0 beq.b 7$ move.b #'h',(0,a0) 7$ btst #6,d0 beq.b 6$ move.b #'s',(1,a0) 6$ btst #5,d0 beq.b 5$ move.b #'p',(2,a0) 5$ btst #4,d0 beq.b 4$ move.b #'a',(3,a0) 4$ btst #3,d0 bne.b 3$ move.b #'r',(4,a0) 3$ btst #2,d0 bne.b 2$ move.b #'w',(5,a0) 2$ btst #1,d0 bne.b 1$ move.b #'e',(6,a0) 1$ btst #0,d0 bne.b 10$ move.b #'d',(7,a0) 10$ PULLALL rts ** Get full pathname from a lock getfull.fname PUSHALL store all registers lea (anchorpath),a0 anchor path move.l (ap_Current,a0),a0 current entry move.l (an_Lock,a0),d1 current lock move.l #volname,d2 name to hold path move.l #MAX_PATHSIZE,d3 size of buffer CALL NameFromLock get name from lock move.l #volname,d1 name to hold path lea (anchorpath),a0 anchor path lea (ap_Info+fib_FileName,a0),a0 filename move.l a0,d2 get a ptr to tha filename move.l #MAX_PATHSIZE,d3 size of buffer CALL AddPart get filename + volume = full path move.l #volname,(filename) store it to a internal pointer PULLALL restore registers rts checkdir.return cmp.b #-1,(rowcount) beq.b 1$ printf return.msg move.b #-1,(rowcount) 1$ rts get.cmpdate lea (Cmpdatetime),a4 move.b #FORMAT_DOS,(dat_Format,a4) move.b #DTB_SUBST|DTB_FUTURE,(dat_Flags,a4) clr.l (dat_StrDay,a4) move.l #CmpDate.msg,(dat_StrDate,a4) clr.l (dat_StrTime,a4) lea (CmpDate.msg),a0 move.l #LEN_DATSTRING-1,d0 1$ move.b (a1)+,(a0)+ dbra d0,1$ move.l a4,d1 CALL StrToDate rts checkdates lea (Cmpdatetime),a3 move.l a3,d1 CALL DateStamp checkdates2 lea (Cmpdatetime),a3 ; compare(Cmpdatetime,datetime) move.l (a3),d0 lea (anchorpath),a4 move.l (ap_Info+fib_DateStamp,a4),d1 cmp.l d0,d1 rts open.cmpfile move.l a0,d1 move.l #ACCESS_READ,d2 CALL Lock tst.l d0 beq .failed move.l d0,d6 move.l d0,d1 move.l #compareblock,d2 CALL Examine cmp.l #DOSFALSE,d0 beq .failed move.l d6,d1 CALL UnLock lea (compareblock),a0 lea (Cmpdatetime),a1 move.l (fib_DateStamp,a0),(ds_Days,a1) moveq #TRUE,d0 rts .failed moveq #FALSE,d0 rts GETDISKINFO PUSHALL move.l #volname,d1 move.l #ACCESS_READ,d2 CALL Lock,dos.base tst.l d0 beq .failed move.l d0,d6 move.l d0,d1 move.l #volumeinfoblock,d2 CALL Info move.l d6,d1 CALL UnLock lea (volumeinfoblock),a3 lea (info.shit,pc),a4 move.l (utility.base),a6 move.l (id_NumBlocks,a3),d0 move.l (id_BytesPerBlock,a3),d1 bsr 1024$ move.b d4,(C_INFOsize1) move.b d4,(C_INFOsize2) move.l (id_NumBlocksUsed,a3),d0 move.l (id_BytesPerBlock,a3),d1 bsr 1024$ move.b d4,(C_INFOused1) move.b d4,(C_INFOused2) move.l (id_NumBlocks,a3),d0 move.l (id_NumBlocksUsed,a3),d1 sub.l d1,d0 move.l (id_BytesPerBlock,a3),d1 bsr 1024$ move.b d4,(C_INFOfree1) move.b d4,(C_INFOfree2) move.l (id_NumBlocksUsed,a3),d0 move.l #100,d1 CALL UMult32 move.l (id_NumBlocks,a3),d1 CALL UDivMod32 move.l d0,(a4)+ move.l (id_NumSoftErrors,a3),(a4)+ move.l (id_DiskState,a3),d0 lea (status_validating,pc),a0 cmp.l #ID_VALIDATED,d0 bne.b 2$ lea (status_validated,pc),a0 2$ cmp.l #ID_WRITE_PROTECTED,d0 bne.b 3$ lea (status_writeprotected,pc),a0 3$ move.l a0,(a4)+ move.l (id_DiskType,a3),d0 lea (type_unreadable,pc),a0 cmp.l #ID_NOT_REALLY_DOS,d0 bne.b 4$ lea (type_notreallydos,pc),a0 4$ cmp.l #ID_DOS_DISK,d0 bne.b 5$ lea (type_dosdisk,pc),a0 5$ cmp.l #ID_FFS_DISK,d0 bne.b 6$ lea (type_ffsdisk,pc),a0 6$ cmp.l #ID_KICKSTART_DISK,d0 bne.b 7$ lea (type_kickstart,pc),a0 7$ move.l a0,(a4)+ .failed PULLALL rts 1024$ CALL UMult32 move.l #1024,d1 CALL UDivMod32 move.b #'k',d4 cmp.l #1024,d0 bls.b 1$ move.l #1024,d1 CALL UDivMod32 moveq #'m',d4 1$ move.l d0,(a4)+ rts * This one multiples d1.LONG! with d2.LONG! in d1.LONG * if both are only word-sized, MULU is beeing used... ext.mulu movem.l d1/d2,-(sp) cmp.l #$FFF,d2 bcc.b 2$ cmp.l #$FFF,d0 bcc.b 2$ mulu d2,d0 movem.l (sp)+,d1/d2 rts 2$ moveq #0,d1 subq.l #1,d2 1$ add.l d0,d1 dbra d2,1$ move.l d1,d0 movem.l (sp)+,d1/d2 rts dos.name DOSNAME utility.name UTILITYNAME falsekick.msg dc.b "Sorry, you don't have OS2.0 V36 or higher installed",10 falsekick.size equ *-falsekick.msg dateerror.msg dc.b "invalid date/time specification",10,0 arg.template dc.b "DIR/M,ALL/S,VERBOSE/S,SHORT/S,LIST/S," dc.b "FULLPATH/S,COLOR/S,NOCOLOR/S,FILES/S,DIRS/S," dc.b "HIDDEN/S,NOHIDDEN/S,NEWER/K,OLDER/K,TODAY/S," dc.b "LARGER/K/N,SMALLER/K/N,SINCE/K,UPTO/K," dc.b "DATES/S,NODATES/S,HELP/S" dc.b 0 addpart.msg dc.b '#?',0 IFND OVERSCAN sfile.msg dc.b '%-18.18s ',0 sdir.msg dc.b '%-18.18s ',0 nfile.msg dc.b '%-16.16s%8ld ',0 ndir.msg dc.b '%-18.18s (DIR) ',0 fnfile.msg dc.b '%s (%ld Bytes)',10,0 fndir.msg dc.b '%s (Directory)',10,0 lfile.msg dc.b '%-27.27s %8ld ',0 ldir.msg dc.b '%-30.30s (DIR) ',0 flfile.msg dc.b '%s (%ld Bytes)',10,0 fldir.msg dc.b '%s (Directory)',10,0 linfo.msg dc.b '%s %-10.10s %s [%8ld]',0 comment.msg dc.b 10,":'%s'",0 flinfo.msg dc.b '%s %-10.10s %s [%8ld]',10,0 fcomment.msg dc.b ":'%s'",10,0 head.msg dc.b "Directory of %-41.41s at %-9.9s %s",10 dc.b 'Size=%ld' C_INFOsize1 dc.b 'kB Used=%ld' C_INFOused1 dc.b 'kB Free=%ld' C_INFOfree1 dc.b 'kB Full=%ld%% Errs=%ld Status=%s Type=%s',10,0 diddir.msg dc.b 10,"[<'%s']",0 dodir.msg dc.b 10,"[>'%s']",0 diddir.msg2 dc.b "[<'%s']",10,0 dodir.msg2 dc.b "[>'%s']",10,0 return.msg dc.b 10,0 fvinfo.msg dc.b 'P:%s %-8.8s %-10.10s %s B:%-6ld K:%-6ld I:%-2d T:??',10,0 volinfo.msg dc.b "%ld Files and %ld Directorys using %ld Bytes and %ld Blocks",10,0 ; the colored messages : C_sdir.msg dc.b '%-18.18s ',0 C_ndir.msg dc.b '%-18.18s (DIR) ',0 C_fndir.msg dc.b '%s (DIR)',10,0 C_ldir.msg dc.b '%-30.30s (DIR) ',0 C_fldir.msg dc.b '%s (Directory)',10,0 C_linfo.msg dc.b '%s %-10.10s %s [%8ld]',0 C_comment.msg dc.b 10,":'%s'",0 C_flinfo.msg dc.b '%s %-10.10s %s [%8ld]',10,0 C_fcomment.msg dc.b ":'%s'",10,0 C_head.msg dc.b "Directory of %-41.41s at %-9.9s %s",10 dc.b 'Size=%ld' C_INFOsize2 dc.b 'kB Used=%ld' C_INFOused2 dc.b 'kB Free=%ld' C_INFOfree2 dc.b 'kB Full=%ld%% Errs=%ld Status=%s Type=%s',10,0 C_diddir.msg dc.b 10,"[<'%s']",0 C_dodir.msg dc.b 10,"[>'%s']",0 C_diddir.msg2 dc.b "[<'%s']",10,0 C_dodir.msg2 dc.b "[>'%s']",10,0 C_fvinfo.msg dc.b 'P:%s %-8.8s %-10.10s %s B:%-6ld K:%-6ld I:%-2d T:??',10,0 C_volinfo.msg dc.b "%ld Files and %ld Directorys using %ld Bytes and %ld Blocks",10,0 ELSE sfile.msg dc.b '%-20.20s ',0 sdir.msg dc.b '%-20.20s ',0 nfile.msg dc.b '%-20.20s%8ld ',0 ndir.msg dc.b '%-22.22s (DIR) ',0 fnfile.msg dc.b '%s (%ld Bytes)',10,0 fndir.msg dc.b '%s (Directory)',10,0 lfile.msg dc.b '%-37.37s %8ld ',0 ldir.msg dc.b '%-40.40s (DIR) ',0 flfile.msg dc.b '%s (%ld Bytes)',10,0 fldir.msg dc.b '%s (Directory)',10,0 linfo.msg dc.b '%s %-10.10s %s [%8ld]',0 comment.msg dc.b 10,":'%s'",0 flinfo.msg dc.b '%s %-10.10s %s [%8ld]',10,0 fcomment.msg dc.b ":'%s'",10,0 head.msg dc.b "Directory of %-51.51s at %-9.9s %s",10 dc.b 'Size=%ld' C_INFOsize1 dc.b 'kB Used=%ld' C_INFOused1 dc.b 'kB Free=%ld' C_INFOfree1 dc.b 'kB Full=%ld%% Errs=%ld Status=%s Type=%s',10,0 diddir.msg dc.b 10,"[<'%s']",0 dodir.msg dc.b 10,"[>'%s']",0 diddir.msg2 dc.b "[<'%s']",10,0 dodir.msg2 dc.b "[>'%s']",10,0 return.msg dc.b 10,0 fvinfo.msg dc.b 'P:%s %-8.8s %-10.10s %s B:%-6ld K:%-6ld I:%-2d T:NOT_IMPLEMENTED',10,0 volinfo.msg dc.b "%ld Files and %ld Directorys using %ld Bytes and %ld Blocks",10,0 ; the colored messages : C_sdir.msg dc.b '%-20.20s ',0 C_ndir.msg dc.b '%-22.22s (DIR) ',0 C_fndir.msg dc.b '%s (DIR)',10,0 C_ldir.msg dc.b '%-40.40s (DIR) ',0 C_fldir.msg dc.b '%s (Directory)',10,0 C_linfo.msg dc.b '%s %-10.10s %s [%8ld]',0 C_comment.msg dc.b 10,":'%s'",0 C_flinfo.msg dc.b '%s %-10.10s %s [%8ld]',10,0 C_fcomment.msg dc.b ":'%s'",10,0 C_head.msg dc.b "Directory of %-51.51s at %-9.9s %s",10 dc.b 'Size=%ld' C_INFOsize2 dc.b 'kB Used=%ld' C_INFOused2 dc.b 'kB Free=%ld' C_INFOfree2 dc.b 'kB Full=%ld%% Errs=%ld Status=%s Type=%s',10,0 C_diddir.msg dc.b 10,"[<'%s']",0 C_dodir.msg dc.b 10,"[>'%s']",0 C_diddir.msg2 dc.b "[<'%s']",10,0 C_dodir.msg2 dc.b "[>'%s']",10,0 C_fvinfo.msg dc.b 'P:%s %-8.8s %-10.10s %s B:%-6ld K:%-6ld I:%-2d T:NOT_IMPLEMENTED',10,0 C_volinfo.msg dc.b "%ld Files and %ld Directorys using %ld Bytes and %ld Blocks",10,0 ENDC ; other messages vol_noentry.msg dc.b "no more entries in directory",10,0 help.msg dc.b 'Deluxe Directory Version ' version dc.b ' written by G.Kurz in 1991',10 dc.b ' Syntax : DDIR [directory(s)] [OPTIONS]',10 dc.b 'Options : ALL - enter all subdirectorys',10 dc.b ' VERBOSE - be verbose as to the information given',10 dc.b ' SHORT - 4 entrys in a row, no filesizes',10 dc.b ' LIST - list-lookalike',10 dc.b ' FULLPATH - display full path of names',10 dc.b ' COLOR - show colorized messages [default]',10 dc.b ' NOCOLOR - don''t use colors',10 dc.b ' FILES - display files only',10 dc.b ' DIRS - display directorys only',10 dc.b ' HIDDEN - show hidden files [default]',10 dc.b ' NOHIDDEN - don''t show hidden files',10 dc.b ' NEWER=object - show files only newer or equal to this',10 dc.b ' OLDER=object - show files only older or equal to this',10 dc.b ' TODAY - show all files of today',10 dc.b ' LARGER=size - show all files larger than this',10 dc.b ' SMALLER=size - show all files smaller than this',10 dc.b ' SINCE=date - show all files since this day',10 dc.b ' UPTO=date - show all files upto this day',10 dc.b ' DATES - show real dates (don''t use ''Today'' etc.)',10 dc.b ' NODATES - use replace-strings if available [default]',10 dc.b ' HELP - display this message',10 dc.b 0 err.head dc.b 'ERROR:',0 even headname dc.l volname dc.l StrDate.msg dc.l StrTime.msg info.shit dc.l 0 ; Size dc.l 0 ; Used dc.l 0 ; Free dc.l 0 ; Full dc.l 0 ; Errs dc.l 0 ; Status dc.l 0 ; type status_validating dc.b 'VALIDATING',0 status_validated dc.b 'READ/WRITE',0 status_writeprotected dc.b 'READ',0 type_unreadable dc.b 'BAD',0 type_notreallydos dc.b 'NDOS',0 type_dosdisk dc.b 'DOS',0 type_ffsdisk dc.b 'FFS',0 type_kickstart dc.b 'KICK',0 even protstring dc.l protstring.data dc.l StrDate.msg dc.l StrTime.msg nrofblocks ds.l 1 protstring2 dc.l protstring.data dc.l StrDay.msg dc.l StrDate.msg dc.l StrTime.msg nrofblocks2 ds.l 1 v_diskkey ds.l 1 v_entrytype ds.l 1 SECTION nirvana,BSS BSS_START arg.dirs ds.l 1 arg.all ds.l 1 arg.verbose ds.l 1 arg.short ds.l 1 arg.list ds.l 1 arg.fullpath ds.l 1 arg.color ds.l 1 arg.nocolor ds.l 1 arg.filesonly ds.l 1 arg.dirsonly ds.l 1 arg.hidden ds.l 1 arg.nohidden ds.l 1 arg.newer ds.l 1 arg.older ds.l 1 arg.today ds.l 1 arg.larger ds.l 1 arg.smaller ds.l 1 arg.since ds.l 1 arg.upto ds.l 1 arg.dates ds.l 1 arg.nodates ds.l 1 arg.help ds.l 1 dos.base ds.l 1 utility.base ds.l 1 arg.rdargs ds.l 1 filename ds.l 1 filesize ds.l 1 comment ds.l 1 NROF_files ds.l 1 NROF_dirs ds.l 1 NROF_bytes ds.l 1 NROF_blocks ds.l 1 anchorpath ds.b ap_SIZEOF volname ds.b MAX_PATHSIZE fileinfoblock ds.b fib_SIZEOF datetime ds.b dat_SIZEOF StrDay.msg ds.b LEN_DATSTRING StrDate.msg ds.b LEN_DATSTRING StrTime.msg ds.b LEN_DATSTRING Cmpdatetime ds.b dat_SIZEOF CmpDay.msg ds.b LEN_DATSTRING CmpDate.msg ds.b LEN_DATSTRING CmpTime.msg ds.b LEN_DATSTRING rowcount ds.b 1 dirflag ds.b 1 maxrows ds.b 1 anyentry.flag ds.b 1 even protstring.data ds.b 9 cnop 0,4 compareblock ds.b fib_SIZEOF cnop 0,4 volumeinfoblock ds.b id_SIZEOF BSS_SIZE equ *-BSS_START END