/* patchlib */

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

static const char rcsid[] = "@@(#)$Id: patchlib.c,v 1.3 2000/07/19 10:06:45 Callan Exp $";

static char *
readFile(char *fileName, int *length)
{
    fpos_t  fileLen;
    FILE    *fptr;
    char    *buffer;

    /* Read file in */
    fptr = fopen(fileName, "rb");
    if (!fptr)
    {
         return (NULL);
    }
    fseek(fptr, 0, SEEK_END);
    if (fgetpos(fptr, &fileLen))
    {
         /* Can't get length */
         return (NULL);
    }
    *length = (int)fileLen;

    buffer = malloc(*length);
    if (!buffer)
    {
         fclose(fptr);
         return (NULL);
    }

    fseek(fptr, 0, SEEK_SET);
    fread(buffer, *length, 1, fptr);
    fclose(fptr);

    return(buffer);
}

static int
writeFile(char *buffer, int libLen, char *fileName)
{
    FILE    *fptr;

    /* Write file out */
    fptr = fopen(fileName, "wb");
    if (!fptr)
    {
        return (0);
    }

    fwrite(buffer, libLen, 1, fptr);
    fclose(fptr);

    return (1);
}

static int
searchAndReplace(char *fileName, char *findThis, char *replaceWithThis)
{
    int     libLen;
    char    *libBuffer;
    int     offset, stringLen;

    if (strlen(findThis) != strlen(replaceWithThis))
    {
        fprintf(stderr, "PATCHLIB: Replacement string not same length as search string\n");
        return (0);
    }

    libBuffer = readFile(fileName, &libLen);
    if (!libBuffer)
    {
        fprintf(stderr, "PATCHLIB: Cannot read file %s\n", fileName);
        return (0);
    }

    stringLen = strlen(findThis);

    /* Scan the file for the string we look for */
    offset = 0;
    while (offset+stringLen < libLen)
    {
        if (strnicmp(&libBuffer[offset], findThis, stringLen) == 0)
        {
            /* Got a match, prepare to patch it */
            memcpy(&libBuffer[offset], replaceWithThis, stringLen);
        }
        offset++;
    }

    if (!writeFile(libBuffer, libLen, fileName))
    {
        fprintf(stderr, "PATCHLIB: Cannot write file %s out\n", fileName);
        free(libBuffer);
        return (0);
    }

    free(libBuffer);

    return (1);
}

int
main(int argc, char *argv[])
{
    if (argc != 2)
    {
        fprintf(stderr, "PATCHLIB: Usage: patchlib <libname>\n");
        return (1);
    }

    if (!searchAndReplace(argv[1], "-defaultlib:libm", "                "))
    {
        fprintf(stderr, "PATCHLIB: Search and replace failed\n");
        return (1);
    }

    return (0);
}
