include	doszip/doszip.inc
include	string.inc
include	conio.inc
include	keyb.inc
include	mouse.inc
include	io.inc
include	iost.inc
include	stdio.inc
include	dos.inc
include	progress.inc
include	format.inc

; Make List File from selection set

	public	cmmklist
	public	mklistidd
	public	mklistadd
	public	cp_ziplst
	public	CRLF$

	extrn	format_lst:dword
	extrn	filelist_bat:dword

MKLID_LIST	= 1*16
MKLID_APPEND	= 2*16
MKLID_FORMAT	= 3*16
MKLID_UNIX	= 4*16
MKLID_EXLCD	= 5*16
MKLID_EXLDRV	= 6*16
MKLID_FILTER	= 9*16

_DATA	SEGMENT

$BACK db '\'		; 5C
BACK$ db '\',0		; '\'
$SIGN db '\'		; 25
SIGN$ db '%',0		; '%'
$TAB9 db '\t',0		; 09
$CRLF db '\n',0		; 0D 0A
TAB9$ db 9,0
CRLF$ db 0Dh,0Ah
NULL$ db 0

$FILE db '%f',0		; File name
$PATH db '%p',0		; Path part of file
$CURD db '%cd',0	; Current directory
$HOME db '%dz',0	; Doszip directory
$name db '%n',0		; Name part of file
$TYPE db '%ext',0	; Extension of file
$SSTR db '%s',0		; Search string
$FCID db '%id',0	; File index or loop counter
$OFFS db '%o',0		; Offset string
$TMP1 db 7,1,0		; unlikely combination 1 '\\'
$TMP2 db 7,2,0		; unlikely combination 2 '\%'

cp_ziplst db	'ziplst',0
$FORSLASH db	'/',0
mklsubcnt dw	?
cp_mklist db	'MKList',0

GCMD_mklist	label word
GCMD KEY_F9,	mklevent_LOAD
		dw	0

_DATA	ENDS

_DZIP	SEGMENT

mklevent_HELP proc dist
	invoke rsmodal, IDD_DZMKListHelp
	ret
mklevent_HELP endp

mklevent_FILTER proc dist
	call cmfilter
	les bx,tdialog
	mov bx,es:[bx+4]
	add bx,0A1Ch
	mov cx,1
	mov al,' '
	.if word ptr filter
	    mov ax,7
	.endif
	call @scputw
	mov ax,_C_NORMAL
	ret
mklevent_FILTER endp

mklevent_LOAD proc dist pascal uses si di
local	string[256]:byte
local	dialog:dword
	movmx dialog,tdialog
	les bx,tdialog
	mov al,es:[bx.dl_index]
	.if !al || al == 2
	    invoke tools_idd,128,addr string,addr cp_mklist
	    mov	si,ax
	    call msloop
	    mov	ax,_C_NORMAL
	    .if si && si != MOUSECMD
		les di,dialog
		mov si,word ptr es:[di+MKLID_FORMAT].to_data
		lea di,string
		.if func(strchr,ss::di,'@')
		    xchg di,ax
		    mov byte ptr es:[di],0
		    les bx,dialog
		    .if ax != di
			invoke strcpy,es:[bx+MKLID_LIST].to_data,ss::ax
		    .endif
		    inc di
		.endif
		les dx,dialog
		invoke strcpy,es::si,ss::di
		mov ax,_C_REOPEN
	    .endif
	.else
	    mov ax,_C_NORMAL
	.endif
	ret
mklevent_LOAD endp

mklistidd proc pascal public uses si di
local DLG_DZMKList:dword
	.if func(rsopen, IDD_DZMKList)
	    stom DLG_DZMKList
	    fpmov es:[bx.to_proc+MKLID_FILTER],mklevent_FILTER
	    mov si,word ptr es:[bx+MKLID_LIST].to_data+2
	    mov di,word ptr es:[bx+MKLID_LIST].to_data
	    mov al,mklist.mkl_append
	    and al,_O_FLAGB
	    or  es:[bx+MKLID_APPEND],al
	    mov word ptr es:[bx+MKLID_APPEND].to_data+2,ds
	    mov word ptr es:[bx+MKLID_APPEND].to_data,offset GCMD_mklist
	    mov al,mklist.mkl_unix
	    and al,_O_FLAGB
	    or  es:[bx+MKLID_UNIX],al
	    mov al,mklist.mkl_excl_cd
	    and al,_O_FLAGB
	    or  es:[bx+MKLID_EXLCD],al
	    mov al,mklist.mkl_excl_drv
	    and al,_O_FLAGB
	    or  es:[bx+MKLID_EXLDRV],al
	    invoke strcpy, es:[bx+MKLID_FORMAT].to_data, format_lst
	    invoke strcpy, si::di, filelist_bat
	    xor ax,ax
	    mov word ptr mklist.mkl_offset+2,ax
	    mov word ptr mklist.mkl_offset,ax
	    LPUSH cs
	    push offset mklevent_HELP
	    call thelp_set
	    invoke dlinit, DLG_DZMKList
	    invoke dlevent, DLG_DZMKList
	    call thelp_pop
	    .if ax
		sub ax,ax
		mov word ptr mklist.mkl_count,ax
		mov word ptr mklist.mkl_count+2,ax
		mov mklist.mkl_macro,1
		mov al,es:[bx+MKLID_APPEND]
		and al,_O_FLAGB
		mov mklist.mkl_append,al
		mov al,es:[bx+MKLID_UNIX]
		and al,_O_FLAGB
		mov mklist.mkl_unix,al
		mov al,es:[bx+MKLID_EXLCD]
		and al,_O_FLAGB
		mov mklist.mkl_excl_cd,al
		mov al,es:[bx+MKLID_EXLDRV]
		and al,_O_FLAGB
		mov mklist.mkl_excl_drv,al
		invoke strcpy, format_lst, es:[bx+MKLID_FORMAT].to_data
		invoke strcpy, filelist_bat, si::di
		invoke dlclose, DLG_DZMKList
		.if mklist.mkl_append
		    invoke filexist, si::di
		    .if ax == 1
			.if func(openfile, si::di, M_WRONLY, A_OPEN)
			    mov mklist.mkl_handle,ax
			    invoke lseek, ax, 0, SEEK_END
			    mov ax,1
			.endif
			jmp @F
		    .elseif ax == 2
			sub ax,ax
			jmp @F
		    .endif
		.endif
	    .else
		invoke dlclose, DLG_DZMKList
		sub ax,ax
		jmp @F
	    .endif
	    invoke ogetouth, si::di
	    mov mklist.mkl_handle,ax
	    test ax,ax
	.endif
      @@:
	ret
