gushi: (Default)
[personal profile] gushi

In trying to get php4 (which I've admin'd for many years) running last night -- it occured to me: why not php3? I mean, that's very, very, very dead, right?

Still, the source code was available. I looked at the output of ./configure --help, and came up with something reasonable:

./configure --with-mysql=/usr/local --with-mcrypt=/usr/local --with-mhash=/usr/local --with-ftp --with-gettext=/usr/local --with-zlib=/usr

And then the trouble started. It wouldn't build.

Outright Build Failure

There were a ton of warnings (this always happens with older code), but the show-stopper was:

functions/crypt.c:133:12: error: 'PHP3_MAX_SALT_LEN' undeclared (first use in this function)

In looking through the source code, I found this:

#if PHP3_STD_DES_CRYPT
#define PHP3_MAX_SALT_LEN 2
#endif
#if PHP3_EXT_DES_CRYPT
#undef PHP3_MAX_SALT_LEN
#define PHP3_MAX_SALT_LEN 9
#endif
#if PHP3_MD5_CRYPT
#undef PHP3_MAX_SALT_LEN
#define PHP3_MAX_SALT_LEN 12
#endif

Stupidly, there was no default being set. So, I had to go figure out why.

gcc on a modern system

Most people who have used configure to make a unix program know it to be this roomba-like script that goes and magically discovers how your system works. To save reinventing the wheel, there's now a tool called GNU Autoconf that basically does most of this. But in the old-days, the way configure worked was by basically trying to trick the C compiler into building a small program.

For example, to figure out if the crypto functions were working, the user would see something like:

checking for standard DES crypt... no
checking for extended DES crypt...

But that "no" didn't come up immediately. Instead, the little c program that configure ran was segfaulting.

#line 4184 "configure" 
#include "confdefs.h"

#if HAVE_CRYPT_H
#include <crypt.h>
#endif

main() {
#if HAVE_CRYPT
exit (strcmp((char *)crypt("rasmuslerdorf","rl"),"rl.3StKT.4T8M"));
#else
exit(0);
#endif
}

You can go ahead and run that program if you like with a modern GCC. It'll complain about "exit" not being properly defined, it'll complain that crypt isn't being included in the right places. Even if it compiles, it'll crash, segfault, and dump core if you try to run it.

So, after manually patching configure to include modern libraries and build the test programs right, it magically started detecting enough crypto functions to let the build work.

That little c program now looked like:

#line 4184 "configure"
#include "confdefs.h"
#define _XOPEN_SOURCE
#if HAVE_CRYPT_H
#include <crypt.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
#if HAVE_CRYPT
  exit (strcmp((char *)crypt("rasmuslerdorf","rl"),"rl.3StKT.4T8M"));
#else
  exit(0);
#endif
}

But there were more failures

If you look at the above, I included a bunch of libraries. Things like zlib, and mysql, and mcrypt. All those have been changing over time, and no longer have the exact same functions they were built with in 1998.

So, I relented: I simply decided to try to get the core functions running as a proof-of-concept.

./configure

It built, and I copied the new "php" binary to /usr/local/bin/php3-cgi

When I tried to run a script with it, however, it simply complained at me:

No input file specified

Hacking around the parser

It became clear to me that in the early days of PHP, there was a supplied CGI binary, but it still required some tight wiring into the webserver to work. So, rather than having suphp load it like other versions of PHP, I wrote a tiny wrapper CGI script, that would just call the "php info" functions:

#!/usr/local/bin/perl
%ENV=();
open FILE, "/usr/local/bin/php3-cgi /home/danm/public_html/phptest/3/php.php|" or die "Cannot open PHP";
while (<FILE>) {
  print;
}

It still cryptically complained that there was no input file specified, and then it occured to me that something was telling it it was running as a CGI, but it wasn't picking up on the path. Thus, I cleared the %ENV hash to make it think it was running on the command line. (It still puts out a header and speaks HTML, tho).

Conclusion

What was the point of this. Well, for starters, one of my long-time claims to fame/shame has been: I am not a C programmer.. I've wanted to learn for a decade, and this is a sysadmin who runs critical internet infrastructure talking here. It bothers me a lot. So saying "nope, doesn't work" wasn't acceptable to me. The cost of an afternoon to know I could tackle this was worth it. And it was a nice excuse to get back to blogging.

Having the interpeter lying around isn't actually super harmful, but it's also not super useful. But I learned about C, and about myself. This silly project got me into the zone.

Proof of life

There You Go

August 2017

S M T W T F S
  12345
678 9101112
13141516171819
20212223242526
27 28293031  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 26th, 2017 07:16 am
Powered by Dreamwidth Studios