home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / lsrc310 / source / lharc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-25  |  99.5 KB  |  5,806 lines

  1.  
  2. #ifdef __SHELL__
  3. #define get_env(v)    (shell ? NULL : getenv(v))
  4. #else
  5. #define get_env(v)    getenv(v)
  6. #endif
  7.  
  8. #include "lharc.h"
  9. #include <fcntl.h>
  10. #include <setjmp.h>
  11.  
  12. #if GERMAN
  13.     #include "usageger.h"
  14. #else
  15.     #include "usageeng.h"
  16. #endif
  17.  
  18. uchar *errmes[]={
  19. M_UNKNOWNERR,M_INVCMDERR,M_MANYPATERR,M_NOARCNMERR,M_NOFNERR,M_NOARCERR,M_RENAMEERR,M_MKTMPERR,
  20. M_DUPFNERR,M_TOOMANYERR,M_TOOLONGERR,M_NOFILEERR,M_MKFILEERR,M_RDERR,M_WTERR,M_MEMOVRERR,M_INVSWERR,
  21. M_CTRLBRK,M_NOMATCHERR,M_COPYERR,M_NOTLZH,M_OVERWT,M_MKDIR,M_MKDIRERR,M_CRCERR,M_RDONLY};
  22.  
  23. ushort    left[2*NC-1],right[2*NC-1];
  24. uchar    c_len[NC],pt_len[NPT],*len;
  25. ushort    c_freq[2*NC-1],c_code[NC],p_freq[2*NP-1],pt_table[256],pt_code[NPT],t_freq[2*NT-1];
  26. ushort    *freq,len_cnt[17];
  27. int        heap[NC+1];
  28.  
  29. _DTA    _dta;
  30. int     file2,args,c_err,skipped,cmd,cmdupdate,cmdlist,errorlevel,oldtos;
  31. int        _gemdos=SUCCS,Nfile,fbfiles,found,outfile,sfx;
  32. long    arcpos0,arcpos1,lastarcpos,lastarclen,nextarcpos,nextoffset,arclen,maxlen,old_afx,buffer_cnt;
  33. long    act_len,file_len,bsize,o_handle=-1,i_handle=-1,o_dev=-1,i_dev=-1,crypt_size,bufsize;
  34. uchar    act_dir[MAXPATH],basedir[MAXPATH],workdir[MAXPATH],incldir[MAXPATH],inclpath[MAXPATH];
  35. uchar    *unpack="*.ZOO,*.ZIP,*.AR[CJ],*.LZ[HS],*.LHA,*.T[GA]Z,*.GIF,*.GZ,*.JPG,*.HPK";
  36. uchar    *infname,*bbuf,*ebuf,*fbuf,*fbnxt,*o_dir,print_buf[1536];
  37. ulong    fblft,fbmax;
  38. filebuf    *fblast;
  39.  
  40. uchar    SystemId,has_crc,back_1,back_2,compress;
  41. int     patno,exno,maxblk=64,UnixFile,regcnt,wild_arc,multi_arc,all;
  42. int        fn_name=12,pt_name=128,Case=_PC_CASECONV,min_len,garbage,Device;
  43.  
  44. int     n,heapsize,hdr_len,header_len,ignfile;
  45. uchar    *buf=text_buf,*pager,*com_name,*buffer_start,*buffer_last;
  46. uchar    flg_r,flg_p,flg_x,flg_m,flg_a,flg_c,flg_v,flg_w,flg_z,flg_g,flg_L=2,flg_N,flg_B,flg_W,flg_5,flg_o,flg_l;
  47. uchar    flg_d,flg_u,flg_s,flg_e,flg_unpacked,flg_j,flg_chk,flg_S,flg_R,flg_I,flg_U=1,flg_K,flg_D,base;
  48. uchar    flg_t,flg_arc,flg_h,flg_i,flg_backup,flg_f,flg_4,flg_q,flg_A,flg_X,flg_Y,pnt='.',buffered;
  49. uchar    method=5,FlgMethod=5,copying,obj,ptitel,pargs;
  50. char    flg_k=-1;
  51.  
  52. #ifndef __SHELL__
  53. uchar    pack;
  54. #endif
  55.  
  56. uchar    swi[]="lo5UwCrpxmacntvhifzedgjqsLSRBAWXKYDybuk4PMNI";
  57. uchar    *swipos[]={&flg_l,&flg_o,&flg_5,&flg_U,&flg_w,&flg_chk,&flg_r,&flg_p,&flg_x,&flg_m,&flg_a,&flg_c,&flg_n,&flg_t,&flg_v,&flg_h,&flg_i,
  58.         &flg_f,&flg_z,&flg_e,&flg_d,&flg_g,&flg_j,&flg_q,&flg_s,&flg_L,&flg_S,&flg_R,&flg_B,&flg_A,&flg_W,&flg_X,&flg_K,&flg_Y,&flg_D};
  59.  
  60. #define    SWI_CNT    35
  61.  
  62. LzHead    Hdr1,Hdr2;
  63. _DOSTIME arcstamp,newer;
  64.  
  65. uchar    arcname[MAXPATH],pathname[MAXPATH],backup1[MAXPATH],backup2[MAXPATH],key_word[256],*key;
  66. uchar    filename[MAXPATH],dosfilename[MAXPATH],matchfilename[MAXPATH],comment[MAXCOMMENT+256];
  67. uchar    buffer[(BUFFERSIZ+128+32)*3],*buffer_1,*buffer_3,*buffer_gen;
  68. uchar    travel_wild[MAX_PAT],*exclude_file[MAX_EXCLD],fileregbuf[FILEBUFSIZ],*fileptr;
  69. uchar    *travel_path[MAX_PAT],travel_rel[MAX_PAT];
  70. int     patcnt[MAX_PAT],travel_len[MAX_PAT],travel_file[MAX_PAT],arc_file[MAX_ARC];
  71.  
  72. #if (BETA && !defined(__SHELL__))
  73. long timer;
  74. #define INIT_TIMER    timer=clock()
  75. #define EXIT_TIMER    timer=clock() - timer; sprintf(print_buf," Time : %ld ms ",(timer*5)); Print(1)
  76. #else
  77. #define INIT_TIMER
  78. #define EXIT_TIMER
  79. #endif
  80.  
  81. #define    rename(o,n)    Frename(0,o,n)
  82.  
  83. #ifdef __SHELL__
  84.  
  85. long dir_handle[40];
  86. int dirs;
  87.  
  88. extern void DialIndicator(int);
  89. extern void make_info(int show,SELECT *sel);
  90. extern void FrozenMsg(int);
  91. extern void SetMsg(uchar *);
  92. extern int OverWrMsg(uchar *);
  93. extern void ErrorAlert(uchar *);
  94. extern void set_crypt(void);
  95.  
  96. static void skip(uchar *,uchar *,int);
  97.  
  98. extern int command,drv_lines,overwr_all,execute,idx,ainf_changed;
  99. extern jmp_buf errorjmp;
  100. extern SELECT drv_sel;
  101. extern _DOSTIME arc_time;
  102.  
  103. extern uchar *view_mem,arc_comment[];
  104. extern long view_length,alert_buf;
  105.  
  106. extern filebuf *arc_buf,*drv_files[];
  107. filebuf *next_buf,*last_buf;
  108.  
  109. int cmd_found = FAULT;
  110. long searchpos;
  111. uchar shell,stop;
  112.  
  113. #endif
  114.  
  115. clock_t now;
  116.  
  117. static void getnow(void)
  118. {
  119.     now=*((unsigned long *) 0x4baL);
  120. }
  121.  
  122. clock_t clock(void)
  123. {
  124.     (void) Supexec(getnow);
  125.     return (now);
  126. }
  127.  
  128. #define  A          16807L
  129. #define  M   2147483647L
  130. #define  Q       127773L
  131. #define  R         2836L
  132.  
  133. long _lseed;
  134.  
  135. static int temp(void)
  136. {
  137.     _lseed=A * ((_lseed % Q) + R) - R * (_lseed / Q);
  138.  
  139.     if (_lseed<0)
  140.         _lseed+=M;
  141.  
  142.     return((int) _lseed & 4095);
  143. }
  144.  
  145. static void fdelete(uchar *path,int attr)
  146. {
  147.     if (attr & FA_DIR)
  148.         return;
  149.     if (attr & FA_RDONLY)
  150.         Fattrib(path,1,0);
  151.     Fdelete(path);
  152. }
  153.  
  154. int multi_wild(uchar *file)
  155. {
  156.     return (flg_W<2 && strchr(file,',')!=NULL);
  157. }
  158.  
  159. int wildcard(uchar *file)
  160. {
  161.     if (!flg_W && strpbrk(file,"*?[]@|^"))
  162.         return(SUCCS);
  163.     else
  164.         return(FAULT);
  165. }
  166.  
  167. void InitTree(void)
  168. {
  169.     register int i,nil_2=NIL<<1,*p;
  170.  
  171.     p=dad;
  172.     for (i=N;--i>=0;)
  173.         *p++=nil_2;
  174.  
  175.     p=&rson[N+1];
  176.     for (i=256;--i>=0;)
  177.         *p++=nil_2;
  178. }
  179.  
  180. int sseek(FILE *file,long pos,long offset)
  181. {
  182.     if (pos>=arclen)
  183.     {
  184.         fseek(file,0l,SEEK_END);
  185.         return(-1);
  186.     }
  187.     else if (offset)
  188.         return(fseek(file,offset,SEEK_CUR));
  189.     else
  190.         return(0);
  191. }
  192.  
  193. void Print(int nl)
  194. {
  195.     print(print_buf,nl);
  196. }
  197.  
  198. void pager_print(int pg)
  199. {
  200.     if (cmd!='P' || flg_v<2)
  201.     {
  202.         if (pager)
  203.             fputs(print_buf,file3);
  204.  
  205.         if (!flg_q && (!pager || pg))
  206.             Print(0);
  207.     }
  208. }
  209.  
  210. void message(uchar *p,uchar *q)
  211. {
  212.     sprintf(print_buf,"%s: %s",p,q);
  213.     print(print_buf,1);
  214. }
  215.  
  216. void print(uchar *p,int nl)
  217. {
  218.     if (!flg_q)
  219.     {
  220.         uchar string[2048];
  221.  
  222.         if (p)
  223.             p=stpcpy(string,p);
  224.         else
  225.             p=string;
  226.  
  227.         for (;--nl>=0;)
  228.             p=stpcpy(p,"\r\n");
  229.         Cconws(string);
  230.     }
  231. }
  232.  
  233. void convert_comment(void)
  234. {
  235.     register uchar c,com[MAXCOMMENT+256],*dst=com,*src=comment;
  236.  
  237.     comment[MAXCOMMENT-1]='\0';
  238.  
  239.     while ((c=*src++)!='\0')
  240.     {
  241.         if (c=='\n' && src[0]!='\r' && src[-2]!='\r')
  242.             *dst++='\r';
  243.         *dst++=c;
  244.     }
  245.  
  246.     *dst='\0';
  247.  
  248.     strcpy(comment,com);
  249. }
  250.  
  251. int slash(register uchar *path,int set)
  252. {
  253.     if (path && *path)
  254.     {
  255.         while (*path++);
  256.         path-=2;
  257.  
  258.         if (*path!='\\')
  259.         {
  260.             if (set>0)
  261.             {
  262.                 *++path='\\';
  263.                 *++path='\0';
  264.             }
  265.             else
  266.                 return(SUCCS);
  267.         }
  268.         else if (set==0)
  269.             *path='\0';
  270.     }
  271.  
  272.     return(FAULT);
  273. }
  274.  
  275. uchar _proc_str[]= "\r         : %3d%% (%Nld/%Nld)";
  276. uchar _frozen_str[]="\r         : %Nld -> %Nld (%3d%%) ";
  277.  
  278. void proc_ind(void)
  279. {
  280.     if ((act_len+=blocksize)>=file_len || blkcnt<=0)
  281.         sprintf(print_buf,_proc_str,100,file_len,file_len);
  282.     else
  283.         sprintf(print_buf,_proc_str,(int) ((act_len*100l)/file_len),act_len,file_len);
  284.     Print(0);
  285. }
  286.  
  287. void copy_to_view(uchar *mem,long length)
  288. {
  289. #ifdef __SHELL__
  290.     if (view_mem>NULL && view_length>0)
  291.     {
  292.         if (length>view_length)
  293.             length = view_length;
  294.         memcpy(view_mem,mem,length);
  295.         view_mem += length;
  296.         view_length -= length;
  297.     }
  298. #endif
  299. }
  300.  
  301. int decrypt(long offset)
  302. {
  303.     if (Hdr1.crypted && crypt_size>0)
  304.     {
  305.         register long len=file1->_cnt+offset;
  306.  
  307.         if (len>crypt_size)
  308.             len=crypt_size;
  309.         code(file1->_ptr-offset,len);
  310.         crypt_size-=len;
  311.     }
  312.  
  313.     if (offset)
  314.         return(*file1->_base);
  315.     else
  316.         return(0);
  317. }
  318.  
  319. int arc_ext(uchar *x)
  320. {
  321.     if (x==NULL)
  322.         return(FAULT);
  323.     else
  324.         x++;
  325.  
  326.     if (stricmp("LZH",x) && stricmp("LHA",x) && stricmp("LZS",x) && stricmp("SFX",x))
  327.         return(FAULT);
  328.     else
  329.         return(SUCCS);
  330. }
  331.  
  332. int path_conf(uchar *path,int mode)
  333. {
  334.     register uchar dir[MAXPATH];
  335.     register long conf;
  336.  
  337.     if (backpath(strcpy(dir,path))>dir)
  338.         conf = pathconf(dir,mode);
  339.     else
  340.         conf = pathconf(act_dir,mode);
  341.  
  342.     return ((conf>32767) ? 32767 : (int) conf);
  343. }
  344.  
  345. int case_sensitive(uchar *path)
  346. {
  347.     if (path_conf(path,-1)<_PC_CASE)
  348.         return(_PC_CASECONV);
  349.     else
  350.         return(path_conf(path,_PC_CASE));
  351. }
  352.  
  353. void wait_for_key(int newline)
  354. {
  355. #ifdef __SHELL__
  356.     if (!shell && flg_h && i_handle<0 && o_handle<0)
  357. #else
  358.     if (flg_h && i_handle<0 && o_handle<0)
  359. #endif
  360.     {
  361.         print(M_PRESSKEY,0);
  362.  
  363.         fflush(stdin);
  364.         getch();
  365.  
  366.         if (newline)
  367.             print(NULL,1);
  368.     }
  369. }
  370.  
  371. void lha_exit(void)
  372. {
  373. #ifdef __SHELL__
  374.     Fsetdta(&_dta);
  375.  
  376.     while (--dirs>=0)
  377.         Dclosedir(dir_handle[dirs]);
  378.     dirs = 0;
  379.  
  380.     if (fbuf)
  381.     {
  382.         Mfree(fbuf);
  383.         fbuf=NULL;
  384.     }
  385.  
  386.     if (bbuf)
  387.     {
  388.         Mfree(bbuf);
  389.         bbuf=NULL;
  390.     }
  391.  
  392.     if (ebuf)
  393.     {
  394.         Mfree(ebuf);
  395.         ebuf=NULL;
  396.     }
  397.  
  398.     buffer_gen=(uchar *) (((long) (buffer+16)) & (~15l));
  399. #endif
  400.  
  401.     if (i_handle>=0)
  402.     {
  403.         if (i_dev>=0)
  404.             Fforce(0,(int) i_dev);
  405.         Fclose((int) i_handle);
  406.     }
  407.  
  408.     if (o_handle>=0)
  409.     {
  410.         if (o_dev>=0)
  411.             Fforce(1,(int) o_dev);
  412.         Fclose((int) o_handle);
  413.     }
  414.  
  415.     if (flg_K)
  416.     {
  417.         register long time=clock()+(CLK_TCK>>2);
  418.  
  419.         for (flg_K<<=2;flg_K>0;flg_K--)
  420.         {
  421.             while (clock()<time);
  422.             time+=(CLK_TCK>>2);
  423.             Cconout(7);
  424.         }
  425.     }
  426.  
  427.     cmdupdate = copying = 0;
  428.  
  429. #ifdef __SHELL__
  430.     if (!shell)
  431. #endif
  432.     {
  433.         wait_for_key(1);
  434.         exit(errorlevel);
  435.     }
  436. #ifdef __SHELL__
  437.     else
  438.     {
  439.         flg_n = 4;
  440.         longjmp(errorjmp,-1);
  441.     }
  442. #endif
  443. }
  444.  
  445. void error(int errcode,uchar *p,int err)
  446. {
  447.     if (err && old_afx)
  448.         afxonoff(old_afx);
  449.  
  450.     if (p==backup2)
  451.     {
  452.         if (flg_w)
  453.         #if GERMAN
  454.             p = "temp. Archiv";
  455.         #else
  456.             p = "temp. archive";
  457.         #endif
  458.         else
  459.             p = arcname;
  460.     }
  461.  
  462. #ifdef __SHELL__
  463.     if (!shell)
  464. #endif
  465.     {
  466.         fflush(stdout);
  467.         print(NULL,1);
  468.     }
  469.  
  470.     if (copying)
  471.     {
  472.     #ifdef __SHELL__
  473.         if (shell)
  474.         {
  475.             if (execute)
  476.             {
  477.                 if (err)
  478.                     ErrorAlert(M_COPYERR);
  479.                 else
  480.                     SetMsg(M_COPYERR);
  481.             }
  482.         }
  483.         else
  484.     #endif
  485.             print(M_COPYERR,1);
  486.         close_file(file1);
  487.         Fdelete(arcname);
  488.     }
  489.  
  490.     if (errcode>=0)
  491.     {
  492.     #ifdef __SHELL__
  493.         if (shell)
  494.         {
  495.             if (execute && !copying)
  496.             {
  497.                 if (p)
  498.                     sprintf(print_buf,"%s %s",errmes[errcode],p);
  499.                 else
  500.                     strcpy(print_buf,errmes[errcode]);
  501.     
  502.                 if (errcode==WTERR)
  503.                     strcat(print_buf," (Disc full?)");
  504.     
  505.                 if (err)
  506.                     ErrorAlert(print_buf);
  507.                 else
  508.                     SetMsg(print_buf);
  509.             }
  510.         }
  511.         else
  512.     #endif
  513.         if (p)
  514.             message(errmes[errcode],p);
  515.         else
  516.             print(errmes[errcode],1);
  517.     }
  518.  
  519.     if (file3 && file3!=stdout)
  520.     {
  521.         close_file(file3);
  522.  
  523.         if (copying && err && !Device && (back_2 || cmd=='C'))
  524.         {
  525.             register uchar path[MAXPATH];
  526.             strcpy(backpath(strcpy(path,backup2)),get_fname(arcname));
  527.             rename(backup2,path);
  528.         }
  529.         else if ((err || cmd=='E') && !cmdupdate && cmd!='C')
  530.             Fdelete(pathname);
  531.     }
  532.  
  533.     if (err)
  534.     {
  535.         if (file1)
  536.         {
  537.             close_file(file1);
  538.             if (!Device && back_1)
  539.                 rename(backup1,arcname);
  540.         }
  541.  
  542.         if (file2)
  543.         {
  544.             close(file2);
  545.             file2=0;
  546.  
  547.             if (!Device && (back_2 || cmd=='C'))
  548.                 Fdelete(backup2);
  549.         }
  550.     }
  551.  
  552.     switch (errcode)
  553.     {
  554.     case MEMOVRERR:
  555.         errorlevel|=512;
  556.         break;
  557.     case RDERR:
  558.     case RDONLY:
  559.         errorlevel|=8;
  560.         break;
  561.     case WTERR:
  562.         errorlevel|=4;
  563.         break;
  564.     case RENAMEERR:
  565.     case MKDIRERR:
  566.         errorlevel|=16;
  567.         break;
  568.     case MKFILEERR:
  569.     case MKTMPERR:
  570.         errorlevel|=32;
  571.         break;
  572.     case NOFILEERR:
  573.     case NOFNERR:
  574.         errorlevel|=256;
  575.         break;
  576.     case NOARCERR:
  577.     case NOARCNMERR:
  578.         errorlevel|=128;
  579.     }
  580.  
  581.     if (copying)
  582.         errorlevel|=32;
  583.  
  584.     if (err==SUCCS)
  585.         lha_exit();
  586. }
  587.  
  588. FILE *e_fopen(uchar *fname,uchar *buffer,uchar *mode,int errID,int err)
  589. {
  590.     register FILE *f;
  591.  
  592.     if ((f=fopen(fname,mode))==NULL)
  593.     {
  594.         if (errno==EACCES)
  595.             error(RDONLY,fname,err);
  596.         else if (errno)
  597.             error(errID,fname,err);
  598.     }
  599.     else if (buffer)
  600.         setvbuf(f,buffer,_IOFBF,bsize);
  601.  
  602.     return(f);
  603. }
  604.  
  605. uint get_key(uchar *keys)
  606. {
  607.     register uchar key;
  608.  
  609.     fflush(stdin);
  610.     do
  611.     {
  612.         key=(uchar) toupper((int) getch());
  613. #if GERMAN
  614.         if (key=='J')
  615.             key='Y';
  616. #endif
  617.     } while (!strchr(keys,key));
  618.  
  619.     print_buf[0]=key;
  620.     print_buf[1]='\0';
  621.     Print(1);
  622.  
  623.     return(key);
  624. }
  625.  
  626. void ShipOut(void)
  627. {
  628.     ship++;
  629.     shipout();
  630.     ship=0;
  631. }
  632.  
  633. void tstpat(void)
  634. {
  635.     register int i;
  636.  
  637. #ifdef __SHELL__
  638.     if (shell)
  639.         return;
  640. #endif
  641.  
  642.     if (!Nfile)
  643.     {
  644.         print(M_NOFILEERR,1);
  645.         errorlevel|=256;
  646.         return;
  647.     }
  648.  
  649.     for (i=patno;--i>=0;)
  650.         if (!patcnt[i] && !travel_wild[i])
  651.         {
  652.             message(M_NOMATCHERR,&fileregbuf[travel_file[i]]);
  653.             errorlevel|=256;
  654.         }
  655. }
  656.  
  657. void sethdr(uchar *fn,uint attr,_DOSTIME *time,LzHead *h,int name)
  658. {
  659.     register uchar *id;
  660.     register uint l;
  661.  
  662.     memset(h,0,sizeof(LzHead));
  663.  
  664.     l=(uint) strlen(fn);
  665.     if (name==SUCCS && flg_x==2 && *fn!='\\')
  666.     {
  667.         h->Fname[1]='\\';
  668.         memcpy(h->Fname+2,fn,l++);
  669.     }
  670.     else
  671.         memcpy(h->Fname+1,fn,l);
  672.  
  673.     if ((attr & FA_DIR) && (h->Fname[l]!='\\'))
  674.         h->Fname[++l]='\\';
  675.  
  676.     h->Fname[0]=l;
  677.     h->Attr=(flg_backup) ? (attr & (~FA_CHANGED)) : attr;
  678.     h->Ftime=*time;
  679.     h->HeadSiz=l;
  680.  
  681.     if (file3)
  682.     {
  683.         h->OrgSiz=textsize=Fseek(0l,fileno(file3),SEEK_END);
  684.         Fseek(0l,fileno(file3),SEEK_SET);
  685.     }
  686.     else
  687.         h->OrgSiz=textsize=0;
  688.  
  689.     method=FlgMethod;
  690.     codesize=compsize=0;
  691.  
  692.     if (attr & FA_DIR)
  693.         id="-lhd-";
  694.     else if (cmd=='C')
  695.         id="-afx-";
  696.     else if (!method)
  697.         id="-lz5-";
  698.     else if (method==1)
  699.         id="-lh1-";
  700.     else if (method==5)
  701.         id="-lh5-";
  702.     else
  703.         id="-lz4-";
  704.  
  705.     memcpy(h->HeadID,id,5);
  706. }
  707.  
  708. uint make_ext(uchar *dest,uchar *source,uchar id,int last)
  709. {
  710.     register uint len;
  711.  
  712.     if ((len=(uint) strlen(source))>0)
  713.     {
  714.         if (last)
  715.             len+=4;
  716.         else
  717.             len+=3;
  718.  
  719.         *dest++=(uchar) (len&0xff);
  720.         *dest++=(uchar) (len>>8);
  721.         *dest++=id;
  722.  
  723.         while (*source!='\0')
  724.             *dest++=*source++;
  725.  
  726.         if (last)
  727.             *dest++=0xff;
  728.     }
  729.  
  730.     return(len);
  731. }
  732.  
  733. void wthdr(LzHead *h,int make,int unpck)
  734. {
  735.     register uchar *ptr,*s,*n=h->Fname+1;
  736.     register uint len=0;
  737.     register int lev=flg_k;
  738.     register ulong size;
  739.     register _DOSTIME time;
  740.  
  741.     if (lev<=0 && (comment[0]!='\0' || flg_s || (flg_Y && h->OrgSiz>0)))
  742.         lev=1;
  743.     else if (lev<0)
  744.         lev=0;
  745.  
  746.     if (make)
  747.     {
  748.         if ((h->Level=lev)==1)
  749.             h->HeadSiz+=25;
  750.         else
  751.             h->HeadSiz+=22;
  752.  
  753.         if (lev && flg_s)
  754.         {
  755.             register uchar c,s='\\';
  756.  
  757.             ptr=n;
  758.             while ((c=*ptr++)!='\0')
  759.                 if (c==s)
  760.                     ptr[-1]='/';
  761.         }
  762.         else
  763.             yen2slash(n);
  764.  
  765.         if (lev)
  766.         {
  767.             if (lev<2)
  768.                 s=n+h->Fname[0]+3;
  769.             else
  770.             {
  771.                 uchar path[MAXPATH];
  772.  
  773.                 strncpy(path,n,h->Fname[0]);
  774.                 path[h->Fname[0]]='\0';
  775.  
  776.                 len+=make_ext(&h->Fname[3],s=get_fname(path),0x01,FAULT);
  777.  
  778.                 if (s>path)
  779.                 {
  780.                     register uchar c;
  781.                     *s='\0';
  782.  
  783.                     ptr=path;
  784.                     while ((c=*ptr++)!='\0')
  785.                         if (c=='\\' || c=='/')
  786.                             ptr[-1]='\xff';
  787.  
  788.                     if (ptr[-2]==(uchar) '\xff')
  789.                         ptr[-2]='\0';
  790.  
  791.                     len+=make_ext(&h->Fname[len+3],path,0x02,SUCCS);
  792.                 }
  793.  
  794.                 s=&h->Fname[len+3];
  795.             }
  796.  
  797.             if (h->Attr!=0x20 || lev==2)
  798.             {
  799.                 len+=5;
  800.                 *s++=5;
  801.                 *s++='\0';
  802.                 *s++=0x40;
  803.                 *s++=h->Attr;
  804.                 *s++='\0';
  805.             }
  806.  
  807.             if (h->OrgSiz>0 && flg_Y)
  808.             {
  809.                 len+=4;
  810.                 *s++=4;
  811.                 *s++='\0';
  812.                 *s++=0x20;
  813.                 *s++=1;
  814.             }
  815.  
  816.              if (*comment)
  817.              {
  818.                  register uint off=make_ext(s,comment,0x3f,SUCCS);
  819.                 len+=off;
  820.                 s+=off;
  821.             }
  822.  
  823.             *s++='\0';
  824.             *s++='\0';
  825.         }
  826.  
  827.         hdr_len=len;
  828.     }
  829.     else
  830.         len=hdr_len;
  831.  
  832.     if (lev<2)
  833.     {
  834.         if (lev==1)
  835.             h->PacSiz+=len;
  836.         ptr=n+h->Fname[0];
  837.     }
  838.     else
  839.         ptr=h->Fname;
  840.  
  841.     *ptr++=(uchar) (crc&0xff);
  842.     *ptr++=(uchar) (crc>>8);
  843.  
  844.     if (lev>0)
  845.     {
  846.         if (flg_s)
  847.             *ptr=flg_s;
  848.         else
  849.             *ptr='a';
  850.         h->Attr=0x20;
  851.     }
  852.  
  853.     if (lev<2)
  854.     {
  855.         len+=h->HeadSiz;
  856.         h->HeadChk=mksum(h,h->HeadSiz+1);
  857.         len+=2;
  858.     }
  859.     else
  860.     {
  861.         len+=26;
  862.         h->HeadSiz=(uchar) (len&0xff);
  863.         h->HeadChk=(uchar) (len>>8);
  864.     }
  865.  
  866.     size=header_len=len;
  867.  
  868.     if (unpck)
  869.         size+=h->OrgSiz;
  870.     else
  871.         size+=(h->OrgSiz>>1);
  872.  
  873.     ilong(&h->PacSiz);
  874.     ilong(&h->OrgSiz);
  875.  
  876.     time=h->Ftime;
  877.     if (lev<2)
  878.         ITIME(h->Ftime);
  879.     else
  880.         dos_2_unixtime((void *) &h->Ftime);
  881.  
  882.     if (make)
  883.     {
  884.         if (outrec.cnt<=(len+1024) || (bsize>size && outrec.cnt<=size))
  885.             ShipOut();
  886.  
  887.         buffer_start=outrec.ptr;
  888.         buffer_last=(outrec.ptr+=len);
  889.         buffer_cnt=(outrec.cnt-=len);
  890.         buffered=1;
  891.     }
  892.  
  893.     ptr=((uchar *) h)+8;
  894.     if (buffered)
  895.     {
  896.         memcpy(buffer_start,ptr-8,7);
  897.         memcpy(buffer_start+7,ptr,len-7);
  898.     }
  899.     else
  900.     {
  901.         register long pos = Fseek(0l,file2,SEEK_CUR);
  902.  
  903.         Fseek(arcpos0-pos,file2,SEEK_CUR);
  904.         memcpy(ptr-1,ptr,len-7);
  905.         write(file2,h,len);
  906.         memcpy(ptr,ptr-1,len-7);
  907.         Fseek(pos-(arcpos0+len),file2,SEEK_CUR);
  908.     }
  909.  
  910.     arcpos1=arcpos0+len;
  911.  
  912.     ilong(&h->PacSiz);
  913.     ilong(&h->OrgSiz);
  914.     h->Ftime=time;
  915. }
  916.  
  917. void unix2dos(uchar *unx,int rel)
  918. {
  919.     register uchar *u=unx,*d=u,c;
  920.  
  921.     yen2slash(unx);
  922.     if (!strncmp(u,"\\dev\\",5))
  923.     {
  924.         u+=5;
  925.  
  926.         if (u[0]!='\0' && (u[1]=='\0' || u[1]=='\\'))
  927.         {
  928.             if (rel)
  929.                 u++;
  930.             else
  931.             {
  932.                 *d++=*u++;
  933.                 *d++=':';
  934.             }
  935.         }
  936.     }
  937.     else if (!strncmp(u,"\\pipe\\",6))
  938.         u+=6;
  939.  
  940.     while ((c=*u++)!='\0')
  941.     {
  942.         if (rel && c==':' && ((d>&unx[1] && d[-2]=='\\') || (d==&unx[1])))
  943.             d=unx;
  944.         else
  945.             *d++=c;
  946.     }
  947.  
  948.     *d++='\0';
  949. }
  950.  
  951. void yen2slash(uchar *p)
  952. {
  953.     register uchar *d=p,c,s;
  954.  
  955.     s='/';
  956.     while ((c=*p++)!='\0')
  957.         if (c==s)
  958.             p[-1]='\\';
  959.  
  960.     s='\\';
  961.     while ((c=*d++)!='\0')
  962.         if (c==s && *d==s)
  963.         {
  964.             d--;
  965.             strcpy(d,d+1);
  966.         }
  967. }
  968.  
  969. void strcnv(uchar *str,int flag)
  970. {
  971.     if (flag && flg_s)
  972.         strlwr(str);
  973.     else
  974.         strupr(str);
  975. }
  976.  
  977. int fnamecmp(uchar *f1,uchar *f2,int Case)
  978. {
  979.     if (flg_S==2 || (!flg_S && Case!=_PC_CASESENS))
  980.         return(stricmp(f1,f2));
  981.     else
  982.         return(strcmp(f1,f2));
  983. }
  984.  
  985. int matchpattern(register uchar *s,register uchar *p)
  986. {
  987.     register uchar s_c,p_c;
  988.     register int matched,reverse;
  989.  
  990.     for (;(p_c=*p++)!='\0';)
  991.     {
  992.         s_c=*s++;
  993.  
  994.         switch (p_c)
  995.         {
  996.         case '@':
  997.             if (s_c!=*p++)
  998.                 return(FAULT);
  999.             break;
  1000.         case '?':
  1001.             if (s_c=='\0')
  1002.                 return(FAULT);
  1003.             break;
  1004.         case '*':
  1005.             if (s_c=='\0')
  1006.                 return((*p=='\0') ? SUCCS :FAULT);
  1007.             else
  1008.             {
  1009.                 if (*p!='\0')
  1010.                 {
  1011.                     s--;
  1012.                     while (!matchpattern(s,p))
  1013.                         if (*++s=='\0')
  1014.                             return(FAULT);
  1015.                 }
  1016.                 return(SUCCS);
  1017.             }
  1018.         case '[':
  1019.             matched=FAULT;
  1020.  
  1021.             if (*p=='^')
  1022.             {
  1023.                 reverse=SUCCS;
  1024.                 p++;
  1025.             }
  1026.             else
  1027.                 reverse=FAULT;
  1028.  
  1029.             for (; (p_c=*p++)!='\0' && p_c!=']';)
  1030.             {
  1031.                 if (p_c=='-')
  1032.                 {
  1033.                     if (s_c<=*p++ && s_c>=p[-3])
  1034.                         matched=SUCCS;
  1035.                 }
  1036.                 else if (p_c=='@' && s_c==*p++)
  1037.                     matched=SUCCS;
  1038.                 else if (s_c==p_c && p_c!='|')
  1039.                     matched=SUCCS;
  1040.             }
  1041.  
  1042.             if (matched==reverse)
  1043.                 return(FAULT);
  1044.  
  1045.             break;
  1046.         default:
  1047.             if (s_c!=p_c)
  1048.                 return(FAULT);
  1049.             break;
  1050.         }
  1051.     }
  1052.  
  1053.     return(*s=='\0');
  1054. }
  1055.  
  1056. int chk_wild(uchar *fname,uchar *fspec,int Wild,int Case)
  1057. {
  1058.     if (*fspec)
  1059.     {
  1060.         register uchar *p=fspec;
  1061.  
  1062.         if (*p++=='*' && (*p=='\0' || (*p++=='.' && *p++=='*' && *p++=='\0')))
  1063.             return(SUCCS);
  1064.         else
  1065.         {
  1066.             register uchar wc[64],fn[64];
  1067.             register int res=0,len=(int) strlen(fspec);
  1068.  
  1069.             if (flg_S==2 || (!flg_S && Case!=_PC_CASESENS))
  1070.             {
  1071.                 Case=FAULT;
  1072.                 strupr(strcpy(fn,fname));
  1073.             }
  1074.             else
  1075.                 Case=SUCCS;
  1076.  
  1077.             p=(Wild==2) ? fspec : strtok(fspec,", ");
  1078.             while (p)
  1079.             {
  1080.                 if (*p!='\0')
  1081.                 {
  1082.                     if (Wild)
  1083.                         res=(!fnamecmp(fname,p,Case));
  1084.                     else if (Case)
  1085.                         res=matchpattern(fname,p);
  1086.                     else
  1087.                     {
  1088.                         strupr(strcpy(wc,p));
  1089.                         res=matchpattern(fn,wc);
  1090.                     }
  1091.                 }
  1092.  
  1093.                 if (res)
  1094.                 {
  1095.                     if (Wild<2)
  1096.                     {
  1097.                         while (*p++);
  1098.                         if ((long) ((--p)-fspec)<len)
  1099.                             *p=',';
  1100.                     }
  1101.  
  1102.                     return(SUCCS);
  1103.                 }
  1104.                 else if (Wild==2)
  1105.                     break;
  1106.                 else if ((p=strtok(NULL,", "))!=NULL)
  1107.                     p[-1]=',';
  1108.             }
  1109.         }
  1110.     }
  1111.  
  1112.     return(FAULT);
  1113. }
  1114.  
  1115. void fnamecnv(uchar *dest,int conv)
  1116. {
  1117.     int sens=Case;
  1118.  
  1119.     yen2slash(dest);
  1120.     if (conv<0)
  1121.         sens=case_sensitive(dest);
  1122.     else if (conv>0)
  1123.         TruncFile(dest);
  1124.  
  1125.     if (!flg_S && sens==_PC_CASECONV)
  1126.         strcnv(dest,cmdupdate);
  1127. }
  1128.  
  1129. #define SECS_PER_MIN    (60L)
  1130. #define SECS_PER_HOUR    (3600L)
  1131. #define SECS_PER_DAY    (86400L)
  1132. #define SECS_PER_YEAR    (31536000L)
  1133. #define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
  1134.  
  1135. static int days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  1136.  
  1137. void unix_2_dostime(void *t)
  1138. {
  1139.     register _DOSTIME *dostime=(_DOSTIME *) t;
  1140.     register long time=*((long *) t);
  1141.     register int year,mday,mon;
  1142.     int hour,min,sec;
  1143.  
  1144.     year = 70;
  1145.     while (time>=SECS_PER_YEAR)
  1146.     {
  1147.         if ((year&3)==0)
  1148.         {
  1149.             if (time<SECS_PER_LEAPYEAR)
  1150.                 break;
  1151.             else
  1152.                 time -= SECS_PER_LEAPYEAR;
  1153.         }
  1154.         else
  1155.             time -= SECS_PER_YEAR;
  1156.         year++;
  1157.     }
  1158.  
  1159.     mday = (int)(time/SECS_PER_DAY);
  1160.     days_per_mth[1] = (year&3) ? 28 : 29;
  1161.     for (mon = 0; mday >= days_per_mth[mon]; mon++)
  1162.         mday -= days_per_mth[mon];
  1163.     mday++;
  1164.  
  1165.     time = time % SECS_PER_DAY;
  1166.     hour = (int) (time/SECS_PER_HOUR);
  1167.     time = time % SECS_PER_HOUR;
  1168.     min = (int) (time/SECS_PER_MIN);
  1169.     sec = (int) (time%SECS_PER_MIN);
  1170.  
  1171.     if (year>=80)
  1172.         year-=80;
  1173.     else
  1174.         year=0;
  1175.     dostime->time=(uint) ((hour<<11)|(min<<5)|(sec>>1));
  1176.     dostime->date=(uint) ((year<<9)|(mon<<5)|mday);
  1177. }
  1178.  
  1179. void dos_2_unixtime(void *time)
  1180. {
  1181.     register _DOSTIME *dostime=(_DOSTIME *) time;
  1182.     register uint val;
  1183.     register struct tm tm,*t=&tm;
  1184.  
  1185.     val=dostime->time;
  1186.     t->tm_sec=(val&31)<<1;
  1187.     t->tm_min=(val>>=5)&63;
  1188.     t->tm_hour=val>>=6;
  1189.  
  1190.     val=dostime->date;
  1191.     t->tm_mday=val&31;
  1192.     t->tm_mon=(val>>=5)&15;
  1193.     t->tm_year=(val>>=4)+80;
  1194.  
  1195.     *((time_t *) time)=mktime(t);
  1196.     ilong((ulong *) time);
  1197. }
  1198.  
  1199. int gethdr(FILE *arc,LzHead *h)
  1200. {
  1201.     uchar exthdr[MAXEXT],fname[MAXPATH];
  1202.     register uchar *p;
  1203.     register uint extsize;
  1204.     register int length,unix;
  1205.     register long pos,read;
  1206.  
  1207. #ifdef __SHELL__
  1208.     if (!cmdupdate && !flg_d && (stop || (command && searchpos<0)))
  1209.         return (FAULT);
  1210. #endif
  1211.  
  1212.     _gethdr:
  1213.     *comment='\0';
  1214.     lastarcpos=nextarcpos;
  1215.     memset(h,0,sizeof(LzHead));
  1216.  
  1217.     if (fread((uchar *) h,7,1,arc)!=1 || fread((uchar *) h+8,14,1,arc)!=1)
  1218.         goto no_hdr;
  1219.  
  1220.     if (h->Level>2)
  1221.         goto no_hdr;
  1222.     else if (h->Level==2)
  1223.         h->HeadSiz=HDRSIZ2;
  1224.     else if    (h->HeadSiz<MINHDR || h->HeadSiz>sizeof(LzHead))
  1225.         goto no_hdr;
  1226.  
  1227.     read=h->HeadSiz+2;
  1228.  
  1229.     if (fread((uchar *) h+22,read-21,1,arc)!=1)
  1230.         goto no_hdr;
  1231.  
  1232.     ilong(&h->PacSiz);
  1233.     ilong(&h->OrgSiz);
  1234.  
  1235.     lastarclen=read+h->PacSiz;
  1236.     pos=lastarcpos+read;
  1237.  
  1238.     if (h->Level<2)
  1239.         ITIME(h->Ftime);
  1240.     else
  1241.     {
  1242.         ilong((ulong *) &h->Ftime);
  1243.         unix_2_dostime((void *) &h->Ftime);
  1244.     }
  1245.     h->Mtime=h->Ftime;
  1246.  
  1247.     if (h->Level<2)
  1248.     {
  1249.         register int i;
  1250.  
  1251.         if (mksum(h,h->HeadSiz)!=h->HeadChk && mksum(h,h->HeadSiz+1)!=h->HeadChk)
  1252.             goto no_hdr;
  1253.  
  1254.         length=h->Fname[0];
  1255.         strncpy(filename,&h->Fname[1],length);
  1256.         filename[length]='\0';
  1257.  
  1258.         i=(int) strlen(filename);
  1259.         p=&h->Fname[i+1];
  1260.         if ((i=length-i)>0)
  1261.         {
  1262.             while (--i>=0)
  1263.                 if (*p++>=' ')
  1264.                 {
  1265.                     strncpy(comment,--p,++i);
  1266.                     comment[i]='\0';
  1267.                     break;
  1268.                 }
  1269.         }
  1270.  
  1271.         length++;
  1272.     }
  1273.     else
  1274.     {
  1275.         filename[0]='\0';
  1276.         length=0;
  1277.     }
  1278.  
  1279.     p=h->Fname+length;
  1280.     h->crc=(uint) *p++;
  1281.     h->crc|=(uint) (*p++<<8);
  1282.     SystemId=*p++;
  1283.  
  1284.     has_crc=(flg_chk) ? FAULT : SUCCS;
  1285.  
  1286.     switch(h->HeadSiz-length)
  1287.     {
  1288.     case (HDRSIZ0-1-2):
  1289.         has_crc=FAULT;
  1290.     case (HDRSIZ0-1):
  1291.         h->Level=0;
  1292.         break;
  1293.     default:
  1294.         if (h->Level==0)
  1295.         {
  1296.             if (SystemId==EXTEND_UNIX || SystemId==EXTEND_OS68K)
  1297.             {
  1298.                 memcpy(&h->Mtime,p+1,4);
  1299.                 ilong((ulong *) &h->Mtime);
  1300.                 unix_2_dostime((void *) &h->Mtime);
  1301.             }
  1302.             else
  1303.                 h->Level++;
  1304.         }
  1305.         break;
  1306.     }
  1307.  
  1308.     if (h->Level>0)
  1309.     {
  1310.         extsize=(uint) *p++;
  1311.         extsize|=(uint) (*p++<<8);
  1312.  
  1313.         while (extsize>0)
  1314.          {
  1315.              pos+=extsize;
  1316.              length=extsize-2;
  1317.              if (extsize>=MAXEXT)
  1318.             {
  1319.                 if (sseek(arc,pos-2,length))
  1320.                     goto no_hdr;
  1321.             }
  1322.             else if (fread(exthdr,length,1,arc)!=1)
  1323.                 goto no_hdr;
  1324.             else
  1325.             {
  1326.                 length--;
  1327.                 switch (exthdr[0])
  1328.                 {
  1329.                 case 0:        /* common header */
  1330.                     break;
  1331.                 case 1:        /* filename header */
  1332.                 case 2:        /* pathname header */
  1333.                     if (length>=pt_name)
  1334.                         break;
  1335.  
  1336.                     strncpy(fname,&exthdr[1],length);
  1337.                     fname[length]='\0';
  1338.  
  1339.                     while ((p=strchr(fname,'\xff'))!=NULL)
  1340.                         *p = '\\';
  1341.                     length = (int) strlen(fname);
  1342.  
  1343.                     if (exthdr[0]==1)
  1344.                     {
  1345.                         p=get_fname(filename);
  1346.                         if (((int) (p - filename) + length)<pt_name)
  1347.                             strcpy(p,fname);
  1348.                     }
  1349.                     else if (((int) strlen(filename) + length + 1)<pt_name)
  1350.                     {
  1351.                         if (fname[length-1]!='\\' && fname[length-1]!='/')
  1352.                             strcat(fname,"\\");
  1353.  
  1354.                         strcat(fname,filename);
  1355.                         strcpy(filename,fname);
  1356.                     }
  1357.                     break;
  1358.                 case 0x20:
  1359.                     h->crypted=exthdr[1];
  1360.                     break;
  1361.                 case 0x3f:    /* comment */
  1362.                     strncpy(comment,&exthdr[1],length);
  1363.                     comment[length]='\0';
  1364.                     if ((p=strchr(comment,'\xff'))!=NULL)
  1365.                         *p='\0';
  1366.                     break;
  1367.                 case 0x40:    /* file attribute */
  1368.                     h->Attr=exthdr[1];
  1369.                     break;
  1370.                 case 0x50:    /* permission */
  1371.                 case 0x51:    /* gid and uid */
  1372.                 case 0x52:    /* group name */
  1373.                 case 0x53:  /* user name */
  1374.                     break;
  1375.                 case 0x54:  /* last modified time */
  1376.                     memcpy(&h->Mtime,&exthdr[1],4);
  1377.                     ilong((ulong *) &h->Mtime);
  1378.                     unix_2_dostime((void *) &h->Mtime);
  1379.                     break;
  1380.                 }
  1381.             }
  1382.  
  1383.             read+=extsize;
  1384.             if (h->Level<2)
  1385.                 h->PacSiz-=extsize;
  1386.             else
  1387.                 lastarclen+=extsize;
  1388.  
  1389.             extsize=getc(arc);
  1390.             extsize+=(uint) getc(arc)<<8;
  1391.         }
  1392.     }
  1393.  
  1394.     convert_comment();
  1395.  
  1396.     if ((unix=strchr("UXHK",SystemId) || strchr(filename,'/'))!=0)
  1397.         flg_s=SystemId;
  1398.  
  1399.     unix2dos(filename,1);
  1400.  
  1401.     if (filename[0] && filename[1]==':')
  1402.         strcpy(filename,filename+2);
  1403.  
  1404.     while (!strncmp(filename,".\\",2))
  1405.         strcpy(filename,filename+1);
  1406.  
  1407.     while (!strncmp(filename,"..\\",3))
  1408.         strcpy(filename,filename+2);
  1409.  
  1410.     if (flg_x==3)
  1411.         while (filename[0]=='\\')
  1412.             strcpy(filename,filename+1);
  1413.  
  1414.     if (slash(strcpy(matchfilename,filename),-1)==FAULT)
  1415.     {
  1416.         slash(matchfilename,0);
  1417.         h->Attr=FA_DIR;
  1418.     }
  1419.     else if (tstID(h->HeadID)==6)
  1420.         h->Attr=FA_DIR;
  1421.     else
  1422.         h->Attr&=0x2f;
  1423.  
  1424.     if (h->Attr & FA_DIR)
  1425.     {
  1426.         if (h->Attr!=FA_DIR)
  1427.             h->Attr&=~FA_DIR;
  1428.         else
  1429.         {
  1430.             h->OrgSiz=h->PacSiz=0;
  1431.             lastarclen=read;
  1432.         }
  1433.     }
  1434.  
  1435.     nextarcpos=lastarcpos+lastarclen;
  1436.     if (nextarcpos>arclen)
  1437.         nextarcpos=arclen;
  1438.     else
  1439.         nextoffset=lastarclen-read;
  1440.  
  1441. #ifdef __SHELL__
  1442.     if (command)
  1443.     {
  1444.         if (lastarcpos==searchpos)
  1445.         {
  1446.             register filebuf *f=next_buf;
  1447.  
  1448.             cmd_found=SUCCS;
  1449.             last_buf=next_buf;
  1450.             searchpos=-1;
  1451.  
  1452.             while ((f=f->next)!=NULL)
  1453.             {
  1454.                 if ((f->flag & (FA_SELECTED|FA_EDITED)) && f->seek_pos>=0)
  1455.                 {
  1456.                     next_buf=f;
  1457.                     searchpos=f->seek_pos;
  1458.                     break;
  1459.                 }
  1460.             }
  1461.  
  1462.             if (!cmdupdate && !flg_d)
  1463.             {
  1464.                 nextoffset+=searchpos-nextarcpos;
  1465.                 nextarcpos=searchpos;
  1466.             }
  1467.         }
  1468.         else
  1469.             cmd_found = FAULT;
  1470.     }
  1471. #endif
  1472.  
  1473.     fnamecnv(strcpy(dosfilename,matchfilename),1);
  1474.     UnixFile=strcmp(get_fname(dosfilename),get_fname(matchfilename));
  1475.  
  1476.     if (!unix && !UnixFile && Case!=_PC_CASECONV)
  1477.     {
  1478.         strupr(strcpy(fname,dosfilename));
  1479.         if (strcmp(fname,dosfilename)==0)
  1480.             strlwr(dosfilename);
  1481.     }
  1482.  
  1483.     if (!cmdlist && !flg_S && Case==_PC_CASECONV)
  1484.         strcnv(matchfilename,FAULT);
  1485.  
  1486.     if (!ferror(arc))
  1487.     {
  1488.         found++;
  1489.         return(SUCCS);
  1490.     }
  1491.  
  1492.     no_hdr:
  1493.     if (ferror(arc))
  1494.         error(RDERR,infname,FAULT);
  1495.     else if (lastarcpos<(arclen-16))
  1496.     {
  1497.         if (search_lzh(arc,-1)>0)
  1498.         {
  1499.         #ifdef __SHELL__
  1500.             if (shell)
  1501.                 SetMsg("Garbage found and skipped");
  1502.             else
  1503.         #endif
  1504.             #if GERMAN
  1505.                 print(" Zerstörte Daten gefunden und überlesen",1);
  1506.             #else
  1507.                 print(" Garbage found and skipped",1);
  1508.             #endif
  1509.  
  1510.             garbage++;
  1511.             errorlevel|=1024;
  1512.             goto _gethdr;
  1513.         }
  1514.         else if (!sfx && ((arclen & (~255l)) || lastarcpos<(arclen-1024) || !found))
  1515.         {
  1516.         #if GERMAN
  1517.             sprintf(print_buf," Überflüssige Daten am Archivende (%ld Bytes)",arclen-lastarcpos);
  1518.         #else
  1519.             sprintf(print_buf," Garbage found at the archive-end (%ld bytes)",arclen-lastarcpos);
  1520.         #endif
  1521.  
  1522.         #ifdef __SHELL__
  1523.             if (shell)
  1524.                 ErrorAlert(print_buf);
  1525.             else
  1526.         #endif
  1527.                 Print(1);
  1528.             errorlevel|=2048;
  1529.         }
  1530.     }
  1531.  
  1532.     return(FAULT);
  1533. }
  1534.  
  1535. int matchpat(uchar *p,register int pat,register int attr)
  1536. {
  1537.     register uchar c,*q,*name,path[MAXPATH];
  1538.     register int i,k,retcode=FAULT,wild;
  1539.  
  1540. #ifdef __SHELL__
  1541.     if (shell && pat<0)
  1542.     {
  1543.         if (stop)
  1544.             return(FAULT);
  1545.         else
  1546.             return(cmd_found && (last_buf->flag & FA_SELECTED));
  1547.     }
  1548. #endif
  1549.  
  1550.     if (*p=='\0')
  1551.         return(FAULT);
  1552.  
  1553.     if (attr & FA_DIR)
  1554.     {
  1555.         if (flg_f<2)
  1556.         {
  1557.             Nfile++;
  1558.             return(SUCCS);
  1559.         }
  1560.     }
  1561.     else if (flg_f==3)
  1562.         return(FAULT);
  1563.  
  1564.     name=get_fname(p);
  1565.     backpath(strcpy(path,p));
  1566.  
  1567.     for (i=(pat>=0) ? (pat+1) : patno;--i>=0;)
  1568.     {
  1569.         wild=(flg_W) ? flg_W : !travel_file[i];
  1570.  
  1571.         if (flg_p)
  1572.         {
  1573.             if (fnamecmp(path,travel_path[i],Case))
  1574.                 continue;
  1575.         }
  1576.         else if ((k=travel_len[i])>0)
  1577.         {
  1578.             q=&path[k];
  1579.             c=*q;
  1580.             *q='\0';
  1581.             k=fnamecmp(path,travel_path[i],Case);
  1582.             *q=c;
  1583.  
  1584.             if (k)
  1585.                 continue;
  1586.         }
  1587.  
  1588.         if (all || chk_wild(name,&fileregbuf[travel_file[i]],wild,Case))
  1589.         {
  1590.             for (k=exno;--k>=0;)
  1591.                 if (chk_wild(name,exclude_file[k],0,Case))
  1592.                     break;
  1593.  
  1594.             if (k<0)
  1595.             {
  1596.                 if (pat<0)
  1597.                 {
  1598.                     patcnt[i]++;
  1599.                     retcode=SUCCS;
  1600.                 }
  1601.                 else
  1602.                     return(SUCCS);
  1603.             }
  1604.         }
  1605.  
  1606.         if (pat>=0)
  1607.             break;
  1608.     }
  1609.  
  1610.     if (retcode)
  1611.         Nfile++;
  1612.  
  1613.     return(retcode);
  1614. }
  1615.  
  1616. uint ratio(ulong a,ulong b)
  1617. {
  1618.     register int i;
  1619.  
  1620.     if (!b)
  1621.         return(1000);
  1622.  
  1623.     for (i=0; i<3 && a<0x19999999L; i++)
  1624.         a*=10;
  1625.     for (;i<3;i++)
  1626.         b/=10;
  1627.     a+=b/2;
  1628.     return((uint) (a/b));
  1629. }
  1630.  
  1631. static void get_mem(void)
  1632. {
  1633.     if (!fbuf)
  1634.     {
  1635.         if ((fbmax=((long) Malloc(-1L)))>160000L && flg_L<2)
  1636.             fbmax>>=1;
  1637.         fbuf=fbnxt=Malloc(fbmax);
  1638.  
  1639.         if (!fbuf)
  1640.             error(MEMOVRERR,NULL,SUCCS);
  1641.  
  1642.         *((long *) fbuf)=0l;
  1643.         fblft=(fbmax-=256)-4;
  1644.         fbnxt+=4;
  1645.         fblast=(filebuf *) fbuf;
  1646.     }
  1647. }
  1648.  
  1649. void regfile(uchar *p,uchar *q,_DTA *file,uchar *f)
  1650. {
  1651.     register uchar *s;
  1652.     register filebuf *f0,*f1;
  1653.     register int attr,len;
  1654.     register uchar ch;
  1655.  
  1656.     attr=(oldtos) ? file->dta_attribute^FA_CHANGED : file->dta_attribute;
  1657.     if (attr & FA_DIR)
  1658.         attr=FA_DIR;
  1659.     else
  1660.     {
  1661.         if (flg_arc && !(attr & FA_CHANGED))
  1662.             return;
  1663.         else if (flg_j && file->dta_size==0)
  1664.             return;
  1665.         else if (maxlen>0 && file->dta_size>maxlen)
  1666.             return;
  1667.         else if (cmd=='C' && file->dta_size<=min_len)
  1668.             return;
  1669.     }
  1670.  
  1671.     if (strstr(f,TEMPFILE))
  1672.         return;
  1673.  
  1674.     get_mem();
  1675.     f1=(filebuf *) fbnxt;
  1676.     strcpy(s=stpcpy(f1->dir,p),f);
  1677.  
  1678.     if (o_dir && !fnamecmp(f1->dir,o_dir,Case))
  1679.         return;
  1680.  
  1681.     f1->time.time=file->dta_time;
  1682.     f1->time.date=file->dta_date;
  1683.  
  1684.     if (flg_N && FTimeToULong(&newer)>FTimeToULong(&f1->time))
  1685.         return;
  1686.  
  1687.     f1->next=NULL;
  1688.     f1->fpos=s-(uchar *) f1;
  1689.     f1->cpos=flg_x ? ((q-p)+f1->dir-(uchar *) f1) : f1->fpos;
  1690.     f1->attr=attr;
  1691.     f1->flag=0;
  1692.     f1->Case=Case;
  1693.     f1->cluster=min_len;
  1694. #ifdef __SHELL__
  1695.     f1->unpacked=file->dta_size;
  1696. #endif
  1697.  
  1698.     if (patno>1 || !flg_x)
  1699.     {
  1700.         f=(uchar *) f1+f1->fpos;
  1701.         f0=(filebuf *) fbuf;
  1702.         ch=*f;
  1703.  
  1704.         while ((f0=f0->next)!=NULL)
  1705.         {
  1706.             p=(uchar *) f0+f0->fpos;
  1707.             if (ch==*p && !strcmp(f,p) && !strcmp((uchar *) f0+f0->cpos,(uchar *) f1+f1->cpos))
  1708.                 return;
  1709.         }
  1710.     }
  1711.  
  1712.     if (fblft<sizeof(filebuf))
  1713.     {
  1714.         ignfile++;
  1715.         return;
  1716.     }
  1717.  
  1718. #ifdef __SHELL__
  1719.     if (shell)
  1720.     {
  1721.         if (attr & FA_DIR)
  1722.             drv_sel.dirs++;
  1723.         else
  1724.         {
  1725.             drv_sel.files++;
  1726.             drv_sel.bytes+=file->dta_size;
  1727.         }
  1728.     }
  1729. #endif
  1730.     len=(int) (strlen(f1->dir)+(f1->dir-(uchar *) f1))+1;
  1731.     len+=len & 1;
  1732.  
  1733.     fblast->next=fbnxt;
  1734.  
  1735.     fblast=(filebuf *) fbnxt;
  1736.     fblft-=len;
  1737.     fbnxt+=len;
  1738.     fbfiles++;
  1739.  
  1740.     if (flg_n!=1 && !(fbfiles & 15))
  1741.     {
  1742.         sprintf(print_buf,"\b\b\b\b%4d",fbfiles);
  1743.         Print(0);
  1744.     }
  1745. }
  1746.  
  1747. void regfreshen(uchar *p,int attr)
  1748. {
  1749.     register filebuf *f1;
  1750.     register int len;
  1751.  
  1752.     get_mem();
  1753.     if (fblft<sizeof(filebuf))
  1754.         return;
  1755.  
  1756.     f1=(filebuf *) fbnxt;
  1757.     f1->next=NULL;
  1758.     strcpy(f1->dir,p);
  1759.     f1->attr=attr;
  1760.  
  1761.     len=(int) (strlen(f1->dir)+(f1->dir-(uchar *) f1))+1;
  1762.     len+=len & 1;
  1763.  
  1764.     fblast->next=fbnxt;
  1765.     fblast=(filebuf *) fbnxt;
  1766.     fblft-=len;
  1767.     fbnxt+=len;
  1768. }
  1769.  
  1770. int read_attr(uchar *path,_DTA *dta)
  1771. {
  1772.     XATTR xattr;
  1773.     int ok;
  1774.  
  1775.     ok=(int) Fxattr(0,path,(uchar *) &xattr);
  1776.  
  1777.     dta->dta_time=xattr.mtime;
  1778.     dta->dta_date=xattr.mdate;
  1779.     dta->dta_size=xattr.size;
  1780.     dta->dta_attribute=xattr.attr;
  1781.  
  1782.     return (ok);
  1783. }
  1784.  
  1785. int tst_fname(uchar *fname)
  1786. {
  1787.     register uchar c,s=' ';
  1788.  
  1789.     if (fname[0]=='\0')
  1790.         return (FAULT);
  1791.     else if (fname[0]!='.' || (fname[1]!='\0' && (fname[1]!='.' || fname[2]!='\0')))
  1792.     {
  1793.         while ((c=*fname++)!='\0')
  1794.         {
  1795.             if (c<s)
  1796.                 return (FAULT);
  1797.         }
  1798.         return (SUCCS);
  1799.     }
  1800.     else
  1801.         return (FAULT);
  1802. }
  1803.  
  1804. void travel(uchar *p,uchar *q,int pat)
  1805. {
  1806.     _DTA dta,*old;
  1807.     register _DTA *d=&dta;
  1808.     register int done,compare,filesys;
  1809.     register long handle,buf[MAXPATH>>2];
  1810.     register uchar *s,*name;
  1811.  
  1812.     filesys=(_gemdos || (!flg_S && Case==_PC_CASECONV));
  1813.     compare=(!flg_S && Case==_PC_CASEINSENS);
  1814.  
  1815.     if (!_gemdos)
  1816.     {
  1817.         name=(uchar *) &buf[1];
  1818.  
  1819.         if (*p!='\0')
  1820.             handle=Dopendir(p,0);
  1821.         else
  1822.             handle=Dopendir(act_dir,0);
  1823.  
  1824.         if ((handle&0xff000000l)==0xff000000l)
  1825.             return;
  1826.         else
  1827.             done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  1828.  
  1829.     #ifdef __SHELL__
  1830.         dir_handle[dirs]=handle;
  1831.         dirs++;
  1832.     #endif
  1833.     }
  1834.     else
  1835.     {
  1836.         name=d->dta_name;
  1837.  
  1838.         strcat(p,"*.*");
  1839.  
  1840.         old=Fgetdta();
  1841.         Fsetdta(d);
  1842.         done=Fsfirst(p,-1);
  1843.     }
  1844.  
  1845.     s=backpath(p);
  1846.  
  1847.     while (!done)
  1848.     {
  1849.         if (tst_fname(name))
  1850.         {
  1851.             if (!_gemdos)
  1852.             {
  1853.                 strcpy(s,name);
  1854.                 read_attr(p,d);
  1855.             }
  1856.  
  1857.             if ((!flg_a && (d->dta_attribute & (FA_HIDDEN|FA_SYSTEM))) || (d->dta_attribute & FA_LABEL))
  1858.                 goto travel_next;
  1859.             else
  1860.             {
  1861.                 if (filesys)
  1862.                     strcnv(name,SUCCS);
  1863.         
  1864.                 if (d->dta_attribute & FA_DIR)
  1865.                 {
  1866.                     if (flg_f>1)
  1867.                     {
  1868.                         strcpy(s,name);
  1869.                         if (compare)
  1870.                             strcnv(s,SUCCS);
  1871.         
  1872.                         if (matchpat(p,pat,FA_DIR))
  1873.                         {
  1874.                             *s='\0';
  1875.                             regfile(p,q,d,name);
  1876.                         }
  1877.                     }
  1878.                     else if (flg_f && travel_wild[pat])
  1879.                     {
  1880.                         *s='\0';
  1881.                         regfile(p,q,d,name);
  1882.                     }
  1883.         
  1884.                     if (flg_r && travel_wild[pat])
  1885.                     {
  1886.                         strcpy(stpcpy(s,name),"\\");
  1887.         
  1888.                         if (strlen(p)>=pt_name)
  1889.                             message(M_TOOLONGERR,p);
  1890.                         else
  1891.                         {
  1892.                         #ifdef __SHELL__
  1893.                             register int old=fbfiles;
  1894.                         #endif
  1895.                             travel(p,q,pat);
  1896.                         #ifdef __SHELL__
  1897.                             if (shell && old==fbfiles)
  1898.                             {
  1899.                                 *s='\0';
  1900.                                 regfile(p,q,d,name);
  1901.                             }
  1902.                         #endif
  1903.                         }
  1904.                     }
  1905.                 }
  1906.                 else if (flg_f<3)
  1907.                 {
  1908.                     strcpy(s,name);
  1909.                     if (compare)
  1910.                         strcnv(s,SUCCS);
  1911.         
  1912.                     if (matchpat(p,pat,0))
  1913.                     {
  1914.                         *s='\0';
  1915.                         regfile(p,q,d,name);
  1916.                     }
  1917.                 }
  1918.             }
  1919.         }
  1920.  
  1921.         travel_next:
  1922.  
  1923.         if (_gemdos)
  1924.             done=Fsnext();
  1925.         else
  1926.             done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  1927.         *s='\0';
  1928.     }
  1929.  
  1930.     if (_gemdos)
  1931.         Fsetdta(old);
  1932.     else
  1933.     {
  1934.         Dclosedir(handle);
  1935.     #ifdef __SHELL__
  1936.         dirs--;
  1937.     #endif
  1938.     }
  1939. }
  1940.  
  1941. int drive(uchar *path,uchar **p)
  1942. {
  1943.     register int drv;
  1944.  
  1945.     if (path[0] && path[1]==':')
  1946.     {
  1947.         drv=toupper(path[0]);
  1948.         path+=2;
  1949.     }
  1950.     else
  1951.     {
  1952.         path=act_dir;
  1953.  
  1954.         if (path[0] && path[1]==':')
  1955.         {
  1956.             drv=toupper(path[0]);
  1957.             path+=2;
  1958.         }
  1959.         else
  1960.             drv=Dgetdrv()+'A';
  1961.     }
  1962.  
  1963.     if (__mint && drv=='U')
  1964.     {
  1965.         if (path[0]=='\\' && path[1] && path[2]=='\\')
  1966.         {
  1967.             drv=toupper(path[1]);
  1968.             path+=2;
  1969.         }
  1970.     }
  1971.  
  1972.     if (p)
  1973.         *p=path;
  1974.     return(drv-'A');
  1975. }
  1976.  
  1977. void mklist(void)
  1978. {
  1979.     register _BPB *bpb;
  1980.     register uchar path[MAXPATH],*rel;
  1981.     register int i,new=0;
  1982.  
  1983. #ifdef __SHELL__
  1984.     register _DTA dta;
  1985.     register filebuf *file;
  1986.     register int last=-1,max=(shell) ? drv_lines : patno;
  1987.  
  1988.     SetMsg("Searching files...");
  1989.  
  1990.     fbfiles=Nfile=0;
  1991.     for (i=0;i<max;i++)
  1992. #else
  1993.     fbfiles=Nfile=0;
  1994.     for (i=0;i<patno;i++)
  1995. #endif
  1996.     {
  1997.     #ifdef __SHELL__
  1998.         file = drv_files[i];
  1999.  
  2000.         if (shell)
  2001.         {
  2002.             if (!(file->flag & FA_SELECTED))
  2003.                 continue;
  2004.         }
  2005.         else
  2006.     #endif
  2007.         {
  2008.         #if GERMAN
  2009.             sprintf(print_buf,"\r Suchmuster : (%d/%d), Dateien gefunden : %4d",i+1,patno,Nfile);
  2010.         #else
  2011.             sprintf(print_buf,"\r Pattern : (%d/%d), Files matched : %4d",i+1,patno,Nfile);
  2012.         #endif
  2013.             Print(0);
  2014.         }
  2015.  
  2016.     #ifdef __SHELL__
  2017.         if (shell)
  2018.         {
  2019.             new = (file->attr & FA_DIR);
  2020.             rel=strcpy(path,file->name+2);
  2021.             if (new)
  2022.                 slash(path,1);
  2023.         }
  2024.         else
  2025.     #endif
  2026.         {
  2027.             rel = travel_path[i];
  2028.  
  2029.             if (!i)
  2030.                 new=SUCCS;
  2031.             else
  2032.                 new=fnamecmp(path,rel,_PC_CASESENS);
  2033.  
  2034.             rel=strcpy(path,rel);
  2035.  
  2036.             if (cmd=='C' && new && (bpb=Getbpb(drive(path,NULL)))!=NULL)
  2037.                 min_len=bpb->clsizb;
  2038.             else
  2039.                 min_len=1024;
  2040.  
  2041.         #ifdef __SHELL__
  2042.             if (flg_X)
  2043.         #else
  2044.             if (pack || flg_X)
  2045.         #endif
  2046.                 rel+=strlen(path);
  2047.             else if (travel_rel[i])
  2048.                 rel+=travel_rel[i];
  2049.             else
  2050.             {
  2051.                 if (*rel && rel[1]==':')
  2052.                     rel+=2;
  2053.     
  2054.                 if (*rel=='\\' && flg_x==3)
  2055.                     rel++;
  2056.     
  2057.                 if (!strncmp(rel,".\\",2))
  2058.                     rel+=2;
  2059.                 else if (!strncmp(rel,"..\\",3))
  2060.                     rel+=3;
  2061.             }
  2062.         }
  2063.  
  2064.     #ifdef __SHELL__
  2065.         if ((shell) ? (new || last) : new)
  2066.         {
  2067.             last = new;
  2068.     #else
  2069.         if (new)
  2070.         {
  2071.     #endif
  2072.             pt_name=path_conf(path,_PC_PATH_MAX);
  2073.             if (pt_name<=0 || pt_name>MAXPATH)
  2074.                 pt_name=MAXPATH;
  2075.             Case=case_sensitive(path);
  2076.  
  2077.             if (__mint)
  2078.                 _gemdos=(path_conf(path,_PC_NAME_MAX)==12 && Case==_PC_CASECONV);
  2079.         }
  2080.  
  2081.     #ifdef __SHELL__
  2082.         if (shell)
  2083.         {
  2084.             if (new && flg_r)
  2085.                 travel(path,rel,0);
  2086.  
  2087.             if (!new || (fbfiles==Nfile))
  2088.             {
  2089.                 rel="";
  2090.                 if (new)
  2091.                     strcpy(path,file->name+2);
  2092.                 if (_gemdos || Case==_PC_CASECONV)
  2093.                     strcnv(path,SUCCS);
  2094.                 dta.dta_time=file->time.time;
  2095.                 dta.dta_date=file->time.date;
  2096.                 dta.dta_size=file->unpacked;
  2097.                 dta.dta_attribute=file->attr;
  2098.                 regfile(rel,rel,&dta,path);
  2099.             }
  2100.         }
  2101.         else
  2102.     #endif
  2103.         {
  2104.             travel(path,rel,i);
  2105.             patcnt[i]=fbfiles-Nfile;
  2106.         }
  2107.         Nfile=fbfiles;
  2108.     }
  2109.  
  2110.     Mshrink(fbuf,fbmax-fblft+32);
  2111.  
  2112. #ifdef __SHELL__
  2113.     if (shell)
  2114.     {
  2115.         make_info(1,&drv_sel);
  2116.         if (ignfile)
  2117.         {
  2118.             stop=SUCCS;
  2119.             sprintf(print_buf,"File table overflow, %d file(s) ignored! Use minimal or medium memory-usage!",ignfile);
  2120.             ErrorAlert(print_buf);
  2121.             error(-1,NULL,SUCCS);
  2122.         }
  2123.     }
  2124.     else
  2125. #endif
  2126.     {
  2127.         if (ignfile)
  2128.         #if GERMAN
  2129.             sprintf(print_buf,"\b\b\b\b%4d\r\nDatei-Tabelle voll, %d Datei(en) ignoriert",ignfile);
  2130.         #else
  2131.             sprintf(print_buf,"\b\b\b\b%4d\r\nFile table overflow, %d file(s) ignored",ignfile);
  2132.         #endif
  2133.         else
  2134.             sprintf(print_buf,"\b\b\b\b%4d",Nfile);
  2135.         Print(2);
  2136.     }
  2137. }
  2138.  
  2139. long _proc_size[]={1000000L,
  2140.                    10000000L,
  2141.                    100000000L,
  2142.                    1000000000L};
  2143.  
  2144. void blkdisp(long len,uchar *s,uchar *fname,uchar *comment)
  2145. {
  2146.     uchar buf[256];
  2147.     register int i;
  2148.  
  2149.     blocksize=(N*2);
  2150.     blkcnt=(int) ((len+blocksize-1)/blocksize);
  2151.  
  2152.     for (i=0;i<(sizeof(_proc_size)>>2);i++)
  2153.         if (len<_proc_size[i])
  2154.             break;
  2155.  
  2156.     _frozen_str[13]=_frozen_str[21]=(i+'6');
  2157.     file_len=len;
  2158.     act_len=0;
  2159.  
  2160.     if (comment && *comment && flg_x && (cmd!='P' || pager))
  2161.     {
  2162.         print(fname,1);
  2163.         fname=NULL;
  2164.  
  2165.         print(comment,1);
  2166.     }
  2167.  
  2168.     if (!flg_n)
  2169.     {
  2170.         register uchar pind[MAXPATH],*p=pind,c=pnt;
  2171.  
  2172.         if (blkcnt>maxblk)
  2173.         {
  2174.             blkcnt=maxblk;
  2175.             blocksize=len/maxblk;
  2176.         }
  2177.         else if (!blkcnt)
  2178.             blkcnt++;
  2179.  
  2180.         for (i=blkcnt;--i>=0;)
  2181.             *p++=c;
  2182.         *p='\0';
  2183.  
  2184.         if (fname)
  2185.             sprintf(buf,"%s\r\n %s :    %s\r %s :    ",fname,s,pind,s);
  2186.         else
  2187.             sprintf(buf," %s :    %s\r %s :    ",s,pind,s);
  2188.         print(buf,0);
  2189.     }
  2190.     else if (flg_n==1)
  2191.     {
  2192.         if (fname)
  2193.             print(fname,1);
  2194.     }
  2195.     else if (flg_n==2)
  2196.     {
  2197.         memcpy(_proc_str+2,s,8);
  2198.         _proc_str[20]=_proc_str[25]=_frozen_str[13];
  2199.  
  2200.         if (fname)
  2201.         {
  2202.             uchar ind[40];
  2203.  
  2204.             strcpy(stpcpy(ind,"%s\r\n"),_proc_str+1);
  2205.             sprintf(buf,ind,fname,0,0l,len);
  2206.         }
  2207.         else
  2208.             sprintf(buf,_proc_str+1,0,0l,len);
  2209.         print(buf,0);
  2210.     }
  2211.     else if (flg_n==3)
  2212.     {
  2213.         if (fname)
  2214.             sprintf(buf,"%s\r\n %s:   -\b",fname,s);
  2215.         else
  2216.             sprintf(buf," %s:   -\b",s);
  2217.         print(buf,0);
  2218.         RotInd=1;
  2219.     }
  2220. #ifdef __SHELL__
  2221.     else if (flg_n==4)
  2222.         DialIndicator(0);
  2223. #endif
  2224. }
  2225.  
  2226. void MakeBuffers(void)
  2227. {
  2228.     register long buf,len=0;
  2229.  
  2230.     if (ebuf==NULL)
  2231.     {
  2232.         if (cmdupdate && !flg_u && FlgMethod==5)
  2233.         {
  2234.             if ((buf=(long) Malloc(ENCODE5))!=0L)
  2235.             {
  2236.                 ebuf=(uchar *) buf;
  2237.                 buf=(buf+=63) & (~15L);
  2238.  
  2239.                 memset(ebuf,0,ENCODE5);
  2240.  
  2241.                 text=(uchar *) buf;
  2242.                 level=(uint *) (buf+=TEXT);
  2243.                 childcount=&level[1];
  2244.                 position=(short *) (buf+=LEVEL);
  2245.                 parent=(short *) (buf+=POSITION);
  2246.                 prev=(short *) (buf+=PARENT);
  2247.                 next=(short *) (buf+=PREV);
  2248.             }
  2249.             else
  2250.                 error(MEMOVRERR,NULL,SUCCS);
  2251.         }
  2252.         else if (FlgMethod!=5 || !cmdupdate)
  2253.         {
  2254.             if ((buf=(long) Malloc(ENCODE))!=0L)
  2255.             {
  2256.                 ebuf=(uchar *) buf;
  2257.                 buf=(buf+=63) & (~15L);
  2258.  
  2259.                 memset(ebuf,0,ENCODE);
  2260.  
  2261.                 lson=(int *) buf;
  2262.                 rson=(int *) (buf+=LSON);
  2263.                 dad=(int *) (buf+=RSON);
  2264.             }
  2265.             else
  2266.                 error(MEMOVRERR,NULL,SUCCS);
  2267.         }
  2268.     }
  2269.  
  2270.     if (!flg_L)
  2271.     {
  2272.         len=((long) Malloc(-1L)/6) & (~8191l);
  2273.         if (len>MAXBUFFER)
  2274.             len=MAXBUFFER;
  2275.     }
  2276.     else if (flg_L==2)
  2277.     {
  2278.     #ifdef __SHELL__
  2279.         if (shell)
  2280.             len=(((long) Malloc(-1L)-120000L-alert_buf)/3) & (~8191l);
  2281.         else
  2282.     #endif
  2283.             len=(((long) Malloc(-1L)-120000L)/3) & (~8191l);
  2284.         if (len>MAXBUFFERL2)
  2285.             len=MAXBUFFERL2;
  2286.     }
  2287.  
  2288.     if (len<=BUFFERSIZ || (buf=(long) Malloc(((len+=128)*3)+128))==0L)
  2289.     {
  2290.         buf=(long) buffer;
  2291.         len=BUFFERSIZ+128;
  2292.     }
  2293.     else
  2294.         bbuf=(uchar *) buf;
  2295.  
  2296.     buffer_gen=(uchar *) ((buf+16) & (~15l));
  2297.     buffer_1=buffer_gen+len;
  2298.     buffer_3=buffer_1+len;
  2299.     bsize=len-128;
  2300. }
  2301.  
  2302. void freeze(uchar *p,int attr,int file,int Case)
  2303. {
  2304.     register int unpck=flg_u;
  2305.     register long arcpos;
  2306.  
  2307.     crc=ship=0;
  2308.  
  2309.     if (!unpck && flg_U && !flg_5 && !compress && chk_wild(get_fname(p),unpack,0,Case))
  2310.         unpck=SUCCS;
  2311.  
  2312.     if (flg_t && FTimeToULong(&arcstamp)<FTimeToULong(&Hdr2.Ftime))
  2313.         arcstamp=Hdr2.Ftime;
  2314.  
  2315.     if (file>0)
  2316.     {
  2317.         if (attr & FA_DIR)
  2318.             sprintf(print_buf,"(%d/%d): %s: Directory",file,Nfile,p);
  2319.         else
  2320.             sprintf(print_buf,"(%d/%d): %s",file,Nfile,p);
  2321.     }
  2322.     else if (attr & FA_DIR)
  2323.         sprintf(print_buf,"%s: Directory",p);
  2324.     else
  2325.         strcpy(print_buf,p);
  2326.  
  2327.     infname=p;
  2328.  
  2329.     if (flg_e)
  2330.     {
  2331.         Print(1);
  2332.         get_comment(stdin);
  2333.         blkdisp(Hdr2.OrgSiz,(unpck || (attr & FA_DIR)) ? "Storing " : "Freezing",NULL,NULL);
  2334.     }
  2335.     else
  2336.         blkdisp(Hdr2.OrgSiz,(unpck || (attr & FA_DIR)) ? "Storing " : "Freezing",print_buf,NULL);
  2337.  
  2338.     if (attr & FA_DIR)
  2339.     {
  2340.         Hdr2.PacSiz=Hdr2.OrgSiz=0;
  2341.         wthdr(&Hdr2,SUCCS,SUCCS);
  2342.         arcpos0=arcpos1;
  2343.         ProcInd();
  2344.     }
  2345.     else
  2346.     {
  2347.         if (!unpck || cmd!='C')
  2348.             wthdr(&Hdr2,SUCCS,unpck);
  2349.  
  2350.         origsize=textsize=Hdr2.OrgSiz;
  2351.         codesize=compsize=0;
  2352.  
  2353.         key=key_word;
  2354.         if (unpck)
  2355.             codesize=textsize+1;
  2356.         else if (!method)
  2357.             EncodeOld();
  2358.         else if (method==1)
  2359.         {
  2360.             ProcInd();
  2361.             memset(hfreq,0,(long) (&text_buf[16384]-(uchar *) hfreq));
  2362.             match_length=match_position=0;
  2363.             Encode();
  2364.         }
  2365.         else if (method==5)
  2366.         {
  2367.             init_encode5();
  2368.             encode5();
  2369.             codesize=compsize;
  2370.         }
  2371.  
  2372.  
  2373.         if (cmd=='C' && ((origsize+min_len-1)/min_len)<=((codesize+header_len+min_len-1)/min_len))
  2374.         {
  2375.             flg_unpacked=1;
  2376.  
  2377.             while ((long) origsize>0)
  2378.                 {
  2379.                     ProcInd();
  2380.                     origsize-=blocksize;
  2381.                 }
  2382.  
  2383.             Hdr2.PacSiz=Hdr2.OrgSiz;
  2384.             goto _freeze_end;
  2385.         }
  2386.         else if (!compress && codesize>=origsize)
  2387.         {
  2388.             flg_unpacked=1;
  2389.  
  2390.             arcpos=arcpos1+Hdr2.OrgSiz;
  2391.             Hdr2.PacSiz=Hdr2.OrgSiz;
  2392.  
  2393.             if (flg_4)
  2394.                 memcpy(Hdr2.HeadID,"-lz4-",5);
  2395.             else
  2396.                 memcpy(Hdr2.HeadID,"-lh0-",5);
  2397.  
  2398.             if (!unpck)
  2399.             {
  2400.                 if (buffered)
  2401.                 {
  2402.                     outrec.ptr=buffer_last;
  2403.                     outrec.cnt=buffer_cnt;
  2404.                 }
  2405.                 else
  2406.                 {
  2407.                     OpenOut(&outrec,buffer_gen);
  2408.                     Fseek(arcpos1,file2,SEEK_SET);
  2409.                 }
  2410.  
  2411.                 fseek(file3,0l,SEEK_SET);
  2412.             }
  2413.  
  2414.             copyfile(file3,NULL,backup2,Hdr2.OrgSiz,1,1);
  2415.         }
  2416.         else
  2417.         {
  2418.             arcpos=arcpos1+codesize;
  2419.             Hdr2.PacSiz=codesize;
  2420.             flg_unpacked=0;
  2421.         }
  2422.  
  2423.         wthdr(&Hdr2,FAULT,FAULT);
  2424.         arcpos0=arcpos;
  2425.     }
  2426.  
  2427.     _freeze_end:
  2428.  
  2429. #ifdef __SHELL__
  2430.     if (shell)
  2431.         FrozenMsg(flg_unpacked || (attr & FA_DIR));
  2432.     else
  2433. #endif
  2434.     if (flg_n!=1)
  2435.     {
  2436.         memcpy(_frozen_str+2,(flg_unpacked || (attr & FA_DIR)) ? "Stored:   " : "Frozen:   ",10);
  2437.         sprintf(print_buf,_frozen_str,Hdr2.OrgSiz,Hdr2.PacSiz,ratio(Hdr2.PacSiz,Hdr2.OrgSiz)/10);
  2438.         Print(1);
  2439.     }
  2440.  
  2441.     *comment='\0';
  2442. }
  2443.  
  2444. void get_comment(FILE *f)
  2445. {
  2446.     register int len;
  2447.     register uchar *input=comment,*q;
  2448.  
  2449.     if (f==stdin)
  2450.         print(M_COMMENT,1);
  2451.  
  2452.     while (fgets(input,255,f))
  2453.     {
  2454.         if ((q=strchr(input,'\r'))!=NULL || (q=strchr(input,'\n'))!=NULL)
  2455.             *q='\0';
  2456.  
  2457.         if ((len=(int) strlen(input))>0 || f!=stdin)
  2458.         {
  2459.             input+=len;
  2460.             if (!flg_s)
  2461.                 *input++='\r';
  2462.             *input++='\n';
  2463.  
  2464.             if ((int) (input-comment)>=MAXCOMMENT)
  2465.                 break;
  2466.         }
  2467.         else
  2468.             break;
  2469.     }
  2470.  
  2471.     if (input>comment)
  2472.     {
  2473.         comment[MAXCOMMENT-1]='\0';
  2474.  
  2475.         if (flg_s)
  2476.             input[-1]='\0';
  2477.         else
  2478.             input[-2]='\0';
  2479.     }
  2480.     else
  2481.         *comment='\0';
  2482. }
  2483.  
  2484. void archive_comment(void)
  2485. {
  2486. #ifdef __SHELL__
  2487.     if (shell)
  2488.         strcpy(comment,arc_comment);
  2489.     else
  2490. #endif
  2491.     if (com_name)
  2492.     {
  2493.         register FILE *f;
  2494.  
  2495.         if ((f=fopen(com_name,"r"))!=NULL)
  2496.         {
  2497.             get_comment(f);
  2498.             fclose(f);
  2499.         }
  2500.     }
  2501.     else
  2502.         get_comment(stdin);
  2503.  
  2504.     if (*comment)
  2505.     {
  2506.         arcpos0=(long) stpcpy(stpcpy(outrec.ptr,COM_ID),comment) - (long) outrec.ptr +1l;
  2507.         outrec.ptr+=arcpos0;
  2508.         outrec.cnt-=arcpos0;
  2509.         *comment='\0';
  2510.     }
  2511. }
  2512.  
  2513. #ifdef __SHELL__
  2514. void free_commem(void)
  2515. {
  2516.     if (shell && cmd_found && (last_buf->flag & FA_COMALLOC))
  2517.         free(last_buf->comment);
  2518. }
  2519. #endif
  2520.  
  2521. void copyold(void)
  2522. {
  2523.     infname=arcname;
  2524.     if (flg_t && FTimeToULong(&arcstamp)<FTimeToULong(&Hdr1.Ftime))
  2525.         arcstamp=Hdr1.Ftime;
  2526.     fseek(file1,lastarcpos,SEEK_SET);
  2527.     copyfile(file1,NULL,backup2,lastarclen,0,1);
  2528.     arcpos0+=lastarclen;
  2529. #ifdef __SHELL__
  2530.     free_commem();
  2531. #endif
  2532. }
  2533.  
  2534. int execappend(void)
  2535. {
  2536.     register filebuf *f0;
  2537.     register uchar *q;
  2538.     int update,in_arc,cnt=0,old=0,file=1;
  2539. #ifdef __SHELL__
  2540.     int found;
  2541. #endif
  2542.  
  2543.     f0=(filebuf *) fbuf;
  2544.     in_arc=(file1) ? gethdr(file1,&Hdr1) : FAULT;
  2545.  
  2546.     for (;;)
  2547.     {
  2548.         #ifdef __SHELL__
  2549.         update=found=FAULT;
  2550.         #else
  2551.         update=FAULT;
  2552.         #endif
  2553.  
  2554.         if (in_arc)
  2555.         {
  2556.             f0=(filebuf *) fbuf;
  2557.             q=get_fname(matchfilename);
  2558.  
  2559.         #ifdef __SHELL__
  2560.             if (!stop)
  2561.         #endif
  2562.             while ((f0=f0->next)!=NULL)
  2563.             {
  2564.                 if (!(f0->flag & FA_DONE) && fnamecmp((uchar *) f0+f0->fpos,q,f0->Case)==0)
  2565.                 {
  2566.                     if (flg_I)
  2567.                     {
  2568.                         strcpy(stpcpy(inclpath,incldir),(uchar *) f0+f0->cpos);
  2569.                         if (!flg_S && f0->Case==_PC_CASECONV)
  2570.                             strcnv(inclpath,SUCCS);
  2571.                     }
  2572.  
  2573.                     if (fnamecmp((flg_I) ? inclpath : (uchar *) f0+f0->cpos,matchfilename,f0->Case)==0)
  2574.                     {
  2575.                     #ifdef __SHELL__
  2576.                         found=SUCCS;
  2577.                     #endif
  2578.                         if (!flg_A)
  2579.                             update=SUCCS;
  2580.                         f0->flag|=FA_DONE;
  2581.                         break;
  2582.                     }
  2583.                 }
  2584.             }
  2585.         }
  2586.         else
  2587.         {
  2588.         #ifdef __SHELL__
  2589.             if (stop)
  2590.                 break;
  2591.         #endif
  2592.             while ((f0=f0->next)!=NULL)
  2593.             {
  2594.                 if (!(f0->flag & FA_DONE))
  2595.                 {
  2596.                     if (flg_I)
  2597.                     {
  2598.                         strcpy(stpcpy(inclpath,incldir),(uchar *) f0+f0->cpos);
  2599.                         if (!flg_S && f0->Case==_PC_CASECONV)
  2600.                             strcnv(inclpath,SUCCS);
  2601.                     }
  2602.  
  2603.                     f0->flag|=FA_DONE;
  2604.                     update=SUCCS;
  2605.                     break;
  2606.                 }
  2607.             }
  2608.  
  2609.             if (!f0)
  2610.                 break;
  2611.         }
  2612.  
  2613.     #ifdef __SHELL__
  2614.         if (shell && (update || found))
  2615.         {
  2616.             infname=f0->dir;
  2617.             Hdr2.OrgSiz=f0->unpacked;
  2618.             Hdr2.Attr=f0->attr;
  2619.         }
  2620.     #endif
  2621.  
  2622.         if (update && (!in_arc || flg_c || (FTimeToULong(&Hdr1.Ftime)<FTimeToULong(&f0->time))))
  2623.         {
  2624.             if (f0->attr & FA_DIR)
  2625.                 file3=NULL;
  2626.             else if ((file3=e_fopen(f0->dir,buffer_3,"rb",RDERR,FAULT))==NULL)
  2627.             {
  2628.             #ifdef __SHELL__
  2629.                 if (shell)
  2630.                     DialIndicator(1);
  2631.             #endif
  2632.                 goto _skip_file;
  2633.             }
  2634.  
  2635.             sethdr((flg_I) ? inclpath : (uchar *) f0+f0->cpos,f0->attr,&f0->time,&Hdr2,SUCCS);
  2636.             freeze(f0->dir,f0->attr,file,f0->Case);
  2637.             close_file(file3);
  2638.             cnt++;
  2639.  
  2640.             if (in_arc)
  2641.                 sseek(file1,nextarcpos,nextoffset);
  2642.         }
  2643.         else
  2644.         {
  2645.             if (old!=file && file<=Nfile)
  2646.             {
  2647.             #ifdef __SHELL__
  2648.                 if (shell)
  2649.                 {
  2650.                     if (found)
  2651.                         skip(infname,(flg_A) ? "File already exists" : "New or same file exists",0);
  2652.                 }
  2653.                 else
  2654.             #endif
  2655.                 {
  2656.                     sprintf(print_buf,"(%d/%d):\r",file,Nfile);
  2657.                     Print(0);
  2658.                     old=file;
  2659.                 }
  2660.             }
  2661.  
  2662.             _skip_file:
  2663.             if (in_arc)
  2664.             {
  2665.                 if (flg_D && !found)
  2666.                     sseek(file1,nextarcpos,nextoffset);
  2667.                 else
  2668.                     copyold();
  2669.             }
  2670.         }
  2671.  
  2672.         if (in_arc && (in_arc=gethdr(file1,&Hdr1))==FAULT)
  2673.             f0=(filebuf *) fbuf;
  2674.  
  2675.         if (update)
  2676.             file++;
  2677.     }
  2678.  
  2679.     return(cnt);
  2680. }
  2681.  
  2682. void delfile(void)
  2683. {
  2684.     register int attr,new_attr;
  2685.     register filebuf *f0;
  2686.  
  2687.     if (!fbuf || !(flg_d || flg_backup))
  2688.         return;
  2689.  
  2690. #ifdef __SHELL__
  2691.     if (shell)
  2692.         SetMsg((flg_d) ? "Deleting original files..." : "Clearing archiv-bits...");
  2693.     else
  2694. #endif
  2695.     #if GERMAN
  2696.         print((flg_d) ? "Lösche Original-Dateien..." : "Lösche Archiv-Bits...",1);
  2697.     #else
  2698.         print((flg_d) ? "Deleting original files..." : "Clearing archiv-bits...",1);
  2699.     #endif
  2700.  
  2701.     f0=(filebuf *) fbuf;
  2702.     while ((f0=f0->next)!=NULL)
  2703.     {
  2704.         attr = f0->attr;
  2705.         if (!(attr & FA_DIR))
  2706.         { 
  2707.             if (flg_d)
  2708.                 fdelete(f0->dir,attr);
  2709.             else
  2710.             {
  2711.                 new_attr=attr & (~FA_CHANGED);
  2712.                 if (attr!=new_attr)
  2713.                     Fattrib(f0->dir,1,(oldtos) ? new_attr^FA_CHANGED : new_attr);
  2714.             }
  2715.         }
  2716.     }
  2717. }
  2718.  
  2719. int search_lzh(FILE *input,int mode)
  2720. {
  2721.     register long len,pos;
  2722.  
  2723.     if (mode<0)
  2724.     {
  2725.         fflush(input);
  2726.         pos=lastarcpos+MINHDR;
  2727.         fseek(input,pos,SEEK_SET);
  2728.     }
  2729.     else
  2730.         arcpos0=arcpos1=nextarcpos=lastarcpos=pos=0;
  2731.  
  2732.     _cont_search:
  2733. #ifdef __SHELL__
  2734.     if (command && mode>=0)
  2735.     {
  2736.         register filebuf *f=arc_buf;
  2737.  
  2738.         searchpos=-1;
  2739.         while ((f=f->next)!=NULL)
  2740.             if ((f->flag & (FA_SELECTED|FA_EDITED)) && f->seek_pos>=0)
  2741.             {
  2742.                 next_buf=f;
  2743.                 searchpos=f->seek_pos;
  2744.  
  2745.                 if (mode==1)
  2746.                 {
  2747.                     fseek(input,nextarcpos=searchpos,SEEK_SET);
  2748.                     return(1);
  2749.                 }
  2750.                 else
  2751.                     break;
  2752.             }
  2753.     
  2754.     }
  2755. #endif
  2756.  
  2757.     if (mode>=0)
  2758.         sfx=0;
  2759.  
  2760.     if ((len=Fread(fileno(input),1024l*10,text_buf))>5)
  2761.     {
  2762.         register uchar *ptr=text_buf,*last=ptr+len-5,c,s='-';
  2763.  
  2764.         if (mode>=0)
  2765.         {
  2766.             arcpos0=Fseek(0l,fileno(input),SEEK_CUR)-len;
  2767.             arclen=Fseek(0l,fileno(input),SEEK_END);
  2768.             Fseek(arcpos0,fileno(input),SEEK_SET);
  2769.             arcpos0=0;
  2770.         }
  2771.  
  2772.         for (;ptr<last;ptr++)
  2773.             if (*ptr==s && ptr[4]==s)
  2774.             {
  2775.                 c=ptr[1];
  2776.                 if (c=='l' || c=='L' || c=='a' || c=='A')
  2777.                 {
  2778.                     if (ptr>=(text_buf+2))
  2779.                     {
  2780.                         if (flg_z && (mode==0 || mode==2))
  2781.                             archive_comment();
  2782.  
  2783.                         fseek(input,nextarcpos=pos+((ptr-2)-text_buf),SEEK_SET);
  2784.                         return(1);
  2785.                     }
  2786.                 }
  2787.                 else if (c=='c' && ptr[2]=='o' && ptr[3]=='m' && mode>=0)
  2788.                 {
  2789.                     if (!flg_z && (mode==0 || mode==2))
  2790.                     {
  2791.                         arcpos0=(long) stpcpy(outrec.ptr,ptr) - (long) outrec.ptr + 1l;
  2792.                         outrec.ptr+=arcpos0;
  2793.                         outrec.cnt-=arcpos0;
  2794.                     }
  2795.  
  2796.                     strncpy(comment,ptr+=5,MAXCOMMENT);
  2797.                     convert_comment();
  2798.  
  2799.                     if (mode>0)
  2800.                     {
  2801.                         sprintf(print_buf,"\r\n%s\r\n\r\n",comment);
  2802.                         pager_print(0);
  2803.  
  2804.                         if (!pager && (cmd!='P' || flg_v<2))
  2805.                             wait_for_key(1);
  2806.                     }
  2807.  
  2808.                     ptr+=strlen(ptr);
  2809.                 }
  2810.             }
  2811.             else if (*ptr=='S' && ptr[1]=='F' && ptr[2]=='X')
  2812.             {
  2813.                 ptr+=3;
  2814.                 sfx++;
  2815.             }
  2816.     }
  2817.  
  2818.     if (mode>=0)
  2819.     {
  2820.         error(NOFILEERR,arcname,(mode>0) ? 128 : SUCCS);
  2821.         if (mode>0 && len<5)
  2822.             return (-1);
  2823.     }
  2824.     else if (len>5 && (pos+=len)<arclen)
  2825.     {
  2826.         Fseek(pos,fileno(input),SEEK_SET);
  2827.         goto _cont_search;
  2828.     }
  2829.  
  2830.     return(0);
  2831. }
  2832.  
  2833. int openarc1(long size,uchar *buffer)
  2834. {
  2835.     int search;
  2836.  
  2837.     if ((file1=e_fopen(infname=arcname,NULL,"rb",NOARCERR,FAULT))!=NULL)
  2838.     {
  2839.         if ((search=search_lzh(file1,1))>0)
  2840.         {
  2841.             if (buffer!=NULL)
  2842.                 setvbuf(file1,buffer,_IOFBF,size);
  2843.             INIT_TIMER;
  2844.         }
  2845.         else
  2846.             close_file(file1);
  2847.         return(search);
  2848.     }
  2849.     else
  2850.         return(-2);
  2851. }
  2852.  
  2853. void get_tempname(uchar *path)
  2854. {
  2855.     register uchar *ext;
  2856.  
  2857.     strcat(path,TEMPFILE);
  2858.     ext=path+strlen(path);
  2859.  
  2860.     do
  2861.     {
  2862.         sprintf(ext,"%X",temp());
  2863.     } while (Attrib(path)>=0);
  2864. }
  2865.  
  2866. void openbackup1(void)
  2867. {
  2868.     back_1++;
  2869.  
  2870.     backpath(strcpy(backup1,arcname));
  2871.     get_tempname(backup1);
  2872.  
  2873.     if (Frename(0,infname=arcname,backup1))
  2874.         error(RENAMEERR,arcname,SUCCS);
  2875.  
  2876.     file1=e_fopen(backup1,buffer_1,"rb",WTERR,SUCCS);
  2877.     arclen=Fseek(0l,fileno(file1),SEEK_END);
  2878.     Fseek(0l,fileno(file1),SEEK_SET);
  2879.     found=0;
  2880. }
  2881.  
  2882. void openbackup2(void)
  2883. {
  2884.     back_2++;
  2885.  
  2886.     if (Device)
  2887.         strcpy(backup2,arcname);
  2888.     else
  2889.     {
  2890.         if (flg_w)
  2891.             strcpy(backup2,workdir);
  2892.         else
  2893.             backpath(strcpy(backup2,arcname));
  2894.         get_tempname(backup2);
  2895.     }
  2896.  
  2897.     arcpos0=errno=0;
  2898.     file2=creat(backup2,0666);
  2899.     if (errno==EACCES)
  2900.         error(RDONLY,backup2,SUCCS);
  2901.     else if (errno)
  2902.         error(MKTMPERR,backup2,SUCCS);
  2903.  
  2904.     *((long *) &arcstamp)=0l;
  2905.  
  2906.     outfile=file2;
  2907.     OpenOut(&outrec,buffer_gen);
  2908.     INIT_TIMER;
  2909. }
  2910.  
  2911. static void set_time(int handle)
  2912. {
  2913.     if (flg_t)
  2914.         Fdatime(&arcstamp,handle,1);
  2915. #ifdef __SHELL__
  2916.     else if (shell && ainf_changed)
  2917.         Fdatime(&arc_time,handle,1);
  2918. #endif
  2919. }
  2920.  
  2921. void endofupdate(int cnt)
  2922. {
  2923.     if (file1)
  2924.     {
  2925.         set_time(fileno(file1));
  2926.         fclose(file1);
  2927.     }
  2928.  
  2929.     tstpat();
  2930.  
  2931. #ifdef __SHELL__
  2932.     if (cnt || ainf_changed)
  2933. #else
  2934.     if (cnt)
  2935. #endif
  2936.     {
  2937.         if (file1)
  2938.         {
  2939.             if (flg_B)
  2940.             {
  2941.                 register uchar bakname[MAXPATH],*f;
  2942.  
  2943.                 strcpy(bakname,arcname);
  2944.                 if ((f=strrchr(get_fname(bakname),'.'))!=NULL && (arc_ext(f) || f[1]=='\0'))
  2945.                     strcpy(f,".BAK");
  2946.                 else
  2947.                     strcat(bakname,".BAK");
  2948.                 Fdelete(bakname);
  2949.                 rename(backup1,bakname);
  2950.             }
  2951.             else
  2952.                 Fdelete(backup1);
  2953.             file1=NULL;
  2954.         }
  2955.  
  2956.         if (arcpos0)
  2957.         {
  2958.             buf_putc(0);
  2959.             ShipOut();
  2960.  
  2961.             if (!Device)
  2962.             {
  2963.                 register int flag = SUCCS;
  2964.  
  2965.                 set_time(file2);
  2966.                 if (close(file2))
  2967.                     error(WTERR,backup2,SUCCS);
  2968.                 file2=0;
  2969.  
  2970.                 if (flg_w==0 || drive(arcname,NULL)==drive(backup2,NULL))
  2971.                     flag=rename(backup2,arcname);
  2972.  
  2973.                 if (flag)
  2974.                 {
  2975.                 #ifdef __SHELL__
  2976.                     if (shell)
  2977.                         SetMsg("Copying temp to archive...");
  2978.                     else
  2979.                 #endif
  2980.                     #if GERMAN
  2981.                         print("Kopiere temporäres Archiv...",1);
  2982.                     #else
  2983.                         print("Copying temp to archive...",1);
  2984.                     #endif
  2985.  
  2986.                     file1=e_fopen(arcname,buffer_1,"wb",MKFILEERR,SUCCS);
  2987.                     file3=e_fopen(backup2,buffer_3,"rb",0,FAULT);
  2988.  
  2989.                     copying++;
  2990.  
  2991.                     copyfile(file3,file1,arcname,arcpos0+1,0,0);
  2992.                     if (fflush(file1))
  2993.                         error(WTERR,arcname,SUCCS);
  2994.  
  2995.                     set_time(fileno(file1));
  2996.                     if (fclose(file1))
  2997.                         error(WTERR,backup2,SUCCS);
  2998.  
  2999.                     copying=0;
  3000.  
  3001.                     close_file(file3);
  3002.                     Fdelete(backup2);
  3003.                 }
  3004.             }
  3005.             else
  3006.                 close(file2);
  3007.         }
  3008.         else
  3009.         {
  3010.             close(file2);
  3011.  
  3012.             if (!Device)
  3013.                 Fdelete(backup2);
  3014.         }
  3015.     }
  3016.     else
  3017.     {
  3018.         close(file2);
  3019.  
  3020.         if (!Device)
  3021.         {
  3022.             Fdelete(backup2);
  3023.             rename(backup1,arcname);
  3024.         }
  3025.     }
  3026.  
  3027.     file1=NULL;
  3028.     file2=0;
  3029. }
  3030.  
  3031. void append(void)
  3032. {
  3033.     register int cnt;
  3034.  
  3035.     if (Device)
  3036.         file1=NULL;
  3037.     else if ((file1=fopen(arcname,"rb"))!=NULL)
  3038.     {
  3039.         close_file(file1);
  3040.         openbackup1();
  3041.     }
  3042.  
  3043.     mklist();
  3044.     if (!Nfile)
  3045.         error(NOFILEERR,NULL,SUCCS);
  3046.  
  3047.     if (flg_u && !flg_n)
  3048.         flg_n++;
  3049.  
  3050.     if (file1)
  3051.         message("Updating archive",arcname);
  3052.     else if (Device)
  3053.         message("Freeze/Store to",arcname);
  3054.     else
  3055.         message("Creating archive",arcname);
  3056.  
  3057.     openbackup2();
  3058.     if (file1)
  3059.         search_lzh(file1,0);
  3060.     else if (flg_z)
  3061.         archive_comment();
  3062.  
  3063.     cnt=execappend();
  3064.     endofupdate(cnt);
  3065.     delfile();
  3066. }
  3067.  
  3068. void pack_afx(void)
  3069. {
  3070.     register filebuf *f0;
  3071.     register int file=1,tst;
  3072.     register uchar *x;
  3073.  
  3074.     flg_x=3;
  3075.     old_afx=afxonoff(0L);
  3076.  
  3077.     mklist();
  3078.     if (!Nfile)
  3079.         error(NOFILEERR,NULL,SUCCS);
  3080.  
  3081.     FlgMethod=flg_x=0;
  3082.     f0=(filebuf *) fbuf;
  3083.  
  3084.     while ((f0=f0->next)!=NULL)
  3085.     {
  3086.         if ((x=strrchr(get_fname(f0->dir),'.'))!=NULL && (!stricmp(x,".O") || !stricmp(x,".LIB")))
  3087.             obj=SUCCS;
  3088.         else
  3089.             obj=FAULT;
  3090.  
  3091.         if ((tst=test_afx(f0->dir))==0)
  3092.         {
  3093.             if ((file3=e_fopen(f0->dir,buffer_3,"rb",RDERR,FAULT))!=NULL)
  3094.             {
  3095.                 strcpy(backpath(strcpy(backup2,f0->dir)),"__temp__.lzs");
  3096.  
  3097.                 errno=0;
  3098.                 file2=creat(backup2,0666);
  3099.                 if (errno==0)
  3100.                 {
  3101.                     outfile=file2;
  3102.                     OpenOut(&outrec,buffer_gen);
  3103.  
  3104.                     arcpos0=buffered=ship=0;
  3105.                     min_len=f0->cluster;
  3106.                     sethdr((uchar *) f0+f0->fpos,f0->attr,&f0->time,&Hdr2,SUCCS);
  3107.                     freeze(f0->dir,f0->attr,file,f0->Case);
  3108.  
  3109.                     if (!flg_unpacked)
  3110.                     {
  3111.                         if (buffered)
  3112.                             ShipOut();
  3113.                         Fdatime(&f0->time,file2,1);
  3114.                     }
  3115.  
  3116.                     close(file2);
  3117.                     file2=0;
  3118.  
  3119.                     close_file(file3);
  3120.  
  3121.                     if (!flg_unpacked)
  3122.                     {
  3123.                         register int attr=f0->attr;
  3124.  
  3125.                         fdelete(f0->dir,attr);
  3126.  
  3127.                         if (rename(backup2,f0->dir))
  3128.                             error(RENAMEERR,f0->dir,FAULT);
  3129.                         else
  3130.                         {
  3131.                             if (flg_backup)
  3132.                                 attr &= ~FA_CHANGED;
  3133.                             Fattrib(f0->dir,1,(oldtos) ? attr^FA_CHANGED : attr);
  3134.                         }
  3135.                     }
  3136.                     else
  3137.                         Fdelete(backup2);
  3138.                 }
  3139.                 else
  3140.                 {
  3141.                     close_file(file3);
  3142.  
  3143.                     if (errno==EACCES)
  3144.                         error(RDONLY,backup2,FAULT);
  3145.                     else if (errno)
  3146.                         error(MKTMPERR,backup2,FAULT);
  3147.                 }
  3148.             }
  3149.         }
  3150.         else
  3151.         {
  3152.             register uchar *m;
  3153.  
  3154.             switch (tst)
  3155.             {
  3156.             case 1:
  3157.             #if GERMAN
  3158.                 m="Datei bereits in AFX-Format";
  3159.             #else
  3160.                 m="Already in AFX-format";
  3161.             #endif
  3162.                 break;
  3163.             case 2:
  3164.             #if GERMAN
  3165.                 m="Datei bereits in LHarc-Format";
  3166.             #else
  3167.                 m="Already in LHarc-format";
  3168.             #endif
  3169.                 break;
  3170.             case 3:
  3171.             #if GERMAN
  3172.                 m="Programm-Datei";
  3173.             #else
  3174.                 m="Program-file";
  3175.             #endif
  3176.                 break;
  3177.             default:
  3178.             #if GERMAN
  3179.                 m="Kann Datei nicht lesen";
  3180.             #else
  3181.                 m="Read-Error";
  3182.             #endif
  3183.             }
  3184.  
  3185.             sprintf(print_buf,"(%d/%d): %s\r\n %s",file,Nfile,f0->dir,m);
  3186.             Print(1);
  3187.         }
  3188.         file++;
  3189.     }
  3190.  
  3191.     if (old_afx)
  3192.     {
  3193.         afxonoff(old_afx);
  3194.         old_afx=0;
  3195.     }
  3196. }
  3197.  
  3198. void make_fullpath(uchar *path)
  3199. {
  3200.     register uchar *p=stpcpy(path,basedir);
  3201.  
  3202.     if (flg_x)
  3203.     {
  3204.         if (dosfilename[0]=='\\')
  3205.         {
  3206.             p=path;
  3207.             if (*p && p[1]==':')
  3208.             {
  3209.                 if (__mint && toupper(*p)=='U' && p[2]=='\\' && p[3] && p[4]=='\\')
  3210.                     p+=4;
  3211.                 else
  3212.                     p+=2;
  3213.             }
  3214.         }
  3215.  
  3216.         strcpy(p,dosfilename);
  3217.     }
  3218.     else
  3219.         strcpy(p,get_fname(dosfilename));
  3220. }
  3221.  
  3222. void freshen(void)
  3223. {
  3224.     _DOSTIME time;
  3225.     register uchar path[MAXPATH];
  3226.     register long ok;
  3227.     register int cnt=0,attr;
  3228.  
  3229.     Case=_PC_CASECONV;
  3230.  
  3231.     openbackup1();
  3232.     message("Freshening archive",arcname);
  3233.  
  3234.     openbackup2();
  3235.     search_lzh(file1,0);
  3236.  
  3237.     while (gethdr(file1,&Hdr1))
  3238.     {
  3239.     #ifdef __SHELL__
  3240.         if (command==4)
  3241.             copyold();
  3242.         else
  3243.     #endif
  3244.         {
  3245.             if (matchpat(matchfilename,-1,Hdr1.Attr))
  3246.             {
  3247.                 ok=SUCCS;
  3248.                 if (!(Hdr1.Attr & FA_DIR))
  3249.                 {
  3250.                     make_fullpath(path);
  3251.                     if (__mint)
  3252.                         ok=read_attr(path,&_dta);
  3253.                     else
  3254.                         ok=Fsfirst(path,0x07);
  3255.  
  3256.                     time.time=_dta.dta_time;
  3257.                     time.date=_dta.dta_date;
  3258.                     attr=_dta.dta_attribute;
  3259.                     if (oldtos)
  3260.                         attr ^= FA_CHANGED;
  3261.     
  3262.                     if (!ok)
  3263.                     {
  3264.                         if (flg_d || flg_backup)
  3265.                             regfreshen(path,attr);
  3266.  
  3267.                         if ((flg_c || (FTimeToULong(&Hdr1.Ftime)<FTimeToULong(&time))) && (file3=fopen(path,"rb"))!=NULL)
  3268.                         {
  3269.                             sethdr(filename,attr,&time,&Hdr2,FAULT);
  3270.                             freeze(path,attr,-1,1);
  3271.                             close_file(file3);
  3272.                             cnt++;
  3273.     
  3274.                             sseek(file1,nextarcpos,nextoffset);
  3275.                             continue;
  3276.                         }
  3277.                 #ifdef __SHELL__
  3278.                         else
  3279.                             skip(filename,"New or same file exists",0);
  3280.                 #endif
  3281.                     }
  3282.                 }
  3283.             #ifdef __SHELL__
  3284.                 if (command && ok)
  3285.                     DialIndicator(1);
  3286.             #endif
  3287.             }
  3288.  
  3289.             copyold();
  3290.         }
  3291.     }
  3292.  
  3293.     endofupdate(cnt);
  3294. #ifdef __SHELL__
  3295.     if (command!=4)
  3296. #endif
  3297.         delfile();
  3298. }
  3299.  
  3300. int Attrib(uchar *p)
  3301. {
  3302.     register int ok;
  3303.  
  3304.     if (__mint)
  3305.         ok=read_attr(p,&_dta);
  3306.     else
  3307.         ok=Fsfirst(p,-1);
  3308.  
  3309.     if (!ok)
  3310.         return(_dta.dta_attribute & 0x3f);
  3311.     else
  3312.         return(0xF000);
  3313. }
  3314.  
  3315. static void skip(uchar *fname,uchar *msg,int plus)
  3316. {
  3317. #ifdef __SHELL__
  3318.     if (shell)
  3319.     {
  3320.         uchar name[MAXPATH];
  3321.  
  3322.         skipped++;
  3323.         slash(strcpy(name,fname),0);
  3324.         sprintf(print_buf,"Skipped %s: %s",get_fname(name),msg);
  3325.         DialIndicator(1);
  3326.         if (idx)
  3327.             SetMsg(print_buf);
  3328.     }
  3329.     else
  3330. #endif
  3331.     {
  3332.         sprintf(print_buf,"Skipped %s: %s",fname,msg);
  3333.         Print(1);
  3334.         skipped+=plus;
  3335.     }
  3336. }
  3337.  
  3338. int tstdir(uchar *name,int flag)
  3339. {
  3340.     register uchar path[MAXPATH],*p,yn;
  3341.     register int attr;
  3342.  
  3343.     if (!flag && flg_R && UnixFile)
  3344.     {
  3345.         sprintf(print_buf,"%s (%s):\r\n%s",name,get_fname(filename),M_ENTERNEW);
  3346.         Print(0);
  3347.         gets(path);
  3348.  
  3349.         if (path[0]!='\0')
  3350.         {
  3351.             strcpy(backpath(name),get_fname(path));
  3352.             fnamecnv(name,0);
  3353.         }
  3354.     }
  3355.  
  3356. Again:
  3357.     if (flag || flg_x)
  3358.     {
  3359.         if (flag>=0 && base>0)
  3360.             p=&name[base];
  3361.         else
  3362.         {
  3363.             p=name;
  3364.             if (*p && p[1]==':')
  3365.             {
  3366.                 p+=2;
  3367.  
  3368.                 if (__mint && toupper(p[-2])=='U' && p[0]=='\\' && p[1] && p[2]=='\\')
  3369.                     p+=2;
  3370.             }
  3371.         }
  3372.  
  3373.         if (*p=='\\')
  3374.             p++;
  3375.  
  3376.         if (flag>=0)
  3377.             yn=(flg_m>0 && flg_m<3) ? 'Y' : 'N';
  3378.         else
  3379.             yn='Y';
  3380.  
  3381.         while ((p=strchr(p,'\\'))!=NULL)
  3382.         {
  3383.             *p='\0';
  3384.             attr=Attrib(name);
  3385.             if (attr<0)
  3386.             {
  3387.                 if (yn=='N')
  3388.                 {
  3389.                     sprintf(print_buf,"%s:\r\n%s",name,M_MKDIR);
  3390.                     Print(0);
  3391.  
  3392.                     if ((yn=get_key("YNA"))=='N')
  3393.                         return(FAULT);
  3394.                     else if (yn=='A')
  3395.                     {
  3396.                         flg_m=(flg_m) ? 1 : 2;
  3397.                         yn='Y';
  3398.                     }
  3399.                 }
  3400.  
  3401.                 if (Dcreate(name))
  3402.                 {
  3403.                     error(MKDIRERR,name,(flag<0) ? SUCCS : FAULT);
  3404.                     return(FAULT);
  3405.                 }
  3406.             }
  3407.             else if (!(attr & FA_DIR))
  3408.             {
  3409.                 error(MKDIRERR,name,(flag<0) ? SUCCS : FAULT);
  3410.                 return(FAULT);
  3411.             }
  3412.             *p++='\\';
  3413.         }
  3414.     }
  3415.  
  3416.     if (!flag)
  3417.     {
  3418.         if ((attr=Attrib(name))>=0)
  3419.         {
  3420.             if ((attr & FA_DIR) && !UnixFile)
  3421.             {
  3422.                 skip(name,"Object with same name exists",0);
  3423.                 return(FAULT);
  3424.             }
  3425.             else if ((!UnixFile || (flg_m & 0x01)) && !flg_c && (((ulong) _dta.dta_date<<16)|(uint) _dta.dta_time)>=FTimeToULong(&Hdr1.Ftime))
  3426.             {
  3427.                 skip(name,"New or same file exists",0);
  3428.                 return(FAULT);
  3429.             }
  3430.         #ifdef __SHELL__
  3431.             else if (shell)
  3432.             {
  3433.                 if (!overwr_all)
  3434.                     switch (OverWrMsg(name))
  3435.                     {
  3436.                     case -1:
  3437.                         if (!stop)
  3438.                             skip(name,"New or same file exists",0);
  3439.                         return(FAULT);
  3440.                     case 0:
  3441.                         fnamecnv(name,0);
  3442.                         goto Again;
  3443.                     }
  3444.             }
  3445.         #endif
  3446.             else if ((flg_m & 0x01)==0)
  3447.             {
  3448.                 if (UnixFile)
  3449.                     sprintf(print_buf,"%s (%s):\r\n%s",name,get_fname(filename),M_OVERWT);
  3450.                 else
  3451.                     sprintf(print_buf,"%s:\r\n%s",name,M_OVERWT);
  3452.                 Print(0);
  3453.  
  3454.                 if ((yn=get_key("YNRA"))=='R')
  3455.                 {
  3456.                     print(M_ENTERNEW,0);
  3457.                     gets(path);
  3458.  
  3459.                     if (path[0]!='\0')
  3460.                     {
  3461.                         strcpy(backpath(name),get_fname(path));
  3462.                         fnamecnv(name,0);
  3463.                         goto Again;
  3464.                     }
  3465.                     else
  3466.                         return(FAULT);
  3467.                 }
  3468.                 else if (yn=='N')
  3469.                     return(FAULT);
  3470.                 else if (yn=='A')
  3471.                     flg_m=(flg_m) ? 1 : 3;
  3472.             }
  3473.  
  3474.             if (attr & FA_RDONLY)
  3475.             {
  3476.                 if (attr!=Hdr1.Attr)
  3477.                 {
  3478.                     skip(name,M_RDONLY,0);
  3479.                     return(FAULT);
  3480.                 }
  3481.                 else
  3482.                     Fattrib(name,1,attr ^ FA_RDONLY);
  3483.             }
  3484.         }
  3485.     }
  3486.  
  3487.     return(SUCCS);
  3488. }
  3489.  
  3490. int tstID(uchar *h)
  3491. {
  3492.     static uchar IDpat[7][6]={"lz4","lz5","lh0","lh1","lh5","afx","lhd"};
  3493.  
  3494.     if (h[0]!='-' || h[4]!='-')
  3495.         return(-1);
  3496.     else
  3497.     {
  3498.         register int m=6;
  3499.  
  3500.         strlwr(++h);
  3501.         while (m>=0 && memcmp(h,IDpat[m],3))
  3502.             m--;
  3503.  
  3504.         return((m==5) ? 1 : m);
  3505.     }
  3506. }
  3507.  
  3508. uchar *Trunc1File(uchar *s,uchar *d)
  3509. {
  3510.     register int l=(int) strlen(s);
  3511.     register uchar c,*t;
  3512.  
  3513.     if (_gemdos)
  3514.     {
  3515.         register i,j,k,m;
  3516.  
  3517.         for (c='.',t=&s[i=l];--i>=0;)
  3518.             if (*--t==c)
  3519.                 break;
  3520.  
  3521.         m=(i<0) ? l : i;
  3522.         for (j=k=0,t=s;j<=7;j++)
  3523.         {
  3524.             c=*t++;
  3525.             if ((i>0 && k++>i) || c=='\0' || j>=m)
  3526.                 break;
  3527.  
  3528.             if (c>32 && c!='.' && c!=':' && c!='*' && c!='?')
  3529.                 *d++=c;
  3530.             else
  3531.                 j--;
  3532.         }
  3533.  
  3534.         if (i>=0)
  3535.             for (t=&s[i],j=4;--j>=0;)
  3536.             {
  3537.                 if ((c=*t++)>32)
  3538.                 {
  3539.                     if (c!=':' && c!='*' && c!='?')
  3540.                         *d++=c;
  3541.                 }
  3542.                 else if (c=='\0')
  3543.                     break;
  3544.             }
  3545.     }
  3546.     else
  3547.     {
  3548.         strcpy(d,s);
  3549.  
  3550.         if (l<=fn_name)
  3551.             d+=l;
  3552.         else if ((t=strrchr(s,'.'))!=NULL && t>s)
  3553.         {
  3554.             l-=(int) (t-s);
  3555.             l=fn_name-l;
  3556.             if (d[l-1]=='.')
  3557.                 l--;
  3558.  
  3559.             strcpy(d+l,t);
  3560.             d+=fn_name;
  3561.         }
  3562.         else
  3563.             d+=fn_name;
  3564.     }
  3565.  
  3566.     *d='\0';
  3567.     return(d);
  3568. }
  3569.  
  3570. void TruncFile(uchar *s)
  3571. {
  3572.     uchar file[MAXPATH],dest[MAXPATH];
  3573.     register uchar *f=file,*d=dest,*s1=s,c;
  3574.  
  3575.     *d='\0';
  3576.     while ((c=*s++)!='\0')
  3577.     {
  3578.         if (c=='\\' || c==':')
  3579.         {
  3580.             *d='\0';
  3581.             f=Trunc1File(dest,f);
  3582.             *f++=c;
  3583.             *f='\0';
  3584.             d=dest;
  3585.         }
  3586.         else
  3587.             *d++=c;
  3588.     }
  3589.  
  3590.     *d='\0';
  3591.     f=Trunc1File(dest,f);
  3592.     strcpy(s1,file);
  3593. }
  3594.  
  3595. int extract(void)
  3596. {
  3597.     register uchar *p,*q;
  3598.     register int m,cnt=0,succs;
  3599.  
  3600.     sprintf(print_buf,"Extract from: %s\r\n",arcname);
  3601.     pager_print(1);
  3602.  
  3603. #ifdef __SHELL__
  3604.     if (!shell && all && exno==0)
  3605. #else
  3606.     if (all && exno==0)
  3607. #endif
  3608.         flg_d=0;
  3609.  
  3610.     if (flg_d)
  3611.     {
  3612.         flg_t = 0;
  3613.     #ifdef __SHELL__
  3614.         if (!shell)
  3615.     #endif
  3616.             flg_z=0;
  3617.         openbackup1();
  3618.         openbackup2();
  3619.         if (search_lzh(file1,2)<=0)
  3620.         {
  3621.             close_file(file1);
  3622.             close(file2);
  3623.             file2=0;
  3624.             Fdelete(backup2);
  3625.             rename(backup1,arcname);
  3626.             return(0);
  3627.         }
  3628.     }
  3629.     else if (openarc1(bsize,buffer_1)<=0)
  3630.         return(0);
  3631.  
  3632.     while (gethdr(file1,&Hdr1))
  3633.     {
  3634.         succs=FAULT;
  3635.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  3636.         {
  3637.             if (cmd=='E')
  3638.                 make_fullpath(pathname);
  3639.  
  3640.         #ifdef __SHELL__
  3641.             if (shell && Hdr1.crypted && !flg_Y)
  3642.                 set_crypt();
  3643.         #endif
  3644.  
  3645.             if ((m=tstID(Hdr1.HeadID))<0)
  3646.                 skip(filename,"Unknown method",1);
  3647.             else if (cmd=='E' && maxlen>0 && Hdr1.OrgSiz>maxlen)
  3648.                 skip(filename,"File too long",1);
  3649.             else if (cmd=='E' && !flg_a && (Hdr1.Attr & (FA_HIDDEN|FA_SYSTEM)))
  3650.                 skip(filename,"Hidden/System file",1);
  3651.             else if (Hdr1.crypted && !flg_Y)
  3652.                 skip(filename,"Encrypted file",1);
  3653.             else if (Hdr1.Attr & FA_DIR)
  3654.             {
  3655.                 if (cmd=='E' && (succs=tstdir(strcat(pathname,"\\"),1))!=0)
  3656.                 {
  3657.                     cnt++;
  3658.                     if (UnixFile)
  3659.                         sprintf(print_buf,"%s (%s): Directory",pathname,filename);
  3660.                     else
  3661.                         sprintf(print_buf,"%s: Directory",pathname);
  3662.  
  3663.                     blkdisp(0l,"Melted  ",print_buf,comment);
  3664.                     ProcInd();
  3665.  
  3666.                     if (flg_n!=1)
  3667.                         print(NULL,1);
  3668.  
  3669.                     if (flg_d)
  3670.                         message("Deleting",filename);
  3671.                 }
  3672.                 else
  3673.                     skip(filename,"Directory",0);
  3674.             }
  3675.             else if (cmd!='E' || tstdir(pathname,0))
  3676.             {
  3677.                 textsize=Hdr1.OrgSiz;
  3678.                 crypt_size=codesize=Hdr1.PacSiz;
  3679.                 key=key_word;
  3680.  
  3681.                 cnt++;
  3682.                 crc=0;
  3683.  
  3684.                 p="Melting ";
  3685.                 q="Melted ";
  3686.  
  3687.                 switch(cmd)
  3688.                 {
  3689.                 case 'E':
  3690.                     if (UnixFile)
  3691.                     {
  3692.                         sprintf(print_buf,"%s (%s)",pathname,filename);
  3693.                         blkdisp(textsize,p,print_buf,comment);
  3694.                     }
  3695.                     else
  3696.                         blkdisp(textsize,p,pathname,comment);
  3697.  
  3698.                     if ((file3=e_fopen(pathname,buffer_3,"wb",WTERR,FAULT))==NULL)
  3699.                         goto _extract_next;
  3700.                     break;
  3701.                 case 'T':
  3702.                     q="Tested ";
  3703.                     blkdisp(textsize,"Testing ",filename,comment);
  3704.                     file3=NULL;
  3705.                     break;
  3706.                 case 'P':
  3707.                     sprintf(print_buf,"<<< %s >>>\r\n\r\n",filename);
  3708.                     pager_print(0);
  3709.                     blkdisp(textsize,p,(pager) ? filename : NULL,comment);
  3710.                     break;
  3711.                 }
  3712.  
  3713.                 if (file3==stdout)
  3714.                     flg_n=1;
  3715.  
  3716.                 succs=SUCCS;
  3717.  
  3718.                 switch(m)
  3719.                 {
  3720.                 case 1:
  3721.                 case 3:
  3722.                     if (cmd=='P')
  3723.                         fflush(file3);
  3724.                     decrypt(0);
  3725.                     if (m==1)
  3726.                         DecodeOld();
  3727.                     else
  3728.                         Decode();
  3729.                     break;
  3730.                 case 4:
  3731.                     decrypt(0);
  3732.                     succs=decode_lh5(textsize,bufsize=codesize);
  3733.                 #ifdef __SHELL__
  3734.                     if (shell && !succs)
  3735.                     {
  3736.                         uchar msg[256];
  3737.  
  3738.                         strcpy(stpcpy(msg,get_fname(filename)),": Bad Table");
  3739.                         SetMsg(msg);
  3740.                     }
  3741.                 #endif
  3742.                     break;
  3743.                 default:
  3744.                     copyfile(file1,file3,pathname,Hdr1.OrgSiz,1,0);
  3745.                 }
  3746.  
  3747.                 crypt_size = -1;
  3748.  
  3749.                 if (cmd=='E')
  3750.                 {
  3751.                     if (fflush(file3))
  3752.                         error(WTERR,pathname,SUCCS);
  3753.  
  3754.                     if ((!flg_i || flg_i==3) && succs)
  3755.                         Fdatime(&Hdr1.Ftime,fileno(file3),1);
  3756.  
  3757.                     if (fclose(file3))
  3758.                         error(WTERR,pathname,SUCCS);
  3759.  
  3760.                     if (!succs)
  3761.                         Fdelete(pathname);
  3762.                     else if ((!flg_i || flg_i==2) && (Hdr1.Attr!=FA_CHANGED))
  3763.                         Fattrib(pathname,1,(oldtos) ? (Hdr1.Attr^FA_CHANGED) : Hdr1.Attr);
  3764.  
  3765.                     file3=NULL;
  3766.                 }
  3767.                 else if (cmd=='P')
  3768.                 {
  3769.                     if (file3==stdout)
  3770.                         fflush(file3);
  3771.                     strcpy(print_buf,"\r\n");
  3772.                     pager_print(0);
  3773.                 }
  3774.  
  3775.                 if (succs)
  3776.                 {
  3777.                     if (has_crc && Hdr1.crc!=crc)
  3778.                     {
  3779.                         errorlevel|=2;
  3780.                         succs=FAULT;
  3781.                         c_err++;
  3782.  
  3783.                         if (cmd=='P')
  3784.                             print(NULL,1);
  3785.  
  3786.                     #ifdef __SHELL__
  3787.                         if (shell)
  3788.                         {
  3789.                             uchar msg[256];
  3790.  
  3791.                             strcpy(stpcpy(msg,get_fname(filename)),": CRC error");
  3792.                             SetMsg(msg);
  3793.                         }
  3794.                         else
  3795.                     #endif
  3796.                         #if GERMAN
  3797.                             print("\r Prüfsummen-Fehler ",1);
  3798.                         #else
  3799.                             print("\r CRC error ",1);
  3800.                         #endif
  3801.                     }
  3802.                     else if (cmd!='P' || pager)
  3803.                     {
  3804.                         if (flg_n!=1)
  3805.                         {
  3806.                             sprintf(print_buf,"\r %s",q);
  3807.                             Print(1);
  3808.                         }
  3809.  
  3810.                         if (flg_d)
  3811.                             message("Deleting",filename);
  3812.                     }
  3813.                 }
  3814.             }
  3815.         }
  3816.  
  3817.         _extract_next:
  3818.         if (succs==FAULT && flg_d)
  3819.             copyold();
  3820.         else
  3821.         {
  3822.         #ifdef __SHELL__
  3823.             if (flg_d)
  3824.                 free_commem();
  3825.         #endif
  3826.             fseek(file1,nextarcpos,SEEK_SET);
  3827.         }
  3828.     }
  3829.  
  3830.     print(NULL,1);
  3831.  
  3832.     if (bad_tab)
  3833.     {
  3834.         sprintf(print_buf,"Bad Tables   :%5d",bad_tab);
  3835.         Print(1);
  3836.     }
  3837.  
  3838.     if (c_err)
  3839.     {
  3840.         sprintf(print_buf,"CRC errors   :%5d",c_err);
  3841.         Print(1);
  3842.     }
  3843.  
  3844.     if (skipped)
  3845.     {
  3846.         sprintf(print_buf,"Skipped files:%5d",skipped);
  3847.         Print(1);
  3848.     }
  3849.  
  3850.     if (garbage)
  3851.     {
  3852.         sprintf(print_buf,"Crashed files:%5d",garbage);
  3853.         Print(1);
  3854.     }
  3855.  
  3856.     if (flg_d)
  3857.         endofupdate(cnt);
  3858.     else
  3859.         close_file(file1);
  3860.  
  3861.     return(cnt);
  3862. }
  3863.  
  3864. void delete(void)
  3865. {
  3866.     register int cnt=0;
  3867.  
  3868. #ifdef __SHELL__
  3869.     if (!shell)
  3870. #endif
  3871.     if (!patno)
  3872.         error(NOFNERR,NULL,SUCCS);
  3873.  
  3874.     Case=_PC_CASECONV;
  3875.  
  3876.     flg_t=0;
  3877.     openbackup1();
  3878.     message("Updating archive",arcname);
  3879.  
  3880.     openbackup2();
  3881.     search_lzh(file1,0);
  3882.  
  3883.     while (gethdr(file1,&Hdr1))
  3884.     {
  3885.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  3886.         {
  3887.     #ifdef __SHELL__
  3888.             if (command)
  3889.             {
  3890.                 DialIndicator(1);
  3891.                 free_commem();
  3892.             }
  3893.     #endif
  3894.             message("Deleting",filename);
  3895.             sseek(file1,nextarcpos,nextoffset);
  3896.             cnt++;
  3897.         }
  3898.         else
  3899.             copyold();
  3900.     }
  3901.  
  3902.     endofupdate(cnt);
  3903. }
  3904.  
  3905. uchar *sysid(char ID)
  3906. {
  3907.     switch(ID)
  3908.     {
  3909.     case 'M':
  3910.         return("MS-DOS");
  3911.     case '2':
  3912.         return("OS/2");
  3913.     case '9':
  3914.         return("OS9");
  3915.     case 'K':
  3916.         return("OS/68K");
  3917.     case '3':
  3918.         return("OS/386");
  3919.     case 'H':
  3920.         return("HUMAN");
  3921.     case 'U':
  3922.         return("UNIX");
  3923.     case 'C':
  3924.         return("CP/M");
  3925.     case 'm':
  3926.         return("Macintosh");
  3927.     case 'R':
  3928.         return("Runser");
  3929.     case 'A':
  3930.         return("Amiga/Atari");
  3931.     case 'a':
  3932.         return("Atari");
  3933.     case 'F':
  3934.         return("FLEX-OS");
  3935.     case 'X':
  3936.         return("XOSK");
  3937.     case 'T':
  3938.         return("TOWNSOS");
  3939.     default:
  3940.     #ifdef __SHELL__
  3941.         if (shell)
  3942.             return("Unknown system");
  3943.         else
  3944.     #endif
  3945.             return("");
  3946.     }
  3947. }
  3948.  
  3949. void make_attr(uchar *buf,int attr)
  3950. {
  3951.     static uchar Attr[7]="rhs-da";
  3952.     register int i,j,k;
  3953.  
  3954.     if (!(attr & FA_DIR))
  3955.         buf[3]='w';
  3956.  
  3957.     for (i=0,j=1;i<6;i++,j<<=1)
  3958.         if (attr & j)
  3959.         {
  3960.             k=Attr[i];
  3961.             if (i<=2)
  3962.                 buf[3-i]=k;
  3963.             else
  3964.                 buf[0]=k;
  3965.         }
  3966. }
  3967.  
  3968. uchar *list_format="               %8lu %8lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d ---- -   - %04X  [%d]";
  3969. uchar *list_end="-------------- -------- -------- ------ -------- --------\r\n";
  3970.  
  3971. int list(void)
  3972. {
  3973.     register uchar buf[120],*p;
  3974.     register ftime *tim=(ftime *) &Hdr1.Ftime;
  3975.     register int i;
  3976.     register uint rt;
  3977.     ulong Osize,Psize;
  3978.     int Fno,Dno;
  3979.  
  3980.     Case=_PC_CASECONV;
  3981.     Osize=Psize=Fno=Dno=0;
  3982.  
  3983. #if GERMAN
  3984.     sprintf(print_buf,"Inhalt von: %s\r\n",arcname);
  3985. #else
  3986.     sprintf(print_buf,"Listing of archive: %s\r\n",arcname);
  3987. #endif
  3988.     pager_print(1);
  3989.  
  3990.     if (openarc1((drive(arcname,NULL)<2) ? 8192L : 1024L,buffer_1)<=0)
  3991.         return(0);
  3992.  
  3993.     if (flg_x<3)
  3994. #if GERMAN
  3995.         sprintf(print_buf,"\r\n Name          Original Gepackt  Rate   Datum    Zeit     Attr Typ   CRC  Level\r\n-------------- -------- -------- ------ -------- -------- ---- ----- ---- -----\r\n");
  3996. #else
  3997.         sprintf(print_buf,"\r\n Name          Original Packed   Ratio  Date     Time     Attr Type  CRC  Level\r\n-------------- -------- -------- ------ -------- -------- ---- ----- ---- -----\r\n");
  3998. #endif
  3999.     else
  4000.         sprintf(print_buf,"\r\n Name\r\n--------------\r\n");
  4001.     pager_print(0);
  4002.  
  4003.     while (gethdr(file1,&Hdr1))
  4004.     {
  4005.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  4006.         {
  4007.             if (flg_x<3)
  4008.             {
  4009.                 rt=ratio(Hdr1.PacSiz,Hdr1.OrgSiz);
  4010.                 sprintf(buf,list_format,Hdr1.OrgSiz,Hdr1.PacSiz,rt/10,rt%10,(tim->year+80)%100,tim->mon,
  4011.                         tim->day,tim->hour,tim->min,tim->sec*2,Hdr1.crc,Hdr1.Level);
  4012.                 memcpy(&buf[63],Hdr1.HeadID,5);
  4013.                 make_attr(&buf[58],Hdr1.Attr);
  4014.  
  4015.                 if (flg_x)
  4016.                 {
  4017.                     p=sysid(SystemId);
  4018.                     memcpy(buf,p,strlen(p));
  4019.                 #if GERMAN
  4020.                     if (flg_x!=2 && *comment!='\0')
  4021.                         sprintf(print_buf,Hdr1.crypted ? "%s (verschlüsselt)\r\n%s\r\n%s\r\n" : "%s\r\n%s\r\n%s\r\n",filename,comment,buf);
  4022.                     else
  4023.                         sprintf(print_buf,Hdr1.crypted ? "%s (verschlüsselt)\r\n%s\r\n" : "%s\r\n%s\r\n",filename,buf);
  4024.                 #else
  4025.                     if (flg_x!=2 && *comment!='\0')
  4026.                         sprintf(print_buf,Hdr1.crypted ? "%s (encrypted)\r\n%s\r\n%s\r\n" : "%s\r\n%s\r\n%s\r\n",filename,comment,buf);
  4027.                     else
  4028.                         sprintf(print_buf,Hdr1.crypted ? "%s (encrypted)\r\n%s\r\n" : "%s\r\n%s\r\n",filename,buf);
  4029.                 #endif
  4030.                     pager_print(0);
  4031.                 }
  4032.                 else
  4033.                 {
  4034.                     slash(filename,0);
  4035.                     if ((p=get_fname(filename))>filename)
  4036.                         buf[0]='+';
  4037.  
  4038.                     if ((i=(int) strlen(p))>13)
  4039.                     {
  4040.                         buf[13]='>';
  4041.                         i=12;
  4042.                     }
  4043.  
  4044.                     memcpy(buf+1,p,i);
  4045.                     strcpy(stpcpy(print_buf,buf),"\r\n");
  4046.                     pager_print(0);
  4047.                 }
  4048.  
  4049.                 Osize+=Hdr1.OrgSiz;
  4050.                 Psize+=Hdr1.PacSiz;
  4051.             }
  4052.             else
  4053.             {
  4054.                 sprintf(print_buf,"%s\r\n",filename);
  4055.                 pager_print(0);
  4056.             }
  4057.  
  4058.             if (Hdr1.Attr & FA_DIR)
  4059.                 Dno++;
  4060.             else
  4061.                 Fno++;
  4062.         }
  4063.         sseek(file1,nextarcpos,nextoffset);
  4064.     }
  4065.  
  4066.     if (Fno || Dno)
  4067.     {
  4068.         if (flg_x<3)
  4069.         {
  4070.             strcpy(print_buf,list_end);
  4071.             pager_print(0);
  4072.  
  4073.             rt=ratio(Psize, Osize);
  4074.             Fdatime(&arcstamp,fileno(file1),0);
  4075.             tim=(ftime *) &arcstamp;
  4076.  
  4077.         #if GERMAN
  4078.             sprintf(print_buf," %4d Dateien, %8lu %8lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d\r\n %4d Verzeichnisse\r\n",
  4079.                     Fno, Osize, Psize, rt / 10, rt % 10,(tim->year + 80) % 100, tim->mon,
  4080.                     tim->day, tim->hour, tim->min, tim->sec * 2,Dno);
  4081.         #else
  4082.             sprintf(print_buf," %4d files,   %8lu %8lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d\r\n %4d directories\r\n",
  4083.                     Fno, Osize, Psize, rt / 10, rt % 10,(tim->year + 80) % 100, tim->mon,
  4084.                     tim->day, tim->hour, tim->min, tim->sec * 2,Dno);
  4085.         #endif
  4086.         }
  4087.         else
  4088.         #if GERMAN
  4089.             sprintf(print_buf,"--------------\r\n  %3d Dateien,\r\n  %3d Verzeichnisse\r\n",Fno,Dno);
  4090.         #else
  4091.             sprintf(print_buf,"--------------\r\n  %3d files,\r\n  %3d directories\r\n",Fno,Dno);
  4092.         #endif
  4093.     }
  4094.     else
  4095.     #if GERMAN
  4096.         sprintf(print_buf,"  Keine Datei\r\n");
  4097.     #else
  4098.         sprintf(print_buf,"  No file\r\n");
  4099.     #endif
  4100.  
  4101.     pager_print(0);
  4102.     close_file(file1);
  4103.  
  4104.     return(Fno+Dno);
  4105. }
  4106.  
  4107. void getsw(uchar *p)
  4108. {
  4109.     register uchar s,*q;
  4110.     register int i;
  4111.  
  4112.     while ((s=*p++)!='\0')
  4113.     {
  4114.         q=strchr(swi,s);
  4115.         if (q)
  4116.         {
  4117.             if ((i=(int) (q-swi))<SWI_CNT)
  4118.             {
  4119.                 if (*p=='+')
  4120.                 {
  4121.                     *swipos[i]=1;
  4122.                     p++;
  4123.                 }
  4124.                 else if (*p=='-')
  4125.                 {
  4126.                     *swipos[i]=0;
  4127.                     p++;
  4128.                 }
  4129.                 else if (*p>='0' && *p<='3')
  4130.                     *swipos[i]=*p++ - '0';
  4131.                 else
  4132.                     *swipos[i]=1;
  4133.             }
  4134.  
  4135.             if (flg_q>1)
  4136.             {
  4137.                 print(NULL,1);
  4138.                 ptitel++;
  4139.                 flg_q=0;
  4140.             }
  4141.  
  4142.             if (s=='v')
  4143.             {
  4144.                 if (cmd=='P' && flg_v==3)
  4145.                     flg_q++;
  4146.  
  4147.                 if ((cmd=='P' || cmd=='L' || cmd=='V') && *p)
  4148.                 {
  4149.                     if (!flg_v)
  4150.                         flg_v++;
  4151.                     pager=p;
  4152.                     flg_L=1;
  4153.                 }
  4154.                 break;
  4155.             }
  4156.             else if (s=='M')
  4157.             {
  4158.                 if (isdigit(*p))
  4159.                     maxlen=strtol(p,NULL,10)<<10;
  4160.                 else
  4161.                     maxlen=0;
  4162.                 break;
  4163.             }
  4164.             else if (s=='Y')
  4165.             {
  4166.                 if (*p)
  4167.                 {
  4168.                     register int len=(int) strlen(p);
  4169.  
  4170.                     i=len;
  4171.                     q=stpcpy(key_word,p);
  4172.                     while ((i+=len)<256)
  4173.                         q=stpcpy(q,p);
  4174.  
  4175.                     flg_Y++;
  4176.                     compress++;
  4177.                     FlgMethod=5;
  4178.                     flg_5=2;
  4179.                     flg_u=0;
  4180.                 }
  4181.                 else
  4182.                     flg_Y=0;
  4183.                 break;
  4184.             }
  4185.             else if (s=='N')
  4186.             {
  4187.                 for (i=6;--i>=0;)
  4188.                     if (!isdigit(*p++))
  4189.                         break;
  4190.  
  4191.                 if (i<0)
  4192.                 {
  4193.                     register ftime *t=(ftime *) &newer;
  4194.  
  4195.                     flg_N++;
  4196.  
  4197.                     p-=6;
  4198.                     t->day=(*p++-'0')*10 + (*p++-'0');
  4199.                     t->mon=((*p++-'0')*10 + (*p++-'0'));
  4200.                     t->year=((*p++-'0')*10 + (*p++-'0'));
  4201.                     if (t->year>=80)
  4202.                         t->year-=80;
  4203.                 }
  4204.                 else
  4205.                     flg_N=0;
  4206.                 break;
  4207.             }
  4208.             else if (s=='w')
  4209.             {
  4210.                 if (*p)
  4211.                 {
  4212.                     flg_w++;
  4213.                     strcpy(workdir,p);
  4214.                 }
  4215.                 break;
  4216.             }
  4217.             else if (s=='I')
  4218.             {
  4219.                 if (*p)
  4220.                 {
  4221.                     flg_I++;
  4222.                     flg_x++;
  4223.                     slash(strcpy(incldir,p),1);
  4224.                 }
  4225.                 break;
  4226.             }
  4227.             else if (s=='U')
  4228.             {
  4229.                 if (*p)
  4230.                 {
  4231.                     flg_U++;
  4232.                     unpack=p;
  4233.                 }
  4234.                 break;
  4235.             }
  4236.             else if (s=='P')
  4237.             {
  4238.                 if (*p)
  4239.                     star=*p++;
  4240.                 if (*p)
  4241.                     pnt=*p++;
  4242.                 break;
  4243.             }
  4244.             else if (s=='s')
  4245.             {
  4246.                 if (flg_k<=0)
  4247.                     flg_k=1;
  4248.             }
  4249.             else if (s=='z')
  4250.             {
  4251.                 if (*p)
  4252.                 {
  4253.                     com_name=p;
  4254.                     flg_z++;
  4255.                 }
  4256.                 break;
  4257.             }
  4258.             else if (s=='r' || s=='X')
  4259.             {
  4260.                 if (!flg_x)
  4261.                     flg_x=3;
  4262.             }
  4263.             else if (s=='A')
  4264.                 flg_D=0;
  4265.             else if (s=='D')
  4266.                 flg_A=0;
  4267.             else if (s=='y')
  4268.                 flg_arc++;
  4269.             else if (s=='b')
  4270.                 flg_backup++;
  4271.             else if (s=='k')
  4272.             {
  4273.                 if (*p>='0' && *p<='2')
  4274.                     flg_k=*p++ - '0';
  4275.                 else
  4276.                     flg_k=0;
  4277.  
  4278.                 if (!flg_k)
  4279.                     flg_e=flg_z=flg_s=flg_Y=compress=0;
  4280.             }
  4281.             else if (s=='5')
  4282.             {
  4283.                 compress=flg_u=0;
  4284.                 if (flg_5==2 || flg_Y)
  4285.                     compress++;
  4286.                 FlgMethod=5;
  4287.             }
  4288.             else if (s=='l')
  4289.             {
  4290.                 compress=FlgMethod=flg_5=flg_u=0;
  4291.                 flg_4++;
  4292.                 if (flg_l==2 || flg_Y)
  4293.                     compress++;
  4294.             }
  4295.             else if (s=='o')
  4296.             {
  4297.                 compress=flg_5=flg_u=0;
  4298.                 if (flg_o==2 || flg_Y)
  4299.                     compress++;
  4300.                 FlgMethod=1;
  4301.             }
  4302.             else if (s=='u')
  4303.             {
  4304.                 compress=flg_5=flg_4=flg_Y=0;
  4305.                 flg_u=1;
  4306.             }
  4307.             else if (s=='4')
  4308.             {
  4309.                 compress=flg_5=flg_Y=0;
  4310.                 flg_u=flg_4=1;
  4311.             }
  4312.         }
  4313.     #ifndef __SHELL__
  4314.         else if (s=='?')
  4315.         {
  4316.             if (!ptitel)
  4317.             {
  4318.                 print(title_x,1);
  4319.                 ptitel=1;
  4320.             }
  4321.  
  4322.             print(use_1,1);
  4323.             print(use_2,1);
  4324.             print(use_3,1);
  4325.         }
  4326.     #endif
  4327.         else if (s!='-' && s!='+')
  4328.             break;
  4329.     }
  4330.  
  4331.     if (flg_q)
  4332.     {
  4333.         flg_n=flg_m=1;
  4334.         flg_e=flg_z=flg_h=flg_R=0;
  4335.     }
  4336.     else if (i_handle>0)
  4337.     {
  4338.         flg_m=1;
  4339.         flg_R=0;
  4340.     }
  4341.  
  4342.     if (flg_u && !flg_n)
  4343.         flg_n++;
  4344.  
  4345.     if (flg_I && flg_x)
  4346.         flg_x=3;
  4347.  
  4348.     if (flg_s)
  4349.         flg_s='U';
  4350. }
  4351.  
  4352. int tstsw(uchar *p)
  4353. {
  4354.     register uchar s,*q;
  4355.     register int i;
  4356.  
  4357.     while ((s=*p++)!='\0')
  4358.     {
  4359.         q=strchr(swi,s);
  4360.         if (q)
  4361.         {
  4362.             if (((int) (q-swi))<SWI_CNT)
  4363.                 if (*p=='+' || *p=='-' || (*p>='0' && *p<='3'))
  4364.                     p++;
  4365.  
  4366.             if (s=='w' || s=='z' || s=='U' || s=='Y' || s=='I' || s=='v')
  4367.                 return(SUCCS);
  4368.             else if (s=='M')
  4369.                 return(isdigit(*p));
  4370.             else if (s=='N')
  4371.             {
  4372.                 for (i=6;--i>=0;)
  4373.                     if (!isdigit(*p++))
  4374.                         return(FAULT);
  4375.                 return(SUCCS);
  4376.             }
  4377.             else if (s=='P')
  4378.             {
  4379.                 if (*p)
  4380.                     p++;
  4381.                 if (*p)
  4382.                     p++;
  4383.                 return((*p!='\0') ? FAULT : SUCCS);
  4384.             }
  4385.             else if (s=='k')
  4386.             {
  4387.                 if (*p>='0' && *p<='2')
  4388.                     p++;
  4389.             }
  4390.         }
  4391.         else if (s!='?')
  4392.             return(FAULT);
  4393.     }
  4394.  
  4395.     return(SUCCS);
  4396. }
  4397.  
  4398. void executecmd(void)
  4399. {
  4400.     register int cnt;
  4401.  
  4402.     INIT_TIMER;
  4403.     arcpos0=back_1=back_2=found=bad_tab=c_err=skipped=garbage=ignfile=buffered=ship=0;
  4404.  
  4405.     base=strlen(basedir);
  4406.  
  4407.     switch(cmd)
  4408.     {
  4409.     case 'M':
  4410.         flg_d=1;
  4411.     case 'A':
  4412.         flg_c=1;
  4413.     case 'U':
  4414.         flg_chk=0;
  4415.         if (cmd=='U')
  4416.             flg_A=0;
  4417.         append();
  4418.         break;
  4419.     case 'C':
  4420.         flg_X=flg_f=flg_e=flg_z=flg_d=flg_u=flg_4=flg_5=flg_I=flg_x=flg_Y=compress=0;
  4421.         if (flg_k==2)
  4422.             flg_k=0;
  4423.         pack_afx();
  4424.         break;
  4425.     case 'R':
  4426.     case 'F':
  4427.         flg_chk=flg_f=0;
  4428.         freshen();
  4429.         break;
  4430.     case 'V':
  4431.         if (!flg_x)
  4432.             flg_x++;
  4433.     case 'L':
  4434.         flg_chk=0;
  4435.         if (pager==NULL)
  4436.         {
  4437.             file3=stdout;
  4438.             list();
  4439.             break;
  4440.         }
  4441.     case 'P':
  4442.         if (pager==NULL)
  4443.         {
  4444.             file3=stdout;
  4445.             setvbuf(stdout,buffer_3,_IOFBF,BUFFERSIZ);
  4446.             flg_n=1;
  4447.             extract();
  4448.             fflush(stdout);
  4449.         }
  4450.         else
  4451.         {
  4452.             if (flg_w)
  4453.                 strcpy(pathname,workdir);
  4454.             else
  4455.                 backpath(strcpy(pathname,arcname));
  4456.             get_tempname(pathname);
  4457.  
  4458.             file3=e_fopen(pathname,buffer_3,"wb",MKTMPERR,SUCCS);
  4459.             if (cmd=='P')
  4460.                 cnt=extract();
  4461.             else
  4462.                 cnt=list();
  4463.             if (fclose(file3))
  4464.                 error(WTERR,pathname,SUCCS);
  4465.             file3=NULL;
  4466.  
  4467.             if (cnt)
  4468.             {
  4469.                 uchar buffer[127]="*";
  4470.                 strncat(buffer,pathname,125);
  4471.                 Pexec(0,pager,buffer,NULL);
  4472.             }
  4473.  
  4474.             Fdelete(pathname);
  4475.         }
  4476.         break;
  4477.     case 'X':
  4478.         flg_x=3;
  4479.         cmd='E';
  4480.     case 'T':
  4481.     case 'E':
  4482.         flg_v=0;
  4483.         extract();
  4484.         break;
  4485.     case 'D':
  4486.         flg_chk=0;
  4487.         if (!flg_f)
  4488.             flg_f=2;
  4489.         delete();
  4490.         break;
  4491.     case 'S':
  4492.         print("Self-Extracting-Files: NOT YET IMPLEMENTED !\7",1);
  4493.         errorlevel|=64;
  4494.         lha_exit();
  4495.     }
  4496.  
  4497.     EXIT_TIMER;
  4498.     print(NULL,1);
  4499. }
  4500.  
  4501. void OneNewFile(uchar *p)
  4502. {
  4503.     register uchar *s;
  4504.     register int len;
  4505.  
  4506.     if ((s=strpbrk(p,"\n"))!=NULL)
  4507.         *s='\0';
  4508.  
  4509.     if ((len=(int) strlen(p)-1)<0)
  4510.         return;
  4511.  
  4512.     if (!patno && !base && !cmdlist && (p[len]=='\\' || p[len]==':'))
  4513.     {
  4514.         slash(strcpy(basedir,p),1);
  4515.         base++;
  4516.     }
  4517.     else if (*p!=EXCLUDE && *p!='~')
  4518.     {
  4519.         if (patno>=MAX_PAT || (fileptr-fileregbuf+strlen(get_fname(p)))>=(FILEBUFSIZ-1))
  4520.             message(M_FILETAB,p);
  4521.         else
  4522.         {
  4523.             travel_file[patno]=travel_rel[patno]=0;
  4524.  
  4525.             while (((s=strstr(p,"\\;"))!=NULL || (s=strstr(p,";\\"))!=NULL))
  4526.             {
  4527.                 if (*s=='\\')
  4528.                     s++;
  4529.                 strcpy(s,s+1);
  4530.                 if (*s=='\\')
  4531.                     s++;
  4532.                 travel_rel[patno]=s-p;
  4533.             }
  4534.  
  4535.             strcpy(fileptr,s=get_fname(p));
  4536.             *s='\0';
  4537.  
  4538.             if (*fileptr=='\0')
  4539.             {
  4540.                 travel_wild[patno]=SUCCS;
  4541.  
  4542.                 if (slash(p,-1))
  4543.                 {
  4544.                     register uchar path[MAXPATH];
  4545.  
  4546.                     slash(strcpy(path,p),1);
  4547.                     if ((p=strdup(path))==NULL)
  4548.                         error(MEMOVRERR,NULL,SUCCS);
  4549.                 }
  4550.             }
  4551.             else if (flg_W<2 && patno>0 && travel_rel[patno]==travel_rel[patno-1] && !fnamecmp(p,travel_path[patno-1],_PC_CASESENS))
  4552.             {
  4553.                 if (travel_file[patno-1]>0)
  4554.                 {
  4555.                     travel_wild[patno-1]|=wildcard(fileptr);
  4556.                     fileptr[-1]=',';
  4557.                     while (*fileptr++);
  4558.                 }
  4559.                 return;
  4560.             }
  4561.             else
  4562.             {
  4563.                 travel_file[patno]=(int) (fileptr-fileregbuf);
  4564.                 travel_wild[patno]=wildcard(fileptr);
  4565.                 while (*fileptr++);
  4566.             }
  4567.  
  4568.             travel_path[patno]=p;
  4569.             travel_len[patno++]=(int) strlen(p);
  4570.         }
  4571.     }
  4572.     else if (*++p!='\0')
  4573.     {
  4574.         if (exno>=MAX_EXCLD)
  4575.             message(M_FILETAB,p);
  4576.         else
  4577.             exclude_file[exno++]=get_fname(p);
  4578.     }
  4579. }
  4580.  
  4581. void newfile(uchar *p)
  4582. {
  4583.     if (*p=='&' || *p==FILE_LIST)
  4584.     {
  4585.         register FILE *f;
  4586.  
  4587.         if (p[1]=='-' && p[2]=='\0')
  4588.             f=stdin;
  4589.         else
  4590.             f=fopen(p+1,"r");
  4591.  
  4592.         if (f!=NULL)
  4593.         {
  4594.             register uchar file[MAXPATH],*space;
  4595.  
  4596.             if (f==stdin)
  4597.                 print(M_PATH,1);
  4598.  
  4599.             while (fgets(file,MAXPATH-1,f))
  4600.             {
  4601.                 space=file;
  4602.                 while (*space==' ')
  4603.                     space++;
  4604.                 strcpy(file,space);
  4605.  
  4606.                 space=strchr(file,' ');
  4607.                 if (space)
  4608.                     *space=0;
  4609.  
  4610.                 fnamecnv(file,-1);
  4611.                 if (file[0]=='&')
  4612.                 {
  4613.                     if (strcmp("&-",file))
  4614.                         newfile(file);
  4615.                 }
  4616.                 else if (file[0]!='\r' && file[0]!='\n')
  4617.                 {
  4618.                     if ((space=strdup(file))==NULL)
  4619.                         error(MEMOVRERR,NULL,SUCCS);
  4620.                     print(space,1);
  4621.                     OneNewFile(space);
  4622.                 }
  4623.                 else if (f==stdin)
  4624.                     break;
  4625.             }
  4626.  
  4627.             if (f!=stdin)
  4628.                 close_file(f);
  4629.         }
  4630.     }
  4631.     else
  4632.         OneNewFile(p);
  4633. }
  4634.  
  4635. void copyfile(FILE *Source,FILE *Dest,uchar *outfname,long size,int crcflg,int bufflg)
  4636. {
  4637.     register uchar *ptr;
  4638.     register long n,block;
  4639.  
  4640.     if (crcflg)
  4641.         crc=0;
  4642.  
  4643.     if (!crcflg || blocksize>bsize || flg_n==1)
  4644.         block=bsize;
  4645.     else
  4646.         block=blocksize;
  4647.  
  4648.     if (bufflg)
  4649.         ptr=outrec.ptr;
  4650.     else
  4651.         ptr=buffer_gen;
  4652.  
  4653.     while (size>0)
  4654.     {
  4655.         n=block>size ? size : block;
  4656.  
  4657.         if (bufflg && (outrec.cnt-n)<0)
  4658.         {
  4659.             ShipOut();
  4660.             ptr=outrec.ptr;
  4661.         }
  4662.  
  4663.         if (fread(ptr,n,1,Source)!=1)
  4664.             error(RDERR,infname,SUCCS);
  4665.  
  4666.         if (crcflg)
  4667.         {
  4668.             if (!flg_chk)
  4669.                 block_crc(n,ptr);
  4670.             code(ptr,n);
  4671.             ProcInd();
  4672.         }
  4673.  
  4674.         if (Dest)
  4675.         {
  4676.             if (fwrite(ptr,n,1,Dest)!=1)
  4677.                 error(WTERR,outfname,SUCCS);
  4678.         }
  4679.         else if (bufflg)
  4680.         {
  4681.             outrec.ptr=(ptr+=n);
  4682.  
  4683.             if ((outrec.cnt-=n)<=0)
  4684.             {
  4685.                 ShipOut();
  4686.                 ptr=outrec.ptr;
  4687.             }
  4688.         }
  4689.  
  4690.         size-=n;
  4691.     }
  4692.  
  4693.     if (ferror(Source))
  4694.         error(RDERR,infname,SUCCS);
  4695. }
  4696.  
  4697. void EncodeOld(void)
  4698. {
  4699.     register uchar code_buf[34],*code=code_buf,*ptr,*tbuf=text_buf;
  4700.     register int i,r,s=0,m=N-1,c,last_match_length;
  4701.     ulong printcount;
  4702.     uchar mask=1;
  4703.     int    len;
  4704.  
  4705.     printcount=textsize=0;
  4706.     InitTree();
  4707.  
  4708.     *code++=0;
  4709.     for (i=r=(N-F),ptr=tbuf;--i>=0;)
  4710.         *ptr++=' ';
  4711.  
  4712.     for (i=0;i<F && (c=crc_getc(file3))!=EOF;i++)
  4713.         *ptr++=c;
  4714.  
  4715.     textsize=(len=i);
  4716.     if (!textsize)
  4717.         return;
  4718.  
  4719.     for (i=1;i<=F;i++)
  4720.         InsertONode(r - i);
  4721.     InsertONode(r);
  4722.  
  4723.     do
  4724.     {
  4725.         if (match_length>len)
  4726.             match_length=len;
  4727.  
  4728.         if (match_length <=THRESHOLD)
  4729.         {
  4730.             match_length=1;
  4731.             code_buf[0]|=mask;
  4732.             *code++=tbuf[r];
  4733.         }
  4734.         else
  4735.         {
  4736.             *code++=(uchar) match_position;
  4737.             *code++=(uchar) (((match_position >> 4) & 0xf0) | (match_length - (THRESHOLD + 1)));
  4738.         }
  4739.  
  4740.         if (!(mask<<=1))
  4741.         {
  4742.             i=(int) (code - code_buf);
  4743.             ptr=(code=code_buf);
  4744.  
  4745.             while (--i>=0)
  4746.                 buf_putc(*ptr++);
  4747.  
  4748.             *code++=0;
  4749.             mask=1;
  4750.         }
  4751.  
  4752.         last_match_length=match_length;
  4753.         for (i=0;i<last_match_length && (c=crc_getc(file3))!=EOF;i++)
  4754.         {
  4755.             DeleteONode(s);
  4756.             tbuf[s]=c;
  4757.             if (s < F - 1)
  4758.                 tbuf[s + N]=c;
  4759.             s=(++s) & m;
  4760.             r=(++r) & m;
  4761.             InsertONode(r);
  4762.         }
  4763.  
  4764.         if ((textsize+=i)>printcount)
  4765.         {
  4766.             ProcInd();
  4767.             printcount+=blocksize;
  4768.         }
  4769.  
  4770.         while (i<last_match_length)
  4771.         {
  4772.             DeleteONode(s);
  4773.             s=(++s) & m;
  4774.             r=(++r) & m;
  4775.             if (--len)
  4776.                 InsertONode(r);
  4777.             i++;
  4778.         }
  4779.     } while (len>0);
  4780.  
  4781.     if ((i=(int) (code - code_buf))>1)
  4782.     {
  4783.         ptr=code_buf;
  4784.         while (--i>=0)
  4785.             buf_putc(*ptr++);
  4786.     }
  4787.  
  4788.     shipout();
  4789. }
  4790.  
  4791. int fread_crc(uchar *p,int n,FILE *f)
  4792. {
  4793.     n=(int) fread(p,1,n,f);
  4794.     if (ferror(f))
  4795.         error(RDERR,infname,SUCCS);
  4796.     block_crc(n,p);
  4797.     return(n);
  4798. }
  4799.  
  4800. void count_t_freq(void)
  4801. {
  4802.     register int i,k,n;
  4803.     register ushort *tfreq,tf0,tf1;
  4804.     register uchar *clen;
  4805.  
  4806.     for (i=NT,tfreq=t_freq,k=0;--i>=0;)
  4807.         *tfreq++=k;
  4808.  
  4809.     clen=&c_len[n=NC];
  4810.     while (*--clen==0 && --n>=0);
  4811.  
  4812.     i=tf0=tf1=0;
  4813.     clen=c_len;
  4814.     tfreq=t_freq;
  4815.  
  4816.     while (i<n)
  4817.     {
  4818.         i++;
  4819.         if ((k=*clen++)==0)
  4820.         {
  4821.             k=1;
  4822.             while (i<n && *clen==0)
  4823.             {
  4824.                 clen++;
  4825.                 k++;
  4826.                 i++;
  4827.             }
  4828.  
  4829.             if (k<=2)
  4830.                 tf0+=k;
  4831.             else if (k<=18)
  4832.                 tf1++;
  4833.             else if (k==19)
  4834.             {
  4835.                 tf0++;
  4836.                 tf1++;
  4837.             }
  4838.             else
  4839.                 tfreq[2]++;
  4840.         }
  4841.         else
  4842.             tfreq[k+2]++;
  4843.     }
  4844.  
  4845.     tfreq[0]+=tf0;
  4846.     tfreq[1]+=tf1;
  4847. }
  4848.  
  4849. void write_pt_len(register int n,int nbit,register int i_special)
  4850. {
  4851.     register uchar *ptlen;
  4852.     register int i,k,c=3;
  4853.  
  4854.     ptlen=&pt_len[n];
  4855.     while (*--ptlen==0 && --n>=0);
  4856.  
  4857.     putbits(nbit,n);
  4858.  
  4859.     i=0;
  4860.     ptlen=pt_len;
  4861.     while (i<n)
  4862.     {
  4863.         i++;
  4864.         if ((k=*ptlen++)<=6)
  4865.             putbits(3,k);
  4866.         else
  4867.         {
  4868.             k-=c;
  4869.             putbits(k,(1U<<k)-2);
  4870.         }
  4871.  
  4872.         if (i==i_special)
  4873.         {
  4874.             while (i<6 && *ptlen==0)
  4875.             {
  4876.                 ptlen++;
  4877.                 i++;
  4878.             }
  4879.  
  4880.             putbits(2,(i-c) & c);
  4881.         }
  4882.     }
  4883. }
  4884.  
  4885. void write_c_len(void)
  4886. {
  4887.     register int i,k,n;
  4888.     register uchar l0=pt_len[0],*clen;
  4889.     register ushort c0=pt_code[0],c1=pt_code[1];
  4890.  
  4891.     clen=&c_len[n=NC];
  4892.     while (*--clen==0 && --n>=0);
  4893.  
  4894.     putbits(CBIT,n);
  4895.  
  4896.     i=0;
  4897.     clen=c_len;
  4898.     while (i<n)
  4899.     {
  4900.         i++;
  4901.         if ((k=*clen++)==0)
  4902.         {
  4903.             k=1;
  4904.             while (i<n && *clen==0)
  4905.             {
  4906.                 clen++;
  4907.                 k++;
  4908.                 i++;
  4909.             }
  4910.  
  4911.             switch (k)
  4912.             {
  4913.             case 2:
  4914.                 putbits(l0,c0);
  4915.             case 1:
  4916.                 putbits(l0,c0);
  4917.                 break;
  4918.             case 19:
  4919.                 putbits(l0,c0);
  4920.                 putbits(pt_len[1],c1);
  4921.                 putbits(4,15);
  4922.                 break;
  4923.             default:
  4924.                 if (k<=18)
  4925.                 {
  4926.                     putbits(pt_len[1],c1);
  4927.                     putbits(4,k-3);
  4928.                 }
  4929.                 else
  4930.                 {
  4931.                     putbits(pt_len[2],pt_code[2]);
  4932.                     putbits(CBIT,k-20);
  4933.                 }
  4934.             }
  4935.         }
  4936.         else
  4937.             putbits(pt_len[k+2],pt_code[k+2]);
  4938.     }
  4939. }
  4940.  
  4941. void start_huf(void)
  4942. {
  4943.     register ushort *p,v=0;
  4944.     register int i;
  4945.  
  4946.     text_buf[0]=v;
  4947.     for (i=NC,p=c_freq;--i>=0;)
  4948.         *p++=v;
  4949.  
  4950.     for (i=NP,p=p_freq; --i>=0;)
  4951.         *p++=v;
  4952.  
  4953.     subbitbuf=v;
  4954.     bitcount=CHAR_BIT;
  4955. }
  4956.  
  4957. void end_huf(void)
  4958. {
  4959.     send_block();
  4960.     putbits(CHAR_BIT-1,0);
  4961. }
  4962.  
  4963. extern long _read(int,void *,unsigned long);
  4964.  
  4965. void make_buf(FILE *file,long len)
  4966. {
  4967.     register long cnt = file->_cnt;
  4968.     register uchar *pos;
  4969.  
  4970.     if (cnt<bufsize && cnt<len)
  4971.     {
  4972.         if (cnt>0)
  4973.             memcpy(file->_base,file->_ptr,cnt);
  4974.         else
  4975.             cnt = 0;
  4976.         pos = &file->_base[cnt];
  4977.         len = file->_bsiz-cnt;
  4978.         cnt = _read(fileno(file),pos,len);
  4979.         if (cnt>0)
  4980.         {
  4981.             file->_cnt += cnt;
  4982.             if (Hdr1.crypted && crypt_size>0)
  4983.             {
  4984.                 if (cnt>crypt_size)
  4985.                     cnt=crypt_size;
  4986.                 code(pos,cnt);
  4987.                 crypt_size-=cnt;
  4988.             }
  4989.         }
  4990.         else
  4991.             file->_flag |= _IOEOF;
  4992.         file->_ptr = file->_base;
  4993.     }
  4994. }
  4995.  
  4996. int read_pt_len(int nn,int nbit,int i_special)
  4997. {
  4998.     register uchar *ptlen=pt_len;
  4999.     register int n;
  5000.  
  5001.     if ((n=getbits(nbit))==0)
  5002.     {
  5003.         register ushort *table=pt_table,c;
  5004.  
  5005.         for (n=nn,c=0;--n>=0;)
  5006.             *ptlen++=c;
  5007.         for (n=256,c=getbits(nbit);--n>=0;)
  5008.             *table++=c;
  5009.     }
  5010.     else
  5011.     {
  5012.         register int c,i=0;
  5013.         register uint mask,bibu;
  5014.  
  5015.         while (i<n)
  5016.         {
  5017.             bibu=bitbuf;
  5018.             if ((c=bibu>>13)==7)
  5019.             {
  5020.                 mask=1U<<12;
  5021.                 while (mask&bibu)
  5022.                 {
  5023.                     mask>>=1;
  5024.                     c++;
  5025.                 }
  5026.             }
  5027.  
  5028.             fillbuf((c<7) ? 3 : c-3);
  5029.             *ptlen++=c;
  5030.  
  5031.             i++;
  5032.             if (i==i_special)
  5033.             {
  5034.                 i+=(c=getbits(2));
  5035.                 mask=0;
  5036.                 while (--c>=0)
  5037.                     *ptlen++=mask;
  5038.             }
  5039.         }
  5040.  
  5041.         c=0;
  5042.         n=nn;
  5043.         while (i<n)
  5044.         {
  5045.             *ptlen++=c;
  5046.             i++;
  5047.         }
  5048.  
  5049.         if (!make_table(n,pt_len,8,pt_table))
  5050.             return(FAULT);
  5051.     }
  5052.  
  5053.     return(SUCCS);
  5054. }
  5055.  
  5056. int read_c_len(void)
  5057. {
  5058.     register uchar *clen=c_len;
  5059.     register int n,i;
  5060.  
  5061.     if ((n=getbits(CBIT))==0)
  5062.     {
  5063.         register ulong *daddy=(ulong *) dad,k;
  5064.  
  5065.         for (i=(NC>>1),k=0;--i>=0;*((int *) clen)++=(int) k);
  5066.         k=getbits(CBIT);
  5067.         k=(k<<16)|k;
  5068.         for (i=2048;--i>=0;*daddy++=k);
  5069.     }
  5070.     else
  5071.     {
  5072.         register ushort *pttable=pt_table;
  5073.         register uint mask,bibu;
  5074.         register int c;
  5075.  
  5076.         i=0;
  5077.         while (i<n)
  5078.         {
  5079.             bibu=bitbuf;
  5080.             c=pttable[bibu>>8];
  5081.             if (c>=NT)
  5082.             {
  5083.                 mask=1U<<7;
  5084.                 do
  5085.                 {
  5086.                     if (bibu&mask)
  5087.                         c=right[c];
  5088.                     else
  5089.                         c=left[c];
  5090.                     mask>>=1;
  5091.                 } while (c>=NT);
  5092.             }
  5093.  
  5094.             fillbuf(pt_len[c]);
  5095.             if (c>2)
  5096.             {
  5097.                 *clen++=(c-2);
  5098.                 i++;
  5099.             }
  5100.             else if (c)
  5101.             {
  5102.                 if (--c==0)
  5103.                     c=getbits(4)+3;
  5104.                 else
  5105.                     c=getbits(CBIT)+20;
  5106.                 i+=c;
  5107.                 mask=0;
  5108.                 while (--c>=0)
  5109.                     *clen++=mask;
  5110.             }
  5111.             else
  5112.             {
  5113.                 *clen++=c;
  5114.                 i++;
  5115.             }
  5116.         }
  5117.  
  5118.         mask=0;
  5119.         bibu=NC;
  5120.         while (i<bibu)
  5121.         {
  5122.             *clen++=mask;
  5123.             i++;
  5124.         }
  5125.  
  5126.         if (!make_table(NC,c_len,12,(ushort *) dad))
  5127.             return(FAULT);
  5128.     }
  5129.  
  5130.     return(SUCCS);
  5131. }
  5132.  
  5133. void make_len(int root)
  5134. {
  5135.     register int i,k;
  5136.     register uint cum=0;
  5137.     register ushort *lencnt=len_cnt,*spt=sortptr;
  5138.  
  5139.     for (i=17;--i>=0;)
  5140.         *lencnt++=cum;
  5141.  
  5142.     count_len(root);
  5143.     for (i=17,k=0,lencnt=&len_cnt[17];--i>=0;)
  5144.         cum+=(*--lencnt)<<(k++);
  5145.  
  5146.     while (cum!=(1U<<16))
  5147.     {
  5148.         len_cnt[16]--;
  5149.  
  5150.         for (i=17,lencnt=&len_cnt[17];--i>=0;)
  5151.             if (*--lencnt)
  5152.             {
  5153.                 lencnt[0]--;
  5154.                 lencnt[1]+=2;
  5155.                 break;
  5156.             }
  5157.         cum--;
  5158.     }
  5159.  
  5160.     for (i=17,lencnt=&len_cnt[17];--i>=0;)
  5161.     {
  5162.         k=*--lencnt;
  5163.         while (--k>=0)
  5164.             len[*spt++]=i;
  5165.     }
  5166.  
  5167.     sortptr=spt;
  5168. }
  5169.  
  5170. void print_title(uchar **argv)
  5171. {
  5172.     #if BETA==0
  5173.     register uchar *env;
  5174.     #endif
  5175.  
  5176.     if (!ptitel)
  5177.     {
  5178.         print(title,1);
  5179.         ptitel++;
  5180.     }
  5181.  
  5182.     #if BETA
  5183.     if (!pargs)
  5184.     #else
  5185.     if (!pargs && (env=get_env("LHARCPAR"))!=NULL && atoi(env))
  5186.     #endif
  5187.     {
  5188.         register int i;
  5189.  
  5190.         pargs++;
  5191.         #if GERMAN
  5192.         print("Argumente:",1);
  5193.         #else
  5194.         print("Arguments:",1);
  5195.         #endif
  5196.  
  5197.         for (i=1;i<args;i++)
  5198.         {
  5199.             sprintf(print_buf,"'%s'",argv[i]);
  5200.             Print(1);
  5201.         }
  5202.  
  5203.         print(NULL,1);
  5204.     }
  5205. }
  5206.  
  5207. uchar *get_ext(void)
  5208. {
  5209.     if (case_sensitive(arcname)!=_PC_CASESENS)
  5210. #ifdef __SHELL__
  5211.         return((cmdupdate || shell || flg_W) ? ".LZH" : ".L[HZ][HAS]");
  5212.     else
  5213.         return((cmdupdate || shell || flg_W) ? ".lzh" : ".l[hz][has]");
  5214. #else
  5215.         return((cmdupdate || flg_W) ? ".LZH" : ".L[HZ][HAS]");
  5216.     else
  5217.         return((cmdupdate || flg_W) ? ".lzh" : ".l[hz][has]");
  5218. #endif
  5219. }
  5220.  
  5221. uchar *device(uchar *name)
  5222. {
  5223.     if (name[3]==':')
  5224.         name[3]='\0';
  5225.  
  5226.     if (!stricmp(name,"PRN") || !stricmp(name,"PRT"))
  5227.         return("PRN:");
  5228.     else if (!stricmp(name,"AUX"))
  5229.         return("AUX:");
  5230.     else if (!stricmp(name,"CON"))
  5231.         return("CON:");
  5232.     else
  5233.     {
  5234.         fnamecnv(name,-1);
  5235.         return(name);
  5236.     }
  5237. }
  5238.  
  5239. int unified_drv(uchar *fname)
  5240. {
  5241.     register uchar buf[MAXPATH],*path;
  5242.  
  5243.     if (__mint)
  5244.     {
  5245.         if (get_fname(fname)==fname)
  5246.             path=act_dir;
  5247.         else
  5248.             path=fname;
  5249.  
  5250.         if (path[0]=='\0' || path[1]!=':')
  5251.         {
  5252.             buf[0]=Dgetdrv()+'a';
  5253.             buf[1]=':';
  5254.             if (path[0]!='\\')
  5255.             {
  5256.                 buf[2]='\\';
  5257.                 strcpy(buf+3,path);
  5258.             }
  5259.             else
  5260.                 strcpy(buf+2,path);
  5261.         }
  5262.         else
  5263.             strcpy(buf,path);
  5264.  
  5265.         strupr(buf);
  5266.  
  5267.         if (buf[0]=='U')
  5268.         {
  5269.             if (!strncmp(buf+3,"DEV\\",4))
  5270.                 return(1);
  5271.             else if (!strncmp(buf+3,"SHM\\",4) || !strncmp(buf+3,"PROC\\",5) || !strncmp(buf+3,"PIPE\\",5))
  5272.                 return(-1);
  5273.         }
  5274.     }
  5275.  
  5276.     return(0);
  5277. }
  5278.  
  5279. void ioredirect(int argc,uchar **argv)
  5280. {
  5281.     register uchar *p,c;
  5282.     register int i;
  5283.  
  5284.     for (i=0;i<argc;i++)
  5285.     {
  5286.         p=*argv++;
  5287.  
  5288.         if ((c=*p++)=='>' && o_handle<0)
  5289.         {
  5290.             if (!args)
  5291.                 args=i;
  5292.  
  5293.             if (*p=='>')
  5294.             {
  5295.                 if ((o_handle=Fopen(o_dir=device(++p),1))>=0)
  5296.                 {
  5297.                     o_dev=Fdup(1);
  5298.                     Fseek(0l,(int) o_handle,SEEK_END);
  5299.                     Fforce(1,(int) o_handle);
  5300.                     continue;
  5301.                 }
  5302.             }
  5303.  
  5304.             if ((o_handle=Fcreate(o_dir=device(p),0))>=0)
  5305.             {
  5306.                 o_dev=Fdup(1);
  5307.                 Fforce(1,(int) o_handle);
  5308.             }
  5309.         }
  5310.         else if (c=='<' && i_handle<0)
  5311.         {
  5312.             if (!args)
  5313.                 args=i;
  5314.  
  5315.             if ((i_handle=Fopen(p,0))>=0)
  5316.             {
  5317.                 i_dev=Fdup(0);
  5318.                 Fforce(0,(int) i_handle);
  5319.                 flg_m=1;
  5320.             }
  5321.         }
  5322.     }
  5323. }
  5324.  
  5325. void init_lharc(void)
  5326. {
  5327.     register uchar *env;
  5328.     register int c;
  5329.  
  5330.     if ((env=get_env("COLUMNS"))!=NULL)
  5331.     {
  5332.         maxblk=atoi(env) - 16;
  5333.         if (maxblk<24)
  5334.             maxblk=24;
  5335.     }
  5336.  
  5337.     _lseed=clock();
  5338.  
  5339.     mkcrc();
  5340.     Fsetdta(&_dta);
  5341.  
  5342.     stdout->_flag |= _IOBIN;
  5343.  
  5344.     if (__mint)
  5345.         oldtos=0;
  5346.     else
  5347.     {
  5348.         register uint vers=Sversion();
  5349.  
  5350.         vers=(vers<<8) | (vers>>8);
  5351.         oldtos=(vers<0x0014);
  5352.     }
  5353.  
  5354.     buffer_gen=(uchar *) (((long) (buffer+16)) & (~15l));
  5355.  
  5356.     env=upper;
  5357.     for (c=0;c<256;c++)
  5358.         if (c>='a' && c<='z')
  5359.             *env++=c^32;
  5360.         else if (c=='ü')
  5361.             *env++='Ü';
  5362.         else if (c=='ö')
  5363.             *env++='Ö';
  5364.         else if (c=='ä')
  5365.             *env++='Ä';
  5366.         else
  5367.             *env++=c;
  5368.  
  5369.     getcwd(act_dir,MAXPATH);
  5370.     unix2dos(act_dir,0);
  5371.     slash(act_dir,1);
  5372.     fnamecnv(act_dir,-1);
  5373. }
  5374.  
  5375. #ifndef __SHELL__
  5376. void main(int argc,uchar **argv)
  5377. #else
  5378. void argvmain(int argc,uchar **argv)
  5379. #endif
  5380. {
  5381.     register uchar *p,*q,*env,*env9,**old_argv=argv;
  5382.  
  5383. #ifndef __SHELL__
  5384.     init_lharc();
  5385.     ioredirect(argc,argv);
  5386. #else
  5387.     if (!shell)
  5388.         ioredirect(argc,argv);
  5389. #endif
  5390.     if (args)
  5391.         argc=args;
  5392.     else
  5393.         args=argc;
  5394.  
  5395.     argc--;
  5396. #ifndef __SHELL__
  5397.     if (argc<=0)
  5398.     {
  5399.         flg_h++;
  5400.         print(title_x,1);
  5401.         print(use_1,1);
  5402.         wait_for_key(0);
  5403.         print(use_2,1);
  5404.         wait_for_key(0);
  5405.         print(use_3,1);
  5406.     }
  5407.     else
  5408. #endif
  5409.     {
  5410.         Fsetdta(&_dta);
  5411.  
  5412.         fileptr=fileregbuf;
  5413.         *fileptr++='*';
  5414.         *fileptr++='\0';
  5415.  
  5416.         arcname[0]='\0';
  5417.  
  5418.         argv++;
  5419.         argc--;
  5420.         cmd=toupper(*(p=*argv++));
  5421.  
  5422. #ifndef __SHELL__
  5423.         if (p[1]!='\0' || strchr("EXTDLVAUMFPRSC",cmd)==NULL || !argc)
  5424.         {
  5425.             register uchar dir[MAXPATH];
  5426.             register int compr;
  5427.  
  5428.             fnamecnv(p,-1);
  5429.             if ((q=strstr(p,"*.*"))>NULL)
  5430.             {
  5431.                 if (q==p)
  5432.                     p=strcpy(dir,act_dir);
  5433.                 else
  5434.                     *q='\0';
  5435.             }
  5436.             slash(p,0);
  5437.  
  5438.             if (Attrib(p) & FA_DIR)
  5439.                 compr=1;
  5440.             else
  5441.             {
  5442.                 switch (test_afx(p))
  5443.                 {
  5444.                 case 3:
  5445.                     {
  5446.                         register uchar *b=buffer_gen;
  5447.  
  5448.                         q=b+2048l;
  5449.                         compr=1;
  5450.  
  5451.                         while (b<q)
  5452.                         {
  5453.                             if (!strncmp(b,"SFX",3))
  5454.                                 goto _extract;
  5455.                             else if (*b++=='-' && b[3]=='-' && (*b=='a' || *b=='A' || *b=='l' || *b=='L'))
  5456.                                 break;
  5457.                         }
  5458.                     }
  5459.                     break;
  5460.                 case 2:
  5461.                     _extract:
  5462.                     compr=0;
  5463.                     break;
  5464.                 default:
  5465.                     compr=1;
  5466.                 }
  5467.             }
  5468.  
  5469.             if (strpbrk(get_fname(p),"*?")==NULL && compr)
  5470.             {
  5471.                 cmd='U';
  5472.                 pack++;
  5473.  
  5474.                 strcpy(arcname,p);
  5475.                 p=get_fname(p);
  5476.                 if ((q=strrchr(p,'.'))!=NULL)
  5477.                     *q='\0';
  5478.  
  5479.                 cmdupdate=SUCCS;
  5480.                 strcpy(stpcpy(backpath(arcname),p),get_ext());
  5481.  
  5482.                 if (q)
  5483.                     *q='.';
  5484.             }
  5485.             else
  5486.             {
  5487.                 cmd='X';
  5488.                 flg_g++;
  5489.                 backpath(strcpy(basedir,p));
  5490.                 base++;
  5491.                 pack+=2;
  5492.             }
  5493.  
  5494.             flg_x=3;
  5495.             flg_m++;
  5496.             argc++;
  5497.             argv--;
  5498.         }
  5499. #endif
  5500.  
  5501.         cmdupdate=strchr("AUMFRD",cmd)!=NULL;
  5502.         cmdlist=strchr("AUMC",cmd)!=NULL;
  5503.  
  5504.         if ((env=get_env("TMP"))!=NULL || (env=get_env("TMPDIR"))!=NULL || (env=get_env("ARCTEMP"))!=NULL)
  5505.         {
  5506.             flg_w++;
  5507.             strcpy(workdir,env);
  5508.         }
  5509.  
  5510.         if ((env=get_env("LHARCDIR"))!=NULL)
  5511.             slash(strcpy(basedir,env),1);
  5512.  
  5513.         if ((env=get_env("UNPACKED"))!=NULL)
  5514.         {
  5515.             flg_U++;
  5516.             unpack=env;
  5517.         }
  5518.  
  5519.         if ((env=get_env("LHARC"))!=NULL || (env=get_env("LHA"))!=NULL)
  5520.         {
  5521.             for (p=env;*p;p++)
  5522.                 if (*p==' ' || *p=='\x08')
  5523.                     *p=0;
  5524.             env9=p;
  5525.             p=env;
  5526.             while (p<env9)
  5527.             {
  5528.                 while (!*p)
  5529.                     p++;
  5530.                 if (*p=='-' || *p=='/')
  5531.                     p++;
  5532.                 getsw(p);
  5533.                 while (*p)
  5534.                     p++;
  5535.             }
  5536.         }
  5537.  
  5538.         if (cmd=='C' || arcname[0])
  5539.             patno=0;
  5540.         else
  5541.             patno=-1;
  5542.  
  5543.         while (argc--)
  5544.         {
  5545.             p=*argv++;
  5546.             if (*p=='-')
  5547.             {
  5548.                 getsw(++p);
  5549.                 continue;
  5550.             }
  5551.             else if (*p=='/' && patno<0 && tstsw(p+1))
  5552.             {
  5553.                 if (cmdupdate && (wildcard(get_fname(p+1)) || multi_wild(p+1)))
  5554.                 {
  5555.                     getsw(++p);
  5556.                     continue;
  5557.                 }
  5558.                 else if ((q=strrchr(get_fname(p),'.'))==NULL || arc_ext(q)==FAULT)
  5559.                 {
  5560.                     getsw(++p);
  5561.                     continue;
  5562.                 }
  5563.             }
  5564.  
  5565.             print_title(old_argv);
  5566.             fnamecnv(p,-1);
  5567.  
  5568.             if (patno<0)
  5569.             {
  5570.                 p=get_fname(strcpy(arcname,p));
  5571.  
  5572.                 if (*p=='\0' || (Device=unified_drv(arcname))<0)
  5573.                     error(NOARCNMERR,NULL,SUCCS);
  5574.  
  5575.                 multi_arc=multi_wild(p);
  5576.  
  5577.                 if (cmdupdate && (strpbrk(p,"*?") || multi_arc))
  5578.                     error(NOARCNMERR,arcname,SUCCS);
  5579.  
  5580.                 if (!multi_arc && !Device)
  5581.                 {
  5582.                     if ((q=strrchr(p,'.'))==NULL)
  5583.                         strcat(arcname,get_ext());
  5584.                     else if (q[1]=='\0')
  5585.                         strcpy(q,get_ext());
  5586.                     else if (flg_m!=1 && cmdupdate && arc_ext(q)==FAULT)
  5587.                     {
  5588.                         sprintf(print_buf,M_NOTLZH,get_fname(arcname));
  5589.                         Print(0);
  5590.  
  5591.                         if (get_key("YN")=='N')
  5592.                         {
  5593.                             errorlevel|=128;
  5594.                             lha_exit();
  5595.                         }
  5596.                     }
  5597.                 }
  5598.  
  5599.                 wild_arc=wildcard(p)|multi_arc;
  5600.                 patno++;
  5601.             }
  5602.         #ifdef __SHELL__
  5603.             else
  5604.         #else
  5605.             else if (pack<2)
  5606.         #endif
  5607.             {
  5608.             #ifndef __SHELL__
  5609.                 if (pack)
  5610.                 {
  5611.                     slash(p,0);
  5612.  
  5613.                     if (strstr(p,"*.*")!=NULL)
  5614.                         flg_r++;
  5615.                     else if (Attrib(p) & FA_DIR)
  5616.                     {
  5617.                         register uchar path[MAXPATH];
  5618.  
  5619.                         flg_r++;
  5620.                         slash(strcpy(path,p),1);
  5621.                         if ((p=strdup(path))==NULL)
  5622.                             error(MEMOVRERR,NULL,SUCCS);
  5623.                     }
  5624.                 }
  5625.             #endif
  5626.  
  5627.                 newfile(p);
  5628.             }
  5629.         }
  5630.  
  5631.     #ifndef __SHELL__
  5632.         if (args>2 && pack==1)
  5633.             pack=0;
  5634.         else if (pack==2)
  5635.             pack=0;
  5636.     #endif
  5637.  
  5638.         print_title(old_argv);
  5639.  
  5640.         if (patno<0)
  5641.             error(NOARCNMERR,NULL,SUCCS);
  5642.         else if (!patno && cmd!='D')
  5643.         {
  5644.             travel_path[0]="";
  5645.             travel_len[0]=travel_file[0]=travel_rel[0]=0;
  5646.             travel_wild[0]=all=SUCCS;
  5647.             patno++;
  5648.             flg_p=0;
  5649.         }
  5650.  
  5651.         fn_name=path_conf(basedir,_PC_NAME_MAX);
  5652.         if (fn_name>64)
  5653.             fn_name=64;
  5654.         else if (fn_name<=0)
  5655.             fn_name=12;
  5656.  
  5657.         pt_name=path_conf(basedir,_PC_PATH_MAX);
  5658.         if (pt_name<=0 || pt_name>MAXPATH)
  5659.             pt_name=MAXPATH;
  5660.         Case=case_sensitive(basedir);
  5661.  
  5662.         unix2dos(workdir,0);
  5663.         slash(workdir,1);
  5664.         fnamecnv(workdir,-1);
  5665.  
  5666.         if (flg_w && (cmdupdate || cmd=='P' || flg_d))
  5667.             tstdir(workdir,-1);
  5668.  
  5669.         if (Device)
  5670.         {
  5671.             if (strchr("AMUEXTPLV",cmd)==NULL)
  5672.                 error(NOARCERR,arcname,SUCCS);
  5673.             else if (strchr("EXTP",cmd))
  5674.                 flg_d=0;
  5675.             flg_w=0;
  5676.         }
  5677.  
  5678.         MakeBuffers();
  5679.  
  5680.         if (cmdupdate || cmd=='C')
  5681.             executecmd();
  5682.         else
  5683.         {
  5684.             register uchar *f,*p,*q,arc[MAXPATH];
  5685.             register long handle,buf[MAXPATH>>2];
  5686.             register int done,cnt=0,len,compare,Case;
  5687.  
  5688.             if (__mint)
  5689.                 _gemdos=(path_conf(arcname,_PC_NAME_MAX)==12 && case_sensitive(arcname)==_PC_CASECONV);
  5690.  
  5691.             if (!_gemdos)
  5692.             {
  5693.                 backpath(strcpy(arc,arcname));
  5694.  
  5695.                 if (arc[0]!='\0')
  5696.                     handle=Dopendir(arc,0);
  5697.                 else
  5698.                     handle=Dopendir(act_dir,0);
  5699.  
  5700.                 if ((handle&0xff000000l)==0xff000000l)
  5701.                     error(NOARCERR,arcname,SUCCS);
  5702.                 else
  5703.                     done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  5704.                 f=(uchar *) &buf[1];
  5705.             }
  5706.             else
  5707.             {
  5708.                 strcpy(arc,arcname);
  5709.                 if (wild_arc)
  5710.                     strcpy(backpath(arc),"*.*");
  5711.                 done=Fsfirst(arc,0x07);
  5712.                 f=_dta.dta_name;
  5713.             }
  5714.  
  5715.             Case=case_sensitive(arcname);
  5716.             compare=(_gemdos || (!flg_S && Case!=_PC_CASESENS));
  5717.             q=get_fname(arcname);
  5718.             p=backpath(arc);
  5719.  
  5720.             while(!done)
  5721.             {
  5722.                 strcpy(p,f);
  5723.                 if (compare)
  5724.                     strcnv(p,SUCCS);
  5725.  
  5726.                 if (tst_fname(f) && ((_gemdos && wild_arc==FAULT) || chk_wild(p,q,flg_W,Case)))
  5727.                 {
  5728.                     if (o_dir && !fnamecmp(p,o_dir,_PC_CASESENS))
  5729.                         goto arc_next;
  5730.  
  5731.                     strcpy(p,f);
  5732.  
  5733.                     if (!_gemdos)
  5734.                     {
  5735.                         read_attr(arc,&_dta);
  5736.                         if (_dta.dta_attribute & (FA_LABEL|FA_DIR))
  5737.                             goto arc_next;
  5738.                     }
  5739.  
  5740.                     if (cnt<MAX_ARC)
  5741.                     {
  5742.                         len=(int) strlen(f)+1;
  5743.                         if ((fileptr-fileregbuf+len)>=(FILEBUFSIZ-1))
  5744.                             message(M_FILETAB,f);
  5745.                         else
  5746.                         {
  5747.                             strcpy(fileptr,f);
  5748.                             arc_file[cnt++]=(int) (fileptr-fileregbuf);
  5749.                             fileptr+=len;
  5750.                         }
  5751.                     }
  5752.                     else
  5753.                         message(M_FILETAB,f);
  5754.                 }
  5755.  
  5756.                 arc_next:
  5757.                 if (_gemdos)
  5758.                     done=Fsnext();
  5759.                 else
  5760.                     done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  5761.             }
  5762.  
  5763.             if (!_gemdos)
  5764.                 Dclosedir(handle);
  5765.  
  5766.             if (!cnt)
  5767.                 error(NOARCERR,arcname,SUCCS);
  5768.             else
  5769.             {
  5770.             #if GERMAN
  5771.                 sprintf(print_buf," Archive gefunden : %d",cnt);
  5772.             #else
  5773.                 sprintf(print_buf," Archives matched : %d",cnt);
  5774.             #endif
  5775.                 Print(1);
  5776.  
  5777.                 if (__mint)
  5778.                     _gemdos=(fn_name==12 && Case==_PC_CASECONV);
  5779.                 q=basedir+strlen(basedir);
  5780.  
  5781.                 while(--cnt>=0)
  5782.                 {
  5783.                     f=&fileregbuf[arc_file[cnt]];
  5784.                     strcpy(backpath(arcname),f);
  5785.                     if (cmd=='X' || cmd=='E')
  5786.                     {
  5787.                         if (flg_g && (p=strrchr(f,'.'))!=NULL)
  5788.                         {
  5789.                             *p='\0';
  5790.                             strcpy(stpcpy(q,f),"\\");
  5791.                         }
  5792.  
  5793.                         tstdir(basedir,-1);
  5794.                     }
  5795.  
  5796.                     executecmd();
  5797.                 }
  5798.             }
  5799.  
  5800.             if (cmd!='L' && cmd!='V')
  5801.                 tstpat();
  5802.         }
  5803.     }
  5804.  
  5805.     lha_exit();
  5806. }
  5807.