{ This code may be used as long as the resulting product is FREE. See the end of the file (after end.) for the zipfile data structure Written by Zak Smith I am reachable the following ways.. sysop Sirius Cybernetics 414-966-3552 Zak Smith @ 1:154/736 fido-land zak.smith@mixcom.com } {$M 32768,0,65520} Program ZipComment; { by Zak, mahahaha } Uses Dos,Crt; Type FindZipType = record id : longint; dn : array[1..2] of byte; sd : array[1..2] of byte; cd : array[1..2] of byte; tcd: array[1..2] of byte; scd: array[1..4] of byte; sdn: array[1..4] of byte; cl : word; end; var total : longint; starttime: longint; type commentfiletype = record len : word; data : array[1..5120] of byte; end; function SecondsSinceMidnight(h,m,s:word):longint; begin SecondsSinceMidnight := (h*3600)+(m*60)+s end; procedure CurTime(var h:word; var m: word;var s:word); Var Hour,Min,Sec,Sec100:word; begin GetTime(Hour,Min,Sec,Sec100); h:=hour; m:=min; s:=sec; end; function nowsecondssincemidnight: longint; var h,m,s: word; begin curtime(h,m,s); nowsecondssincemidnight:=secondssincemidnight(h,m,s); end; (********* The following search engine routines are sneakly swiped *********) (********* from Turbo Technix v1n6. See there for further details *********) type ProcType= procedure(var S: SearchRec; P: PathStr); var EngineMask: PathStr; EngineAttr: byte; EngineProc: ProcType; EngineCode: byte; function ValidExtention(var S: SearchRec): boolean; var Junk1: dirstr ; junk2: namestr; E: ExtStr; begin if S.Attr and Directory=Directory then begin ValidExtention := true; exit; end; FSplit(S.Name,Junk1,Junk2,E); if (E='.ZIP') then ValidExtention := true else ValidExtention := false; end; procedure SearchEngine(M: dirstr; Attr: byte; Proc: ProcType; var ErrorCode: byte); var S: SearchRec; P: dirStr; Ext: ExtStr; Mask: Namestr; begin FSplit(M, P, Mask, Ext); Mask := Mask+Ext; FindFirst(P+Mask,Attr,S); if DosError<>0 then begin ErrorCode := DosError; exit; end; while DosError=0 do begin if ValidExtention(S) then Proc(S, P); FindNext(S); end; if DosError=18 then ErrorCode := 0 else ErrorCode := DosError; end; function GoodDirectory(S: SearchRec): boolean; begin GoodDirectory := (S.name<>'.') and (S.Name<>'..') and (S.Attr and Directory=Directory); end; procedure SearchOneDir(var S: SearchRec; P: PathStr); far; begin if GoodDirectory(S) then begin P := P+S.Name; SearchEngine(P+'\'+EngineMask,EngineAttr,EngineProc,EngineCode); SearchEngine(P+'\*.*',Directory or Archive, SearchOneDir ,EngineCode); end; end; procedure SearchEngineAll(Path: PathStr; Mask: pathStr; Attr: byte; Proc: ProcType; var ErrorCode: byte); begin EngineMask := Mask; EngineProc := Proc; EngineAttr := Attr; SearchEngine(Path+Mask,Attr,Proc,ErrorCode); SearchEngine(Path+'*.*',Directory or Archive,SearchOneDir,ErrorCode); ErrorCode := EngineCode; end; (************** Thus ends the sneakly swiped code *************) (**** We now return you to our regularly scheduled program ****) procedure status(p,f:string); var tt:longint; begin gotoxy(1,wherey); textcolor(cyan); write('File: '); textcolor(lightcyan); write(p,f); gotoxy(50,wherey); textcolor(lightgray); write('Time: '); textcolor(white); tt:=(NowSecondsSinceMidnight-StartTime); write(tt:5); textcolor(lightgray); write(' / '); write(total:5); end; var c:^commentfiletype; procedure AddComment(var s:searchrec; p:pathstr); far; type bffrtype = array[1..1500] of byte; var f :file; b :^bffrtype; ofs: longint; tv : longint; zd : findziptype; function inray:word; var i:word; begin inray:=0; for i:= 1 to tv do begin move(b^[i],zd,sizeof(zd)); if zd.id= $06054b50 then begin inray:=i; exit; end; end; end; begin assign(f,p+s.name); {$I-} reset(f,1); if ioresult<>0 then exit; {$I+} new (b); fillchar(b^,sizeof(b^),#0); tv:=filesize(f); if tv>sizeof(b^) then tv:=sizeof(b^); seek(f,filesize(f)-tv); blockread(f,b^,tv); ofs:=inray; if not (ofs=0) then begin zd.cl:=c^.len; seek(f,filesize(f)-1-tv+ofs); blockwrite(f,zd,sizeof(zd)); blockwrite(f,c^.data,c^.len); end; close(f); dispose(b); inc(total); status(p,s.name); end; procedure loadcommentfile; var f:file; begin assign(f,getenv('ZIPCOMNT')); reset(f,1); blockread(f,c^.data,filesize(f)); c^.len:=filesize(f); close(f); end; var err:byte; begin total:=0; StartTime:=NowSecondsSinceMidnight; writeln; writeln('ZipC - Zak''s semiPersonal Hyper-Speed Zipfile Commenter'); writeln; directvideo:=true; new(c); loadcommentfile; SearchEngineAll ( fExpand('.\'), '*.ZIP', anyfile, AddComment, err); writeln; writeln; writeln('ZipC Done.'); dispose(c); end. Specific ZIP data struct. used here.. end of central dir signature 4 bytes (0x06054b50) number of this disk 2 bytes number of the disk with the start of the central directory 2 bytes total number of entries in the central dir on this disk 2 bytes total number of entries in the central dir 2 bytes size of the central directory 4 bytes offset of start of central directory with respect to the starting disk number 4 bytes zipfile comment length 2 bytes zipfile comment (variable size)