// (c) 1990-2007 Electronic Arts Inc.

const char *SPIT_history[] =
{
"------------------------------------------------------------------",
"                                                                  ",
"                             ZCopy v1.02                          ",
"                                                                  ",
"                     by FrANK G. Barchard, EAC                    ",
"                                                                  ",
"                    Main program - Jul 18, 2002                   ",
"                                                                  ",
"------------------------------------------------------------------",
"                                                                  ",
" Version Date   SE History:                                       ",
" ------- ----   -- --------                                       ",
"    1.00 000414 FB based on zcut                                  ",
"    1.01 000926 FB ported to C++                                  ",
"    1.02 020718 FB copy normal files, 2 args checks               ",
"                                                                  ",
"------------------------------------------------------------------",
"\0"
};

/****************************************************************/
/*  Spit Setup                                                  */
/****************************************************************/

#include "spit.h"
#include "range.h"
#include "ranger.h"

#if defined(_MSC_VER)
#pragma warning(push,1)
#include <windows.h>
#include <wininet.h>
#pragma warning(pop)
#endif

const char TextVersion[]="1.02 (Samba) 2007.12.4";
#define TOOL_VERSION 102
#define TOOL_NAME "zcopy"

static char OPTbytes[SPITMAXLINE];

static double TIMEload;
static double TIMEcut;
static double TIMEsave;

/****************************************************************/
/*  Internal Functions                                          */
/****************************************************************/

// is this a URL? typical url looks like this:
// http://garp.eac.ea.com/bugzilla/show_bug.cgi?id=2846

static bool ZCOPY_isurl(const char *fname)
{
    bool isurl=false;
    if (strstr(fname,"://"))
        isurl = true;
    return isurl;
}


static bool URL_loadfile(SPITMEM *mem, const char *fname, int verbose)
{
    int ok=0;
    int len;
    HINTERNET internethandle;
    HINTERNET filehandle;

    internethandle = InternetOpen("ZCopy",
    //using either of these causes the read to read a proxy authentication error html
    //                            INTERNET_OPEN_TYPE_PRECONFIG,
    //                            INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY,
    //                            INTERNET_OPEN_TYPE_DIRECT,    //this was is ok but use proxy
                                  INTERNET_OPEN_TYPE_PROXY,
                                  NULL,
                                  NULL,
                                  0);//INTERNET_FLAG_ASYNC);
    if (verbose>=6)
        printf("InternetOpen %lx\n",internethandle);
    if (internethandle)
    {
        filehandle = InternetOpenUrl(internethandle,
                                         fname,
                                         NULL,
                                         0,
                                         INTERNET_FLAG_KEEP_CONNECTION,
                                         0);

        if (verbose>=6)
            printf("InternetOpenUrl%lx\n",filehandle);
        if (filehandle)
        {
            unsigned int out;
            int beginning;

            len = InternetSetFilePointer(filehandle, 0, NULL, FILE_END, 0);
            beginning = InternetSetFilePointer(filehandle, 0, NULL, FILE_BEGIN, 0);

            if (verbose>=6)
            {
                printf("InternetSetFilePointer end %d\n",len);
                printf("InternetSetFilePointer beginning %d\n",beginning);
            }

            if (len<=0)
            {
                char buf[1024];
                len = 0;

                do
                {
                    if (InternetReadFile(filehandle, buf, 1024, (LPDWORD) &out))
                    {
                        len += out;
                    }
                    else
                        break;
                } while (out);

                InternetCloseHandle(filehandle);

                filehandle = InternetOpenUrl(internethandle,
                                         fname,
                                         NULL,
                                         0,
                                         INTERNET_FLAG_KEEP_CONNECTION,
                                         0);


                if (verbose>=6)
                    printf("read file for size %d\n",len);
            }


            if (len>0)
            {
                int amtread = 0;
                int amtleft = len;
                char *buffer = (char *) galloc(len);

                if (buffer)
                {
                    ok = 1;
                    mem->ptr = buffer;
                    mem->len = len;
                    do
                    {
                        if (InternetReadFile(filehandle, buffer, amtleft, (LPDWORD) &out))
                        {
                            if (out)
                            {
                                amtread += out;
                                amtleft -= out;
                                buffer += out;
                            }
                        }
                        else
                            out = 0;
                    } while (out);

                    if (verbose>=6)
                        printf("read %d\n",amtread);

                    if (!ok)
                        gfree(buffer);
                }
            }
            InternetCloseHandle(filehandle);
        }

        InternetCloseHandle(internethandle);
    }

    return ok?true:false;
}