mklistidd endp

expand_macro proc
	push ax
	push bp	; buf
	push ax
	push dx	; old
	push ax
	push cx	; new
	push ax
	push dx
	call strlen
	push ax	; len
	call strxchg
	ret
expand_macro endp

mklistadd proc		; dx:ax=file name
	push bp
	sub sp,WMAXPATH*3
	mov bp,sp
	push si
	push di
	mov bx,ax
	xor ax,ax
	mov cx,ax
	incm mklist.mkl_count
	.if mklist.mkl_excl_drv != al
	    mov es,dx
	    .if byte ptr es:[bx+1] == ':'
		add cx,2
	    .endif
	.endif
	add bx,cx
	.if mklist.mkl_excl_cd != al
	    add bx,mklist.mkl_offspath
	    sub bx,cx
	.endif
	.if mklist.mkl_unix != al
	    invoke dostounix, dx::bx
	    mov bx,ax
	.endif
	lea di,[bp+WMAXPATH*2]
	invoke strcpy, ss::di, dx::bx
	invoke strcpy, ss::bp, format_lst
	.if mklist.mkl_macro != 1
	    invoke strcpy, dx::ax, dx::di
	    jmp mklistadd_nomacro
	.endif
	mov ax,dx
	mov dx,offset $BACK	; '\\'
	mov cx,offset $TMP1	; --> 07 01
	call expand_macro
	mov ax,ss
	mov dx,offset $CRLF	; '\n'
	mov cx,offset CRLF$	; --> 0D 0A
	call expand_macro
	mov ax,ss
	mov dx,offset $TAB9	; '\t'
	mov cx,offset TAB9$	; --> 09
	call expand_macro
	mov ax,ss
	mov dx,offset $SIGN ; '\%'
	mov cx,offset $TMP2	; --> 07 02
	call expand_macro
	mov ax,ss
	mov dx,offset $TMP1	; 07 01
	mov cx,offset BACK$	; --> '\'
	call expand_macro
	mov ax,ss
	mov dx,offset $HOME
	mov cx,offset configpath
	call expand_macro
	mov ax,ss
	mov dx,offset $FILE
	mov cx,di
	call expand_macro
	invoke strfn, ss::di
	mov si,ax
	invoke strrchr, dx::ax, '.'
	mov di,ax
	.if ZERO?
	    mov ax,offset NULL$
	.endif
	mov cx,ax
	mov ax,ss
	mov dx,offset $TYPE
	call expand_macro
	sub ax,ax
	.if ax != di
	    mov [di],al
	.endif
	mov cx,si
	mov ax,ss
	mov dx,offset $name
	call expand_macro
	lea di,[bp+WMAXPATH*2]
	.if di != si
	    mov cx,di
	    xor ax,ax
	    mov [si-1],al
	.else
	    mov cx,offset NULL$
	.endif
	mov ax,ss
	mov dx,offset $PATH
	call expand_macro
	xor ax,ax
	mov cx,di
	mov bx,di
	add bx,mklist.mkl_offspath
	.if bx != cx
	    dec bx
	.endif
	mov [bx],al
	mov ax,ss
	mov dx,offset $CURD
	call expand_macro
	mov ax,ss
	mov dx,offset $SSTR
	mov cx,offset searchstring
	call expand_macro
	mov ax,word ptr mklist.mkl_count
	dec ax
	push ax
	mov ax,offset format_u
	mov dx,ss
	mov bx,di
	call @sprintf
	add sp,2
	mov ax,ss
	mov dx,offset $FCID
	mov cx,di
	call expand_macro
	pushm mklist.mkl_offset
	mov ax,offset format_lu
	mov dx,ss
	mov bx,di
	call @sprintf
	add sp,4
	mov ax,ss
	mov dx,offset $OFFS
	mov cx,di
	call expand_macro
	mov ax,ss
	mov dx,offset $TMP2 ; 07 02 00
	mov cx,offset SIGN$ ; --> '%'
	call expand_macro
    mklistadd_nomacro:
	invoke strlen, ss::bp
	.if func(oswrite, mklist.mkl_handle, ss::bp, ax)
	    mov ax,0
	    .if mklist.mkl_macro != 1
		invoke oswrite, mklist.mkl_handle, addr CRLF$, 2
		sub ax,2
		.if ax
		    inc ax
		.endif
	    .endif
	.else
	   inc ax
	.endif
    mklistadd_end:
	or ax,ax
	pop di
	pop si
	add sp,WMAXPATH*3
	pop bp
	ret
