"Fossies" - the Fresh Open Source Software Archive

Member "sfk-1.9.6/sfkbase.hpp" (22 Feb 2020, 84589 Bytes) of package /linux/misc/sfk-1.9.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sfkbase.hpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.9.5_vs_1.9.6.

    1 #ifndef _SFKBASE_HPP_
    2 #define _SFKBASE_HPP_
    3 /*
    4    swiss file knife base include
    5 */
    6 
    7 // ========== core includes and operating system abstraction ==========
    8 
    9 // enable LFS esp. on linux:
   10 #define _LARGEFILE_SOURCE
   11 #define _LARGEFILE64_SOURCE
   12 #define _FILE_OFFSET_BITS 64
   13 
   14 #ifdef _WIN32
   15  #define WINFULL
   16 #else
   17  #ifdef __APPLE__
   18   #ifndef MAC_OS_X
   19    #define MAC_OS_X
   20   #endif
   21  #endif
   22  #if defined(__sun) && defined(__SVR4)
   23   #define SOLARIS
   24  #endif
   25 #endif
   26 
   27 #include <stdlib.h>
   28 #include <stdio.h>
   29 #include <string.h>
   30 #include <stdarg.h>
   31 #include <ctype.h>
   32 #include <assert.h>
   33 #include <time.h>
   34 #include <math.h>
   35 #include <sys/timeb.h>
   36 #include <sys/types.h>
   37 #include <sys/stat.h>
   38 #include <limits.h>
   39 
   40 #ifdef _WIN32
   41   #define FD_SETSIZE 300
   42   #ifdef _MSC_VER
   43    #ifndef SFKPRO
   44     #define SFKWINST
   45    #endif
   46    #include <comdef.h>
   47    #include <ShlObj.h>
   48    #include <Shlwapi.h>
   49   #endif
   50   #include <windows.h>
   51   #ifndef _MSC_VER
   52    #include <ws2tcpip.h>
   53   #endif
   54   #include <sys/timeb.h>
   55   #include <time.h>
   56   #include <process.h>
   57   #define getpid() _getpid()
   58   #include <errno.h>
   59   #include <direct.h>
   60   #include <signal.h>
   61   #include <io.h>
   62   #ifndef socklen_t
   63    #define socklen_t int
   64   #endif
   65   #ifndef SD_RECEIVE
   66    #define SD_RECEIVE 0x00
   67    #define SD_SEND    0x01
   68    #define SD_BOTH    0x02
   69   #endif
   70   #ifndef SHUT_RD
   71    #define  SHUT_RD   SD_RECEIVE
   72    #define  SHUT_WR   SD_SEND
   73    #define  SHUT_RDWR SD_BOTH
   74   #endif
   75   #define vsnprintf _vsnprintf
   76   #define snprintf  _snprintf
   77   // FILE_ATTRIBUTE_READONLY    0x00000001
   78   // FILE_ATTRIBUTE_HIDDEN      0x00000002
   79   // FILE_ATTRIBUTE_SYSTEM      0x00000004
   80   // FILE_ATTRIBUTE_DIRECTORY   0x00000010
   81   // FILE_ATTRIBUTE_ARCHIVE     0x00000020
   82   // FILE_ATTRIBUTE_NORMAL      0x00000080
   83   // FILE_ATTRIBUTE_TEMPORARY   0x00000100
   84   #define WINFILE_ATTRIB_MASK   0x0000001F
   85 #else
   86   #include <unistd.h>
   87   #include <dirent.h>
   88   #include <sys/stat.h>
   89   #include <netinet/in.h>
   90   #include <sys/socket.h>
   91   #include <sys/ioctl.h>
   92   #include <sys/time.h>
   93   #include <arpa/inet.h>
   94   #include <netdb.h>
   95   #include <errno.h>
   96   #include <sched.h>
   97   #include <signal.h>
   98   #include <sys/statvfs.h>
   99   #include <utime.h>
  100   #include <pthread.h>
  101   #include <pwd.h>
  102   #include <ifaddrs.h>
  103   #include <fcntl.h>
  104   #ifndef MAC_OS_X
  105    #define SFK_NATIVE_LINUX
  106    #include <wait.h>
  107    #include <net/if_arp.h>
  108    #include <linux/sockios.h>
  109   #endif
  110   #ifndef  _S_IFDIR
  111    #define _S_IFDIR 0040000 // = 0x4000
  112   #endif
  113   #ifndef  _S_IREAD
  114    #ifdef S_IREAD
  115     #define _S_IREAD  S_IREAD
  116     #define _S_IWRITE S_IWRITE
  117    #else
  118     #define _S_IREAD  __S_IREAD  // by owner
  119    #define  _S_IWRITE __S_IWRITE // by owner
  120    #endif
  121   #endif
  122   typedef int SOCKET;
  123   #define INVALID_SOCKET -1
  124   #define SOCKET_ERROR   -1
  125   #define ioctlsocket ioctl
  126   #define WSAEWOULDBLOCK EWOULDBLOCK
  127 #endif
  128 
  129 // - - - - - basic types and tracing - - - - -
  130 
  131 #ifdef MAC_OS_X
  132  #define fpos64_t  fpos_t
  133  #define fgetpos64 fgetpos
  134  #define fsetpos64 fsetpos
  135  #define statvfs64 statvfs
  136  #define stat64    stat
  137  #define __dev_t   dev_t
  138 #endif // MAC_OS_X
  139 
  140 #ifdef SOLARIS
  141  #define __dev_t   dev_t
  142  // #define FIONBIO   0
  143 #endif
  144 
  145 #define uchar unsigned char
  146 #define ushort unsigned short
  147 #define uint  unsigned int
  148 #define ulong unsigned long
  149 #define cchar const char
  150 #define str(x) (char*)x
  151 
  152 #ifdef __GNUC__
  153    #if __GNUC__ < 8
  154       #define bool unsigned char
  155    #endif
  156    // else use predefined type
  157 #else
  158    #define bool unsigned char
  159 #endif
  160 
  161 #define mclear(x) memset(&x, 0, sizeof(x))
  162 
  163 #ifdef CALLBACK_TRACING
  164  #define mtklog  cbtrace
  165  #define mtkerr  cbtrace
  166  #define mtkwarn cbtrace
  167  #define mtkdump
  168  #define _
  169  #define __
  170 #else
  171  #ifdef WITH_TRACING
  172   #include "mtk/mtktrace.hpp"
  173   #ifdef MTKTRACE_CODE
  174    #include "mtk/mtktrace.cpp"
  175   #endif
  176   #define _  mtklog(("[sfk %d]",__LINE__));
  177   #define __ MTKBlock tmp983452(__FILE__,__LINE__,"");tmp983452.dummy();
  178  #else
  179   #define mtklog(x)
  180   #define mtkerr(x)
  181   #define mtkwarn(x)
  182   #define mtkdump
  183   #define _
  184   #define __
  185  #endif
  186 #endif
  187 
  188 extern const char  glblPathChar    ;
  189 extern const char  glblWrongPChar  ;
  190 extern const char *glblPathStr     ;
  191 extern const char *glblAddWildCard ;
  192 extern const char *glblDotSlash    ;
  193 extern       char  glblNotChar     ;
  194 extern       char  glblRunChar     ;
  195 extern       char  glblWildChar    ;
  196 
  197 #ifdef _WIN32
  198  #define SFK_FILT_NOT1 "-!"
  199  #define SFK_FILT_NOT2 "-ls!"
  200  #define SFK_FILT_NOT3 "-le!"
  201  #define EXE_EXT ".exe"
  202  #define SFK_SETENV_CMD "set"
  203 #else
  204  #define SFK_FILT_NOT1 "-:"
  205  #define SFK_FILT_NOT2 "-ls:"
  206  #define SFK_FILT_NOT3 "-le:"
  207  #define EXE_EXT ""
  208  #define SFK_SETENV_CMD "export"
  209 #endif
  210 
  211 #define mymin(a,b) ((a<b)?(a):(b))
  212 #define mymax(a,b) ((a>b)?(a):(b))
  213 
  214 // - - - - - 64 bit abstractions - - - - -
  215 
  216 #ifdef WINFULL
  217  #if _MSC_VER >= 1310
  218   #define SFK_W64
  219  #endif
  220  #if _MSC_VER >= 1900 // visual c++ 14.0
  221   #define SFK_NO_MEMTRACE
  222   #define SFK_VC14
  223   #define sfkfinddata64_t _wfinddata64_t
  224  #else
  225   #define sfkfinddata64_t __wfinddata64_t
  226  #endif
  227 #endif
  228 
  229 #ifdef _WIN32
  230  typedef __int64 num;
  231  typedef unsigned __int64 unum;
  232  #ifdef SFK_W64
  233   typedef __time64_t mytime_t;
  234   #define mymktime _mktime64
  235   #define mytime _time64
  236   #ifndef WITH_SSL
  237    // #define time_t bad_time_t_use_mytime_t
  238   #endif
  239  #else
  240   typedef time_t mytime_t;
  241   #define mymktime mktime
  242   #define mytime time
  243  #endif
  244 #else
  245  typedef long long num;
  246  typedef unsigned long long unum;
  247  typedef time_t mytime_t;
  248  #define mymktime mktime
  249  #define mytime time
  250 #endif
  251 
  252 extern struct tm *mylocaltime(mytime_t *ptime);
  253 extern struct tm *mygmtime(mytime_t *ptime);
  254 
  255 extern char *numtostr(num n, int nDigits, char *pszBuf, int nRadix);
  256 extern char *numtoa_blank(num n, int nDigits=12);
  257 extern char *numtoa(num n, int nDigits, char *pszBuf);
  258 extern char *numtohex(num n, int nDigits, char *pszBuf);
  259 extern num   atonum(char *psz);
  260 extern num   myatonum(char *psz);
  261 extern mytime_t getSystemTime();
  262 extern int shrinkFormTextBlock(char *psz, int &rLen, bool bstrict, bool xchars=0, uchar **ppFlags=0);
  263 
  264 #ifndef SIG_UNBLOCK
  265    #define SIG_UNBLOCK 2
  266 #endif
  267 
  268 #ifndef SIGALRM
  269    #define SIGALRM 14
  270 #endif
  271 
  272 #ifndef sigset_t
  273    #define sigset_t int
  274 #endif
  275 
  276 #ifndef sigemptyset
  277    #define sigemptyset(sig)
  278 #endif
  279 
  280 #ifndef sigaddset
  281    #define sigaddset( set, sig)
  282 #endif
  283 
  284 #ifndef sigprocmask
  285    #define sigprocmask(a, b, c)
  286 #endif
  287 
  288 // ========== end core includes and operating system abstraction ==========
  289 
  290 #define SFK18
  291 
  292 #ifndef SFKNOVFILE
  293  #define VFILEBASE
  294  #define VFILENET
  295  // #define USE_WEBCONCACHE
  296 #endif // SFKNOVFILE
  297 
  298 #if defined(SFKPRO)
  299  #ifndef USE_SFK_BASE
  300   #define SFKXDXE // pro compile
  301  #endif
  302 #else
  303  #ifndef USE_SFK_BASE
  304   #if defined(SFKXD) // base+xd
  305    #define SFKXDXE
  306   #else
  307    #define SFKOSE    // default
  308   #endif
  309  #endif // USE_SFK_BASE
  310 #endif // defined(SFKPRO)
  311 
  312 #define WITH_CASE_XNN
  313 #define SFKDEEPZIP   // sfk175
  314 
  315 #ifndef SFKNOPACK
  316  #define SFKPACK     // sfk191
  317  #define SFKOFFICE   // sfk194
  318 #endif
  319 
  320 #ifdef _WIN32
  321  #define SFK_UNAME   // sfk190
  322 #endif
  323 
  324 int isDir(char *pszName);
  325 cchar *sfkLastError();
  326 
  327 #define MAX_ABBUF_SIZE 100000
  328 #define MAX_LINE_LEN     4096
  329 
  330 class Coi;
  331 extern int (*pGlblJamCheckCallBack)(char *pszFilename);
  332 extern int (*pGlblJamFileCallBack)(char *pszFilename, num &rLines, num &rBytes);
  333 extern int (*pGlblJamLineCallBack)(char *pszLine, int nLineLen, bool bAddLF);
  334 extern int (*pGlblJamStatCallBack)(Coi *pCoiOrNull, uint nFiles, uint nLines, uint nMBytes, uint nSkipped, char *pszSkipInfo);
  335 extern int (*pGlblShowDataCallBack)(char *pszLine, int nLineLen);
  336 extern int bGlblPassThroughSnap;
  337 
  338 char *findPathLocation(cchar *pszCmd, bool bExcludeWorkDir=0);
  339 extern int fileExists(char *pszFileName, bool bOrDir=0);
  340 
  341 #define strcopy(dst,src) mystrcopy(dst,src,sizeof(dst)-10)
  342 void  mystrcopy      (char *pszDst, cchar *pszSrc, int nMaxDst);
  343 char *mystrstri      (char *phay, cchar *ppat);
  344 int  mystrstrip      (char *pszHayStack, cchar *pszNeedle, int *lpAtPosition);
  345 char *mystrrstr      (char *psrc, cchar *ppat);
  346 char *mystrristr     (char *psrc, cchar *ppat);
  347 int  mystrncmp      (char *psz1, cchar *psz2, int nLen, bool bCase=0);
  348 int  mystricmp      (char *psz1, cchar *psz2);
  349 int  mystrnicmp     (char *psz1, cchar *psz2, int nLen);
  350 bool  strBegins      (char *pszStr, cchar *pszPat);
  351 bool  striBegins     (char *pszStr, cchar *pszPat);
  352 bool  strEnds        (char *pszStr, cchar *pszPat);
  353 void  trimCR         (char *pszBuf);
  354 void  removeCRLF     (char *pszBuf);
  355 bool  sfkisalpha     (uchar uc);
  356 bool  sfkisalnum     (uchar uc);
  357 bool  sfkisprint     (uchar uc);
  358 void  myrtrim        (char *pszBuf);
  359 void  skipToWhite    (char **pp);
  360 void  skipWhite      (char **pp);
  361 
  362 char *loadFile       (char *pszFile, bool bquiet=0);
  363 num   getFileSize    (char *pszName);
  364 num   getCurrentTime ( );
  365 num   atonum         (char *psz);   // decimal only
  366 num   myatonum       (char *psz);   // with 0x support
  367 char *numtoa         (num n, int nDigits=1, char *pszBuf=0);
  368 char *numtohex       (num n, int nDigits=1, char *pszBuf=0);
  369 int  timeFromString  (char *psz, num &nRetTime, bool bsilent=0, bool bUTC=0);
  370 void  doSleep        (int nmsec);
  371 uchar *loadBinaryFile(char *pszFile, num &rnFileSize);
  372 uchar *loadBinaryFlex(char *pszFile, num &rnFileSize);
  373 bool  infoAllowed    ( );
  374 struct hostent *sfkhostbyname(const char *pstr, bool bsilent=0);
  375 int   setaddr(struct sockaddr_in *paddr, char *pszHostOrIPPart, int iflags=0);
  376 
  377 class IOStatusPhase {
  378 public:
  379       IOStatusPhase  (cchar *pinfo);
  380      ~IOStatusPhase  ( );
  381 };
  382 
  383 void  resetIOStatus  ( );
  384 num   countIOBytes   (num nbytes);
  385 char  *getIOStatus   (num &nagemsec, num &nbytes, num &nmaxbytes);
  386 // returns NULL if no status is set
  387 
  388 class CharAutoDel {
  389 public:
  390       CharAutoDel (char *p) { pClPtr = p; }
  391      ~CharAutoDel ( )       { if (pClPtr) delete [] pClPtr; }
  392      void deleteNow ( )     { if (pClPtr) delete [] pClPtr; pClPtr = 0; }
  393 private:
  394       char *pClPtr;
  395 };
  396 
  397 class UCharAutoDel {
  398 public:
  399       UCharAutoDel (uchar *p) { pClPtr = p; }
  400      ~UCharAutoDel ( )        { if (pClPtr) delete [] pClPtr; }
  401       void deleteNow ( )      { if (pClPtr) delete [] pClPtr; pClPtr = 0; }
  402 private:
  403       uchar *pClPtr;
  404 };
  405 
  406 class CharAutoDelPP {
  407 public:
  408       CharAutoDelPP (char **pp) { ppClPtr = pp; }
  409      ~CharAutoDelPP ( )         { if (*ppClPtr) delete [] *ppClPtr; }
  410 private:
  411       char **ppClPtr;
  412 };
  413 
  414 class AutoRestoreInt {
  415 public:
  416       AutoRestoreInt (int *pInt) { pClPtr = pInt; iClVal = *pInt; }
  417      ~AutoRestoreInt ( )         { *pClPtr = iClVal; }
  418 private:
  419       int *pClPtr;
  420       int  iClVal;
  421 };
  422 
  423 // max length of sfk (internal) filenames and URL's
  424 #define SFK_MAX_PATH 512
  425 
  426 #ifdef  MAX_PATH
  427  #undef MAX_PATH
  428 #endif
  429 #define MAX_PATH error_use_sfk_max_path
  430 
  431 #ifdef  PATH_MAX
  432  #undef PATH_MAX
  433 #endif
  434 #define PATH_MAX error_use_sfk_max_path
  435 
  436 #ifdef VFILEBASE
  437 extern void  setDiskCacheActive(bool b);
  438 extern bool  getDiskCacheActive( );
  439 extern void  setDiskCachePath(char *p);
  440 extern char *getDiskCachePath( );
  441 #endif // VFILEBASE
  442 
  443 extern void myclosesocket(SOCKET hsock, bool bread=1, bool bwrite=1);
  444 bool userInterrupt   (bool bSilent=0, bool bWaitForRelease=0);
  445 
  446 // some linux/mac sys\param.h define that:
  447 #ifdef isset
  448  #undef isset
  449 #endif
  450 
  451 typedef unsigned uint32_t;
  452 
  453 class SFKMD5
  454 {
  455 public:
  456     SFKMD5  ( );
  457    ~SFKMD5  ( );
  458 
  459    void   update  (uchar *pData, uint32_t nLen);
  460    uchar *digest  ( );
  461    void   reset   ( );
  462 
  463 private:
  464    void   update     (uchar c);
  465    void   transform  ( );
  466 
  467    uint32_t nClCntHigh, nClCntLow;
  468    uchar    *pClBuf;
  469    uint32_t nClBufLen,nClBufCnt;
  470    uchar    *pClDig;
  471    uint32_t nClDigLen;
  472    uchar    aClBuf[100];
  473    uchar    aClDig[100];
  474    uint32_t alClSta[4];
  475    uint32_t alClBuf[16];
  476    uint32_t nClCRC;
  477    bool     bClDigDone;
  478 };
  479 
  480 // map of managed keys and NOT MANAGED values.
  481 class KeyMap {
  482 public:
  483       KeyMap   ( );
  484      ~KeyMap   ( );
  485 
  486    void  reset ( );
  487    // removes all entries. keys are deleted.
  488    // values are not deleted, as their type is unknown.
  489 
  490    int  put   (char *pkey, void *pvalue=0);
  491    // set a key, or put a value under a key.
  492    // the key is copied. pvalue is not copied.
  493    // if the key exists already, old pvalue is replaced.
  494    // rc 0:done >0:error.
  495 
  496    void  *get  (char *pkey, int *poutidx=0);
  497    // if a value was stored then it is returned.
  498    // if not, null is returned, no matter if the key is set.
  499    // if poutidx is given, it returns the nearest comparison index,
  500    // even if no direct hit for the key was found. this index
  501    // however must be used with care, as it can be < 0 or >= size.
  502 
  503    bool  isset (char *pkey);
  504    // tell if the key was ever put (with or without value).
  505    // rc: 0:not_set 1:is_set.
  506 
  507    void  setcase(bool bYesNo);
  508    // default for key comparison is CASE SENSITIVE.
  509    // use setcase(0) to select CASE INSENSITIVE.
  510 
  511    void  setreverse(bool bYesNo);
  512    // toggle reverse sorting order.
  513 
  514    int  remove(char *pkey);
  515    // remove entry with that key, if any.
  516    // rc: 0:done 1:no_such_key >=5:error.
  517 
  518    void *iget  (int nindex, char **ppkey=0);
  519    // walk through map entries, sorted by the key.
  520    // nindex must be 0 ... size()-1.
  521    // returns value, if any.
  522    // if key ptr is provided, it is set.
  523 
  524    int  put   (num nkey, void *pvalue=0);
  525    void *get   (num nkey);
  526    bool  isset (num nkey);
  527    int  remove(num nkey);
  528    void *iget  (int nindex, num *pkey);
  529 
  530    int  size  ( );
  531    // number of entries in KeyMap.
  532 
  533 protected:
  534    void  wipe     ( );
  535    int  expand   (int n);
  536    int   bfind    (char *pkey, int &rindex);
  537    int  remove   (int nindex);
  538 
  539    int  nClArrayAlloc;
  540    int  nClArrayUsed;
  541    char  **apClKey;
  542    void  **apClVal;
  543 
  544    bool  bClCase;
  545    bool  bClRev;
  546 };
  547 
  548 // map of MANAGED string values.
  549 class StringMap : public KeyMap {
  550 public:
  551       StringMap   ( );
  552      ~StringMap   ( );
  553 
  554    void  reset    ( );
  555 
  556    int  put      (char *pkey, char *pvalue);
  557    // value is COPIED and MANAGED by StringMap.
  558    // also accepts NULL values, if you want to use
  559    // only isset() instead of get.
  560 
  561    char  *get     (char *pkey, char *pszOptDefault=0);
  562    char  *iget    (int nindex, char **ppkey);
  563    int   remove  (char *pkey);
  564 
  565    int  put      (num nkey, char *pvalue);
  566    char *get      (num nkey);
  567    char *iget     (int nindex, num *pkey);
  568    int  remove   (num nkey);
  569 };
  570 
  571 // map of MANAGED strings with attributes.
  572 class AttribStringMap : public StringMap {
  573 public:
  574       AttribStringMap   ( );
  575      ~AttribStringMap   ( );
  576 
  577    int  put      (char *pkey, char *ptext, char *pattr);
  578    char  *get     (char *pkey, char **ppattr);
  579    char  *iget    (int nindex, char **ppkey, char **ppattr);
  580 
  581    int  put      (num nkey, char *ptext, char *pattr);
  582    char *get      (num nkey, char **ppattr);
  583    char *iget     (int nindex, num *pkey, char **ppattr);
  584 
  585 private:
  586    char *mixdup   (char *ptext, char *pattr);
  587    int  demix    (char *pmixed, char **pptext, char **ppattr);
  588 };
  589 
  590 class LongTable {
  591 public:
  592    LongTable            ( );
  593   ~LongTable            ( );
  594    int addEntry        (int nValue, int nAtPos=-1);
  595    int updateEntry     (int nValue, int nIndex);
  596    int numberOfEntries ( );
  597    int getEntry        (int iIndex, int nTraceLine);
  598    void resetEntries    ( );
  599 private:
  600    int expand          (int nSoMuch);
  601    int nClArraySize;
  602    int nClArrayUsed;
  603    int *pClArray;
  604 };
  605 
  606 class StringTable {
  607 friend class Array;
  608 public:
  609    StringTable          ( );
  610   ~StringTable          ( );
  611    int addEntry        (char *psz, int nAtPos=-1, char **ppCopy=0);
  612    int removeEntry     (int nAtPos);
  613    int numberOfEntries ( );
  614    char *getEntry       (int iIndex, int nTraceLine);
  615    int  setEntry       (int iIndex, char *psz);
  616    void resetEntries    ( );
  617    bool isSet           (int iIndex);
  618    void dump            (int nIndent=0);
  619    int find            (char *psz); // out: index, or -1
  620 private:
  621    int addEntryPrefixed(char *psz, char cPrefix);
  622    int setEntryPrefixed(int iIndex, char *psz, char cPrefix);
  623    int expand          (int nSoMuch);
  624    int nClArraySize;
  625    int nClArrayUsed;
  626    char **apClArray;
  627 };
  628 
  629 class NumTable {
  630 public:
  631    NumTable            ( );
  632   ~NumTable            ( );
  633    int addEntry        (num nValue, int nAtPos=-1);
  634    int updateEntry     (num nValue, int nAtPos);
  635    int numberOfEntries ( );
  636    num  getEntry        (int iIndex, int nTraceLine);
  637    void resetEntries    ( );
  638 private:
  639    int expand          (int nSoMuch);
  640    int nClArraySize;
  641    int nClArrayUsed;
  642    num  *pClArray;
  643 };
  644 
  645 class Array {
  646 public:
  647    Array                (const char *pszID); // one-dimensional by default
  648   ~Array                ( );
  649    int addString       (char *psz);   // to current row (0 by default)
  650    int addString       (int lRow, char *psz);
  651    int setString       (int lRow, int iIndex, char *psz);
  652    char *getString      (int iIndex); // use isStringSet() before
  653    char *getString      (int lRow, int iIndex);
  654    int addLong         (int nValue, int nTraceLine); // to current row (0 by default)
  655    int addLong         (int lRow, int nValue, int nTraceLine);
  656    int getLong         (int iIndex); // use isLongSet() before
  657    int getLong         (int lRow, int iIndex, int nTraceLine);
  658    int setLong         (int lRow, int iIndex, int nValue, int nTraceLine);
  659    int numberOfEntries ( );           // in current row (0 by default)
  660    int numberOfEntries (int lRow);
  661    bool isLongSet       (int lRow, int iIndex); // index and type test
  662    bool isStringSet     (int iIndex); // index and type test
  663    bool isStringSet     (int lRow, int iIndex);
  664    int addRow          (int nTraceLine); // add empty row, set as current
  665    int setRow          (int iCurRow, int nTraceLine);// set current row
  666    bool hasRow          (int iRow);   // tell if row exists
  667    void reset           ( );           // removes all entries
  668    void dump            ( );
  669    int addNull         (int lRow);
  670 private:
  671    bool isSet           (int iIndex); // in current row (0 by default)
  672    int ensureBase      ( );  // make sure at least one row exists
  673    int expand          (int nSoMuch);
  674    int nClRowsSize;
  675    int nClRowsUsed;
  676    StringTable **apClRows;
  677    int nClCurRow;
  678    const char *pszClID;
  679 };
  680 
  681 class FileSet {
  682 public:
  683    FileSet  ( );
  684   ~FileSet  ( );
  685    int  beginLayer     (bool bWithEmptyCommand, int nTraceLine);
  686    int  addRootDir     (char *pszName, int nTraceLine, bool bNoCmdFillup,
  687                         bool bAutoUseArc=false); // sfk193 addrootdir
  688    int  addDirMask     (char *pszName);
  689    int  addDirCommand  (int);
  690    int  addFileMask    (char *pszName);
  691    int  autoCompleteFileMasks   (int nWhat);
  692    void  setBaseLayer   ( );
  693    void  reset          ( );
  694    void  shutdown       ( );
  695    bool  hasRoot        (int iIndex);
  696    char* setCurrentRoot (int iIndex);
  697    bool  changeFirstRoot(char *pszNewRoot);
  698    char* getCurrentRoot ( );
  699    char* root           (bool braw=0); // like above, but returns "" if none, with braw: 0 if none
  700    int  numberOfRootDirs ( );
  701    Array &rootDirs      ( ) { return clRootDirs; }
  702    Array &dirMasks      ( ) { return clDirMasks; }
  703    Array &fileMasks     ( ) { return clFileMasks; }
  704    bool  anyRootAdded   ( );
  705    bool  anyFileMasks   ( );  // that are non-"*"
  706    char* firstFileMask  ( );  // of current root
  707    void  dump           ( );
  708    void  info           (void (*pout)(int nrectype, char *pline));
  709    int  getDirCommand  ( );  // of current root
  710    int  checkConsistency  ( );
  711    char *currentInfoLine(int iLine);
  712 // private:
  713    int  ensureBase     (int nTraceLine);
  714    void  resetAddFlags  ( ); // per layer
  715    Array clRootDirs;    // row 0: names/str, row 1: command/int, row 2: layer/int
  716    Array clDirMasks;    // row == layer
  717    Array clFileMasks;   // row == layer
  718    int   nClCurDir;
  719    int   nClCurLayer;
  720    char  *pClLineBuf;
  721    int   bClGotAllMask;
  722    int   bClGotPosFile;
  723    int   bClGotNegFile;
  724 };
  725 
  726 class StringPipe
  727 {
  728 public:
  729       StringPipe  ( );
  730       char *read  (char **ppAttr=0);  // returns 0 on EOD
  731       void  resetPipe ( );
  732       bool  eod   ( );
  733       void  dump  (cchar *pszTitle);
  734       int  numberOfEntries ( ) { return clText.numberOfEntries(); }
  735       char *getEntry        (int nIndex, int nLine, char **pAttr=0);
  736       void  resetEntries    ( );
  737       int  addEntry        (char *psz, char *pAttr);
  738       int  setEntry        (int iIndex, char *psz, char *pAttr);
  739 private:
  740    StringTable clText;
  741    StringTable clAttr;
  742    int nReadIndex;
  743 };
  744 
  745 class FileList {
  746 public:
  747    FileList       ( );
  748   ~FileList       ( );
  749    int  addFile        (char *pszAbsName, char *pszRoot, num nTimeStamp, num nSize, char cSortedBy=0);
  750    int  checkAndMark   (char *pszName, num nSize);
  751    void  reset          ( );
  752    StringTable clNames;
  753    StringTable clRoots;
  754    NumTable    clTimes;
  755    NumTable    clSizes;
  756 };
  757 
  758 #ifdef _WIN32
  759  #ifdef SFK_W64
  760   typedef __finddata64_t SFKFindData;
  761  #else
  762   typedef _finddata_t SFKFindData;
  763  #endif
  764 #else
  765 struct SFKFindData 
  766 {
  767    char *name;
  768    int   attrib;
  769    num   time_write;
  770    num   time_create;
  771    num   size;
  772    bool  islink;
  773    uint rawmode; // for tracing
  774    uint rawtype; // for tracing
  775    uint rawnlnk; // link count
  776    num   ninode;     // under linux
  777    __dev_t ostdev;   // under linux
  778    bool  bhavenode;  // under linux
  779 };
  780 #endif
  781 
  782 class CoiData;
  783 
  784 // the caching object identifer (Coi) represents
  785 // a file, a directory, or an url to a remote object.
  786 class Coi
  787 {
  788 public:
  789     Coi  (char *pszName, char *pszRootDir);
  790     Coi  (int iFromInfo);  // any number, to avoid unwanted tmp objects
  791    ~Coi  ( );
  792 
  793     // create deep copy, however containing only
  794     // the lightweight data like filename.
  795     Coi  *copy( );
  796 
  797    char  *name( );         // must be set
  798    char  *relName( );      // without any path portion
  799    char  *rootRelName( );  // returns full name if no root
  800    // in case of zip entries, may return subdir/thefile.txt
  801    char  *root(bool braw=0);  // "" if none, with braw: 0 if none
  802    char  *ref (bool braw=0);  // "" if none, with braw: 0 if none
  803 
  804    #ifdef WINFULL
  805    bool    haswname( );
  806    ushort *wname( );
  807    int     setwname(ushort *p);
  808    #endif
  809 
  810    #ifdef VFILEBASE
  811    char  *orgName( );      // same as name() except on redirects
  812    bool   wasRedirected( );
  813    #endif // VFILEBASE
  814 
  815    int  status   ( );
  816    // 0:yet_unknown 1:ok 9:fails_to_read
  817 
  818    // Coi's must have an initial filename,
  819    // but it can be changed later by this:
  820    int  setName  (char *pszName, char *pszOptRootDir=0);
  821    // if rootdir is not given, the old one is kept.
  822 
  823    bool hasName      ( );
  824    bool hasBadName   ( );
  825 
  826    void  setIsDir    (bool bYesNo); // sets anydir status
  827    bool  isAnyDir    (int ilevel=0);
  828    bool  isTravelDir (bool bTreatOfficeAsFile=0);
  829    bool  isDirLink   ( );
  830 
  831    int  setRef   (char *pszName);
  832 
  833    bool  hasSize  ( );
  834    bool  hasTime  ( );
  835    bool  hasAttr  ( );
  836 
  837    num   getSize  ( );
  838    num   getTime  ( );
  839    uint  getAttr  ( );
  840    // bits 2,1,0  : rwx other
  841    // bits 5,4,3  : rwx group
  842    // bits 8,7,6  : rwx user
  843    // bits 11,10,9: uid, gid, sticky
  844    // bits 12...15: linux file types
  845    // ------------
  846    // bit  30     : sfk: from linux
  847    // bit  31     : sfk: attributes are valid
  848 
  849    void  setSize  (num nSize );
  850    void  setTime  (num nMTime, num nCTime = 0); // just in memory
  851 
  852    int   setFileTime (num nMTime); // on disk
  853 
  854    int   writeAttr(uint nattr, bool bFullPreserve); // set and change on disk
  855    // RC 0: OK, else error
  856    // Changes only bits 0..11 but not the file type.
  857    // By default conforms to umask under linux.
  858    // With bFullPreserve, umask is ignored and all attribs are written.
  859 
  860    bool  isWriteable ( );
  861 
  862    void  fillFrom (void *pfdat); // SFKFindData ptr
  863 
  864    // available after fillFrom() only:
  865    bool  isHidden ( );
  866    bool  isLink   ( );
  867 
  868    // extra string outside coi definition:
  869    int  setExtStr   (char *psz);   // is copied
  870    char  *getExtStr  ( );           // null if none
  871 
  872    // check if coi is an existing file
  873    bool  existsFile  (bool bOrDir=0, int *pIsDir=0);
  874 
  875    // data I/O functions:
  876    bool   isFileOpen ( );
  877    int    open       (cchar *pmode); // like fopen, but RC 0 == OK
  878    // supported pmodes: "rb", "r", "r+b", "wb"
  879    // with "r", reading stops as soon as binary is detected.
  880    size_t read       (void *pbuf, size_t nbufsize);
  881    size_t readRaw    (void *pbuf, size_t nbufsize);
  882    void   close      ( );
  883    int    remove     ( );
  884    int    closeAndRemove   ( );
  885 
  886    int    seek       (num nOffset, int nOrigin);
  887    // rc0:ok >=0:failed to seek
  888 
  889    size_t write      (uchar *pbuf, size_t nbytes);
  890    // guarantees to write nbytes (incl. workaround
  891    // for windows network file writing bug).
  892    // rc: number of bytes written
  893    // in case of error, rc != nbytes
  894 
  895    int writeLine     (char *psz);
  896    // auto appends LF or CRLF depending on mode used in open()
  897 
  898    // heuristic check by file header if it's binary.
  899    // status can also be set from external.
  900    void   setBinaryFile (bool bYesNo);
  901    bool   isBinaryFile  ( );
  902    uchar  isUTF16       ( ); // 0x00==none 0xFE==le 0xEF==be
  903    bool   isSnapFile    ( );
  904    void   probeFile     ( ); // read file header if not done yet
  905 
  906    // readLine alloc's another I/O buffer on demand:
  907    int   readLine   (char *pszOutBuf, int nOutBufLen);
  908 
  909    int   renameto   (char *pszDst);
  910 
  911    // directory and archive processing:
  912    int   openDir     (int ilevel=0);  // prep for nextEntry()
  913    Coi   *nextEntry  ( );  // result owned by CALLER.
  914    void   closeDir   ( );  // required after processing.
  915    bool   isDirOpen  ( );
  916 
  917    #ifndef VFILEZIP
  918    int  isZipSubEntry  ( )   { return 0; }
  919    bool   isTravelZip   (int iTraceFrom, bool braw=0) { return 0; }
  920    void   setArc        (bool bIsArchive) { }
  921    bool   isKnownArc    ( )   { return 0; }
  922    #endif
  923 
  924    #ifdef SFKPACK
  925    bool   isOffice            (int iTraceFrom, bool bIgnoreOfficeMode=0);
  926    char  *officeSubName       ( );
  927    int    isOfficeSubEntry    ( );
  928    int    rawLoadOfficeDir    ( );
  929    Coi   *rawNextOfficeEntry  ( );
  930    void   rawCloseOfficeDir   ( );
  931    int    loadOfficeSubFile   (cchar *pszFromInfo);
  932    void   stripOfficeName     ( );
  933    #endif // SFKPACK
  934 
  935    #ifdef VFILEBASE
  936 
  937    int   rawLoadDir (int ilevel=0);
  938 
  939    Coi   *getElementByAbsName (char *pabs); // result is NOT locked
  940 
  941    bool  isNet    ( );  // ftp OR http
  942    bool  isFtp    ( );
  943    bool  isHttp   (char *pszOptURL=0);
  944 
  945    // if it's zip, http or ftp, then it's virtual
  946    bool  isVirtual(bool bWithRootZips=0);
  947 
  948    num   getUsedBytes   ( );  // info for the cache
  949 
  950    int    prefetch      (bool bLoadNonArcBinaries, num nFogSizeLimit, num nHardSizeLimit);
  951 
  952    // direct query of http header fields, if any given
  953    StringMap &headers     ( );            // creates on demand
  954    char      *header      (cchar *pname);  // returns NULL or the value
  955 
  956    static char *cacheName (char *pnamein, char *pbufin, int nbufsize, int *prDirPartLen=0);
  957    // nbufsize should be >= SFK_MAX_PATH
  958 
  959    #endif // VFILEBASE
  960 
  961    // reference counting:
  962    int  incref   (cchar *pTraceFrom); // increment refcnt
  963    int  decref   ( );  // decrement refcnt
  964    int  refcnt   ( );  // current no. of refs
  965 
  966    static bool bClDebug;
  967 
  968    bool   rawIsDir      ( );  // native filesystem dir
  969 
  970    int   getContent    (uchar **ppdata, num &rnSize);
  971    // ppdata is MANAGED BY COI! i.e. as soon as Coi
  972    // is deleted, returned data is deleted as well.
  973    // rc >0: unable to access file content.
  974 
  975    void   setContent    (uchar *pdata, num nsize, num ntime=0);
  976    // releases old content, if any.
  977 
  978    int   releaseContent( );
  979    // after getContent(), tell that data buffer can be freed.
  980 
  981    cchar  *lasterr      ( );
  982 
  983    #ifndef _WIN32
  984    // linux only:
  985    bool   haveNode      ( );
  986    num    getNode       ( );  // not always unique
  987    bool   haveFileID    ( );  // same as haveNode
  988    char  *getFileID     ( );  // built from node and device
  989    #endif
  990 
  991    // if status()==0, can call this:
  992    int  readStat        (char cFromInfo);
  993    
  994    int  getOpenElapsedTime  ( );  // elapsed msec since open(), or 0
  995 
  996    int  setKeepTime     (Coi *pSrc);
  997 
  998    // how much bytes of a file should be read to detect binary
  999    static int iBinaryCheckSize;
 1000 
 1001    // internal
 1002    static int writeAttrRaw(char *pszFile, uint nattr, bool bFullPreserve, bool bVerbose);
 1003    static int forceWriteable(char *pszFile);
 1004 
 1005 private:
 1006    // nextEntry() does additional checks, this does none:
 1007    Coi   *nextEntryRaw  ( );  // result owned by CALLER.
 1008 
 1009    // native file system
 1010    int   rawOpenDir    ( );  // prep for nextEntry()
 1011    Coi   *rawNextEntry  ( );  // result owned by CALLER.
 1012    void   rawCloseDir   ( );  // required after processing.
 1013 
 1014 public:
 1015 
 1016    #ifdef VFILEBASE
 1017 
 1018    int   preload       (cchar *pszFromInfo, bool bsilent, int iStopMode, bool bfile=0);
 1019    int   preload       (cchar *pszFromInfo, uchar **ppout, num &rsize, int iStopMode);
 1020    int   provideInput  (cchar *pszFromInfo, bool bsilent=0);
 1021    int   loadOwnFileRaw(num nmaxsize, uchar **ppout, num &rsize);
 1022    int   preloadFromWeb( );
 1023 
 1024    // ftp folders and files
 1025    bool   rawIsFtpDir    ( );
 1026    //     rawLoadDir     ( )  // is generic
 1027    Coi   *rawNextFtpEntry( );
 1028    void   rawCloseFtpDir ( ); 
 1029    int   rawLoadFtpDir  ( ); // load remote dir listing
 1030 
 1031    int   rawOpenFtpSubFile   (cchar *pmode);
 1032    size_t rawReadFtpSubFile   (void *pbufin, size_t nBufSize);
 1033    void   rawCloseFtpSubFile  ( );
 1034 
 1035    // http pages and files
 1036    int    readWebHead      ( );
 1037    bool   rawIsHttpDir     (int ilevel);
 1038    //     rawLoadDir       ( )  // is generic
 1039    Coi   *rawNextHttpEntry ( );
 1040    void   rawCloseHttpDir  ( ); 
 1041    bool   isHttpDirByName  (char *psz);
 1042 
 1043    int   rawOpenHttpSubFile  (cchar *pmode);
 1044    size_t rawReadHttpSubFile  (void *pbufin, size_t nBufSize);
 1045    void   rawCloseHttpSubFile ( );
 1046 
 1047    #endif // VFILEBASE
 1048 
 1049    int   applyWriteCloseTime( );
 1050 
 1051    bool  debug    ( );
 1052 
 1053    // core data for every lightweight Coi:
 1054    char  *pszClName;    // ansi or utf
 1055    char  *pszClUName;   // just utf
 1056    ushort *pwClName;    // windows: wide char name
 1057    char  *pszClRoot;
 1058    char  *pszClRef;
 1059    char  *pszClExtStr;
 1060 
 1061    uchar nClStatus;
 1062    uint  nClHave;
 1063    num   nClSize;
 1064    num   nClMTime;   // modification time
 1065    num   nClCTime;   // creation time, or <= 0
 1066    bool  bClRead;
 1067    bool  bClWrite;
 1068    bool  bClDir;     // any dir, e.g. by name
 1069    bool  bClFSDir;   // verified native filesystem dir
 1070    bool  bClHidden;
 1071    bool  bClLink;
 1072    bool  bClBinary;
 1073    bool  bClArc;
 1074    uchar nClUCS;     // 0:none 0xFE:LE 0xEF:BE
 1075    bool  bClSnap;    // sfk snapfile
 1076    bool  bClSetWriteCloseTime;
 1077    bool  bClBadName; // windows: after conversion
 1078    bool  bClUniName; // set cs.uname when processing
 1079    // after close(), set file time using MTime and/or CTime
 1080    uint  nClAttr;    // file attributes
 1081    uint  crc;
 1082 
 1083    // simplified infos for http cois
 1084    int   setTypeFromHeaders      ( );
 1085    int   setTypeFromContentType  (char *pctype);
 1086    bool  bClWebText;
 1087    bool  bClWebBinary;
 1088    bool  bClWebPage;
 1089    bool  bClWebJpeg;
 1090    bool  bClWebPNG;
 1091    bool  bClWebImage;
 1092 
 1093    // ON EXTENSIONS ABOVE, ADAPT COI::COPY, Coi::fillFrom!
 1094    // also check FileStat::readFrom, writeTo
 1095 
 1096    int  nClRefs;    // not to be coi::copied
 1097 
 1098    #ifndef _WIN32
 1099 public: // not yet defined
 1100    // additional informal stuff
 1101    uint rawmode;  // for tracing
 1102    uint rawtype;  // for tracing
 1103    uint rawnlnk;  // link count
 1104    num   nClINode;   // under linux
 1105    __dev_t oClStDev; // under linux
 1106    // file id is made from:
 1107    //   16 bytes stdev (expanded as string)
 1108    //   16 bytes inode (expanded as string)
 1109    //   zero terminator
 1110    char  szClFileID[40];
 1111    #endif
 1112 
 1113 public: // not really
 1114    // heavyweight Coi's use this as well:
 1115    CoiData *pdata;
 1116    CoiData  &data    ( );
 1117    bool   hasData    ( );  // has a CoiData object
 1118 
 1119    #ifdef VFILEBASE
 1120    bool   bClInCache;
 1121    bool   isCached   ( );
 1122    bool   hasContent ( );  // has CoiData AND cached data
 1123    #endif // VFILEBASE
 1124 
 1125    // adapt ctr and copy() on extensions!
 1126 };
 1127 
 1128 #define COI_HAVE_SIZE   (1UL<<0)
 1129 #define COI_HAVE_TIME   (1UL<<1)
 1130 #define COI_HAVE_READ   (1UL<<2)
 1131 #define COI_HAVE_WRITE  (1UL<<3)
 1132 #define COI_HAVE_DIR    (1UL<<4)
 1133 #define COI_HAVE_HIDDEN (1UL<<5)
 1134 #define COI_HAVE_LINK   (1UL<<6)
 1135 #define COI_HAVE_BINARY (1UL<<7)
 1136 #define COI_HAVE_NODE   (1UL<<8)
 1137 #define COI_HAVE_ARC    (1UL<<9)
 1138 #define COI_HAVE_ATTR   (1UL<<10)
 1139 
 1140 class CoiTable {
 1141 public:
 1142    CoiTable             ( );
 1143   ~CoiTable             ( );
 1144 
 1145    // use THIS for a simple coi list:
 1146    int addEntry         (Coi &ocoi, int nAtPos=-1);
 1147    // it adds a COPY of the supplied coi.
 1148 
 1149    int  removeEntry     (int nAtPos);
 1150    int  numberOfEntries ( );
 1151    Coi  *getEntry       (int iIndex, int nTraceLine);
 1152    int  setEntry        (int iIndex, Coi *pcoi);
 1153    int  addSorted       (Coi &ocoi, char cSortedBy, bool bUseCase);
 1154    void resetEntries    ( );
 1155    bool isSet           (int iIndex);
 1156    int  hasEntry        (char *pszFilename);
 1157 
 1158 private:
 1159    int expand           (int nSoMuch);
 1160    int nClArraySize;
 1161    int nClArrayUsed;
 1162    Coi  **apClArray;
 1163 };
 1164 
 1165 #ifdef VFILEBASE
 1166 class ZipReader;
 1167 class HTTPClient;
 1168 class FTPClient;
 1169 #endif // VFILEBASE
 1170 
 1171 // data for directory and archive processing:
 1172 // must be declared before ~coi otherwise data dtr is not called?
 1173 class CoiData {
 1174 public:
 1175     CoiData  ( );
 1176    ~CoiData  ( );
 1177 
 1178    // directory traversal data
 1179    bool   bdiropen;
 1180    char   *prelsubname;  // filename within directory
 1181 
 1182    // generic I/O support
 1183    bool   bfileopen;     // between open() ... close() of files
 1184    char   szmode[10];    // i/o mode: "rb","r+b","wb"
 1185    bool   bwrite;        // (also) writing to file
 1186    bool   bstoprdbin;    // stop read if binary detected
 1187    num    ntotalread;    // bytes read since open()
 1188    uint  ntold;         // warnings told about this file
 1189    char   szlasterr[50]; // most recent error info
 1190    #ifdef VFILEBASE
 1191    bool   bloaddirdone;  // don't repeat dir loading
 1192    bool   bstopread;
 1193    #endif // VFILEBASE
 1194    bool   banyread;      // anything yet read after open()?
 1195    num    nopentime;     // time point of open, or 0
 1196 
 1197    // this buffer is for high-level Coi read functions:
 1198    // -  readLine()
 1199    // -  isBinaryFile()
 1200    // it shall NOT be used by low-level read functions.
 1201    struct CoiReadBuf {
 1202       uchar  *data;     // alloc'ed on demand
 1203       int    getsize;
 1204       int    getindex;
 1205       int    geteod;
 1206       num     getpos;
 1207    } rbuf;  // overlapping read cache buffer
 1208 
 1209    // this buffer can optionally cache the whole input
 1210    struct CoiSrcBuf {
 1211       uchar  *data;  // NULL if not yet cached
 1212       num     size;
 1213       num     index; // current read index
 1214       num     time;  // src mtime
 1215    } src;
 1216 
 1217    // native filesystem I/O
 1218    char  *pdirpat;
 1219    #ifdef _WIN32
 1220    bool   bdir1stdone;
 1221    intptr_t otrav;
 1222    #else
 1223    DIR     *ptrav;
 1224    #endif
 1225    FILE    *pfile;   // managed by Coi, not by CoiData
 1226 
 1227    #ifdef VFILEBASE
 1228    // INTERNAL list of subfiles (zip, net).
 1229    // elements shall NOT be passed directly
 1230    // to callers, but only copies of them.
 1231    CoiTable *pelements;
 1232    CoiTable &elements ( );
 1233 
 1234    int nNextElemEntry;
 1235 
 1236    num  nPreCacheFileCnt;
 1237    num  nPreCacheFileBytes;
 1238 
 1239    // ftp support
 1240    FTPClient *pClFtp;
 1241    // when set, it is allocated by the coi,
 1242    // and must be released after use.
 1243    int  getFtp(char *purl);
 1244    // on rc0, can use pClFtp.
 1245    int  releaseFtp( );
 1246    // does NOT close connection, but clears pClFtp.
 1247 
 1248    // http support
 1249    HTTPClient *pClHttp;
 1250    // when set, it is allocated by the coi,
 1251    // and must be released after use.
 1252    int  getHttp(char *purl);
 1253    // on rc0, can use pClHttp.
 1254    int  releaseHttp( );
 1255    // clears pClHttp, but if connection is
 1256    // in keep-alive, does NOT close it yet.
 1257    StringMap &headers( );
 1258    // http headers, so far only non-redundant entries
 1259    // like content-type, but not multiple set-cookies.
 1260    StringMap *pClHeaders;
 1261 
 1262    // if the coi was http redirected, then
 1263    bool  bRedirected;   // this is true
 1264    char  *pClOrgName;   // this is the first coi name
 1265    #endif // VFILEBASE
 1266 };
 1267 
 1268 class CoiAutoDelete {
 1269 public:
 1270       CoiAutoDelete (Coi *pcoi, bool bDecRef)
 1271          { pClCoi = pcoi; bClDecRef = bDecRef; }
 1272      ~CoiAutoDelete ( ) {
 1273          if (!pClCoi)
 1274             return;
 1275          if (bClDecRef)
 1276             pClCoi->decref();
 1277          if (!pClCoi->refcnt())
 1278             delete pClCoi; 
 1279       }
 1280 private:
 1281       Coi *pClCoi;      // can be NULL
 1282       bool bClDecRef;   // on dtr, do a single decref
 1283 };
 1284 
 1285 class AutoCoiDirClose {
 1286 public:
 1287       AutoCoiDirClose (Coi *pcoi) { pClCoi = pcoi; }
 1288      ~AutoCoiDirClose ( ) {
 1289          if (pClCoi->isDirOpen()) {
 1290             mtklog(("auto-close coi %p", pClCoi));
 1291             pClCoi->closeDir();
 1292          }
 1293       }
 1294    Coi *pClCoi;
 1295 };
 1296 
 1297 enum eProgressInfoKeepFlags {
 1298    eKeepProg   = (1<<0),
 1299    eKeepAdd    = (1<<1),
 1300    eNoCycle    = (1<<2),
 1301    eSlowCycle  = (1<<4),
 1302    eNoPrint    = (1<<5)
 1303 };
 1304 
 1305 class ProgressInfo
 1306 {
 1307 public:
 1308    ProgressInfo          ( );
 1309    void  setWidth        (int nColumns);
 1310    void  setAddInfoWidth (int nColumns); // abs. columns, high prio
 1311    void  setAddInfoHalve ( );  // fills half of line, with low prio
 1312    void  setAddInfo      (const char *pszFormat, ...);
 1313    void  setAction       (cchar *pszVerb, cchar *pszSubject, cchar *pszAddInfo=0, int nKeepFlags=0);
 1314    void  setStatus       (cchar *pszVerb, cchar *pszSubject, cchar *pszAddInfo=0, int nKeepFlags=0);
 1315    void  print           ( );  // print status now, keep line
 1316    void  printLine       (int nFilter=0); // print final status, including newline
 1317    void  cycle           ( );  // print status if enough time elapsed
 1318    void  clear           ( );  // clear status, if it was printed
 1319    int   print           (const char *pszFormat, ...);
 1320    void  setProgress     (num nMax, num nCur, cchar *pszUnit, bool btriple=0);
 1321    void  setStatProg     (cchar *pverb, cchar *psubj, num nMax, num nCur, cchar *pszUnit);
 1322    void  clearProgress   ( );
 1323 
 1324 // private:
 1325    void  fixAddInfoWidth ( );
 1326    void  dumpTermStatus  ( );
 1327    void  clearTermStatus ( );  // if anything to clear
 1328    int  nMaxChars;
 1329    int  nMaxSubChars;
 1330    int  nAddInfoCols;
 1331    int  nDumped;
 1332    num   nLastDumpTime;
 1333    bool  bAddInfoPrio;
 1334    int  nAddInfoReserve;
 1335    int  nTurn;
 1336    char  szVerb   [200];
 1337    char  szSubject[200];
 1338    char  szAddInfo[200];
 1339    char  szTermBuf[400];
 1340    char  szPrintBuf[400];
 1341    char  szPerc   [20];
 1342 };
 1343 
 1344 extern ProgressInfo info;
 1345 
 1346 // simple double linked list
 1347 
 1348 class ListEntry
 1349 {
 1350 public:
 1351     ListEntry   ( );
 1352    ~ListEntry   ( );
 1353 
 1354    ListEntry *next      ( ) { return pClNext; }
 1355    ListEntry *previous  ( ) { return pClPrevious; }
 1356 
 1357    ListEntry *pClNext;
 1358    ListEntry *pClPrevious;
 1359 
 1360    // user payload
 1361    void  *data;
 1362 };
 1363 
 1364 class List
 1365 {
 1366 public:
 1367    List  ( );
 1368   ~List  ( );
 1369 
 1370    ListEntry *first  ( ) { return pClFirst; }
 1371    ListEntry *last   ( ) { return pClLast; }
 1372 
 1373    void add          (ListEntry *p);
 1374    void addAsFirst   (ListEntry *p);
 1375    void addAfter     (ListEntry *after, ListEntry *toadd);
 1376    void remove       (ListEntry *entry);
 1377    void reset        ( );
 1378    int  size         ( );
 1379 
 1380 private:
 1381    ListEntry *pClFirst;
 1382    ListEntry *pClLast;
 1383 };
 1384 
 1385 #ifdef SFK_PROFILING // windows only
 1386 
 1387 class StaticPerformancePoint;
 1388 
 1389 #define MAX_PERF_POINTS 100
 1390 
 1391 class StaticPerformanceStats
 1392 {
 1393 public:
 1394       StaticPerformanceStats  ( );
 1395 
 1396    void  addPoint       (StaticPerformancePoint *pPoint);
 1397    int   numberOfPoints ( );
 1398    StaticPerformancePoint *getPoint(int iIndex);
 1399 
 1400 StaticPerformancePoint
 1401    *apClPoints [MAX_PERF_POINTS+10],
 1402    *pClCurrentPoint;
 1403 int
 1404     iClPoints;
 1405 };
 1406 
 1407 extern StaticPerformanceStats glblPerfStats;
 1408 
 1409 class StaticPerformancePoint
 1410 {
 1411 public:
 1412       StaticPerformancePoint  (const char *pszID, const char *pszFile, int iTraceLine);
 1413 
 1414       inline void  blockEntry ( );
 1415       inline void  blockExit  (int iElapsedTicks);
 1416 
 1417 const char *pszClID;
 1418 const char *pszClFile;
 1419 int   iClTraceLine;
 1420 num   iClHits;
 1421 num   iClTotalTime;
 1422 num   iClSubTimes;
 1423 };
 1424 
 1425 class DynamicPerformancePoint
 1426 {
 1427 public:
 1428        DynamicPerformancePoint (StaticPerformancePoint *pStaticPoint);
 1429       ~DynamicPerformancePoint ( );
 1430 
 1431 StaticPerformancePoint
 1432       *pClStaticPoint,
 1433       *pClStaticParent;
 1434 num
 1435        nClEntryTickCount;
 1436 };
 1437 
 1438 #define _p2(id,file,line)  \
 1439    static StaticPerformancePoint oStatPoint##line(id,file,line); \
 1440    DynamicPerformancePoint oDynaPoint##line(&oStatPoint##line);
 1441 
 1442 #define _p(id) _p2(id,__FILE__,__LINE__)
 1443 
 1444 extern void logProfile();
 1445 
 1446 inline num getPerfCnt()
 1447 {
 1448    LARGE_INTEGER val1;
 1449    QueryPerformanceCounter(&val1);
 1450    return val1.QuadPart;
 1451 }
 1452 
 1453 inline num getPerfFreq()
 1454 {
 1455    LARGE_INTEGER val1;
 1456    QueryPerformanceFrequency(&val1);
 1457    return val1.QuadPart;
 1458 }
 1459 
 1460 #else
 1461 
 1462 #define _p(id)
 1463 
 1464 extern void logProfile();
 1465 
 1466 #endif
 1467 
 1468 int getFileSystemInfo(
 1469    char  *pszPath,         // e.g. "D:\\", "/home/user/"
 1470    num   &nOutTotalBytes,  // total volume size
 1471    num   &nOutFreeBytes,   // free bytes usable for normal users
 1472    char  *pszOutFSName,    // file system name buffer
 1473    int   nOutFSNMaxSize,   // size of this buffer
 1474    char  *pszOutVolID,     // volume name and serial, if any
 1475    int   nOutVolIDMaxSize, // size of this buffer
 1476    uint &rOutVolID
 1477    );
 1478    
 1479 int createOutDirTree(char *pszOutFile, KeyMap *pOptMap=0, bool bForDir=0);
 1480 
 1481 #ifdef _WIN32
 1482 void timetToFileTime(num ntimet, FILETIME *pft);
 1483 num fileTimeToTimeT(num nwft);
 1484 num fileTimeToTimeT(FILETIME *pft);
 1485 #endif
 1486 
 1487 inline void sfkSetBit(uchar *pField, uint iBit) 
 1488 {
 1489    pField[iBit>>3] |= (1U << (iBit & 7));
 1490 }
 1491 
 1492 inline uchar sfkGetBit(uchar *pField, uint iBit)
 1493 {
 1494    return (pField[iBit>>3] & (1U << (iBit & 7))) ? 1 : 0;
 1495 }
 1496 
 1497 extern int (*pGlblSFKStatusCallBack)(int nMsgType, char *pmsg);
 1498 
 1499 char *dataAsHex(void *pAnyData, int iDataSize, char *pszBuf=0, int iMaxBuf=0, bool bLowerCase=0);
 1500 char *dataAsTrace(void *pAnyData, int iDataSize=-1, char *pszBuf=0, int iMaxBuf=0);
 1501 char *dataAsTraceW(ushort *pAnyData);
 1502 
 1503 /*
 1504     Simplest possible utf8 decoder, primarily for 16 bit code points.
 1505     No support for surrogates or any complex sequences.
 1506 
 1507     UTFDecoder odec(szInText);
 1508     while (odec.haveChar())
 1509     {
 1510         uint u = odec.nextChar();
 1511         ...
 1512     }
 1513 */
 1514 class UTF8Codec
 1515 {
 1516 public:
 1517    UTF8Codec   (char *pOptInData=0, int iOptionalInputLength=-1);
 1518 
 1519    void  init  (char *pInputData, int iOptionalInputLength=-1);
 1520 
 1521    static int toutf8 (char *pszOut, int iMaxOut, uint ch);
 1522    static int toutf8 (char *pszOut, int iMaxOut, char *pszIsoText, bool bSafe=0);
 1523    static bool isValidUTF8 (char *psz);
 1524 
 1525    bool  hasChar();
 1526    uint  nextChar();
 1527    bool  eod();
 1528 
 1529    static int  validSeqLen    (char *pszSrc, int iMaxSrc);
 1530           int  validSeqLenInt (char *pszSrc, int iMaxSrc);
 1531 
 1532    int   readRaw();
 1533    int   readSeq();
 1534 
 1535    int   icur, imax;
 1536    bool  banychars;
 1537    bool  bbadchars;
 1538    bool  bdecodexml;
 1539    bool  bkeeputf;   // sfk1942
 1540    uchar *psrc;
 1541 };
 1542 
 1543 class SFKMatch;
 1544 
 1545 struct CommandStats
 1546 {
 1547 public:
 1548    CommandStats   ( );
 1549    void reset     ( );
 1550    bool showstat  ( );
 1551 
 1552    int debug     ;
 1553    int memcheck  ;
 1554    int verbose   ;  // 0,1,2
 1555    int iotrace   ;
 1556    int tracechain;
 1557    bool shortsyntax        ; // sfk1812 i/o bGlblShortSyntax
 1558    bool anyused            ; // sfk1812 i/o bGlblAnyUsed
 1559    bool delStaleFiles      ;
 1560    bool skipOwnMetaDir     ;
 1561    bool blockAutoComplete  ;
 1562    int tabSize   ;
 1563    int tabsDone  ;
 1564    int tabFiles  ;
 1565    int scanTabs  ;
 1566    bool scanIndent;
 1567    int indentFilt;
 1568 
 1569    int files     ; // visible plus hidden
 1570    int filesChg  ; // no. of files changed
 1571    int filesZip  ; // no. of files (un)zipped
 1572    int noFiles   ; // fnames that failed to stat etc.
 1573    int dirs      ; // visible plus hidden
 1574    int filesCloned ; // no. of files with attributes copied
 1575    int dirsCloned  ; // no. of dirs with attributes copied
 1576    bool hidden    ; // include hidden files and dirs
 1577    int numHiddenFiles ; // for list stats
 1578    int numHiddenDirs  ; // for list stats
 1579    int numHiddenFilesSkipped ;
 1580    int numHiddenDirsSkipped  ;
 1581    int numBadFileNames; // unreadable unicodes
 1582    int binariesSkipped ;
 1583    int addedFilesSkipped ; // on -sincedif
 1584    int shadowsWritten ;
 1585    int shadowFallbacks ;
 1586    int filesDeleted ;
 1587    int filesDeletedWP;
 1588    int dirsDeleted  ;
 1589    int dirsDelFailed;
 1590    int dirsDeletedWP;
 1591    int filesScanned ;
 1592    int dirsScanned  ;
 1593    int filesMoved   ;
 1594    int filesDelFailed;
 1595    int filesNewerInDst ;
 1596    int filesStale ; // deletion candidate
 1597    int filesRedundant;  // rename
 1598    int filesExisting;   // rename
 1599    int noOutDir;        // rename
 1600    int badOutDir;       // rename
 1601    int lines    ;
 1602    num  maxFileTime;
 1603    uint listForm;    // list -size etc.
 1604    bool listTabs;    // split columns by tab char
 1605    bool listContent; // list zip etc. info
 1606    int  flatTime;    // show flat file times
 1607    bool sim   ;      // just simulate command
 1608    bool nohead;      // leave out some header, trailer info
 1609    bool pure  ;      // extra info if -pure was specified
 1610    bool dostat;      // copy: list just size statistics
 1611    bool tailTail;    // running tail, not head
 1612    int tailLines;    // head, tail
 1613    bool tailFollow;  // head, tail
 1614    char *tomask;     // output filename mask
 1615    char *todir;      // output dir
 1616    bool  tomaskfile; // -to mask is a single filename
 1617    char tomake[200]; // option -tomake
 1618    char curcmd[50+10]; // current command. sfk1834 no pointer
 1619    bool rootrelname; // use filenames relative to root dir
 1620    bool rootabsname;  // copy
 1621    bool forceabsname; // list
 1622    bool writeall;    // write all files, not only changed ones
 1623    bool spat;        // enable slash patterns \t etc.
 1624    bool wpat;        // support * and ?
 1625    bool xpat;        // dummy within base
 1626    bool usecase;     // case-sensitive search or not
 1627    bool fuzz;        // fuzzy case search
 1628    bool nocase;      // optional: forced nocase on binary search
 1629    int blankRunFiles;  // no. of filenames w/blanks passing run
 1630    int wrongpcRunFiles;// no. of filenames w/wrong path chars
 1631    int badNameForm;    // set by execRunFile on bad filename formats
 1632    bool nocheck;     // do not perform any checks
 1633    bool noinfo;      // do not tell infos
 1634    bool nochain;     // disable command chains
 1635    int  useJustNames;// create a list of filenames
 1636    bool countMatchLines; // count no. of matching lines
 1637    bool yes;
 1638    bool logcmd;
 1639    bool force;
 1640    bool nostop;      // command specific
 1641    bool keepchain;   // keep chain always running
 1642    bool syncFiles;   // sync files instead of copy
 1643    bool syncOlder;   // with sync, copy older over newer files
 1644    int  flat;        // copy: flat output filenames
 1645    char cflatpat;    // how to join flat output name
 1646    bool nonames;     // do NOT print/pass :file records
 1647    bool noind;       // no indentation
 1648    char *runCmd;     // default: "" if not set.
 1649    bool printcmd;    // run: print raw command
 1650    int stoprc;      // run: stop on rc >= stoprc
 1651    bool anymatches;  // find: found at least 1 matching line in 1 file
 1652    bool showrc;      // print rc at program end
 1653    bool deplist;     // deplist command selected
 1654    int refsrccnt;   // reflist, deplist: no. of sources
 1655    bool depsingle;   // process dependencies of a single file
 1656    bool coldstnames; // reflist, deplist: execRefColSrc also collects DstNames
 1657    bool refstripsrc; // strip source file contents from unused chars
 1658    int listByTime;
 1659    bool listByTimeAll;
 1660    int listBySize;
 1661    bool listBySizeAll;
 1662    int listByName;
 1663    bool listByNameAll;
 1664    bool tellExecTime;
 1665    int timeOutMSec;
 1666    bool timeOutAutoSelect;
 1667    num  selMinSize;  // consider only files >= so many bytes
 1668    bool nowarn;      // disable all warning output
 1669    bool noerr;       // disalbe all error output
 1670    bool showerr;     // sft
 1671    bool nonotes;     // disalbe all note output
 1672    bool skipLinks;   // do not follow symbolic directory links
 1673    bool traceFileFlags;
 1674    bool fileMaskAndMatch;  // AND match of file mask parts
 1675    bool dirMaskAndMatch;  // AND match of path mask parts
 1676    bool incFNameInPath;    // include filename in path mask check
 1677    bool verifyEarly;       // copy: verify directly after write
 1678    bool verifyLate;        // copy: verify in a separate pass
 1679    FILE *outfile;          // can be used by chain.print
 1680    bool listTargets;       // force target name listing i/o src
 1681    int idleMode;          // low prio processing, 0 (off) to 2
 1682    int walkDirDelay;      // low prio file processing with delays
 1683    int walkFileDelay;     // low prio file processing with delays
 1684    int treeStopRC;        // stop tree processing on internal RC >= this
 1685    bool stopTree(int nrc, bool *psilent=0); // tells if to stop on the supplied rc
 1686    bool toldTreeStop;
 1687    bool skipDirFileColl;   // optim: do not collect flist per dir.
 1688    // cannot be set w/functions that strictly need those lists.
 1689    bool rcFromError;       // change shell rc on skipped errors
 1690    bool repDump;           // replace: create hexdump of hits
 1691    bool repDumpHalve;      // replace: hexdump only source side
 1692    bool useFirstHitOnly;   // skip to next file after first hit
 1693    bool withdirs;          // include directories in command
 1694    bool withrootdirs;      // if withdirs is used, include root dirs?
 1695    bool justdirs;          // process only directories
 1696    bool predir;
 1697    bool usesnap;           // interpret snapfile format and list titles
 1698    bool usesnapfiltname;   // filter filenames as well
 1699    int addsnapraw;        // snapto raw mode 1 or 2
 1700    const char *addsnaplf;  // "\n" or "\r\n" depending on mode and OS
 1701    uint addsnapmeta;      // bit 0:time 1:size 2:encoding
 1702    int stathilitelevel;   // stat command: highlight dirs <= this
 1703    bool travelzips;        // traverse zipfile contents
 1704    int  office;            // traverse office contents
 1705    int  justoffice;        // select just office files
 1706    bool infilelist;        // processing a file list, not dir and mask
 1707    bool probefiles;        // look into file headers to detect zip etc.
 1708    bool incbin;            // include all binary files in processing
 1709    bool incwlbin;          // include white listed binary files
 1710    bool reldist;           // hexfind: tell also relative distances
 1711    #ifdef VFILEBASE
 1712    bool shallowzips;       // list only first level of zips
 1713    bool precachezip;
 1714    bool extdomref;         // include external domain refs
 1715    bool xelike;            // set xe default behaviour and help text
 1716    bool cacheall;          // no direct processing of files
 1717    bool cachestat;         // cache statistics at program end
 1718    bool travelHttp;        // decided per command, esp. list
 1719    #endif // VFILEBASE
 1720    bool  recurl;
 1721    bool subdirs;           // recurse into subdirs
 1722    bool hidesubdirs;       // do not process subdir names at all
 1723    bool utf8dec;           // utf-8  detect and decode (not yet impl.)
 1724    bool wchardec;          // utf-16 detect and decode
 1725    int utf16found;         // statistic for post-command info
 1726    int utf16read;          // statistic for post-command info
 1727    bool showdupdirs;       // linux: tell if dir link contents are skipped
 1728    bool usecirclemap;      // linux: allow circle map, on by default
 1729    num  sincetime;         // process only files modified since that time
 1730    num  untiltime;         // process only files modified until that time
 1731    bool usectime;          // use creation time instead of modification time
 1732    bool useutc;            // all times in UTC/GMT instead of local
 1733    char paramprefix[30];   // for user defined script input parameter names
 1734    int wrapcol;            // if >0, auto-wrap lines in snapfile
 1735    int wrapbincol;         // only on binary to text conversion
 1736    num nlineswrapped;      // number of hard wraps
 1737    bool rewrap;            // ignore linefeeds, rewrap all
 1738    char listunit;          // stat output in 'b'ytes, 'k'bytes or default.
 1739    bool flatdirstat;       // list no. of files per dir, not dir tree
 1740    int flatfilecnt;        // global stats if flatdirstat is set
 1741    int flatdircnt;         // "
 1742    num  flatbytecnt;       // "
 1743    bool statonlysum;       // sfk stat: quiet except summary
 1744    int quiet;              // quiet mode
 1745    bool ftpupdate;         // mput, mget: explicite -update
 1746    bool ftpall;            // mput, mget: disable -update mode
 1747    bool ftpwidelist;       // with webserv
 1748    bool noclone;           // disable time stamp replication
 1749    bool preserve;          // copy full attributes with sft
 1750    int fast;               // command dependent optimization
 1751    bool verify;            // command dependent optimization
 1752    bool prog;              // with progress indicator
 1753    bool noprog;            // no progress indicator
 1754    // bool notext;         // no result text (never used)
 1755    bool test;              // filter: run in test mode
 1756    bool copyLinks;         // copy symlinks     , windows only, untested
 1757    bool copyNoBuf;         // copy w/o buffering, windows only, untested
 1758    bool copyDecrypt;       // copy and decrypt  , windows only, untested
 1759    bool extrun;            // sfk run -re
 1760    bool textfiles;         // process only textfiles
 1761    bool binaryfiles;       // process only binaryfiles
 1762    bool packalnum;         // deblank: reduce filenames to alnum
 1763    bool noipexpand;        // disallow ip number expansion
 1764    int  stopcnt;           // stop command after n events
 1765    char szownip[60];       // manually set own ip
 1766    bool anyFileTooLarge;   // info after command execution
 1767    bool crashtest;         // enforce crash to test handling
 1768    bool justvernum;        // version command
 1769    bool separator;         // print separator between outputs
 1770    char szseparator[100];  // with xfind
 1771    bool nolf;              // skip lf output on some commands
 1772    bool multicast;         // udpclient
 1773    int  dumptrail;         // hexdump: trailing chars at line end
 1774    int  bytesperline;      // hexdump: when using hex/decsrc
 1775    num  recordsize;        // for some commands
 1776    bool usetmp;            // use temporary file
 1777    bool knx;               // internal
 1778    char *knxtext;          // internal
 1779    bool ntp;               // internal
 1780    bool echoonerr;         // echo whole command on error
 1781    int  argc;              // copy of main() argument
 1782    char **argv;            // copy of main() argument
 1783    int  selfilenum;        // current processed file number
 1784    int  selfileoff;        // process only files from this offset
 1785    int  selfilerange;      // process only so many files
 1786    bool stopfiletree;      // stop dir tree processing silently
 1787    bool showip;            // show automatic ip expansion result
 1788    bool justrc;            // no terminal output on filter
 1789    num  minsize;           // select only files >= that size
 1790    num  maxsize;           // select only files <= that size
 1791    bool keeptime;          // keep input filetime on output file
 1792    uint timemask;          // bit mask of what times to list
 1793    bool tabform;           // use tab separators
 1794    bool autoclose;         // ftpserv: on second client
 1795    num  diskspace;         // required free disk space for writing
 1796    bool xchars;            // treat \xnn as characters
 1797    bool extract;           // replace, hexfind
 1798    FILE *extractOutFile;   // ""
 1799    int  xmaxlen;           // xpat default maxlen
 1800    int  xmaxlit;           // xpat max literal size
 1801    bool nodirtime;         // copy should not clone dir times
 1802    bool collines;          // sfk193 with xed
 1803    bool fixedbylist;       // force fixed record -bylist file
 1804    bool showpre;           // replace
 1805    bool showpost;          // replace
 1806    bool showlist;          // replace
 1807    bool rawfilename;       // with hexdump
 1808    bool hexfind;           // running (x)hexfind
 1809    bool xtext;             // running xtext
 1810    bool xfind;             // running xfind
 1811    char placeholder;       // for null bytes
 1812    bool rawterm;           // dump output as is
 1813    bool usefilehead;       // use mask given below
 1814    char szfilehead[200];   // per result file header with "%s" internal
 1815    bool maxdump;           // tcpdump -maxdump
 1816    bool fullhelp;
 1817    int  reprep;            // repeat replace option
 1818    bool perf;              // performance statistics
 1819    char szeol[10];         // crlf or lf
 1820    bool toiso;             // utf8 to iso conversion
 1821    char toisodef;          // default character '.'
 1822    bool toutf;             // iso to utf8 conversion
 1823    char *delim;            // list of delimiters for soft word wrapping
 1824    bool astext;            // with xhexdump
 1825    bool joinlines;         // with find
 1826    int  rtrim;             // with find
 1827    bool nostat;            // xhexfind: no no. of hits statistics
 1828    char litattr;           // literal highlight attribute, or 0 for none
 1829    char leattr;            // line end attribute, or 0 for none
 1830    bool leauto;            // auto detect text file then set leattr
 1831    bool forcele;           // force line endings with addcr/remcr
 1832    int  fastopt;           // fast option, function specific
 1833    // csvtotab, tabtocsv
 1834    char cinsep;
 1835    char coutsep;
 1836    char cquote;
 1837    char coutsepesc;
 1838    bool quotetext;
 1839    bool quoteall;
 1840    int  contextlines;      // xfind: 1=currentline 2=previous and post line
 1841    int  contextchars;      // max chars of all context lines together
 1842    int  indent;
 1843    char *renexp;           // rename expression
 1844    char *rentodir;         // rename moveto dir
 1845    bool exact;
 1846    bool listfiles;
 1847    bool uname;             // windows: utf names
 1848    bool unameauto;
 1849    bool unameout;
 1850    bool showrawname;
 1851    bool tname;             // windows: transcript names
 1852    bool aname;             // windows: ansi from wide char read
 1853    bool dewide;            // fixfile
 1854    bool rewide;            // fixfile
 1855    bool setftime;          // fixfile
 1856    bool setndate;          // fixfile
 1857    bool dumpfrom;          // (x)replace
 1858    bool dumpboth;          // (x)replace
 1859    num  maxscan;           // (x)replace
 1860    bool nodump;            // udpdump -forward
 1861    bool prefix;            // udpcast -prefix
 1862    int  maxwebwait;        // network
 1863    int  maxftpwait;        // network
 1864    bool upath;             // run
 1865    char *puser;
 1866    char *ppass;
 1867    bool errtotext;
 1868    bool trimscript;
 1869    char mlquotes;          // multi line quotes format
 1870    int  headers;           // print web headers
 1871    bool showreq;           // print web requests
 1872    num  maxwebsize;        // web download limit
 1873    bool execweb;
 1874    bool openbyapp;
 1875    int  maxlines;          // max lines to read
 1876    int  taillines;         // lines from eof
 1877    bool usevars;
 1878    bool sellines;          // select lines from input
 1879    int  linesfrom;         // if sellines
 1880    int  linesto;           // if sellines
 1881    int  strict;            // run, -to, perline mask
 1882    bool relaxedvar;        // for filter
 1883    bool fullheader;        // (x)hexfind, (x)rep etc.
 1884    bool winver;
 1885    bool nosft;             // force ftp protocol
 1886    bool allowsft;          // allow sft protocol
 1887    bool showprotocol;
 1888    bool brackets;
 1889    bool cweb;              // +web expects chain input
 1890    bool movefiles;
 1891    SFKMatch *apexp;        // xrename
 1892    int  iexp;              // xrename
 1893    num  totalinbytes;
 1894    num  totaloutbytes;
 1895    num  totalbytes;        // sfk1934
 1896    int  icomp;
 1897    bool fastcomp;
 1898    int  numBadFiles;
 1899    int  numFilesOK;
 1900    bool usecolor;          // sfk189
 1901    bool usehelpcolor;      // sfk189
 1902    #ifdef SFKPACK
 1903    void *zfout;
 1904    bool bzip2;
 1905    bool force64;
 1906    bool catzip;
 1907    Coi  *pOutCoi;
 1908    bool toziplist;
 1909    bool hidezipcomment;
 1910    bool addmeta;
 1911    char *tozipname;
 1912    uint nzipredundant;
 1913    uint mofftime;          // apply for 0:dos 1:unix 2:ntfs
 1914    bool bjustcrc;
 1915    uint njustcrc;
 1916    #endif // SFKPACK
 1917    int  tracecase;
 1918    bool nocasemin;         // sfk190 just latin a-z
 1919    bool binallchars;       // sfk190 for binary extracts
 1920    bool outcconv;
 1921    bool forcecconv;
 1922    int  ifailedchars;
 1923    int  iinvalidutfmarks;
 1924    int  inonutfhicodes;
 1925    bool nozipmeta;
 1926    bool keepbadout;
 1927    int  iutfnames;
 1928    int  iexecfiles;
 1929    bool bzipto;
 1930    bool bnoextutf;
 1931    bool utfout;            // sfk1942
 1932    int  nmore;
 1933    int  imore;
 1934    int  morepage;
 1935    int  makemd5;
 1936    bool crcmd5;            // use crc instead of md5
 1937    bool keepdata;          // keep chaindata with setvar
 1938    char *notifyto;         // sft(serv)
 1939    int  justevery;
 1940    int  everycnt;
 1941    bool sanecheck;         // crccheck -sane
 1942    num  sanetime;          // of crc list file
 1943    int  usehta;            // webserv internal
 1944    bool usingflist;        // sfk196 with -flist
 1945 };
 1946 
 1947 // extern struct CommandStats gs;
 1948 // extern struct CommandStats cs;
 1949 
 1950 enum eWalkTreeFuncs {
 1951    eFunc_MD5Write = 1,
 1952    eFunc_JamFile  = 2,  // fixed value
 1953    eFunc_CallBack = 3,  // fixed value
 1954    eFunc_Detab       ,
 1955    eFunc_Entab       ,
 1956    eFunc_JamIndex    ,
 1957    eFunc_SnapAdd     ,
 1958    eFunc_FileStat    ,
 1959    eFunc_FileTime    ,
 1960    eFunc_Touch       ,  // 10
 1961    eFunc_Find        ,
 1962    eFunc_Mirror      ,  // deprecated
 1963    eFunc_Run         ,
 1964    eFunc_FormConv    ,
 1965    eFunc_Inst        ,
 1966    eFunc_RefColSrc   ,  // collect reflist sources
 1967    eFunc_RefColDst   ,  // collect reflist targets
 1968    eFunc_Deblank     ,
 1969    eFunc_FTPList     ,
 1970    eFunc_FTPNList    ,  // 20
 1971    eFunc_FTPLocList  ,
 1972    eFunc_Hexdump     ,
 1973    eFunc_Copy        ,
 1974    eFunc_Cleanup     ,
 1975    eFunc_AliasList   ,
 1976    eFunc_ReplaceFix  ,  // 26
 1977    eFunc_ReplaceVar  ,  // 27
 1978    eFunc_MetaUpd     ,
 1979    eFunc_MetaCheck   ,
 1980    eFunc_Scantab     ,
 1981    eFunc_Filter      ,
 1982    eFunc_Load        ,
 1983    eFunc_Delete      ,
 1984    eFunc_DupScan     ,
 1985    eFunc_Version     ,
 1986    eFunc_Media       ,
 1987    eFunc_XHexDemo    ,
 1988    eFunc_Rename      ,
 1989    eFunc_XRename     ,
 1990    eFunc_GetPic      ,
 1991    eFunc_XFind       ,
 1992    eFunc_Move        ,
 1993    eFunc_SumFiles
 1994    #ifdef SFKPACK
 1995    , eFunc_ZipTo
 1996    #endif // SFKPACK
 1997 };
 1998 
 1999 // temporary file class, REMOVING THE FILE IN DESTRUCTOR.
 2000 class SFTmpFile
 2001 {
 2002 public:
 2003    SFTmpFile   (const char *pszExt, bool bNoAutoDelete, uint nTmpFileNum = 0);
 2004   ~SFTmpFile   ( );
 2005    char *name  ( );
 2006    static void setTmpDir(char *pszDir);
 2007    static bool tmpDirWasSet( );
 2008 private:
 2009    bool  bClAutoDel;
 2010    uint nClNum;
 2011    char szClExt[100];
 2012    char *pszClName;
 2013    static int ncnt;
 2014    static char *pszTmpDir;
 2015 };
 2016 
 2017 class FileStat {
 2018 public:
 2019    FileStat       ( );
 2020    int  readFrom (char *pszSrcFile, bool bWithFSInfo=0, bool bSilent=0);
 2021    int  writeTo  (char *pszDstFile, int nTraceLine, bool bWriteJustTime=0);
 2022    int  differs  (FileStat &oref, bool bSameIfOlderSrc, bool *pSrcIsOlder=0);
 2023    int  copyFrom (FileStat &src);
 2024    int  setFilename(char *psz);
 2025    char *filename( );
 2026    int  writeStat(int iTraceLine); // using stored filename
 2027    int  dump     ( );
 2028    int  dumpTimeDiff (FileStat &rdst);
 2029    num   getSize  ( )   { return src.nSize; }
 2030    uchar *marshal (int &nRetSize);
 2031    int  setFrom  (uchar *pBuf, int nBufSize);
 2032    char  *attrStr ( );
 2033    const char *diffReason  (int nReason);
 2034 
 2035    num   getUnixTime ( ) { return src.nMTime; }
 2036    num   getWinTime  ( );
 2037 
 2038 public:
 2039    int   dumpSub  (int nRow, uint nmask, char *pszOut, int iMaxOut);
 2040    void  reset    ( );
 2041 
 2042    struct FileStatSrcInfo
 2043    {
 2044       int  bIsDir;
 2045       int  bIsReadable;
 2046       int  bIsWriteable;
 2047  
 2048       // time of MODIFICATION or LAST WRITE is ALWAYS available.
 2049       num   nMTime;
 2050  
 2051       // time of CREATION and LAST ACCESS is only available on
 2052       // SOME file systems, e.g. NTFS. on FAT32, ATime is 0,
 2053       // and CTime == MTime.
 2054       num   nCTime;
 2055       num   nATime;
 2056  
 2057       #ifdef _WIN32
 2058       FILETIME ftMTime;
 2059       FILETIME ftCTime;
 2060       FILETIME ftATime;
 2061       bool  nHaveWFT;   // 1 = have at least windows mod file time
 2062       #endif            // 2 = also have windows C and A time
 2063  
 2064       num   nSize;
 2065       int  bIsUTCTime;
 2066       uint nAttribs;
 2067    }
 2068    src;
 2069 
 2070    char  szClFileName[SFK_MAX_PATH+10];
 2071    char  szClSrcPath[SFK_MAX_PATH+10];
 2072    char  szClSrcFSName[200];
 2073    char  szClSrcVolID[200];
 2074    char  szClTextBuf1[200];
 2075    char  szClTextBuf2[200];
 2076    char  szClAttrStr[50];
 2077    char  szClDiffReason[100];
 2078 };
 2079 
 2080 #define MAX_MOV_CMD 100
 2081 #define SFKMOV_KEEP   1
 2082 #define SFKMOV_CUT    2
 2083 
 2084 class Media
 2085 {
 2086 public:
 2087       Media ( );
 2088 
 2089    void  reset             ( );
 2090    void  closeOutput       ( );
 2091    void  clearCommands     ( );
 2092    void  shutdown          ( );
 2093    int   parseM3UFile      (char *pszFilename);
 2094    int   processMediaFile  (char *pszSrc, char *pszOutFile);
 2095    int   findSeconds       (num nBytePos); // with M3U only
 2096    int   renderTempName    (char *pszFromname);
 2097    int   analyze           (uchar *pbuf, int isize);
 2098    void  setFixParms       (char *psz);
 2099 
 2100 static Media *pClCurrent;
 2101 static Media &current ( );
 2102 
 2103 int   aCmd[MAX_MOV_CMD];
 2104 num   aBeg[MAX_MOV_CMD];
 2105 num   aEnd[MAX_MOV_CMD];
 2106 int   aBegSec[MAX_MOV_CMD];
 2107 int   aEndSec[MAX_MOV_CMD];
 2108 int   iFirstCmd,iCmd;
 2109 int   iClInvalidFiles;
 2110 int   iClDoneFiles;
 2111 int   iClDoneTS;
 2112 bool  bClHaveM3UCommands;
 2113 bool  bClHaveKeep;
 2114 bool  bClKeepAll;
 2115 bool  bClJoinOutput;
 2116 bool  bClFixOutput;
 2117 bool  bClScan;
 2118 bool  bClKeepTmp;
 2119 bool  bClShowTmp;
 2120 num   nClGlobalBytes;
 2121 
 2122 char  szClTmpOutFile[SFK_MAX_PATH+10];
 2123 char  szClRecentOutFile[SFK_MAX_PATH+10];
 2124 char  szClFinalFile[SFK_MAX_PATH+10];
 2125 char  szClFixParms[200];
 2126 
 2127 char  szClMoveSrcOutDir[200];
 2128 char  szClMoveSrcOutFile[SFK_MAX_PATH+10];
 2129 
 2130 FILE  *fClOut;
 2131 FileStat clOutStat;
 2132 
 2133 char  *pszClM3UText;
 2134 char  *pszClM3UFileEntry;  // pointer into M3UText
 2135 };
 2136 
 2137 class FileCloser {
 2138 public:
 2139     FileCloser  (Coi *pcoi); // can be NULL
 2140    ~FileCloser  ( );
 2141 private:
 2142     Coi *pClCoi;
 2143 };
 2144 
 2145 class CommandChaining
 2146 {
 2147 public:
 2148    CommandChaining ( );
 2149 
 2150    bool  colfiles;   // collect filenames
 2151    bool  usefiles;   // use collected filenames
 2152    bool  coldata;    // collect data
 2153    bool  usedata;    // use collected data
 2154    bool  colbinary;  // with coldata: next command accepts binary
 2155 
 2156    CoiTable *infiles;   // while using filenames
 2157    CoiTable *outfiles;  // while collecting filenames
 2158 
 2159    StringPipe *indata;  // text and attributes
 2160    StringPipe *outdata; // text and attributes
 2161    StringPipe *storedata;
 2162    bool        storetextdone;
 2163    StringPipe *perlinein;
 2164    StringPipe *perlineout;
 2165 
 2166    KeyMap *justNamesFilter;
 2167 
 2168    bool  text2files;
 2169    bool  files2text;
 2170 
 2171    int  init();
 2172    void  reset();    // per loop
 2173    void  shutdown();
 2174    bool  colany() { return colfiles || coldata; }
 2175    bool  useany() { return usefiles || usedata; }
 2176    int  moveOutToIn(char *pszCmd);
 2177    int  convInDataToInFiles ( );
 2178 
 2179    int  addLine(char *pszText, char *pszAttr, bool bSplitByLF=0);
 2180    int  addToCurLine(char *pszWords, char *pszAttr, bool bNewLine=0);
 2181    int  addStreamAsLines(int iCmd, char *pData, int iData);
 2182    int  addBlockAsLines(char *pData, int iData);
 2183 
 2184    int  addFile(Coi &ocoi); // is COPIED
 2185    int  hasFile(char *psz);
 2186    int  numberOfInFiles() { return infiles->numberOfEntries(); }
 2187    Coi  *getFile(int nIndex); // returns null on wrong index
 2188 
 2189    int  print(char cattrib, int nflags, cchar *pszFormat, ...);
 2190    int  print(cchar *pszFormat, ...); // multi-line support
 2191 
 2192    int  printFile(cchar *pszOutFile, bool bWriteFile, cchar *pszFormat, ...);
 2193 
 2194    void  dumpContents();   // to terminal
 2195 
 2196    int   addBinary(uchar *pData, int iSize);
 2197    uchar *loadBinary(num &rSize); // owned by caller
 2198 
 2199    num   nClOutBinarySize;  // for binary write
 2200    num   nClInBinarySize;   // for binary read
 2201    uint  nClOutCheckSum;
 2202    uint  nClInCheckSum;
 2203 
 2204 private:
 2205    char  szClPreBuf[MAX_LINE_LEN+10];
 2206    char  szClPreAttr[MAX_LINE_LEN+10];
 2207    char  szClBuf[MAX_LINE_LEN+10];
 2208    char  szClAttr[MAX_LINE_LEN+10];
 2209    char  szClBinBuf[32768+100];
 2210    int   iClBinBufUsed;
 2211    bool  btold1;
 2212 };
 2213 
 2214 extern CommandChaining chain;
 2215 
 2216 enum eConvTargetFormats
 2217 {
 2218    eConvFormat_LF     = 1,
 2219    eConvFormat_CRLF   = 2,
 2220    eConvFormat_ShowLE = 4
 2221 };
 2222 
 2223 int joinPath(char *pszDst, int nMaxDst, char *pszSrc1, char *pszSrc2, int *pFlexible=0);
 2224 void printColorText(char *pszText, char *pszAttrib, bool bWithLF=1);
 2225 char *timeAsString(num nTime, int iMode=0, bool bUTC=0);
 2226 void dumpRepOut(uchar *pSrcCtxData, int iSrcCtxLen,
 2227    int iHitOff, int iHitLen,
 2228    uchar *pDstData, int iDstLen,
 2229    num nListOffset
 2230  );
 2231 void dumpFromToSeparator();
 2232 int atomovrange(char *psz, num *pstart, num *pend);
 2233 int atomovrange(char *psz, int *pstart, int *pend, bool bUseBytes);
 2234 bool matchesDirMask(char *pszFullPath, bool bTakeFullPath, bool bApplyWhiteMasks, int iFromInfo);
 2235 int execSingleFile(Coi  *pcoi, int lLevel, int &lGlobFiles, int nDirFileCnt, int &lDirs, num &lBytes, num &ntime1, num &ntime2);
 2236 int execSingleDir(Coi  *pcoi, int lLevel, int &lGlobFiles, FileList &oDirFiles, int &lDirs, num &lBytes, num &ntime1, num &ntime2);
 2237 bool matchesCurrentRoot(char *pszDir);
 2238 int matchesFileMask (char *pszFile, char *pszInfoAbsName, int iFromInfo);
 2239 extern bool bGlblNoRootDirFiles;
 2240 int saveFile(char *pszName, uchar *pData, int iSize, const char *pszMode="wb");
 2241 int execFileCopySub(char *pszSrc, char *pszDst, char *pszShSrc=0, char *pszShDst=0);
 2242 int execFileMoveSub(char *pszSrc, char *pszDst);
 2243 int joinShadowPath(char *pszDst, int nMaxDst, char *pszSrc1, char *pszSrc2);
 2244 int createSubDirTree(char *pszDstRoot, char *pszDirTree, char *pszRefRoot);
 2245 int mygetpos64(FILE *f, num &rpos, char *pszFile);
 2246 int mysetpos64(FILE *f, num pos, char *pszFile);
 2247 extern int bGlblCollectHelp;
 2248 
 2249 #ifdef _WIN32
 2250 char *winSysError();
 2251 int makeWinFileTime(num nsrctime, FILETIME &rdsttime, num nSrcNanoSec=0, bool bUTC=0);
 2252 #endif
 2253 
 2254 class ExtProgram // call external program
 2255 {
 2256 public:
 2257       ExtProgram  ( );
 2258 
 2259    int   start (int iTimeout, const char *pszMask, ...);
 2260 
 2261    int   stop  ( );
 2262 
 2263    int   readFull (uchar *pBuf, int iToRead);
 2264 
 2265    int   readFull (uchar **ppBuf, int *pIOBufSize);
 2266    // Note: this will alloc given *pIOBufSize.
 2267    // RC 0: OK *pBufSize contains data size, caller is owner.
 2268    // RC 5: timeout
 2269    // RC 9: error
 2270 
 2271    char *readLine ( );
 2272 
 2273    // internal
 2274    int   read  (uchar *pBuf, int iMaxBuf);
 2275    // RC >0: bytes read
 2276    // RC  0: no data yet
 2277    // RC -1: completed
 2278    // RC -5: timeout
 2279    // RC -9: other error
 2280 
 2281 #ifdef _WIN32
 2282 int winFork(char *pszCmd,HANDLE hChildStdOut,HANDLE hChildStdIn,HANDLE hChildStdErr);
 2283 HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
 2284 HANDLE hInputWriteTmp,hInputRead,hInputWrite;
 2285 HANDLE hErrorWrite;
 2286 HANDLE clXPid;
 2287 #else
 2288 pid_t mypopen2(char *commandin[], int *infp, int *outfp);
 2289 pid_t clXPid;
 2290 int   clXFin;
 2291 #endif
 2292 
 2293 int   clXTimeout;
 2294 num   clXRunStart;
 2295 char  szClXCmdBuf    [1000+20];
 2296 char  szClXDataBuf   [4000+20];
 2297 char  szClXLineBuf   [1000+20];
 2298 char *aClXCmdParms   [100];
 2299 };
 2300 
 2301 extern KeyMap glblSFKVar;
 2302 bool   sfkhavevars();
 2303 int    sfksetvar(char *pname, uchar *pdata, int idata, int badd=0);
 2304 uchar *sfkgetvar(char *pname, int *plen);
 2305 uchar *sfkgetvar(int i, char **ppname, int *plen);
 2306 void   sfkfreevars();
 2307 bool   isHttpURL(char *psz);
 2308 
 2309 #ifndef USE_SFK_BASE
 2310 
 2311  #if defined(WINFULL) && defined(_MSC_VER) && !defined(SFK_NO_MEMTRACE)
 2312   #define SFK_MEMTRACE
 2313  #endif
 2314 
 2315 class FileMetaDB
 2316 {
 2317 public:
 2318    FileMetaDB  ( );
 2319 
 2320    bool  canRead     ( ) { return nClMode == 1; }
 2321    bool  canUpdate   ( ) { return nClMode == 2; }
 2322 
 2323    int  openUpdate  (char *pszFilename);
 2324    int  openRead    (char *pszBaseName, bool bVerbose); // zz-sign w/o .dat
 2325    int  updateFile  (char *pszName, uchar *pmd5cont = 0, bool bJustKeep=false);
 2326    int  removeFile  (char *pszName, bool bPrefixLF = 0);
 2327    int  updateDir   (char *pszName);
 2328    int  save        (int &rnSignsWritten);
 2329    void  reset       ( );
 2330    int  checkFile   (char *pszName);
 2331    int  numberOfFiles  ( ) { return aUnixTime.numberOfEntries(); }
 2332 
 2333    int  getFileFlags   (int nIndex) { return aFlags.getEntry(nIndex, __LINE__); }
 2334 
 2335    int  verifyFile  (char *pszFilename, char *pszShFile=0, bool bSilentAttribs=0);
 2336    int  verifyFile  (int nIndex, bool bCleanup);
 2337    // 0:ok 1:notfound 9:file_differs_inconsistently
 2338 
 2339    int  numberOfVerifies  ( ) { return nClVerified; }
 2340    int  numberOfVerMissing( ) { return nClVerMissing; }
 2341    int  numberOfVerFailed ( ) { return nClVerFailed; }
 2342    bool  anyEvents         ( ) { return nClVerified || nClVerMissing || nClVerFailed; }
 2343    char *filename          ( ) { return pszClDBFile; }
 2344    int  setMetaDir        (char *psz);
 2345    char  *metaDir          ( ) { return pszClMetaDir; }
 2346    bool  isSignatureFile   (char *pszFile);
 2347 
 2348 private:
 2349    int  indexOf     (char *pszFile);
 2350    int  writeRecord (FILE *fout, int nIndex, SFKMD5 *pmd5, bool bIsLastRec);
 2351    int  writeEpilogue     (FILE *fout, SFKMD5 *pmd5);
 2352    int  loadDB      (char *pszBasePath, bool bVerbose);
 2353    int  loadRecord  (FILE *fin, SFKMD5 *pmd5, bool bSim); // uses szLineBuf
 2354    int  loadHeader  (FILE *fin, SFKMD5 *pmd5);
 2355    int  loadCheckEpilogue (FILE *fin, SFKMD5 *pmd5);
 2356 
 2357    static char *pszClFileDBHead;
 2358 
 2359    char     *pszClDBPath;
 2360    char     *pszClDBFile;
 2361    char     *pszClLineBuf;
 2362    char     *pszClMetaDir;
 2363    int     nClMode;
 2364    int     nClVerified;
 2365    int     nClVerMissing;
 2366    int     nClVerFailed;
 2367    NumTable  aUnixTime;
 2368    NumTable  aWinTime;
 2369    NumTable  aContSumLo;
 2370    NumTable  aContSumHi;
 2371    LongTable aFlags;
 2372    StringTable aPath;
 2373 
 2374    uchar     abClRecBuf[1024];
 2375 };
 2376 
 2377 extern FileMetaDB filedb;
 2378 
 2379 class FileVerifier
 2380 {
 2381 public:
 2382    FileVerifier   ( );
 2383    int  remember (char *pszDstName, num nsumhi, num nsumlo);
 2384    int  verify   ( );
 2385    void  reset    ( );
 2386    int  matchedFiles( ) { return nClMatched; }
 2387    int  failedFiles ( ) { return nClFailed; }
 2388    int  totalFiles  ( ) { return aClDst.numberOfEntries(); }
 2389 private:
 2390    NumTable    aClSumHi;
 2391    NumTable    aClSumLo;
 2392    StringTable aClDst;
 2393    int  nClMatched;
 2394    int  nClFailed;
 2395 };
 2396 
 2397 extern FileVerifier glblVerifier;
 2398 
 2399 class CopyCache
 2400 {
 2401 public:
 2402    CopyCache      ( );
 2403    void setBuf    (uchar *pBuf, num nBufSize);
 2404    int process   (char *pszSrcFile, char *pszDstFile, char *pszShDst, uint nflags);
 2405    int flush     ( );
 2406    void setEmpty  ( );
 2407 private:
 2408    int putBlock  (uchar *pData, int nDataSize);
 2409    uchar *pClBuf;
 2410    num   nClBufSize;
 2411    num   nClUsed;
 2412    char  szTmpBuf[MAX_LINE_LEN+10];
 2413 };
 2414 
 2415 extern CopyCache glblCopyCache;
 2416 
 2417 class SFKMapArgs
 2418 {
 2419 public:
 2420       SFKMapArgs  (char *pszCmd, int argc, char *argv[], int iDir);
 2421      ~SFKMapArgs  ( );
 2422    char  *eval    (char *pszExp);
 2423 
 2424    bool  bdead;
 2425 
 2426    StringTable  clDynaStrings;
 2427    char       **clargx;
 2428    bool         bDoneAlloc;
 2429 
 2430    char         szClEvalOut[300];   // for small results
 2431    char        *pszClEvalOut;       // for large results
 2432 };
 2433 
 2434 #ifdef SFKINT
 2435  #define WITH_FTP_LIMITS
 2436  // #define WITH_VAR_CALC
 2437 #endif
 2438 
 2439 #define MAX_FTP_VDIR 10
 2440 
 2441 class FTPServer
 2442 {
 2443 public:
 2444       FTPServer   ( );
 2445      ~FTPServer   ( );
 2446 
 2447    int run           (uint nPort, bool bRW, bool bRun, bool bDeep, uint nPort2, uint nPasvPort);
 2448    char *absPath     (char *pszFilePath=0);
 2449    char *sysPath     (char *pszFilePath=0, int *piVDir=0);
 2450    int   mapPath     (char *pszRelPath, bool bAllowRoot=0, bool bCheckDiskSpace=0);
 2451    int   mapPathInt  (char *pszRelPath, bool bAllowRoot, bool bCheckDiskSpace);
 2452    int   reply       (cchar *pszMask, ...);
 2453    int   replyFromRC (int iSubRC);
 2454    int   readLine    ( );
 2455    void  setStart    ( );
 2456    int   isTimeout   (int iTimeout);
 2457    int   addUseDir   (char *psz);
 2458    int   setFixDir   (char *psz);
 2459 
 2460 private:
 2461    int   addTrailSlash     (char *pszBuf, int iMaxBuf);
 2462    void  stripTrailSlash   (char *pszPath, char cSlash);
 2463    char *notslash          (char *pszPath);
 2464    int   setLocalWalkDir   (char *pszPath);
 2465    int   checkPath         (char *pszPath, bool bDeep);
 2466    int   copyNormalized    (char *pdst, int imaxdst, char *psrc);
 2467 
 2468 public:
 2469 char
 2470    szClAuthUser      [50],
 2471    szClAuthPW        [50],
 2472    szClRunPW         [50],
 2473    szClEnvInfoUser   [50],
 2474    szClEnvInfoPW     [50],
 2475    szClEnvInfoRunPW  [50];
 2476 
 2477 private:
 2478 char
 2479    szClWorkDir    [800],
 2480    szClOldWorkDir [800],
 2481    szClAbsPathBuf [800],
 2482    szClSysPathBuf [800],
 2483    szClTmpPathBuf [800],
 2484    szClTmpPathBuf2[800],
 2485    szClCmpPathBuf [800],
 2486    szClFixSysDir  [800],
 2487    szClRenameFrom [800],
 2488    szClReplyBuf   [1024];
 2489 
 2490 int
 2491    xrerun   (char *pszCmd, int iTimeout),
 2492    xpipe    ( ),
 2493    xstop    ( );
 2494 
 2495 // #define WITH_FTP_EXTPROG
 2496 // linux: unexpected "command completed by eod"
 2497 
 2498 #ifdef WITH_FTP_EXTPROG
 2499 ExtProgram
 2500    clXProg;
 2501 #else
 2502 
 2503 #ifdef _WIN32
 2504 int winFork(char *pszCmd,HANDLE hChildStdOut,HANDLE hChildStdIn,HANDLE hChildStdErr);
 2505 HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
 2506 HANDLE hInputWriteTmp,hInputRead,hInputWrite;
 2507 HANDLE hErrorWrite;
 2508 HANDLE clXPid;
 2509 #else
 2510 pid_t mypopen2    (char *commandin[], int *infp, int *outfp);
 2511 int   mysystemio  (char *pszCmd, int iTimeout);
 2512 pid_t
 2513    clXPid;
 2514 int
 2515    clXFin;
 2516 #endif
 2517 
 2518 #endif
 2519 
 2520 int
 2521    clXTimeout;
 2522 num
 2523    clXRunStart;
 2524 char
 2525    szClXCmdBuf    [1000+20],
 2526    szClXDataBuf   [4000+20];
 2527 char
 2528    *aClXCmdParms  [100];
 2529 
 2530 int  iClVDir;
 2531 char aClVDirSrc[MAX_FTP_VDIR+2][100];
 2532 char aClVDirDst[MAX_FTP_VDIR+2][200];
 2533 
 2534 #ifdef WITH_FTP_LIMITS
 2535 char aClVDirLimMode[MAX_FTP_VDIR+2];    // null, 'd'eep, 'f'lat
 2536 int  aClVDirLimFreeMB[MAX_FTP_VDIR+2];  // with 'd'eep and 'flat'
 2537 int  aClVDirLimUsedMB[MAX_FTP_VDIR+2];  // 'f'lat only
 2538 int  aClVDirLimUsedFil[MAX_FTP_VDIR+2]; // 'f'lat only
 2539 #endif
 2540 
 2541 struct sockaddr_in
 2542    clServerAdr,
 2543    clPasServAdr,
 2544    clClientAdr,
 2545    clDataAdr;
 2546 
 2547 SOCKET
 2548    hClServer,
 2549    hClClient,
 2550    hClPasServ,
 2551    hClData;
 2552  
 2553 num
 2554    nClStart,
 2555    nClDiskFree;
 2556 
 2557 bool
 2558    bClSendFailed,
 2559    bClTimeout,
 2560    bClDeep;
 2561 };
 2562 
 2563 #endif
 2564 
 2565 // SFK home dir creation and filename building
 2566 class SFKHome
 2567 {
 2568 public:
 2569       SFKHome  ( );
 2570 
 2571 bool
 2572       noHomeDir   ( );
 2573 char
 2574       *makePath   (char *pszRelPath, bool bReadOnly=0),
 2575        // also creates required folders.
 2576        // returns NULL on any error.
 2577       *getPath    (char *pszRelPath);
 2578        // for readonly access.
 2579        // returns NULL on any error.
 2580 
 2581 bool  bClTold;
 2582 char  szClDir     [SFK_MAX_PATH+10];
 2583 char  szClPathBuf [SFK_MAX_PATH+10];
 2584 };
 2585 
 2586 // find: BinTexter remembers so many chars from previous line
 2587 //       to detect AND patterns spawning across soft-wraps.
 2588 #define BINTEXT_RECSIZE 3000
 2589 // 600 * 2 = 1200, 1200 * 2 = 2400
 2590 
 2591 class BinTexter
 2592 {
 2593 public:
 2594    BinTexter         (Coi *pcoi);
 2595   ~BinTexter         ( );
 2596 
 2597    enum eDoWhat {
 2598       eBT_Print   = 1,  // floating output, LFs blanked
 2599       eBT_Grep    = 2,  // LFs lead to hard line break
 2600       eBT_JamFile = 3   // floating output, LFs blanked
 2601    };
 2602 
 2603    // uses szLineBuf, szLineBuf2.
 2604    int  process     (int nDoWhat);
 2605    int  processLine (char *pszBuf, int nDoWhat, int nLine, bool bHardWrap);
 2606 
 2607 private:
 2608    Coi  *pClCoi;
 2609    char  szClPreBuf[80];   // just a short per line prefix
 2610    char  szClOutBuf[BINTEXT_RECSIZE+100]; // fix: 1703: buffer too small.
 2611    char  szClAttBuf[BINTEXT_RECSIZE+100]; // fix: 1703: buffer too small
 2612    char  szClLastLine[BINTEXT_RECSIZE+100];
 2613    bool  bClDumpedFileName;
 2614 };
 2615 
 2616 // --- sfk190 nocase with variable table ---
 2617 
 2618 class SFKChars
 2619 {
 2620 public:
 2621       SFKChars ( );
 2622 
 2623    int    init       ( );
 2624    int    setocp     (ushort i);
 2625    int    setacp     (ushort i);
 2626    ushort getocp     ( );  // calls init().
 2627    ushort getacp     ( );  // calls init().
 2628 
 2629    int    wlen       (ushort *puni);
 2630 
 2631    // fast calls using maps
 2632    ushort ansitouni  (uchar  c);
 2633    ushort oemtouni   (uchar  c);
 2634    uchar  unitoansi  (ushort n); // returns 0 if n/a
 2635    uchar  unitooem   (ushort n); // returns 0 if n/a
 2636 
 2637    uchar  oemtoansi  (uchar  c);
 2638    uchar  ansitooem  (uchar  c);
 2639 
 2640    int    stroemtoansi  (char *psz, int *pChg=0, bool bNoDefault=0);
 2641    int    stransitooem  (char *psz, int *pChg=0, bool bNoDefault=0);
 2642 
 2643    int    strunitoansi  (ushort *puni, int iunilen,
 2644                          char *pansi, int imaxansi);
 2645 
 2646    // internal
 2647    ushort ibytetouni (uchar c, ushort icp);
 2648 
 2649 bool     bclinited;
 2650 ushort   iclocp, iclacp;
 2651 bool     bsysocp, bsysacp, banycp;
 2652 
 2653 ushort   amap1[256];    // oem to uni
 2654 uchar    amap2[65536];  // uni to oem
 2655 
 2656 ushort   amap3[256];    // ans to uni
 2657 uchar    amap4[65536];  // uni to ans
 2658 
 2659 uchar    amap5[256];    // oem to ans
 2660 uchar    amap6[256];    // ans to oem
 2661 
 2662 uchar    amap5err[256];
 2663 uchar    amap6err[256];
 2664 
 2665 char     sztmp[50];
 2666 ushort   awtmp[50];
 2667 };
 2668 
 2669 class SFKNoCase
 2670 {
 2671 public:
 2672    SFKNoCase   (bool bfuzz);
 2673 
 2674    void  tellPage    ( );
 2675 
 2676    uchar itolower    (uchar c);
 2677    uchar itoupper    (uchar c);
 2678    uchar map1to1     (uchar c, uchar btolower, ushort *puni);
 2679    bool  iisalpha    (uchar c);
 2680    bool  iisalnum    (uchar c);
 2681    bool  iisprint    (uchar c);
 2682 
 2683    // compat with xfind etc. calls
 2684    uchar mapChar (uchar c, uchar bCase) { return bCase ? c : itolower(c); }
 2685    uchar lowerUChar(uchar c) { return itolower(c); }
 2686    uchar upperUChar(uchar c) { return itoupper(c); }
 2687    void  isetStringToLower(char *psz);
 2688 
 2689 bool   bclfuzz;
 2690 bool   bcltoldcp;
 2691 
 2692 uchar  atolower [256];
 2693 uchar  atoupper [256];
 2694 uchar  aisalpha [256];
 2695 };
 2696 
 2697 extern SFKNoCase sfknocasesharp;
 2698 extern SFKNoCase sfknocasefuzz;
 2699 
 2700 #define sfkmaxname 1000
 2701 
 2702 class sfkname
 2703 {
 2704 public:
 2705    sfkname  (const char *psz, bool bpure=0);
 2706    sfkname  (ushort *pwsz);
 2707 
 2708    char   *vname  ( );
 2709    ushort *wname  ( );
 2710 
 2711 char   szname  [sfkmaxname+20];
 2712 ushort awname  [sfkmaxname+20];
 2713 ushort nstate;
 2714 bool   bbadconv;
 2715 };
 2716 
 2717 #ifdef SFKPIC
 2718 
 2719 #include "sfkpicio.hpp"
 2720 
 2721 class SFKPic
 2722 {
 2723 public:
 2724    SFKPic   ( );
 2725   ~SFKPic   ( );
 2726 
 2727    int   load     (char *pszFile);
 2728    int   load     (uchar *pPacked, int nPacked);
 2729    int   save     (char *pszFile);
 2730    int   allocpix (uint w, uint h);
 2731    void  freepix  ( );
 2732 
 2733    uint  width    ( )   { return octl.width;  }
 2734    uint  height   ( )   { return octl.height; }
 2735 
 2736    uint  pix      (uchar a,uchar r,uchar g,uchar b);
 2737    uchar red      (uint c) { return (uchar)(c >> 16); }
 2738    uchar grn      (uint c) { return (uchar)(c >>  8); }
 2739    uchar blu      (uint c) { return (uchar)(c >>  0); }
 2740    uchar alp      (uint c) { return (uchar)(c >> 24); }
 2741 
 2742    void  setpix   (uint x, uint y, uint c);
 2743    uint  getpix   (uint x, uint y);
 2744    void  copyFrom (SFKPic *pSrc, uint x1dst, uint y1dst, uint wdst, uint hdst, uint x1src, uint y1src, uint wsrc, uint hsrc);
 2745 
 2746    int   getErrNum   ( );
 2747    char *getErrStr   ( );
 2748 
 2749    int   getObjectSize  ( );  // for internal checks
 2750 
 2751 struct SFKPicData
 2752    octl;
 2753 };
 2754 #endif // SFKPIC
 2755 
 2756 extern void sfkmem_checklist(const char *pszCheckPoint);
 2757 extern int  prepareTCP();
 2758 extern void shutdownTCP();
 2759 extern int  sfktolower(int c);
 2760 extern int  sfktoupper(int c);
 2761 extern void sfkSetStringToLower(char *psz);
 2762 extern uchar sfkMapChar(char ch, uchar bCase);
 2763 extern uchar sfkLowerUChar(uchar c);
 2764 extern uchar sfkUpperUChar(uchar c);
 2765 extern void  sfkSetHeadMatch(uchar ucFirst, uchar aHeadMatch[]);
 2766 extern char *getMacForIP(uint uiIP);
 2767 extern bool  useOfficeBaseNames();
 2768 extern void  setUsingFileList(int bYesNo);
 2769 extern bool  ispathchr(char c);
 2770 extern int   myfseek(FILE *f, num nOffset, int nOrigin);
 2771 extern SFKChars sfkchars;
 2772 
 2773 #endif // _SFKBASE_HPP_
 2774