manugarg / pacparser

A library to parse proxy auto-config (PAC) files
http://pacparser.manugarg.com
GNU Lesser General Public License v3.0
506 stars 116 forks source link

Getting a standalone Pactester exe on Windows or Unix #108

Open zx70 opened 3 years ago

zx70 commented 3 years ago

I noticed that the way GCC runs on Windows heavily depends on the local setup (Cygwin, Mingw, Msys, etc..). This is how to get straight to the goal without much care for a clean build process. ..first of all let me suggest to try the pre-packaged development environment crested by the MAME team to build their emulator, it can be unzipped without needing to be installed and is complete (and updated) enough to provide the two parallel environments for MinGW32 and MingGw64. I worked on the shell provided by mingw64.exe.

So, get a ZIP pacparser snapshot from the github code tree, extract it somewhere, and move into src/spidermonkey.

rm jswkgen*
rm *.lib
rm js/src/*.lib
rm js/src/*.o

rm js/src/jsautokw.h

now let's build the code generator for the js keywords and run it:

gcc -o jskwgen js/src/jskwgen.c
./jskwgen > js/src/jsautokw.h

THE TRAP HERE WAS THE WAY 'jskwgen' WAS CALLED, A 'MISSING ./' PATH SPECIFIER ENDS UP IN CREATING AN EMPTY 'jsautokw.h' FILE. An empty file would still permit the build process to succeed, BUT THE RESULTING LIBRARY WON'T WORK CORRECTLY.

The remaining part of the Makefiles should work, thus:

 make -f Makefile.win32

..or use the regular Makefile if you're on Unix. Now pick the library you've got and move one level up:

mv js.lib ..
cd ..

Since our goal is to get a standalone executable, let's skip the DLL/shared library stuff, we just knit the modules together (change -DXP_WIN to -DXP_UNIX if you're not on Windows):

gcc -DXP_WIN pactester.c pacparser.c js.lib -lws2_32 -o pactester -I. -I spidermonkey/js/src

It should do the trick.

You might want to edit pacparser.c and fix the output message for the '-v' parameter, a good practice is to state it is a custom build based on a snapshot, including the point in time of the shapshot.

====== == EXTRA STEP FOR WINDOWS BUILDS, TO USE THE CURRENT CLIENT IP ADDRESS WHEN NOT SPECIFIED

Want more? Ok then, edit 'pactester.c', and include also:

include

Then locate 'int main(' and add more local variables:

char hostname[255];
WORD wVersionRequested;
WSADATA wsaData;
struct hostent *lpHost;
struct in_addr addr;
struct IPv4
{
    unsigned char b1, b2, b3, b4;
};
struct IPv4 myIP;
char c_ip[100];
int err;

..now spot the client_ip definition, it should be:

 if (client_ip)
    pacparser_setmyip(client_ip);

...change to:

  if (client_ip)
    pacparser_setmyip(client_ip);

  else {

    wVersionRequested = MAKEWORD(2, 2);

    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
        printf("WSAStartup failed with error: %d\n", err);
    }

    err = gethostname(hostname,255);

    if (err != 0) {
        printf("gethostname failed with error: %d\n", err);
    }
    //else 
    //  fprintf(stderr, "\nReferring to host '%s' for IP assignment.\n", hostname);

    lpHost = gethostbyname(hostname);

    if (lpHost == NULL) {
        printf("gethostbyname failed with error: %d\n", WSAGetLastError());
    } else {

        /*
        i = 0;
        if (lpHost->h_addrtype == AF_INET)
        {
            while (lpHost->h_addr_list[i] != 0) {
                addr.s_addr = *(u_long *) lpHost->h_addr_list[i++];
                printf("\tIP Address #%d: %s\n", i, inet_ntoa(addr));
            }
        }
        else if (lpHost->h_addrtype == AF_NETBIOS)
        {   
            printf("NETBIOS address was returned\n");
        } 
        */      

        //Obtain the computer's IP
        myIP.b1 = ((struct in_addr *)(lpHost->h_addr))->S_un.S_un_b.s_b1;
        myIP.b2 = ((struct in_addr *)(lpHost->h_addr))->S_un.S_un_b.s_b2;
        myIP.b3 = ((struct in_addr *)(lpHost->h_addr))->S_un.S_un_b.s_b3;
        myIP.b4 = ((struct in_addr *)(lpHost->h_addr))->S_un.S_un_b.s_b4;

        sprintf(c_ip, "%d.%d.%d.%d", myIP.b1, myIP.b2, myIP.b3, myIP.b4);
        client_ip=c_ip;
        //fprintf(stderr, "Setting client IP to '%s'.\n", client_ip);

    }

    pacparser_setmyip(client_ip);

    WSACleanup();
  }

Now use the same command line as before to build it.