#if 0
/*
;
; ABSTRACT
;
; zcopy - copy a file from internet to local file
;
; SUMMARY
;
; zcopy -options [files]
;   @file     response file, containing a list of options and files
;   =file     specify a output file ie zcopy source=dest
;   -f<range> range of bytes to extract (default all)
;   -nologo   disable banner
;   -v0       no console output
;   -v1       prints source file name and errors
;   -v2       status line for each file (default)
;   -v3       additional info
;   -w0       don't output file
;   -w1       output to file (default)
;
; RANGE SYNTAX
;
;     [[!][<start>][..][<end>][+=<step>][,]]*
;     ie  5            byte 5
;         5..9         bytes 5..9 inclusive
;         !10          all except byte 10
;         5,7,9        bytes 5,7 and 9
;         10..98+=2    even bytes in range between 10 and 98
;
; DESCRIPTION
;
; ZCopy copies a file from http, ftp or file to a local file.
;
;
; RETURNS
;
; no return code
;
; SEE ALSO
;
; copy, xd, Spit
;
; SAMPLE OUTPUT
;
; >zcopy zcopy.c =bob -n10..49
;
;   ZCopy v1.01 (Axe) 951116 by FrANK Barchard, EAC
;   zcopy.c: Reading, Cutting, Writing, 40 bytes extracted.
;
; END ABSTRACT
;
*/
#endif

/****************************************************************/
/*  SPIT Routines                                               */
/****************************************************************/

void SPIT_reset(void)
{
    OPTbytes[0] = 0;
    return;
}


void SPIT_usage(const char *prgname, const char *envname, const char *urlname, int utype)
{
    printf("ZCopy v%s by FrANK Barchard, EAC\n",TextVersion);
    if (utype)
        printf("USAGE: %s -options <url> =<file>\n", prgname);

    switch (utype)
    {
        case 2:
            puts("    -f range of bytes to copy    -v verbose");
            puts("    -w write file");
            puts("     @ response file              = output file");
          printf("type '%s -h' for more help\n", prgname);
          printf("type '%s -help' for web page (%s)\n", prgname, urlname);
            break;

        case 3:
            puts("");
          printf("VERSION: %s v%s, Spit v%.2f\n",SPIT_MACHINE,TextVersion,(float)SPIT_VERSION/100.0f);
            puts("SUMMARY: ZCopy file from url to file");
          printf("         SPIT environment variable is %s\n",envname);
            puts("");
            puts("    @file     response file, containing a list of options and files");
          printf("    =file     specify a output file ie %s source=dest\n", prgname);
            puts("    -f<range> range of bytes to extract (default all)");
            puts("    -nologo   disable banner");
            puts("    -time     display timing diagnostic");
            puts("    -v0       no console output");
            puts("    -v1       prints source file name and errors");
            puts("    -v2       status line for each file (default)");
            puts("    -v3       additional info");
            puts("    -w0       don't output file");
            puts("    -w1       output to file (default)");
            puts("");
            puts("RANGE SYNTAX:");
            puts("    [[!][<start>][..][<end>][+=<step>][,]]*");
            puts("    ie  5            byte 5");
            puts("        5..9         bytes 5..9 inclusive");
            puts("        !10          all except byte 10");
            puts("        5,7,9        bytes 5,7 and 9");
            puts("        10..98+=2    even bytes in range between 10 and 98");

        default:
            break;
    }
}

char *SPIT_opt(const char* optptr)
{
    char *d=(char *)0;
    switch (*optptr|(char)' ')
    {
        case 'n':
        case 'f':
            d = SPIT_getrangeopt( OPTbytes,optptr+1, "range of bytes to extract",0,0x7fffffff);
            break;

        default: ;
    }
    return(d);
}

int main(int argc,char **argv)
{
    int more;
    int i;
    struct SPITMEM infile;
    bool ok=false;

    SPIT_init(SPIT_reset, SPIT_usage, SPIT_opt, SPIT_history);
    do
    {
        bool copy1=false;
        more = SPIT_parse(argc, argv, TOOL_NAME, TOOL_VERSION);
        if (SPITargnum==2 && !stricmp(SPITsargv[0],SPITdargv[0]))
            copy1=true;

        for (i=0; (i<SPITargnum && !copy1) || (SPITargnum && i==0); ++i)
        {
            if (ZCOPY_isurl(SPITsargv[i]))
                ok = URL_loadfile(&infile, SPITsargv[i],OPTverbose);
            else
                ok = SPIT_loadfile(&infile, SPITsargv[i])?true:false;

            if (ok)
            {
                const char *filename = SPITdargv[i];
                if (copy1)
                    filename = SPITdargv[1];

#if 0
                char bakname[SPITMAXLINE];

                SPIT_tempname(bakname,filename);
                remove(bakname);
#endif


                if (OPTverbose>=3)
                {   printf("Copying, ");
                    SPIT_flush();
                }

                TIMEsave = SPIT_gettime();

                SPIT_savefile(&infile, filename);

                TIMEsave = SPIT_gettime()-TIMEsave;

                if (OPTverbose>=3)
                {
                    printf("%ld bytes copied.\n", infile.len);
                    if (OPTtime && OPTverbose)
                        printf(" Time load %.2fms, copy %.2fms, save %.2fms\n",TIMEload,TIMEcut,TIMEsave);
                    SPIT_flush();
                }
                SPIT_free(&infile);
            }
        }
        if (OPTverbose==1)
            puts("");

    } while (more>0);

    return(0);
}

