source: project/chicken/branches/hygienic/henrietta.scm @ 11642

Last change on this file since 11642 was 11642, checked in by felix winkelmann, 13 years ago

terminate response with eof object

File size: 4.9 KB
Line 
1;;;; henrietta.scm - Server program (CGI) for serving eggs from a repository over HTTP
2;
3; Copyright (c) 2008, The Chicken Team
4; All rights reserved.
5;
6; Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
7; conditions are met:
8;
9;   Redistributions of source code must retain the above copyright notice, this list of conditions and the following
10;     disclaimer.
11;   Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
12;     disclaimer in the documentation and/or other materials provided with the distribution.
13;   Neither the name of the author nor the names of its contributors may be used to endorse or promote
14;     products derived from this software without specific prior written permission.
15;
16; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
17; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24; POSSIBILITY OF SUCH DAMAGE.
25
26
27(require-library setup-download regex extras utils ports srfi-1 posix)
28
29
30(module main ()
31
32  (import scheme chicken regex extras utils ports srfi-1 posix)
33  (import setup-utils setup-download)
34
35  (define *default-transport* 'svn)
36  (define *default-location* (current-directory))
37
38  (define (headers)
39    (print "Connection: close\r\nContent-type: application/octet-stream\r\n\r\n"))
40
41  (define (fail msg . args)
42    (pp `(error ,msg ,@args))
43    (cleanup)
44    (exit 0))
45
46  (define (cleanup)
47    (and-let* ((tmpdir (temporary-directory)))
48      (fprintf (current-error-port) "removing temporary directory `~a'~%" tmpdir)
49      (remove-directory tmpdir)))
50
51  (define (retrieve name version)
52    (let ((dir (retrieve-extension 
53                name *default-transport* *default-location*
54                version #t)))
55      (let walk ((dir dir) (prefix "."))
56        (let ((files (directory dir)))
57          (for-each
58           (lambda (f)
59             (let ((ff (string-append dir "/" f))
60                   (pf (string-append prefix "/" f)))
61               (cond ((directory? ff)
62                      (print "\n#|--------------------|# \"" pf "/\" 0\n")
63                      (walk ff pf))
64                     (else
65                      (print "\n#|--------------------|# \"" pf "\" " (file-size ff) "\n")
66                      (display (read-all ff))))))
67           files)))
68      (print "\n#!eof") ) )
69
70  (define (service)
71    (let ((qs (getenv "QUERY_STRING")))
72      (unless qs
73        (error "no QUERY_STRING set"))
74      (let ((m (string-match "[^?]+\\?(.+)" qs))
75            (egg #f)
76            (version #f))
77        (let loop ((qs (if m (cadr m) qs)))
78          (let* ((m (string-search-positions "^(\\w+)=([^&]+)" qs))
79                 (ms (and m (apply substring qs (cadr m))))
80                 (rest (and m (substring qs (cadar m)))))
81            (cond ((not m)
82                   (headers)            ; from here on use `fail'
83                   (if egg
84                       (retrieve egg version)
85                       (fail "no extension name specified") ) )
86                  ((string=? ms "version")
87                   (set! version (apply substring qs (caddr m)))
88                   (loop rest))
89                  ((string=? ms "name")
90                   (set! egg (apply substring qs (caddr m)))
91                   (loop rest))
92                  (else
93                   (warning "unrecognized query option" ms)
94                   (loop rest))))))))
95 
96
97  (define (usage code)
98    (print #<#EOF
99usage: henrietta [OPTION ...]
100
101  -h   -help                    show this message
102  -l   -location LOCATION       install from given location (default: current directory)
103  -t   -transport TRANSPORT     use given transport instead of default (#{*default-transport*})
104EOF
105);|
106    (exit code))
107
108  (define *short-options* '(#\h #\l #\t))
109
110  (define (main args)
111    (let loop ((args args))
112      (if (null? args)
113          (service)
114          (let ((arg (car args)))
115            (cond ((or (string=? arg "-help") 
116                       (string=? arg "-h")
117                       (string=? arg "--help"))
118                   (usage 0))
119                  ((or (string=? arg "-l") (string=? arg "-location"))
120                   (unless (pair? (cdr args)) (usage 1))
121                   (set! *default-location* (cadr args))
122                   (loop (cddr args)))
123                  ((or (string=? arg "-t") (string=? arg "-transport"))
124                   (unless (pair? (cdr args)) (usage 1))
125                   (set! *default-transport* (string->symbol (cadr args)))
126                   (loop (cddr args)))
127                  ((and (positive? (string-length arg))
128                        (char=? #\- (string-ref arg 0)))
129                   (if (> (string-length arg) 2)
130                       (let ((sos (string->list (substring arg 1))))
131                         (if (null? (lset-intersection eq? *short-options* sos))
132                             (loop (append (map (cut string #\- <>) sos) (cdr args)))
133                             (usage 1)))
134                       (usage 1)))
135                  (else (loop (cdr args))))))))
136
137  (main (command-line-arguments))
138 
139)
Note: See TracBrowser for help on using the repository browser.