/* Copyright (C) 1996,1997,1998,1999 by Salvador E. Tropea (SET),
   see copyrigh file for details */
#include <ceditint.h>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h> /* for mode definitions */
#include <string.h>

#ifdef SUP_GZ
#include <zlib.h>
#endif

#include <gzfiles.h>

#define Uses_MsgBox
#include <tv.h>

#if !defined(__linux__) && !defined(SUP_GZ)
/*
  This routine checks if gzip is there. If we can't find it we must put a warning
*/
int GZFiles_CheckForGZIP(void)
{
 static isGZIPInstalled=0;

 if (!isGZIPInstalled)
   {
    int h_err=open("/dev/null",O_WRONLY | O_CREAT | O_TRUNC,S_IREAD | S_IWRITE);
    int h_errbak=dup(2);
    fflush(stderr);  /* so any buffered chars will be written out */
    dup2(h_err,2);
    int ret=system("gzip");
    dup2(h_errbak,2);
    close(h_err);
    close(h_errbak);

    if (ret>0)
       isGZIPInstalled=1;
    else
       messageBox(_("You must install gzip to browse compressed files!"), mfError | mfOKButton);
   }

 return isGZIPInstalled;
}
#endif

#ifdef SUP_GZ
const int eachRead=16300;

int GZFiles_Expand(char *dest, char *orig)
{
 // First I alloc a 16Kb buffer
 char *buf=new char[eachRead];
 if (!buf)
    return 1;

 gzFile file;
 file=gzopen(orig,"rb");
 if (file==NULL)
   {
    delete buf;
    return 2;
   }

 FILE *f;
 f=fopen(dest,"wb");
 if (!f)
   {
    gzclose(file);
    delete buf;
    return 3;
   }

 int read;
 do
   {
    read=gzread(file,buf,eachRead);
    fwrite(buf,read,1,f);
   }
 while(read==eachRead);

 fclose(f);
 gzclose(file);
 delete buf;

 return 0;
}
#endif // SUP_GZ


int GZFiles_ExpandHL(char *dest, char *orig)
{
 int ret=0;

#ifdef SUP_GZ

 // If libz is linked use this routine
 ret=GZFiles_Expand(dest,orig);

#else // SUP_GZ

 //---- NO libz call gzip

 char Buf2[PATH_MAX*3];
# ifndef __linux__

 // Just run the gzip and get your output in __infc__
 sprintf(Buf2,"gzip -d -c %s > %s",orig,dest);
 if (GZFiles_CheckForGZIP())
    system(Buf2);

# else // __linux__
 // Not so easy, here we create another process, extract your output and copy
 // it to __infc__, the DOS technique doesn't work well.
 FILE *f,*d;

 strcpy(Buf2,"gzip -d -c ");
 strcat(Buf2,orig);
 f=popen(Buf2,"r");
 #ifdef DEBSTD
 fprintf(stderr,"Piping: %s returns %s\n",Buf2,f==NULL ? "fail" : "ok");
 #endif
 if (!f)
    return 1;
 if ((d=fopen(dest,"wb"))==NULL) return 0;
 do
  {
   fputc(fgetc(f),d);
  }
 while(!feof(f));
 fclose(d);
 pclose(f);
 strcpy(orig,dest);

# endif // !__linux__
#endif // !SUP_GZ

 return ret;
}

int GZFiles_IsGZ(FILE *f)
{
 unsigned val=0;
 long pos=ftell(f);

 fread(&val,2,1,f);
 //fseek(f,-2,SEEK_CUR); no no, we don't know if the file even have 2 bytes
 fseek(f,pos,SEEK_SET);

 return (val==0x8B1F);
}

TGZFileWrite::TGZFileWrite(char *fileName, int comp)
{
 if (comp)
   {
    fc=gzopen(fileName,"wb9");
    ok=fc!=NULL;
   }
 else
   {
    f=fopen(fileName,"wb");
    ok=f!=NULL;
   }
 compressed=comp;
}

TGZFileWrite::~TGZFileWrite()
{
 if (compressed)
   {
    if (fc)
       gzclose(fc);
   }
 else
   {
    if (f)
       fclose(f);
   }
}

size_t TGZFileWrite::write(void *buffer, size_t len)
{
 size_t ret;
 if (len==0)
    return 0;
 if (compressed)
   {
    ret=gzwrite(fc,buffer,len);
    if (ret==0)
      {
       ok=0;
       return (size_t)-1;
      }
    return ret;
   }
 ret=fwrite(buffer,len,1,f);
 if (ret<1)
    ok=0;
 return ret;
}


