/* FileExtract
   By Marc Le Douarain
   mavati@club-internet.fr
   13 April 1999
   Update:30 November 2001
   Made on an idea of Mickaël Le Quer
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NO 0
#define ODD 1
#define EVEN 2

char Version[]="$VER:FileExtract 0.9 " __DATE__;

long HexaToLong(char *str)
{
    int i;
    int pw;
    int lgt;
    static int car;
    long res=0;
    lgt=strlen(str);
    pw=1;
    for (i=lgt-1;i>=0;i--)
    {
        car=str[i];
        if (car>='A')
        {
            if (car>='a')
            {
                car=car-'a'+10;
            }
            else
            {
                car=car-'A'+10;
            }
        }
        else
        {
            car=car-'0';
        }
        res=res+(car*pw);
        pw=pw*16;
    }
    return res;
}

void main(int argc, char *argv[])
{
    char *FichierSrc;
    char *FichierDest;
    FILE *FSrc;
    FILE *FDest;
    char Octet,OctetUnused;
    long i;
    long StartPos;
    long EndPos;
    unsigned char NbrArgc;
    char EnterlaceMode;
    char Enterlaced;

    NbrArgc = (unsigned char)argc;
    EnterlaceMode = NO;
    Enterlaced = 0;
    if (argc>1)
    {
        if (argv[1][0]=='-')
        {
            if (argv[1][1]=='o' || argv[1][1]=='O')
                EnterlaceMode = ODD;
            if (argv[1][1]=='e' || argv[1][1]=='E')
                EnterlaceMode = EVEN;
            NbrArgc--;
            Enterlaced = 1;
        }
    }

    if ( (NbrArgc>3) && (strcmp(argv[1+Enterlaced],"?")!=0) )
    {
        FichierSrc=argv[1+Enterlaced];
        FichierDest=argv[2+Enterlaced];
        if (argv[3+Enterlaced][0]=='$')
        {
            StartPos=HexaToLong(&argv[3+Enterlaced][1]);
        }
        else
        {
            StartPos=atol(argv[3+Enterlaced]);
        }
        if (NbrArgc>4)
        {
            if (argv[4+Enterlaced][0]=='+')
            {
                if (argv[4+Enterlaced][1]=='$')
                {
                    EndPos=StartPos+HexaToLong(&argv[4+Enterlaced][2]);
                }
                else
                {
                    EndPos=StartPos+atol(&argv[4+Enterlaced][1]);
                }
            }
            else
            {
                if (argv[4+Enterlaced][0]=='$')
                {
                    EndPos=HexaToLong(&argv[4+Enterlaced][1]);
                }
                else
                {
                    EndPos=atol(argv[4+Enterlaced]);
                }
            }
        }
        else
        {
            EndPos=-1;
        }

        if ((EndPos!=-1)&&(EndPos<StartPos))
        {
            printf("Error: The EndOffset (%d) must be greater than the StartOffset (%d) !\n",StartPos,EndPos);
            printf("If you use the fourth parameter as length : DO NOT FORGET the '+' behind the number!\n");
        }
        else
        {
            FSrc=fopen(FichierSrc,"rb");
            if (FSrc)
            {
                FDest=fopen(FichierDest,"wb");
                if (FDest)
                {
                    fseek(FSrc, StartPos, SEEK_SET);
                    for(i=StartPos;( ( ((i<=EndPos)&&(EndPos!=-1)) || (EndPos==-1) ) && (!(feof(FSrc))) );i++)
                    {
                        if (EnterlaceMode == EVEN)
                        {
                            fread(&OctetUnused,sizeof(char),1,FSrc);
                            i++;
                        }
                        if (fread(&Octet,sizeof(char),1,FSrc))
                        {
                            if (EnterlaceMode == ODD)
                            {
                                fread(&OctetUnused,sizeof(char),1,FSrc);
                                i++;
                            }
                            fwrite(&Octet,sizeof(char),1,FDest);
                        }
                    }
                    fclose(FDest);
                }
                else
                {
                    printf("Failed to write file:%s\n",FichierDest);
                }
                fclose(FSrc);
            }
            else
            {
                printf("Failed to open file:%s\n",FichierSrc);
            }
        }
    }
    else
    {
        printf("%s By Marc Le Douarain (mavati@club-internet.fr)\n",Version+sizeof(char)*5);
        printf("Usage: FileExtract [-mode] <SourceFile> <DestinationFile> <StartOffset> [<EndOffset>or<+Length>]\n"
               "Numbers in hexadecimal usable with the first caracter '$'\n"
               "-mode can be : -odd or -even\n");
    }
}

