Tuesday, January 25, 2011

Guile web challenge: a mysql/php blog on sizzweb -- take 1

Today's internet challenge will be to set up a mysql/php blog on sizzweb, a webserver written entirely in Guile scheme.

Like yesterday, the blog software for today will be b2evolution version 4.0.3.

The webserver for today will be sizzweb version 1.12.

Again, why would I even want to do such a thing?  Because I find it fun.  I don't make fun of you for going golfing, and that's an even bigger waste of time.

sizzweb depends on the guile-www package.  I downloaded and installed guile-www-2.29.

A small bug in latest rev of guile-www-2.29 kept it from building on my machine guile-www bug #32244.

Part 1: getting sizzweb to run


Last time I tried to install this, it was a bit of a failure (not that I tried very hard, or at all).  The problem is that sizzweb is part of a larger package called ttn-do, and ttn-do historically has been targeted on a fork of Guile that had a more powerful set of install and configure tools that the official Guile.

I downloaded ttn-do-379.tar.gz and did ./configure and make, and the build failed with an error in a call to guile-toolsguile-tools is distributed with guile and is sort of a meta tool that calls on of a dozen other scripts that work with scheme sources. ttn-do was looking for the c2x script which is not a script in the mainline guile distribution. This is the sort of thing I thought would happen. This means I won't be able to build the modules in the ttn-do/zz directory because they rely on c2x.

Also guile-tools does not give a nice warning if it can't find a script. Guile bug #32243

So, instead I directly copied the scheme files in ttn-do and ttn-to/zzz into my my guile site directory manually.  Then, to get it to work I
  • ttn-do/zzz/filesystem.scm: changed all calls to make-shared-substring to substring
  • ttn-do/zzz/publishing.scm: use (ice-9 optargs) instead of (ice-9 optargs-kw) 
I also added my own version of the module (ttn-do zz sys linux-gnu) to replace the one function that sizzweb uses from it.

 (define-module (ttn-do zz sys linux-gnu)
  #:use-module (system foreign)
  #:use-module (rnrs bytevectors)
  #:export (sendfile/never-fewer))

;;(define libc (dynamic-link "/usr/lib64/libc.so"))
(define libc (dynamic-link))

(define sendfile
  (pointer->procedure
   long    ; really ssize_t, but, (system
           ; foreign) doesn't have a
           ; ssize_t.
   (dynamic-func "sendfile" libc)
   (list
    int
    int
    unsigned-long   ; Really this is a pointer to
                    ; an off_t, but, we always
                    ; pass it a null pointer
    size_t)))

(define errno (dynamic-pointer "errno" libc))

(define (errno-val)
  (let ((bv (pointer->bytevector errno int)))
    ;; assuming errno is a 4-byte int
    (bytevector-s32-native-ref bv 0))) 

(define (sendfile/never-fewer outfd infd unused count)
  (let loop ((count count))
    (let ((bytes-written (sendfile outfd infd 0 count)))
      (cond
       ((< bytes-written 0)
        (scm-error 'system-error
                   "sendfile/never-fewer"
                   (strerror (errno-val))
                   '()
                   (list (errno-val))))
       ((and (>= bytes-written count))
        *unspecified*)
       ((and (> bytes-written 0) (> count bytes-written))
        (loop (- count bytes-written)))))))
And with all that, I've got the webserver up and running.

Part 2: getting PHP to run

sizzweb has no native php support, but it does have a plug-in architecture called `servlets'.  Basically you create a file named servlets.scm and then write a custom responder that gets used when the input path matches a given regular expression.


The way the servlets system works is that if it matches the regex it gets passed to the handler whether or not there is actually a document at that location.  There would actually be a fair bit of work involved to get it to run PHP.  Subtasks would include
  • Adding index.php to the list of default files
  • Checking to see if the php file is actually there, is not a symlink, and is readable
  • Parsing the GET variables out of the URI
  • And calling php-cgi
But that is enough hacking fun for one day.  Tomorrow, we shall see what the future holds.

No comments:

Post a Comment