gino@voder.UUCP (Gino Bloch) (10/01/84)
[don't touch this line] A while back someone asked how to touch(*) a file under PC-DOS. Since I had a need for that capability, I wrote a program to do that; here it is. * ie, change its date & time fields to the current time without any other changes - useful with a `make' facility, for instance. ...................... tear on the dotted line ......................... title "touch files" page ,132 ; Touch changes the date & time of directory entries to the current ; date & time. It requires one argument (and ignores extra arguments). ; The argument is the full path name of a file. You can also specify ; a set of files by using wild card characters in the file name portion, ; but not the path name portion, of the argument. In the absence of path ; name specifiers, only the default directory is searched. In the absence ; of a drive name specifier, only the default drive is searched. Thus there ; are four ways to invoke touch; `d:\dd' means the default drive and its ; default directory, and `x:\xd' means some other drive and its default ; directory: ; touch file.ext affects d:\dd\file.ext ; touch x:file.ext affects x:\xd\file.ext ; touch \path\file.ext affects d:\path\file.ext ; touch x:\path\file.ext affects x:\path\file.ext ; In all four cases, `file.ext' can contain `?' and `*' characters by the ; usual rules. ; Copyright (C) 1984 by Gene E. Bloch assume ds:dseg,ss:sseg sseg segment stack 'stack' db 512 dup (?) stk equ $ sseg ends dseg segment 'data' no_file db 'touch: file not found',0dh,0ah,'$' no_tail db 'syntax: touch file_descriptor (may be ambiguous)',0dh,0ah,'$' unopen db " (can't be opened)$" crlf db 0dh,0ah,'$' clk_time dw 2 dup (?) clk_date dw 2 dup (?) file_time dw ? file_date dw ? handle dw ? file_name db 80h dup (?),'$' name_end equ $ name_tail dw file_name dseg ends cseg segment 'code' assume cs:cseg ; main touch: mov ax,dseg ; set up ds mov ds,ax call read_clok ; set up current date & time call set_date call set_time call find_first ; get first file name jnz short err_out ; no file, analyze error more: call make_name ; make up the full path name call show_name ; print the full path name call open ; open the file jnc short open_ok ; successful mov dx,offset unopen ; unsuccessful, report it mov ah,9 int 21h jmp short finder ; and skip the rest open_ok: call touch_it ; re-date & -time the file call close ; close it finder: mov dx,offset crlf ; newline mov ah,9 int 21h call find_next ; try to get next file je short more ; got one, touch it done: mov ah,4ch ; exit mov al,0 int 21h err_out: mov dx,offset no_file ; get `no file found' message jg short print_it mov dx,offset no_tail ; get `no command tail' message print_it: mov ah,9 ; print string int 21h jmp done ; bye ; subroutines read_clok: mov ah,2ch ; get clock time int 21h mov clk_time,cx mov clk_time[2],dx mov ah,2ah ; get clock date int 21h mov clk_date,cx mov clk_date[2],dx ret set_date: mov ax,clk_date ; convert date to directory fmt sub ax,1980 ; year first mov cl,9 shl ax,cl mov bx,clk_date[2] ; month next mov cl,3 shr bx,cl or ax,bx and ax,0ffe0h mov bx,clk_date[2] ; finally day and bl,1fh or al,bl mov file_date,ax ; that's it ret set_time: mov ax,clk_time ; convert time to directory format mov cl,3 ; hours shl ax,cl and ax,0f800h mov bh,byte ptr clk_time ; minutes mov cl,3 shr bx,cl or ax,bx and ax,0ffe0h mov bl,byte ptr clk_time[3] ; seconds shr bl,1 or al,bl mov file_time,ax ; done ret printable: cmp al,'!' ; see if legal jb short p_done ; no cmp al,7fh ; more legality ja short p_done ; no printable cmp al,al ; set flag 0 == ok p_done: ret to_upper: cmp al,'a' ; convert to UC jb short uc_end ; this isn't lc cmp al,'z' ja short uc_end ; nor is this xor al,'a' xor 'A' ; this one was uc_end: ret file_delim: cmp al,':' ; could be drive designator je short set_mark ; if so, make a mark cmp al,'\' ; could be subdirectory je short set_mark ; yeah cmp al,'/' ; even this kind of subdirectory jne short fd_end ; no set_mark: mov bx,di ; remember this place mov es:name_tail,bx fd_end: ret find_first: cld ; copy filename from parameter block mov ch,0 ; set up count mov cl,es:[80h] ; get the arg length for loops below push ds ; save ds push es ; save es push es ; point ds & si to command tail in PSP pop ds mov si,81h mov ax,dseg ; point es & di to file_name buffer mov es,ax mov di,offset file_name blank_loop: jcxz short no_arg ; still trucking? dec cx ; loop counter lodsb ; skip white space cmp al,' ' ; space je blank_loop cmp al,9 ; tab je blank_loop or al,al ; look out for spacy args jz short no_arg dec si ; get last (nonblank) char back inc cx ; and count it copy_loop: lodsb ; get next char call printable ; see if printable jnz short copy_end ; not printable call to_upper ; all letters to UPPERCASE stosb ; good character, save it call file_delim ; remember the last tree delimiter cl_end: loop copy_loop ; continue copy_end: xor al,al ; add the terminating null stosb pop es ; restore extra seg pop ds ; restore data seg mov dx,offset file_name ; set up find_first call mov cx,0 ; attribute: normal files only mov ah,4eh int 21h or ax,ax ; set condition code ret no_arg: pop es ; restore extra seg pop ds ; restore data seg mov ax,-1 ; set an error flag or ax,ax ret make_name: push es ; save the hummers push ds mov ah,2fh ; find the DTA int 21h push es ; we'll need this value in just a mo' mov ax,name_tail ; this is where new name will go mov di,ax mov ax,dseg mov es,ax add bx,30 ; point to file name field of DTA mov si,bx ; source of the copy pop ds ; this was pushed right after int 21/2f cld mov cx,13 ; max size of filename name_loop: lodsb ; copy name to path prefix stosb or al,al ; quit on '\0' loopnz name_loop name_done: mov al,'$' ; terminate the print command stosb pop ds ; restore segments pop es ret show_name: mov dx,offset file_name ; get file name string mov ah,9 ; print string int 21h ret open: mov dx,offset file_name ; going to open this one mov al,2 ; open for append mov ah,3dh int 21h mov handle,ax ; save it ret touch_it: mov dx,file_date ; set file's date & time mov cx,file_time mov bx,handle mov ah,57h mov al,1 int 21h ret close: mov bx,handle ; close this one mov ah,3eh int 21h ret find_next: mov ah,4fh ; set up find_next call int 21h or ax,ax ; set condition code ret cseg ends end touch -- Gene E. Bloch (...!nsc!voder!gino)
ali@bradley.UUCP (10/08/84)
[]
Whats wrong with:
>COPY filename+,,