mklistadd endp

fp_mklist proc dist pascal path:dword, wblk:dword
	.if func(filter_wblk, wblk)
	    add word ptr wblk,wf_name
	    invoke strfcat, addr __srcfile, path, wblk
	    mov bx,ax
	    .if !func(progress_set, 0, dx::ax, 1)
		mov ax,bx
		call mklistadd
	    .endif
	.endif
	ret
fp_mklist endp

mksublist proc pascal uses si di zip_list:word, path:dword
local fblk:dword
	mov ax,1
	mov mklist.mkl_macro,al
	.if zip_list == ax
	    mov mklist.mkl_excl_cd,al
	    mov ax,offset cp_ziplst
	    mov dx,ds
	    dec mklist.mkl_macro
	.else
	    call mklistidd
	    lodm filelist_bat
	    jz mksublist_end
	.endif
	LMOV word ptr fp_fileblock+2,cs
	LMOV word ptr fp_directory+2,SEG _TEXT
	mov word ptr fp_fileblock,offset fp_mklist
	mov word ptr fp_directory,offset scan_files
	invoke progress_open, dx::ax, 0
	invoke strlen, path
	mov bx,word ptr path
	add bx,ax
	.if byte ptr es:[bx-1] != '\'
	    inc ax
	.endif
	mov mklist.mkl_offspath,ax
	.if func(cpanel_findfirst)
	  @@:
	    .if cx & _A_ARCHEXT
		mov mklist.mkl_offspath,0
	    .endif
	    mov di,cx
	    mov [bp-4],bx
	    mov [bp-2],dx
	    invoke strfcat, addr __outpath, path, dx::ax
	    .if !func(progress_set, 0, dx::ax, 1)
		.if di & _A_SUBDIR
		    .if di & _A_ARCHIVE
			invoke strcat, addr __outpath, addr BACK$
			.if mklist.mkl_mask
			    mov bx,cpanel
			    mov bx,word ptr [bx.pn_wsub]
			    invoke strcat, dx::ax, [bx.ws_mask]
			.endif
			call mklistadd
			inc mklsubcnt
		    .else
			.if func(scansub, addr __outpath, addr cp_stdmask, 0)
			    jmp @F
			.endif
		    .endif
		.else
		    .if func(filter_fblk, fblk)
			mov dx,ds
			mov ax,offset __outpath
			call mklistadd
		    .endif
		.endif
		les bx,fblk
		and es:[bx.fb_flag],not _A_SELECTED
		mov ax,cpanel
		call panel_findnext
		jnz @B
	    .endif
	  @@:
	    push ax
	    call progress_close
	    invoke close, mklist.mkl_handle
	    pop ax
	.else
	    jmp @B
	.endif
    mksublist_end:
	ret
mksublist endp

mkwslist proc
	push si
	mov si,ax
	.if func(cpanel_findfirst)
	    mov bx,cpanel
	    mov bx,[bx]
	    mov ax,[bx]
	    .if ax & _W_ARCHIVE
		add bx,wp_arch
	    .else
		add bx,wp_path
	    .endif
	    invoke mksublist, si, ds::bx
	.endif
	pop si
	ret
mkwslist endp

cmmklist proc dist
	sub ax,ax
	call mkwslist
	mov ax,cpanel
	call panel_reread
	ret
cmmklist endp

ifdef __DLL__

	public	mkziplst
	public	mkziplst_open

mkziplst_open proc dist
	push bp
	sub sp,WMAXPATH
	mov bp,sp
	invoke strfcat, ss::bp, envtemp, addr cp_ziplst
	invoke ogetouth, dx::ax
	add sp,WMAXPATH
	pop bp
	mov mklist.mkl_handle,ax
	.if ax
	    inc ax
	    .if ax
		or cflag,_C_DELTEMP
		mov ax,1
	    .endif
	.endif
	ret
mkziplst_open endp

mkziplst proc dist
	xor ax,ax
	mov mklsubcnt,ax
	inc ax
	call mkwslist
	mov bx,mklsubcnt
	ret
mkziplst endp

endif

_DZIP	ENDS

	END
