home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1996 September / Simtel-MSDOS-Sep1996-CD2.iso / disc2 / dirutl / whereis.asm < prev    next >
Assembly Source File  |  1985-10-23  |  11KB  |  413 lines

  1.     title WHEREIS
  2.     page  55,131
  3. ;********************************************************
  4. ;*                                                      *
  5. ;*      WHEREIS.ASM                     24FEB84         *
  6. ;*                                                      *
  7. ;********************************************************
  8.  
  9. ; Modified 10/22/85 by Tom Brengle (BRENGLE%LLL@LLL-MFE)
  10. ;   If no extension is included in the command line filespec,
  11. ;   WHEREIS now acts the same as the DOS DIR command, that is
  12. ;
  13. ;    WHEREIS file
  14. ;
  15. ;   performs the same search as if
  16. ;
  17. ;    WHEREIS file.*
  18. ;
  19. ;   had been entered.  WHEREIS can still look for files
  20. ;   with only null extensions by using
  21. ;
  22. ;    WHEREIS file.
  23.  
  24.  
  25. whereis segment public
  26.         assume cs:whereis,ds:whereis
  27.  
  28. ;equates
  29.  
  30. COMMAND_LINE    EQU     80H + 2
  31. NULL            EQU     00H
  32. CR              EQU     0DH
  33. LF              EQU     0AH
  34. MAX_SCAN_LEN    EQU     64
  35. TERMINATE       EQU     20H
  36. DIRECTORY       EQU     10H
  37. DOT             EQU     '.'
  38. STAR        EQU    '*'
  39. PRINT_CHAR      EQU     02H
  40. SET_DTA         EQU     1AH
  41. SEARCH_FIRST    EQU     4EH
  42. SEARCH_NEXT     EQU     4FH
  43. DOS_CALL        EQU     21H
  44. PATH_SEPARATOR  EQU     '\'
  45.  
  46. ;macros
  47.  
  48. CLEAR   macro   reg
  49.         xor     reg,reg
  50.         endm
  51.  
  52. ;this is the format for the dos data transfer area used when dos 2.0
  53. ;searches for file match in directories
  54.  
  55. dta     struc
  56.         reserved        db      21 dup (?)
  57.         attribute       db    ?
  58.         time            dw    ?
  59.         date            dw    ?
  60.         size            dd    ?
  61.         name_found      db      13 dup (?)
  62. dta     ends
  63.  
  64.         org     100h
  65. main    proc    far
  66.  
  67. ;  this is the main program that sets up the initial conditions for
  68. ;  search_directory which in turn, does a recursive search.
  69. ;       reads:  path_name
  70. ;       writes: file_name
  71. ;       calls:  search_directory
  72. ;
  73.  
  74. mainline proc   near
  75.  
  76. start:
  77.     mov    bp, 0                ;Clear DOT_FLAG.
  78.         mov     si, COMMAND_LINE                ;start of command line
  79.         mov     di, offset file_name
  80.  
  81. get_search_name:
  82.         lodsb                           ;get first char
  83.     cmp    al, DOT            ;Is it a dot?
  84.     jne    check_CR        ;No, then check for carriage return.
  85.     mov    bp, 1            ;Yes, then set DOT_FLAG.
  86.     stosb
  87.     jmp    get_search_name        ;Loop --
  88. check_CR:
  89.         cmp     al, CR
  90.         je      done_reading_name       ;if carriage return
  91.         stosb
  92.         jmp     get_search_name         ;Loop --
  93. done_reading_name:
  94.     cmp    bp, 1            ;Was a dot seen?
  95.     je    terminate_name        ;Yes, go finish name processing.
  96.     mov    al, DOT            ;No, then append ".*" to file spec.
  97.     stosb
  98.     mov    al, STAR
  99.     stosb
  100. terminate_name:
  101.         CLEAR   al                      ;store zero at end
  102.         stosb
  103.         mov     di, offset path_name
  104.         CLEAR   al
  105.         cld
  106.         mov     cx, MAX_SCAN_LEN
  107.         repnz   scasb
  108.         mov     bx,di
  109.         dec     bx                      ;ds:bx points to end of path_name
  110.         mov     dx,NULL
  111.         call search_directory
  112.         int     TERMINATE
  113. mainline endp
  114.  
  115. ; this procedure searches all the files in the current directory
  116. ; looking for a match.  It also prints the full name for each match
  117. ;
  118. ;       ds:bx   pointer to end of current path name
  119. ;       ds:dx   old disk transfer area (dta)
  120. ;
  121. ; reads:        disk transfer area (dta)
  122. ; writes:       disk transfer area (dta)
  123. ; calls         build_name, get_first_Match
  124. ;               write_matched_name, get_next_match
  125. ;               build_star_name, search_sub_directory
  126. ;
  127. search_directory proc   near
  128.  
  129.         push    si
  130.         push    dx
  131.         call    build_name
  132.         call    get_first_match
  133.         jc      no_match                                ;If no match --
  134.         call    write_matched_name
  135. find_next_file:
  136.         call    get_next_match
  137.         jc      no_match
  138.         call    write_matched_name
  139.         jmp     find_next_file                          ;Loop --
  140.  
  141. no_match:
  142.         pop     dx
  143.         push    dx
  144.         call    build_star_name
  145.         call    get_first_match
  146.         jc      no_more_matches                 ;If no match --
  147.         mov     si,dx
  148.         test    [si].attribute,DIRECTORY
  149.         jnz     is_directory                    ;If directory entry --
  150. find_next_directory:
  151.         call    get_next_match
  152.         jc      no_more_matches                 ;If no more entries --
  153.         test    [si].attribute,DIRECTORY
  154.         jz      find_next_directory             ;If not a directory --
  155. is_directory:
  156.         cmp     [si].name_found,DOT
  157.         je      find_next_directory             ;If it's . or ..
  158.         call    search_sub_directory            ;search sub directory
  159.         push    ax
  160.         mov     ah,SET_DTA
  161.         int     DOS_CALL
  162.         pop     ax
  163.         jmp     find_next_directory
  164. no_more_matches:
  165.         pop     dx
  166.         pop     si
  167.         ret
  168.  
  169. search_directory  endp
  170. page
  171. ; This procedure searches the sub directory who's name is in dta
  172. ;
  173. ;       ds:bx   end of the current pathname
  174. ;       ds:[dx].name_found      name of subdirectory for search
  175. ;
  176. ; reads:        path_name
  177. ; writes:       path_name
  178. ; calls:        search_directory
  179. ;
  180.  
  181. search_sub_directory  proc  near
  182.  
  183.         push    di
  184.         push    si
  185.         push    ax
  186.         push    bx
  187.         cld
  188.         mov     si, dx
  189.         add     si, offset name_found
  190.         mov     di,bx
  191. copy_loop:
  192.         lodsb
  193.         stosb
  194.         or      al,al
  195.         jnz     copy_loop
  196.         mov     bx,di
  197.         std
  198.         stosb
  199.         mov     al,PATH_SEPARATOR
  200.         stosb
  201.         call    search_directory
  202.         pop     bx
  203.         mov     byte ptr [bx],NULL
  204.         pop     ax
  205.         pop     si
  206.         pop     di
  207.         ret
  208.  
  209. search_sub_directory  endp
  210. page
  211.  
  212. ; This procedure prints the matched name after the path name
  213. ;
  214. ;  ds:dx        pointer to current disk transfer area
  215. ;
  216. ; reads:        path_name, name_found (in dta)
  217. ; writes:       write_string, send_crlf
  218. ;
  219.  
  220. write_matched_name      proc    near
  221.  
  222.         push    ax
  223.         push    dx
  224.         mov     dx,offset path_name
  225.         mov     al,[bx]
  226.         mov     byte ptr [bx],NULL
  227.         call    write_string
  228.         mov     [bx],al
  229.         pop     dx
  230.         push    dx
  231.         add     dx, offset name_found
  232.         call    write_string
  233.         call    send_crlf
  234.         pop     dx
  235.         pop     ax
  236.         ret
  237. write_matched_name endp
  238.  
  239.  
  240. ;  This procedure builds an absolute search name from path_name
  241. ;  followed by file_name
  242. ;
  243. ;  reads:       file_name
  244. ;  calls:       build   (to build the name)
  245. ;
  246.  
  247. build_name      proc    near
  248.  
  249.         push    si
  250.         mov     si, offset file_name
  251.         call    build
  252.         pop     si
  253.         ret
  254. build_name      endp
  255.  
  256. build_star_name proc    near
  257.         push    si
  258.         mov     si, offset star_name
  259.         call    build
  260.         pop     si
  261.         ret
  262. build_star_name endp
  263.  
  264. page
  265. ; This procedure appends the string at ds:si to path_name in
  266. ; path_name.  It knows where the path name ends from knowing
  267. ; how long path_name is.
  268. ;
  269. ;       ds:si   name of file
  270. ;       ds:bx   end of path_name
  271. ;
  272. ; reads:        ds:si
  273. ; writes:       path_name
  274. ;
  275.  
  276. build   proc    near
  277.         push    ax
  278.         push    di
  279.         mov     di,bx
  280.         cld
  281. copy_name:
  282.         lodsb
  283.         stosb
  284.         or      al,al
  285.         jnz     copy_name                       ;If not end of string yet --
  286.         pop     di
  287.         pop     ax
  288.         ret
  289. build   endp
  290.  
  291. ; This procedure find the first match between the name given by
  292. ; ds:dx and the directory entries found in the directory path_name
  293. ;
  294. ;       ds:dx   pointer to current disk transfer area
  295. ;
  296. ;  returns:
  297. ;       cf      0       a match was found
  298. ;               1       no match found
  299. ;       ax              error code returned
  300. ;               2       file not found
  301. ;               18      no more files
  302. ;       ds:dx           pointer to new disk transfer area
  303. ;
  304. ; reads:        path_name
  305. ; writes:       disk_transfer_areas
  306. ;
  307.  
  308. get_first_match proc    near
  309.  
  310.         push    cx
  311.         cmp     dx,NULL
  312.         ja      allocate                ;go allocate space --
  313.         mov     dx, offset disk_transfer_areas-type dta
  314. allocate:
  315.         add     dx,type dta
  316.         mov     cx,DIRECTORY
  317.         mov     ah,SET_DTA
  318.         int     DOS_CALL
  319.         push    dx
  320.         mov     dx, offset path_name
  321.         mov     ah,SEARCH_FIRST                 ;call for find first match
  322.         int     DOS_CALL
  323.         pop     dx
  324.         pop     cx
  325.         ret
  326. get_first_match endp
  327.  
  328.  
  329. ; This procedure is much like get_first_match
  330. ;
  331. ; returns:
  332. ;       cf      0       a match was found
  333. ;               1       no match found
  334. ;       ax              error code returned
  335. ;               2       file not found
  336. ;               18      no more files
  337. ;
  338. ; reads:        path_name
  339. ; writes:       disk_transfer_areas
  340. ;
  341.  
  342. get_next_match  proc    near
  343.         push    cx
  344.         push    dx
  345.         mov     dx, offset path_name
  346.         mov     cx,DIRECTORY
  347.         mov     ah,SEARCH_NEXT
  348.         int     DOS_CALL
  349.         pop     dx
  350.         pop     cx
  351.         ret
  352. get_next_match  endp
  353.  
  354. ; This procedure sends a crlf pair of characters to the screen
  355. ;
  356.  
  357. send_crlf       proc    near
  358.  
  359.         push    ax
  360.         push    dx
  361.         mov     ah,PRINT_CHAR
  362.         mov     dl,CR
  363.         int     DOS_CALL
  364.         mov     dl,LF
  365.         int     DOS_CALL
  366.         pop     dx
  367.         pop     ax
  368.         ret
  369. send_crlf       endp
  370.  
  371. ; This procedure writes the asciiz string at
  372. ;  ds:dx        address of asciiz string
  373. ;
  374.  
  375. write_string    proc    near
  376.  
  377.         push    ax
  378.         push    dx
  379.         push    si
  380.         cld
  381.         mov     si,dx
  382.         mov     ah,PRINT_CHAR
  383.         lodsb
  384. write_string_loop:
  385.         mov     dl,al
  386.         int     DOS_CALL
  387.         lodsb
  388.         or      al,al
  389.         jnz     write_string_loop
  390.         pop     si
  391.         pop     dx
  392.         pop     ax
  393.         ret
  394. write_string    endp
  395.  
  396. ; This is the data storage area and must be the last thing
  397. ; in the program.
  398. ;
  399.  
  400. star_name       db      '*.*',NULL
  401. path_name       db      PATH_SEPARATOR,NULL
  402.                 db      80 dup (0)      ;space for 64 char pathname and
  403.                                         ;13 char filename
  404. file_name       db      13 dup (0)      ;save room for full dos filename
  405.  
  406. disk_transfer_areas label byte          ;this must start at the end of whereis
  407.  
  408. main    endp
  409.  
  410. whereis ends
  411.  
  412.         end     start
  413.