Date: 22 Jan 2005 00:39:47 -0000 From: David Thiel <lx@redundancy.redundancy.org> To: FreeBSD-gnats-submit@FreeBSD.org Cc: edwin@FreeBSD.org Subject: ports/76556: Update: www/publicfile optional patches Message-ID: <20050122003947.37931.qmail@redundancy.redundancy.org> Resent-Message-ID: <200501220040.j0M0eLEg095829@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 76556 >Category: ports >Synopsis: Update: www/publicfile optional patches >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: update >Submitter-Id: current-users >Arrival-Date: Sat Jan 22 00:40:21 GMT 2005 >Closed-Date: >Last-Modified: >Originator: David Thiel >Release: FreeBSD 5.3-STABLE i386 >Organization: >Environment: System: FreeBSD redundancy.redundancy.org 5.3-STABLE FreeBSD 5.3-STABLE #0: Sun Jan 9 21:41:16 PST 2005 root@redundancy.redundancy.org:/usr/obj/usr/src/sys/REDUNDANCY i386 >Description: Adding the following optional patches to publicfile, djb's web/ftp server: WITH_BASICAUTH - basic HTTP authentication support WITH_COMMONLOG - support for Apache common log format WITH_REDIRECT_SLASH - don't complain when omitting trailing slash WITH_SSL - provide SSL support through ucspi-ssl Also, take maintainership of the port. >How-To-Repeat: >Fix: diff -ruN publicfile/Makefile publicfile.new/Makefile --- publicfile/Makefile Tue Apr 20 01:33:16 2004 +++ publicfile.new/Makefile Fri Jan 21 16:28:59 2005 @@ -7,19 +7,85 @@ PORTNAME= publicfile PORTVERSION= 0.52 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= www ftp MASTER_SITES= http://cr.yp.to/publicfile/ \ ftp://cr.yp.to/publicfile/ -MAINTAINER= ports@FreeBSD.org +MAINTAINER= lx@redundancy.redundancy.org COMMENT= A secure, read-only, anonymous HTTP/FTP server RUN_DEPENDS= setuidgid:${PORTSDIR}/sysutils/daemontools \ tcpserver:${PORTSDIR}/sysutils/ucspi-tcp +pre-everything:: + + @${ECHO_MSG} + @${ECHO_MSG} "This port can use the following tuneables:" + @${ECHO_MSG} + @${ECHO_MSG} "WITH_BASICAUTH basic HTTP authentication support" + @${ECHO_MSG} "WITH_COMMONLOG support for Apache common log format" + @${ECHO_MSG} "WITH_REDIRECT_SLASH don't complain when omitting trailing slash" + @${ECHO_MSG} "WITH_SSL provide SSL support through ucspi-ssl" + @${ECHO_MSG} + +.if defined(WITH_BASICAUTH) && defined(WITH_COMMONLOG) + @${ECHO_MSG} + @${ECHO_MSG} "Currently the common log and auth patches conflict." + @${ECHO_MSG} +BROKEN= "Currently the common log and auth patches conflict." +.endif + +.if defined(WITH_BASICAUTH) && defined(WITH_REDIRECT_SLASH) + @${ECHO_MSG} + @${ECHO_MSG} "Currently the redirect slash and auth patches conflict." + @${ECHO_MSG} +BROKEN= "Currently the redirect slash and auth patches conflict." +.endif + +.if defined(WITH_REDIRECT_SLASH) +pre-configure:: + @${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/redirect-slash-patch +.endif + +.if defined(WITH_ENV_FILETYPES) +pre-configure:: + @${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/publicfile-0.52-filetype-diff +.endif + +.if defined(WITH_SSL) +pre-configure:: + @${PATCH} ${PATCH_ARGS} < ${PATCHDIR}/publicfile.sslserver +RUN_DEPENDS+= sslserver:${PORTSDIR}/sysutils/ucspi-ssl +.endif + +.if defined(WITH_BASICAUTH) +pre-configure:: + @${SED} -e "s:__PORTSDIR__:${PORTSDIR}:g" \ + -e "s:__WRKSRC__:${WRKSRC}:g" \ + ${PATCHDIR}/publicfile-0.52_basicauth.patch.in > \ + ${PATCHDIR}/publicfile-0.52_basicauth.patch + @${PATCH} ${PATCH_ARGS} -p1 < \ + ${PATCHDIR}/publicfile-0.52_basicauth.patch +BUILD_DEPENDS+= ${NONEXISTENT}:${PORTSDIR}/databases/cdb:extract +PLIST_SUB+= BASICAUTH="" +.else +PLIST_SUB+= BASICAUTH="@comment " +.endif + +.if defined(WITH_COMMONLOG) +pre-configure:: + @${PATCH} ${PATCH_ARGS} -p1 < \ + ${PATCHDIR}/publicfile-0.52-commonlog-2.patch +.endif + ALL_TARGET= it INSTALL_TARGET= setup check + +post-extract: +.if defined(WITH_BASICAUTH) + @${LN} -s ${PORTSDIR}/databases/cdb/work/cdb-0.75 ${WRKSRC}/cdb-0.75 +.endif post-patch: @${ECHO_CMD} "${CC} ${CFLAGS}" > ${WRKSRC}/conf-cc diff -ruN publicfile/distinfo publicfile.new/distinfo --- publicfile/distinfo Fri Jan 28 08:41:09 2000 +++ publicfile.new/distinfo Tue Jan 4 11:12:19 2005 @@ -1 +1,2 @@ MD5 (publicfile-0.52.tar.gz) = e493d69627b4fb2c7c764c0ff34330d7 +SIZE (publicfile-0.52.tar.gz) = 34892 diff -ruN publicfile/files/publicfile-0.52-commonlog-2.patch publicfile.new/files/publicfile-0.52-commonlog-2.patch --- publicfile/files/publicfile-0.52-commonlog-2.patch Wed Dec 31 16:00:00 1969 +++ publicfile.new/files/publicfile-0.52-commonlog-2.patch Tue Jan 4 11:11:47 2005 @@ -0,0 +1,463 @@ +diff -rNC3 publicfile-0.52.orig/Makefile publicfile-0.52/Makefile +*** publicfile-0.52.orig/Makefile Tue Nov 9 08:23:46 1999 +--- publicfile-0.52/Makefile Fri Nov 9 10:09:45 2001 +*************** +*** 450,460 **** + stralloc.a: \ + makelib stralloc_cat.o stralloc_catb.o stralloc_cats.o \ + stralloc_copy.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \ +! stralloc_pend.o stralloc_num.o + ./makelib stralloc.a stralloc_cat.o stralloc_catb.o \ + stralloc_cats.o stralloc_copy.o stralloc_eady.o \ + stralloc_opyb.o stralloc_opys.o stralloc_pend.o \ +! stralloc_num.o + + stralloc_cat.o: \ + compile stralloc_cat.c byte.h stralloc.h gen_alloc.h +--- 450,460 ---- + stralloc.a: \ + makelib stralloc_cat.o stralloc_catb.o stralloc_cats.o \ + stralloc_copy.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \ +! stralloc_pend.o stralloc_num.o stralloc_opytrim.o + ./makelib stralloc.a stralloc_cat.o stralloc_catb.o \ + stralloc_cats.o stralloc_copy.o stralloc_eady.o \ + stralloc_opyb.o stralloc_opys.o stralloc_pend.o \ +! stralloc_num.o stralloc_opytrim.o + + stralloc_cat.o: \ + compile stralloc_cat.c byte.h stralloc.h gen_alloc.h +*************** +*** 484,489 **** +--- 484,493 ---- + stralloc_opyb.o: \ + compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h + ./compile stralloc_opyb.c ++ ++ stralloc_opytrim.o: \ ++ compile stralloc_opytrim.c stralloc.h ++ ./compile stralloc_opytrim.c + + stralloc_opys.o: \ + compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h +diff -rNC3 publicfile-0.52.orig/README.log_combined publicfile-0.52/README.log_combined +*** publicfile-0.52.orig/README.log_combined Thu Jan 1 01:00:00 1970 +--- publicfile-0.52/README.log_combined Fri Nov 9 10:09:45 2001 +*************** +*** 0 **** +--- 1,36 ---- ++ This version of publicfile has been patched to write *additional* log ++ information to STDERR. This additional information conforms to Apache's ++ and Netscape's "common" or "combined" log formats, i. e. a line may look ++ like this (common log format): ++ ++ 127.0.0.1 - - [23/Oct/2001:14:04:56 +0200] "HEAD /~conrad/hello_world_gen.swf HTTP/1.0" 200 0 ++ ++ or like this (combined log format): ++ ++ 127.0.0.1 - - [23/Oct/2001:14:04:56 +0200] "HEAD /~conrad/hello_world_gen.swf HTTP/1.0" 200 0 "http://localhost/~conrad/hello_world.html" "Mozilla 4" ++ ++ The meaning of the (space-separated) fields is as follows: ++ ++ 1. Client IP-address ++ 2. Remote logname (from ident (RFC-...) lookup - always "-" in publicfile) ++ 3. Authenticated username (from Basic-Auth - always "-" in publicfile) ++ 4. Human-readable timestamp enclosed in [] ++ 5. The request line enclosed in "" ++ 6. HTTP status code ++ 7. Number of bytes sent excluding HTTP headers ++ 8. Referrer information sent by the browser ++ 9. User-Agent information sent by the browser ++ ++ These log lines can easily be distinguished from other log lines using the ++ second field: this will always be "-" for common and combined log lines, ++ and "read" or "dir" for publicfile standard log lines (see ++ http://cr.yp.to/publicfile/log.html). The script "splitPublicfileLog.pl" ++ may serve as an example how to split the log into interesting parts. ++ ++ The logformat to be used can be selected via environment variables: ++ ++ - HTTPD_LOG_COMMON selects common log format ++ - HTTPD_LOG_COMBINED selects combined log format ++ ++ The latter takes precedence over the former. ++ +diff -rNC3 publicfile-0.52.orig/httpd.c publicfile-0.52/httpd.c +*** publicfile-0.52.orig/httpd.c Tue Nov 9 08:23:46 1999 +--- publicfile-0.52/httpd.c Fri Nov 9 10:10:51 2001 +*************** +*** 15,20 **** +--- 15,102 ---- + #include "substdio.h" + #include "error.h" + #include "getln.h" ++ #include "caltime.h" ++ #include "subfd.h" ++ #include "env.h" ++ ++ char logformat = 0; ++ char *remoteip; ++ char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", ++ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; ++ stralloc referer = {0}; ++ stralloc agent = {0}; ++ ++ char strnum[FMT_ULONG]; ++ stralloc method = {0}; ++ stralloc url = {0}; ++ stralloc protocol = {0}; ++ stralloc host = {0}; ++ ++ void log(char *code, unsigned long length) { ++ struct caltime ct; ++ int dummy1, dummy2; ++ struct tai now; ++ ++ if (!logformat) return; ++ ++ substdio_puts(subfderr,remoteip); ++ substdio_puts(subfderr," - - ["); ++ tai_now(&now); ++ caltime_utc(&ct, &now, &dummy1, &dummy2); ++ if (ct.date.day < 10) ++ substdio_puts(subfderr,"0"); ++ dummy1 = fmt_ulong(strnum,ct.date.day); ++ substdio_put(subfderr,strnum,dummy1); ++ substdio_puts(subfderr,"/"); ++ if (ct.date.month > 0 && ct.date.month < 13) ++ substdio_puts(subfderr,months[ct.date.month-1]); ++ substdio_puts(subfderr,"/"); ++ dummy1 = fmt_ulong(strnum,ct.date.year); ++ substdio_put(subfderr,strnum,dummy1); ++ substdio_puts(subfderr,":"); ++ if (ct.hour < 10) ++ substdio_puts(subfderr,"0"); ++ dummy1 = fmt_ulong(strnum,ct.hour); ++ substdio_put(subfderr,strnum,dummy1); ++ substdio_puts(subfderr,":"); ++ if (ct.minute < 10) ++ substdio_puts(subfderr,"0"); ++ dummy1 = fmt_ulong(strnum,ct.minute); ++ substdio_put(subfderr,strnum,dummy1); ++ substdio_puts(subfderr,":"); ++ if (ct.second < 10) ++ substdio_puts(subfderr,"0"); ++ dummy1 = fmt_ulong(strnum,ct.second); ++ substdio_put(subfderr,strnum,dummy1); ++ substdio_puts(subfderr," +0000] \""); ++ substdio_put(subfderr,method.s,method.len - 1); /* len includes \0 */ ++ substdio_puts(subfderr," "); ++ substdio_put(subfderr,url.s,url.len); ++ substdio_puts(subfderr," "); ++ substdio_put(subfderr,protocol.s,protocol.len > 0 ? protocol.len - 1 : 0); /* len includes \0 */ ++ substdio_puts(subfderr,"\" "); ++ substdio_put(subfderr,code,str_len(code) < 3 ? str_len(code) : 3); ++ substdio_puts(subfderr," "); ++ if (length > 0) { ++ dummy1 = fmt_ulong(strnum,length); ++ substdio_put(subfderr,strnum,dummy1); ++ } else { ++ substdio_puts(subfderr,"-"); ++ } ++ ++ if (logformat > 1) { ++ substdio_puts(subfderr," \""); ++ substdio_put(subfderr,referer.s,referer.len); ++ substdio_puts(subfderr,"\" \""); ++ substdio_put(subfderr,agent.s,agent.len); ++ substdio_puts(subfderr,"\""); ++ } ++ ++ substdio_puts(subfderr," \""); ++ substdio_put(subfderr,host.s,host.len); ++ substdio_puts(subfderr,"\"\n"); ++ substdio_flush(subfderr); ++ } + + int safewrite(int fd,char *buf,int len) + { +*************** +*** 42,54 **** + substdio_flush(&out); + } + +- char strnum[FMT_ULONG]; +- +- stralloc protocol = {0}; + int protocolnum = 0; +- stralloc method = {0}; +- stralloc url = {0}; +- stralloc host = {0}; + stralloc path = {0}; + stralloc ims = {0}; + int flagbody = 1; +--- 124,130 ---- +*************** +*** 93,98 **** +--- 169,175 ---- + out_puts("</body></html>\r\n"); + } + out_flush(); ++ log(code, str_len(message) + 28); + if (protocolnum >= 2) { + shutdown(1,1); + sleep(1); /* XXX */ +*************** +*** 105,108 **** +--- 182,186 ---- + + void get(void) + { ++ char *code; + unsigned long length; +*************** +*** 133,143 **** + tai_now(&now); + if (!httpdate(&mtimestr,&mtime)) _exit(21); + if ((ims.len < mtimestr.len) || byte_diff(mtimestr.s,mtimestr.len,ims.s)) +! header("200 ","OK"); + else { +! header("304 ","OK"); + flagbody = 0; + } + if (tai_less(&mtime,&now)) { + tai_sub(&mtimeage,&now,&mtime); + if (tai_approx(&mtimeage) >= 60.0) { +--- 211,222 ---- + tai_now(&now); + if (!httpdate(&mtimestr,&mtime)) _exit(21); + if ((ims.len < mtimestr.len) || byte_diff(mtimestr.s,mtimestr.len,ims.s)) +! code = "200 "; + else { +! code = "304 "; + flagbody = 0; + } ++ header(code,"OK"); + if (tai_less(&mtime,&now)) { + tai_sub(&mtimeage,&now,&mtime); + if (tai_approx(&mtimeage) >= 60.0) { +*************** +*** 166,171 **** +--- 245,253 ---- + if (r == 0) break; + out_put(filebuf,r); + } ++ else ++ length = 0; ++ log(code,length); + out_flush(); + _exit(0); + } +*************** +*** 180,185 **** +--- 262,270 ---- + out_put(filebuf,r); + out_puts("\r\n"); + } ++ else ++ length = 0; ++ log(code,length); + + close(fd); + } +*************** +*** 216,221 **** +--- 301,314 ---- + + sig_pipeignore(); + ++ if (env_get("HTTPD_LOG_COMMON")) ++ logformat = 1; ++ if (env_get("HTTPD_LOG_COMBINED")) ++ logformat = 2; ++ remoteip = env_get("TCPREMOTEIP"); ++ if (!remoteip) ++ remoteip = "0"; ++ + for (;;) { + readline(); + +*************** +*** 227,232 **** +--- 320,327 ---- + if (!stralloc_copys(&path,"")) _exit(21); + if (!stralloc_copys(&protocol,"")) _exit(21); + if (!stralloc_copys(&ims,"")) _exit(21); ++ if (!stralloc_copys(&referer,"")) _exit(21); ++ if (!stralloc_copys(&agent,"")) _exit(21); + protocolnum = 2; + + spaces = 0; +*************** +*** 294,299 **** +--- 389,398 ---- + barf("412 ","I do not accept If-None-Match"); + if (case_startb(field.s,field.len,"if-unmodified-since:")) + barf("412 ","I do not accept If-Unmodified-Since"); ++ if (case_startb(field.s,field.len,"referer:")) ++ if (!stralloc_copytrim(&referer,field.s + 8,field.len - 8)) _exit(21); ++ if (case_startb(field.s,field.len,"user-agent:")) ++ if (!stralloc_copytrim(&agent,field.s + 11,field.len - 11)) _exit(21); + if (case_startb(field.s,field.len,"host:")) + if (!host.len) + for (i = 5;i < field.len;++i) +diff -rNC3 publicfile-0.52.orig/splitPublicfileLog.pl publicfile-0.52/splitPublicfileLog.pl +*** publicfile-0.52.orig/splitPublicfileLog.pl Thu Jan 1 01:00:00 1970 +--- publicfile-0.52/splitPublicfileLog.pl Fri Nov 9 10:09:45 2001 +*************** +*** 0 **** +--- 1,119 ---- ++ #!/usr/bin/perl -w ++ ++ # This script will read lines from stdin. All lines starting with ++ # "a.b.c.d - " (for an IP-number a.b.c.d) will be written to the ++ # "access logfile" given as the first argument. Anything else will be ++ # prepended with a timestamp and ++ # written to the "error logfile" given as the second argument. ++ # Note that the messages usually are not really *error* messages, but ++ # simply the standard publicfile output. ++ ++ use strict; ++ use Symbol; ++ ++ if ($#ARGV < 0 || $#ARGV > 3) { ++ &usage(); ++ } ++ ++ local $main::logdir; ++ local $main::accessfile; ++ local $main::errorfile; ++ local $main::multilog; ++ local %main::handles = (); ++ ++ if ($ARGV[0] eq "-m") { ++ $main::multilog = 1; ++ if ($#ARGV != 3) { &usage(); } ++ $main::logdir = $ARGV[1]."/"; ++ $main::accessfile = $main::logdir.$ARGV[2]; ++ $main::errorfile = $main::logdir.$ARGV[3]; ++ } else { ++ $main::multilog = 0; ++ if ($#ARGV != 1) { &usage(); } ++ $main::accessfile = $ARGV[0]; ++ $main::errorfile = $ARGV[1]; ++ } ++ ++ #open(ACCESS, ">>".$ARGV[0]) || die("Can't open access logfile!"); ++ #open(ERROR, ">>".$ARGV[1]) || die("Can't open error logfile!"); ++ $SIG{PIPE} = \&closeAndExit; ++ $SIG{TERM} = \&closeAndExit; ++ $SIG{QUIT} = \&closeAndExit; ++ $SIG{INT} = \&closeAndExit; ++ $SIG{HUP} = \&closeAll; ++ ++ while($_ = <STDIN>) { ++ if (/^\d+\.\d+\.\d+\.\d+ - /) { ++ my $host = ""; ++ if ($main::multilog && / \"([^\"\/]*)\"[\r\n]*$/) { ++ $_ = $`."\n"; ++ $host = $1; ++ } ++ my $fh = &getHandle($host); ++ print $fh $_; ++ } else { ++ my $fh = &getHandle($main::errorfile); ++ print $fh time()." $_"; ++ } ++ } ++ ++ closeAndExit("End of input"); ++ ++ sub closeAll { ++ foreach my $key (keys %main::handles) { ++ my $fh = $main::handles{$key}; ++ close $fh; ++ delete $main::handles{$key}; ++ } ++ } ++ ++ sub closeAndExit { ++ my $reason = shift; ++ my $now = time(); ++ ++ my $fh = &getHandle($main::errorfile); ++ print $fh "$now $reason received\n"; ++ print STDERR "$now $reason received\n"; ++ &closeAll(); ++ exit 0; ++ } ++ ++ sub getHandle { ++ my $key = shift; ++ my $res = 0; ++ ++ if (defined($main::handles{$key})) { ++ return $main::handles{$key}; ++ } ++ ++ my $fh = Symbol::gensym(); ++ if ($key eq $main::errorfile) { ++ open($fh, ">>".$main::errorfile) || die("Can't open error logfile!"); ++ } else { ++ if ($main::multilog) { ++ my $fn = $main::logdir.$key; ++ if (-f $fn && -w $fn) { ++ $res = open($fh, ">>$fn"); ++ } ++ } ++ if (!$res) { ++ open($fh, ">>".$main::accessfile) || die("Can't open error logfile!"); ++ } ++ } ++ ++ $main::handles{$key} = $fh; ++ return $fh; ++ } ++ ++ sub usage { ++ print STDERR "Usage: $0 <access-path> <error-path>\n"; ++ print STDERR " or: $0 -m <logdir> <access-file> <error-file>\n"; ++ print STDERR "The first form will separate publicfile standard messages from \"common\" log\n"; ++ print STDERR "lines. The second form will write \"common\" lines to <logdir>/<hostname>\n"; ++ print STDERR "where <hostname> is the host given in the request. The file <logdir>/<hostname>\n"; ++ print STDERR "must exist before it will be used. Anything for which no suitable logfile can\n"; ++ print STDERR "be found will be logged to <logdir>/<access-path>.\n"; ++ ++ exit 1; ++ } ++ +diff -rNC3 publicfile-0.52.orig/stralloc.h publicfile-0.52/stralloc.h +*** publicfile-0.52.orig/stralloc.h Tue Nov 9 08:23:46 1999 +--- publicfile-0.52/stralloc.h Fri Nov 9 10:09:45 2001 +*************** +*** 12,17 **** +--- 12,18 ---- + extern int stralloc_copys(); + extern int stralloc_cats(); + extern int stralloc_copyb(); ++ extern int stralloc_copytrim(); + extern int stralloc_catb(); + extern int stralloc_append(); /* beware: this takes a pointer to 1 char */ + extern int stralloc_starts(); +diff -rNC3 publicfile-0.52.orig/stralloc_opytrim.c publicfile-0.52/stralloc_opytrim.c +*** publicfile-0.52.orig/stralloc_opytrim.c Thu Jan 1 01:00:00 1970 +--- publicfile-0.52/stralloc_opytrim.c Fri Nov 9 10:09:45 2001 +*************** +*** 0 **** +--- 1,17 ---- ++ #include "stralloc.h" ++ ++ int stralloc_copytrim(sa,s,n) ++ stralloc *sa; ++ char *s; ++ unsigned int n; ++ { ++ while (n > 0 && ++ (s[n] == ' ' || s[n] == '\t' || s[n] == '\n' || s[n] == '\r')) n--; ++ while (n > 0 && ++ (s[0] == ' ' || s[0] == '\t' || s[0] == '\n' || s[0] == '\r')) { ++ n--; ++ s++; ++ } ++ ++ return stralloc_copyb(sa,s,n); ++ } diff -ruN publicfile/files/publicfile-0.52-filetype-diff publicfile.new/files/publicfile-0.52-filetype-diff --- publicfile/files/publicfile-0.52-filetype-diff Wed Dec 31 16:00:00 1969 +++ publicfile.new/files/publicfile-0.52-filetype-diff Tue Jan 4 11:11:47 2005 @@ -0,0 +1,34 @@ +--- filetype.c.old Mon Dec 6 10:43:36 1999 ++++ filetype.c Mon Dec 6 10:50:36 1999 +@@ -1,5 +1,6 @@ + #include "filetype.h" + #include "str.h" ++#include "env.h" + + void filetype(char *fn,stralloc *contenttype) + { +@@ -22,7 +23,7 @@ + if (!stralloc_append(contenttype,&ch)) _exit(21); + } + else { +- result = "text/plain"; ++ result = 0; + if (str_equal(x,".html")) result = "text/html"; + else if (str_equal(x,".gz")) result = "application/x-gzip"; + else if (str_equal(x,".dvi")) result = "application/x-dvi"; +@@ -32,6 +33,15 @@ + else if (str_equal(x,".jpeg")) result = "image/jpeg"; + else if (str_equal(x,".png")) result = "image/png"; + else if (str_equal(x,".mpeg")) result = "video/mpeg"; ++ if (!result) { ++ stralloc envname = {0}; ++ if (!stralloc_copys(&envname,"CT_")) _exit(21); ++ if (!stralloc_cats(&envname,x+1)) _exit(21); ++ if (!stralloc_0(&envname)) _exit(21); ++ result=env_get(envname.s); ++ alloc_free(envname.s); /* is this the right function */ ++ } ++ if (!result) result="text/plain"; + + if (!stralloc_cats(contenttype,result)) _exit(21); + } diff -ruN publicfile/files/publicfile-0.52_basicauth.patch publicfile.new/files/publicfile-0.52_basicauth.patch --- publicfile/files/publicfile-0.52_basicauth.patch Wed Dec 31 16:00:00 1969 +++ publicfile.new/files/publicfile-0.52_basicauth.patch Thu Jan 6 14:41:18 2005 @@ -0,0 +1,638 @@ +diff -N -u -r publicfile-0.52.orig/Makefile publicfile-0.52/Makefile +--- publicfile-0.52.orig/Makefile Mon Nov 8 23:23:46 1999 ++++ publicfile-0.52/Makefile Wed Aug 29 20:27:09 2001 +@@ -234,21 +234,43 @@ + compile hier.c auto_home.h + ./compile hier.c + ++htrules: \ ++load htrules.o base64.o ++ ./load htrules cdb.a base64.o byte.a getln.a stralloc.a alloc.a \ ++ substdio.a str.a buffer.a unix.a ++ ++htrules.o: \ ++compile htrules.c strerr.h stralloc.h gen_alloc.h getln.h buffer.h \ ++stralloc.h buffer.h exit.h fmt.h byte.h cdb_make.h buffer.h uint32.h \ ++base64.h ++ ./compile htrules.c ++ ++base64.o: \ ++compile base64.c base64.h ++ ./compile base64.c ++ + httpd: \ + load httpd.o main.o pathdecode.o file.o filetype.o httpdate.o \ + percent.o prot.o timeoutread.o timeoutwrite.o libtai.a case.a getln.a \ + stralloc.a alloc.a substdio.a error.a open.a sig.a env.a str.a fs.a \ +-socket.lib ++socket.lib readclose.o openreadclose.o + ./load httpd main.o pathdecode.o file.o filetype.o \ + httpdate.o percent.o prot.o timeoutread.o timeoutwrite.o \ + libtai.a case.a getln.a stralloc.a alloc.a substdio.a \ +- error.a open.a sig.a env.a str.a fs.a `cat socket.lib` ++ error.a open.a sig.a env.a str.a fs.a cdb.a byte.a seek_set.o \ ++ readclose.o openreadclose.o `cat socket.lib` ++ ++cdb: ++ (cd /usr/ports/databases/cdb/work/cdb-0.75 && \ ++ make && \ ++ cp -p cdb_make.h buffer.h cdb.h uint32.h cdb.a byte.a seek_set.o \ ++ cdb_make.o error.c buffer.a unix.a /usr/ports/www/publicfile.new/work/publicfile-0.52/) + + httpd.o: \ + compile httpd.c pathdecode.h stralloc.h gen_alloc.h file.h tai.h \ + uint64.h filetype.h stralloc.h percent.h stralloc.h stralloc.h sig.h \ + exit.h fmt.h case.h str.h tai.h httpdate.h stralloc.h tai.h \ +-timeoutread.h timeoutwrite.h substdio.h error.h getln.h ++timeoutread.h timeoutwrite.h substdio.h error.h getln.h byte.h + ./compile httpd.c + + httpdate.o: \ +@@ -358,6 +380,11 @@ + compile open_trunc.c open.h + ./compile open_trunc.c + ++openreadclose.o: \ ++compile openreadclose.c error.h open.h readclose.h stralloc.h \ ++gen_alloc.h openreadclose.h stralloc.h ++ ./compile openreadclose.c ++ + pathdecode.o: \ + compile pathdecode.c pathdecode.h stralloc.h gen_alloc.h + ./compile pathdecode.c +@@ -367,7 +394,7 @@ + ./compile percent.c + + prog: \ +-configure httpd ftpd rts utime ++cdb configure httpd ftpd rts utime htrules + + prot.o: \ + compile prot.c hasshsgr.h prot.h +diff -N -u -r publicfile-0.52.orig/README.basicauth publicfile-0.52/README.basicauth +--- publicfile-0.52.orig/README.basicauth Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/README.basicauth Wed Aug 29 22:16:02 2001 +@@ -0,0 +1,100 @@ ++Here is a patch for publicfile to allow for Basic Auth. ++ ++Building Instructions: ++ ++Save this patch as publicfile-0.52.basicauth.patch ++Download publicfile-0.52 ++Download cdb-0.75 ++ ++gunzip publicfile-0.52.tar ++gunzip cdb-0.75.tar ++tar -xf publicfile-0.52.tar ++cd publicfile-0.52 ++tar -xf ../cdb-0.75.tar ++patch -p1 < publicfile-0.52.basicauth.patch ++ ++Follow normal installation instructions for publicfile beginning with ++'make setup check' ++ ++Usage Instructions: ++ ++Once this patch has been applied, httpd will check for a file ++called '.access' in the current directory of any requested ++file. e.g, if /public/file/0/path/to/file.html is requested, httpd ++will first check for /public/file/0/path/to/.access. ++ ++.access should have the format: ++ realm_id:realm_txt ++ ++realm_id is used as documented below. realm_txt is typically ++presented by the user's browser. .access must be readable by httpd ++and only protects a specific directory. Sub-directories are not ++protected unless they also contain a .access file. ++ ++An additional program will be installed in /usr/local/publicfile (or ++whatever conf-home is) called htrules. Use this like tcprules: ++ ++cd /public/file ++htrules access.cdb access.tmp < access ++ ++This may safely be run at any time. ++ ++access should have the format: ++ ++ # this is a comment. blank lines are allowed too. ++ # the next line authorizes a user to a specific realm_id ++ realm_id:username:password ++ # the next line authorizes host class. ++ realm_id:LOCALHOST ++ ++access.cdb must be readable by httpd. ++ ++realm_id corresponds to the realm_id in the .access file(s). ++ ++Each realm_id line specifies either a username:password combination ++or a host class. Note that the same username may have different ++passwords in different realm_id's. ++ ++A host is mapped into a host class via the environment ++variable HTTPCLIENT. This environment variable should be ++set in tcpserver's rules.cdb. ++ ++Here is an example: ++ ++ === /public/file/0/private1/.access === ++ realm1:Dr. Suess ++ ++ === /public/file/0/private2/.access === ++ realm2:Sesame Street ++ ++ === /public/file/access === ++ # realm1 are Dr Suess users/clients ++ realm1:john:catinthehat ++ realm1:mary:greeneggswithham ++ realm1:LOCALHOST ++ realm1:DR SUESS ++ # realm1 are Sesame Street users/clients ++ realm2:tom:bigbird ++ realm2:abi:cookiemonster ++ realm2:mary:earnie ++ realm2:LOCALHOST ++ realm2:SESAME STREET ++ ++ === /etc/rules === ++ 127.0.0.1:allow,HTTPCLIENT="LOCALHOST" ++ 10.0.0.:allow,HTTPCLIENT="DR SUESS" ++ 10.1.0.:allow,HTTPCLIENT="SESAME STREET" ++ :allow ++ ++The changes to the Makefile aren't very clean, but everything compiles ++correctly. ++ ++Thanks to Eric M. Johnston's for base64.{c,h} from YAQSAP ++(Yet Another qmail SMTP AUTH Patch) - ++http://qmail.goof.com/qmail-auth-20010105.tar.gz ++ ++This patch available at ++http://www.soffian.org/downloads/publicfile-0.52_basicauth.patch ++ ++Jay Soffian <jay@soffian.org> 29 Aug 2001 ++ +diff -N -u -r publicfile-0.52.orig/base64.c publicfile-0.52/base64.c +--- publicfile-0.52.orig/base64.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/base64.c Wed Aug 22 22:17:39 2001 +@@ -0,0 +1,90 @@ ++#include "base64.h" ++#include "stralloc.h" ++#include "substdio.h" ++#include "str.h" ++ ++static char *b64alpha = ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ++#define B64PAD '=' ++ ++/* returns 0 ok, 1 illegal, -1 problem */ ++ ++int b64decode(in,l,out) ++const unsigned char *in; ++int l; ++stralloc *out; /* not null terminated */ ++{ ++ int i, j; ++ unsigned char a[4]; ++ unsigned char b[3]; ++ char *s; ++ ++ if (l == 0) ++ { ++ if (!stralloc_copys(out,"")) return -1; ++ return 0; ++ } ++ ++ if (!stralloc_ready(out,l + 2)) return -1; /* XXX generous */ ++ s = out->s; ++ ++ for (i = 0;i < l;i += 4) { ++ for (j = 0;j < 4;j++) ++ if ((i + j) < l && in[i + j] != B64PAD) ++ { ++ a[j] = str_chr(b64alpha,in[i + j]); ++ if (a[j] > 63) return 1; ++ } ++ else a[j] = 0; ++ ++ b[0] = (a[0] << 2) | (a[1] >> 4); ++ b[1] = (a[1] << 4) | (a[2] >> 2); ++ b[2] = (a[2] << 6) | (a[3]); ++ ++ *s++ = b[0]; ++ ++ if (in[i + 1] == B64PAD) break; ++ *s++ = b[1]; ++ ++ if (in[i + 2] == B64PAD) break; ++ *s++ = b[2]; ++ } ++ out->len = s - out->s; ++ while (out->len && !out->s[out->len - 1]) --out->len; /* XXX avoid? */ ++ return 0; ++} ++ ++int b64encode(in,out) ++stralloc *in; ++stralloc *out; /* not null terminated */ ++{ ++ unsigned char a, b, c; ++ int i; ++ char *s; ++ ++ if (in->len == 0) ++ { ++ if (!stralloc_copys(out,"")) return -1; ++ return 0; ++ } ++ ++ if (!stralloc_ready(out,in->len / 3 * 4 + 4)) return -1; ++ s = out->s; ++ ++ for (i = 0;i < in->len;i += 3) { ++ a = in->s[i]; ++ b = i + 1 < in->len ? in->s[i + 1] : 0; ++ c = i + 2 < in->len ? in->s[i + 2] : 0; ++ ++ *s++ = b64alpha[a >> 2]; ++ *s++ = b64alpha[((a & 3 ) << 4) | (b >> 4)]; ++ ++ if (i + 1 >= in->len) *s++ = B64PAD; ++ else *s++ = b64alpha[((b & 15) << 2) | (c >> 6)]; ++ ++ if (i + 2 >= in->len) *s++ = B64PAD; ++ else *s++ = b64alpha[c & 63]; ++ } ++ out->len = s - out->s; ++ return 0; ++} +diff -N -u -r publicfile-0.52.orig/base64.h publicfile-0.52/base64.h +--- publicfile-0.52.orig/base64.h Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/base64.h Wed Aug 22 22:17:39 2001 +@@ -0,0 +1,7 @@ ++#ifndef BASE64_H ++#define BASE64_H ++ ++extern int b64decode(); ++extern int b64encode(); ++ ++#endif +diff -N -u -r publicfile-0.52.orig/hier.c publicfile-0.52/hier.c +--- publicfile-0.52.orig/hier.c Mon Nov 8 23:23:46 1999 ++++ publicfile-0.52/hier.c Wed Aug 22 22:17:39 2001 +@@ -7,6 +7,7 @@ + d(auto_home,"bin",-1,-1,02755); + + c(auto_home,"bin","configure",-1,-1,0755); ++ c(auto_home,"bin","htrules",-1,-1,0755); + c(auto_home,"bin","httpd",-1,-1,0755); + c(auto_home,"bin","ftpd",-1,-1,0755); + } +diff -N -u -r publicfile-0.52.orig/htrules.c publicfile-0.52/htrules.c +--- publicfile-0.52.orig/htrules.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/htrules.c Wed Aug 29 21:27:42 2001 +@@ -0,0 +1,117 @@ ++#include "strerr.h" ++#include "stralloc.h" ++#include "getln.h" ++#include "buffer.h" ++#include "exit.h" ++#include "fmt.h" ++#include "byte.h" ++#include "base64.h" ++#include "cdb_make.h" ++ ++#define FATAL "htrules: fatal: " ++ ++unsigned long linenum = 0; ++char *fntemp; ++char *fn; ++ ++stralloc line = {0}; ++int match = 1; ++ ++stralloc base64 = {0}; ++stralloc key = {0}; ++stralloc realm = {0}; ++stralloc userpass = {0}; ++ ++struct cdb_make c; ++ ++void nomem(void) ++{ ++ strerr_die2x(111,FATAL,"out of memory"); ++} ++void usage(void) ++{ ++ strerr_die1x(100,"htrules: usage: htrules access.cdb access.tmp"); ++} ++void die_bad(void) ++{ ++ if (!stralloc_0(&line)) nomem(); ++ strerr_die3x(100,FATAL,"unable to parse this line: ",line.s); ++} ++void die_write(void) ++{ ++ strerr_die4sys(111,FATAL,"unable to write to ",fntemp,": "); ++} ++ ++main(int argc,char **argv) ++{ ++ int colon; ++ char *x; ++ int len; ++ int fd; ++ int i; ++ char ch; ++ ++ fn = argv[1]; ++ if (!fn) usage(); ++ fntemp = argv[2]; ++ if (!fntemp) usage(); ++ ++ fd = open_trunc(fntemp); ++ if (fd == -1) ++ strerr_die4sys(111,FATAL,"unable to create ",fntemp,": "); ++ if (cdb_make_start(&c,fd) == -1) die_write(); ++ ++ while (match) { ++ if (getln(buffer_0,&line,&match,'\n') == -1) ++ strerr_die2sys(111,FATAL,"unable to read input: "); ++ ++ x = line.s; len = line.len; ++ ++ if (!len) break; ++ if (x[0] == '#') continue; ++ if (x[0] == '\n') continue; ++ ++ while (len) { ++ ch = x[len - 1]; ++ if (ch != '\n') if (ch != ' ') if (ch != '\t') break; ++ --len; ++ } ++ line.len = len; /* for die_bad() */ ++ if (!len) continue; ++ ++ colon = byte_chr(x,len,':'); ++ if (!colon || colon == len) die_bad(); ++ if (!stralloc_copyb(&realm,x,colon)) nomem(); ++ x += colon + 1; len -= colon + 1; ++ ++ colon = byte_chr(x,len,':'); ++ if (colon == len) { ++ if (!stralloc_copyb(&key,"C",1)) nomem(); ++ if (!stralloc_cat(&key,&realm)) nomem(); ++ if (!stralloc_catb(&key,":",1)) nomem(); ++ if (!stralloc_catb(&key,x,len)) nomem(); ++ if (cdb_make_add(&c,key.s,key.len,"",0) == -1) die_write(); ++ } else { ++ if (!stralloc_copyb(&userpass,x,len)) nomem(); ++ if (b64encode(&userpass,&base64) == -1) nomem(); ++ ++ if (!stralloc_copyb(&key,"U",1)) nomem(); ++ if (!stralloc_cat(&key,&base64)) nomem(); ++ if (cdb_make_add(&c,key.s,key.len,"",0) == -1) die_write(); ++ ++ if (!stralloc_copyb(&key,"R",1)) nomem(); ++ if (!stralloc_cat(&key,&realm)) nomem(); ++ if (!stralloc_catb(&key,":",1)) nomem(); ++ if (!stralloc_cat(&key,&base64)) nomem(); ++ if (cdb_make_add(&c,key.s,key.len,"",0) == -1) die_write(); ++ } ++ } ++ ++ if (cdb_make_finish(&c) == -1) die_write(); ++ if (fsync(fd) == -1) die_write(); ++ if (close(fd) == -1) die_write(); /* NFS stupidity */ ++ if (rename(fntemp,fn)) ++ strerr_die6sys(111,FATAL,"unable to move ",fntemp," to ",fn,": "); ++ ++ _exit(0); ++} +diff -N -u -r publicfile-0.52.orig/httpd.c publicfile-0.52/httpd.c +--- publicfile-0.52.orig/httpd.c Mon Nov 8 23:23:46 1999 ++++ publicfile-0.52/httpd.c Wed Aug 29 21:30:34 2001 +@@ -15,6 +15,10 @@ + #include "substdio.h" + #include "error.h" + #include "getln.h" ++#include "byte.h" ++#include "cdb.h" ++#include "openreadclose.h" ++#include "env.h" + + int safewrite(int fd,char *buf,int len) + { +@@ -51,6 +55,7 @@ + stralloc host = {0}; + stralloc path = {0}; + stralloc ims = {0}; ++stralloc basic_auth = {0}; + int flagbody = 1; + + char filebuf[1024]; +@@ -75,11 +80,16 @@ + out_puts("\r\n"); + } + +-void barf(char *code,char *message) ++void barf2(char *code,char *message,char *realm) + { + if (protocolnum > 0) { + tai_now(&now); + header(code,message); ++ if(realm) { ++ out_puts("WWW-Authenticate: Basic realm=\""); ++ out_puts(realm); ++ out_puts("\"\r\n"); ++ } + out_puts("Content-Length: "); + out_put(strnum,fmt_ulong(strnum,str_len(message) + 28)); + out_puts("\r\n"); +@@ -100,8 +110,81 @@ + _exit(0); + } + ++void barf(char *code,char *message) ++{ ++ barf2(code,message,(char *)0); ++} ++ + stralloc fn = {0}; ++stralloc accessfn = {0}; + stralloc contenttype = {0}; ++stralloc realm = {0}; ++stralloc realmtxt = {0}; ++stralloc key = {0}; ++ ++void checkauth(void) ++{ ++ int len; ++ int fd; ++ int colon; ++ static struct cdb c; ++ char *x; ++ ++ len = byte_rchr(fn.s,fn.len,'/'); ++ if (!stralloc_copyb(&accessfn,fn.s,len)) _exit(21); ++ if (!stralloc_cats(&accessfn,"/.access")) _exit(21); ++ if (!stralloc_0(&accessfn)) _exit(21); ++ ++ if (openreadclose(accessfn.s,&realm,256) == 0) return; ++ if (!realm.len) _exit(23); /* no realm */ ++ realm.len = byte_chr(realm.s,realm.len,'\n'); ++ while (realm.len) { ++ if (realm.s[realm.len - 1] != ' ') ++ if (realm.s[realm.len - 1] != '\t') ++ break; ++ --realm.len; ++ } ++ colon = byte_chr(realm.s,realm.len,':'); ++ if (!colon) _exit(23); /* no realm */ ++ if (colon == realm.len) { ++ if (!stralloc_copys(&realmtxt,"restricted access")) _exit(21); ++ } else { ++ if (!stralloc_copyb(&realmtxt,realm.s+colon+1,realm.len-(colon+1))) _exit(21); ++ realm.len = colon; ++ } ++ if (!stralloc_0(&realmtxt)) _exit(21); ++ ++ fd = open_read("/access.cdb"); ++ if (fd == -1) _exit(23); ++ cdb_init(&c,fd); ++ ++ x = env_get("HTTPCLIENT"); ++ if (x) { ++ if (!stralloc_copyb(&key,"C",1)) _exit(21); ++ if (!stralloc_cat(&key,&realm)) _exit(21); ++ if (!stralloc_catb(&key,":",1)) _exit(21); ++ if (!stralloc_cats(&key,x)) _exit(21); ++ if (cdb_find(&c,key.s,key.len) == 1) goto AUTH_OK; ++ } ++ ++ if (!basic_auth.len) barf2("401 ","Authorization Required", realmtxt.s); ++ ++ if (!stralloc_copyb(&key,"U",1)) _exit(21); ++ if (!stralloc_cat(&key,&basic_auth)) _exit(21); ++ if (cdb_find(&c,key.s,key.len) != 1) ++ barf2("401 ","Authorization Required",realmtxt.s); ++ ++ if (!stralloc_copyb(&key,"R",1)) _exit(21); ++ if (!stralloc_cat(&key,&realm)) _exit(21); ++ if (!stralloc_catb(&key,":",1)) _exit(21); ++ if (!stralloc_cat(&key,&basic_auth)) _exit(21); ++ if (cdb_find(&c,key.s,key.len) != 1) barf("403 ","Forbidden"); ++ ++ AUTH_OK: ++ alloc_free(key); ++ cdb_free(&c); ++ close(fd); ++} + + void get(void) + { +@@ -124,6 +207,8 @@ + if (!stralloc_cat(&fn,&path)) _exit(21); + pathdecode(&fn); + if (!stralloc_0(&fn)) _exit(21); ++ ++ checkauth(); + + fd = file_open(fn.s,&mtime,&length,1); + if (fd == -1) +@@ -227,6 +312,7 @@ + if (!stralloc_copys(&path,"")) _exit(21); + if (!stralloc_copys(&protocol,"")) _exit(21); + if (!stralloc_copys(&ims,"")) _exit(21); ++ if (!stralloc_copys(&basic_auth,"")) _exit(21); + protocolnum = 2; + + spaces = 0; +@@ -302,6 +388,8 @@ + if (!stralloc_append(&host,&field.s[i])) _exit(21); + if (case_startb(field.s,field.len,"if-modified-since:")) + if (!stralloc_copyb(&ims,field.s + 18,field.len - 18)) _exit(21); ++ if (case_startb(field.s,field.len,"authorization: basic ")) ++ if (!stralloc_copyb(&basic_auth,field.s + 21,field.len - 21)) _exit(21); + field.len = 0; + } + if (!line.len) break; +diff -N -u -r publicfile-0.52.orig/openreadclose.c publicfile-0.52/openreadclose.c +--- publicfile-0.52.orig/openreadclose.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/openreadclose.c Wed Aug 29 14:24:21 2001 +@@ -0,0 +1,18 @@ ++/* Public domain. */ ++ ++#include "error.h" ++#include "open.h" ++#include "readclose.h" ++#include "openreadclose.h" ++ ++int openreadclose(const char *fn,stralloc *sa,unsigned int bufsize) ++{ ++ int fd; ++ fd = open_read(fn); ++ if (fd == -1) { ++ if (errno == error_noent) return 0; ++ return -1; ++ } ++ if (readclose(fd,sa,bufsize) == -1) return -1; ++ return 1; ++} +diff -N -u -r publicfile-0.52.orig/openreadclose.h publicfile-0.52/openreadclose.h +--- publicfile-0.52.orig/openreadclose.h Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/openreadclose.h Wed Aug 29 14:24:21 2001 +@@ -0,0 +1,10 @@ ++/* Public domain. */ ++ ++#ifndef OPENREADCLOSE_H ++#define OPENREADCLOSE_H ++ ++#include "stralloc.h" ++ ++extern int openreadclose(const char *,stralloc *,unsigned int); ++ ++#endif +diff -N -u -r publicfile-0.52.orig/readclose.c publicfile-0.52/readclose.c +--- publicfile-0.52.orig/readclose.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/readclose.c Wed Aug 29 14:30:52 2001 +@@ -0,0 +1,23 @@ ++/* Public domain. */ ++ ++#include <unistd.h> ++#include "error.h" ++#include "readclose.h" ++ ++int readclose_append(int fd,stralloc *sa,unsigned int bufsize) ++{ ++ int r; ++ for (;;) { ++ if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; } ++ r = read(fd,sa->s + sa->len,bufsize); ++ if (r == -1) if (errno == error_intr) continue; ++ if (r <= 0) { close(fd); return r; } ++ sa->len += r; ++ } ++} ++ ++int readclose(int fd,stralloc *sa,unsigned int bufsize) ++{ ++ if (!stralloc_copys(sa,"")) { close(fd); return -1; } ++ return readclose_append(fd,sa,bufsize); ++} +diff -N -u -r publicfile-0.52.orig/readclose.h publicfile-0.52/readclose.h +--- publicfile-0.52.orig/readclose.h Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/readclose.h Wed Aug 29 14:30:52 2001 +@@ -0,0 +1,11 @@ ++/* Public domain. */ ++ ++#ifndef READCLOSE_H ++#define READCLOSE_H ++ ++#include "stralloc.h" ++ ++extern int readclose_append(int,stralloc *,unsigned int); ++extern int readclose(int,stralloc *,unsigned int); ++ ++#endif diff -ruN publicfile/files/publicfile-0.52_basicauth.patch.in publicfile.new/files/publicfile-0.52_basicauth.patch.in --- publicfile/files/publicfile-0.52_basicauth.patch.in Wed Dec 31 16:00:00 1969 +++ publicfile.new/files/publicfile-0.52_basicauth.patch.in Tue Jan 4 11:24:01 2005 @@ -0,0 +1,638 @@ +diff -N -u -r publicfile-0.52.orig/Makefile publicfile-0.52/Makefile +--- publicfile-0.52.orig/Makefile Mon Nov 8 23:23:46 1999 ++++ publicfile-0.52/Makefile Wed Aug 29 20:27:09 2001 +@@ -234,21 +234,43 @@ + compile hier.c auto_home.h + ./compile hier.c + ++htrules: \ ++load htrules.o base64.o ++ ./load htrules cdb.a base64.o byte.a getln.a stralloc.a alloc.a \ ++ substdio.a str.a buffer.a unix.a ++ ++htrules.o: \ ++compile htrules.c strerr.h stralloc.h gen_alloc.h getln.h buffer.h \ ++stralloc.h buffer.h exit.h fmt.h byte.h cdb_make.h buffer.h uint32.h \ ++base64.h ++ ./compile htrules.c ++ ++base64.o: \ ++compile base64.c base64.h ++ ./compile base64.c ++ + httpd: \ + load httpd.o main.o pathdecode.o file.o filetype.o httpdate.o \ + percent.o prot.o timeoutread.o timeoutwrite.o libtai.a case.a getln.a \ + stralloc.a alloc.a substdio.a error.a open.a sig.a env.a str.a fs.a \ +-socket.lib ++socket.lib readclose.o openreadclose.o + ./load httpd main.o pathdecode.o file.o filetype.o \ + httpdate.o percent.o prot.o timeoutread.o timeoutwrite.o \ + libtai.a case.a getln.a stralloc.a alloc.a substdio.a \ +- error.a open.a sig.a env.a str.a fs.a `cat socket.lib` ++ error.a open.a sig.a env.a str.a fs.a cdb.a byte.a seek_set.o \ ++ readclose.o openreadclose.o `cat socket.lib` ++ ++cdb: ++ (cd __PORTSDIR__/databases/cdb/work/cdb-0.75 && \ ++ make && \ ++ cp -p cdb_make.h buffer.h cdb.h uint32.h cdb.a byte.a seek_set.o \ ++ cdb_make.o error.c buffer.a unix.a __WRKSRC__/) + + httpd.o: \ + compile httpd.c pathdecode.h stralloc.h gen_alloc.h file.h tai.h \ + uint64.h filetype.h stralloc.h percent.h stralloc.h stralloc.h sig.h \ + exit.h fmt.h case.h str.h tai.h httpdate.h stralloc.h tai.h \ +-timeoutread.h timeoutwrite.h substdio.h error.h getln.h ++timeoutread.h timeoutwrite.h substdio.h error.h getln.h byte.h + ./compile httpd.c + + httpdate.o: \ +@@ -358,6 +380,11 @@ + compile open_trunc.c open.h + ./compile open_trunc.c + ++openreadclose.o: \ ++compile openreadclose.c error.h open.h readclose.h stralloc.h \ ++gen_alloc.h openreadclose.h stralloc.h ++ ./compile openreadclose.c ++ + pathdecode.o: \ + compile pathdecode.c pathdecode.h stralloc.h gen_alloc.h + ./compile pathdecode.c +@@ -367,7 +394,7 @@ + ./compile percent.c + + prog: \ +-configure httpd ftpd rts utime ++cdb configure httpd ftpd rts utime htrules + + prot.o: \ + compile prot.c hasshsgr.h prot.h +diff -N -u -r publicfile-0.52.orig/README.basicauth publicfile-0.52/README.basicauth +--- publicfile-0.52.orig/README.basicauth Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/README.basicauth Wed Aug 29 22:16:02 2001 +@@ -0,0 +1,100 @@ ++Here is a patch for publicfile to allow for Basic Auth. ++ ++Building Instructions: ++ ++Save this patch as publicfile-0.52.basicauth.patch ++Download publicfile-0.52 ++Download cdb-0.75 ++ ++gunzip publicfile-0.52.tar ++gunzip cdb-0.75.tar ++tar -xf publicfile-0.52.tar ++cd publicfile-0.52 ++tar -xf ../cdb-0.75.tar ++patch -p1 < publicfile-0.52.basicauth.patch ++ ++Follow normal installation instructions for publicfile beginning with ++'make setup check' ++ ++Usage Instructions: ++ ++Once this patch has been applied, httpd will check for a file ++called '.access' in the current directory of any requested ++file. e.g, if /public/file/0/path/to/file.html is requested, httpd ++will first check for /public/file/0/path/to/.access. ++ ++.access should have the format: ++ realm_id:realm_txt ++ ++realm_id is used as documented below. realm_txt is typically ++presented by the user's browser. .access must be readable by httpd ++and only protects a specific directory. Sub-directories are not ++protected unless they also contain a .access file. ++ ++An additional program will be installed in /usr/local/publicfile (or ++whatever conf-home is) called htrules. Use this like tcprules: ++ ++cd /public/file ++htrules access.cdb access.tmp < access ++ ++This may safely be run at any time. ++ ++access should have the format: ++ ++ # this is a comment. blank lines are allowed too. ++ # the next line authorizes a user to a specific realm_id ++ realm_id:username:password ++ # the next line authorizes host class. ++ realm_id:LOCALHOST ++ ++access.cdb must be readable by httpd. ++ ++realm_id corresponds to the realm_id in the .access file(s). ++ ++Each realm_id line specifies either a username:password combination ++or a host class. Note that the same username may have different ++passwords in different realm_id's. ++ ++A host is mapped into a host class via the environment ++variable HTTPCLIENT. This environment variable should be ++set in tcpserver's rules.cdb. ++ ++Here is an example: ++ ++ === /public/file/0/private1/.access === ++ realm1:Dr. Suess ++ ++ === /public/file/0/private2/.access === ++ realm2:Sesame Street ++ ++ === /public/file/access === ++ # realm1 are Dr Suess users/clients ++ realm1:john:catinthehat ++ realm1:mary:greeneggswithham ++ realm1:LOCALHOST ++ realm1:DR SUESS ++ # realm1 are Sesame Street users/clients ++ realm2:tom:bigbird ++ realm2:abi:cookiemonster ++ realm2:mary:earnie ++ realm2:LOCALHOST ++ realm2:SESAME STREET ++ ++ === /etc/rules === ++ 127.0.0.1:allow,HTTPCLIENT="LOCALHOST" ++ 10.0.0.:allow,HTTPCLIENT="DR SUESS" ++ 10.1.0.:allow,HTTPCLIENT="SESAME STREET" ++ :allow ++ ++The changes to the Makefile aren't very clean, but everything compiles ++correctly. ++ ++Thanks to Eric M. Johnston's for base64.{c,h} from YAQSAP ++(Yet Another qmail SMTP AUTH Patch) - ++http://qmail.goof.com/qmail-auth-20010105.tar.gz ++ ++This patch available at ++http://www.soffian.org/downloads/publicfile-0.52_basicauth.patch ++ ++Jay Soffian <jay@soffian.org> 29 Aug 2001 ++ +diff -N -u -r publicfile-0.52.orig/base64.c publicfile-0.52/base64.c +--- publicfile-0.52.orig/base64.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/base64.c Wed Aug 22 22:17:39 2001 +@@ -0,0 +1,90 @@ ++#include "base64.h" ++#include "stralloc.h" ++#include "substdio.h" ++#include "str.h" ++ ++static char *b64alpha = ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ++#define B64PAD '=' ++ ++/* returns 0 ok, 1 illegal, -1 problem */ ++ ++int b64decode(in,l,out) ++const unsigned char *in; ++int l; ++stralloc *out; /* not null terminated */ ++{ ++ int i, j; ++ unsigned char a[4]; ++ unsigned char b[3]; ++ char *s; ++ ++ if (l == 0) ++ { ++ if (!stralloc_copys(out,"")) return -1; ++ return 0; ++ } ++ ++ if (!stralloc_ready(out,l + 2)) return -1; /* XXX generous */ ++ s = out->s; ++ ++ for (i = 0;i < l;i += 4) { ++ for (j = 0;j < 4;j++) ++ if ((i + j) < l && in[i + j] != B64PAD) ++ { ++ a[j] = str_chr(b64alpha,in[i + j]); ++ if (a[j] > 63) return 1; ++ } ++ else a[j] = 0; ++ ++ b[0] = (a[0] << 2) | (a[1] >> 4); ++ b[1] = (a[1] << 4) | (a[2] >> 2); ++ b[2] = (a[2] << 6) | (a[3]); ++ ++ *s++ = b[0]; ++ ++ if (in[i + 1] == B64PAD) break; ++ *s++ = b[1]; ++ ++ if (in[i + 2] == B64PAD) break; ++ *s++ = b[2]; ++ } ++ out->len = s - out->s; ++ while (out->len && !out->s[out->len - 1]) --out->len; /* XXX avoid? */ ++ return 0; ++} ++ ++int b64encode(in,out) ++stralloc *in; ++stralloc *out; /* not null terminated */ ++{ ++ unsigned char a, b, c; ++ int i; ++ char *s; ++ ++ if (in->len == 0) ++ { ++ if (!stralloc_copys(out,"")) return -1; ++ return 0; ++ } ++ ++ if (!stralloc_ready(out,in->len / 3 * 4 + 4)) return -1; ++ s = out->s; ++ ++ for (i = 0;i < in->len;i += 3) { ++ a = in->s[i]; ++ b = i + 1 < in->len ? in->s[i + 1] : 0; ++ c = i + 2 < in->len ? in->s[i + 2] : 0; ++ ++ *s++ = b64alpha[a >> 2]; ++ *s++ = b64alpha[((a & 3 ) << 4) | (b >> 4)]; ++ ++ if (i + 1 >= in->len) *s++ = B64PAD; ++ else *s++ = b64alpha[((b & 15) << 2) | (c >> 6)]; ++ ++ if (i + 2 >= in->len) *s++ = B64PAD; ++ else *s++ = b64alpha[c & 63]; ++ } ++ out->len = s - out->s; ++ return 0; ++} +diff -N -u -r publicfile-0.52.orig/base64.h publicfile-0.52/base64.h +--- publicfile-0.52.orig/base64.h Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/base64.h Wed Aug 22 22:17:39 2001 +@@ -0,0 +1,7 @@ ++#ifndef BASE64_H ++#define BASE64_H ++ ++extern int b64decode(); ++extern int b64encode(); ++ ++#endif +diff -N -u -r publicfile-0.52.orig/hier.c publicfile-0.52/hier.c +--- publicfile-0.52.orig/hier.c Mon Nov 8 23:23:46 1999 ++++ publicfile-0.52/hier.c Wed Aug 22 22:17:39 2001 +@@ -7,6 +7,7 @@ + d(auto_home,"bin",-1,-1,02755); + + c(auto_home,"bin","configure",-1,-1,0755); ++ c(auto_home,"bin","htrules",-1,-1,0755); + c(auto_home,"bin","httpd",-1,-1,0755); + c(auto_home,"bin","ftpd",-1,-1,0755); + } +diff -N -u -r publicfile-0.52.orig/htrules.c publicfile-0.52/htrules.c +--- publicfile-0.52.orig/htrules.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/htrules.c Wed Aug 29 21:27:42 2001 +@@ -0,0 +1,117 @@ ++#include "strerr.h" ++#include "stralloc.h" ++#include "getln.h" ++#include "buffer.h" ++#include "exit.h" ++#include "fmt.h" ++#include "byte.h" ++#include "base64.h" ++#include "cdb_make.h" ++ ++#define FATAL "htrules: fatal: " ++ ++unsigned long linenum = 0; ++char *fntemp; ++char *fn; ++ ++stralloc line = {0}; ++int match = 1; ++ ++stralloc base64 = {0}; ++stralloc key = {0}; ++stralloc realm = {0}; ++stralloc userpass = {0}; ++ ++struct cdb_make c; ++ ++void nomem(void) ++{ ++ strerr_die2x(111,FATAL,"out of memory"); ++} ++void usage(void) ++{ ++ strerr_die1x(100,"htrules: usage: htrules access.cdb access.tmp"); ++} ++void die_bad(void) ++{ ++ if (!stralloc_0(&line)) nomem(); ++ strerr_die3x(100,FATAL,"unable to parse this line: ",line.s); ++} ++void die_write(void) ++{ ++ strerr_die4sys(111,FATAL,"unable to write to ",fntemp,": "); ++} ++ ++main(int argc,char **argv) ++{ ++ int colon; ++ char *x; ++ int len; ++ int fd; ++ int i; ++ char ch; ++ ++ fn = argv[1]; ++ if (!fn) usage(); ++ fntemp = argv[2]; ++ if (!fntemp) usage(); ++ ++ fd = open_trunc(fntemp); ++ if (fd == -1) ++ strerr_die4sys(111,FATAL,"unable to create ",fntemp,": "); ++ if (cdb_make_start(&c,fd) == -1) die_write(); ++ ++ while (match) { ++ if (getln(buffer_0,&line,&match,'\n') == -1) ++ strerr_die2sys(111,FATAL,"unable to read input: "); ++ ++ x = line.s; len = line.len; ++ ++ if (!len) break; ++ if (x[0] == '#') continue; ++ if (x[0] == '\n') continue; ++ ++ while (len) { ++ ch = x[len - 1]; ++ if (ch != '\n') if (ch != ' ') if (ch != '\t') break; ++ --len; ++ } ++ line.len = len; /* for die_bad() */ ++ if (!len) continue; ++ ++ colon = byte_chr(x,len,':'); ++ if (!colon || colon == len) die_bad(); ++ if (!stralloc_copyb(&realm,x,colon)) nomem(); ++ x += colon + 1; len -= colon + 1; ++ ++ colon = byte_chr(x,len,':'); ++ if (colon == len) { ++ if (!stralloc_copyb(&key,"C",1)) nomem(); ++ if (!stralloc_cat(&key,&realm)) nomem(); ++ if (!stralloc_catb(&key,":",1)) nomem(); ++ if (!stralloc_catb(&key,x,len)) nomem(); ++ if (cdb_make_add(&c,key.s,key.len,"",0) == -1) die_write(); ++ } else { ++ if (!stralloc_copyb(&userpass,x,len)) nomem(); ++ if (b64encode(&userpass,&base64) == -1) nomem(); ++ ++ if (!stralloc_copyb(&key,"U",1)) nomem(); ++ if (!stralloc_cat(&key,&base64)) nomem(); ++ if (cdb_make_add(&c,key.s,key.len,"",0) == -1) die_write(); ++ ++ if (!stralloc_copyb(&key,"R",1)) nomem(); ++ if (!stralloc_cat(&key,&realm)) nomem(); ++ if (!stralloc_catb(&key,":",1)) nomem(); ++ if (!stralloc_cat(&key,&base64)) nomem(); ++ if (cdb_make_add(&c,key.s,key.len,"",0) == -1) die_write(); ++ } ++ } ++ ++ if (cdb_make_finish(&c) == -1) die_write(); ++ if (fsync(fd) == -1) die_write(); ++ if (close(fd) == -1) die_write(); /* NFS stupidity */ ++ if (rename(fntemp,fn)) ++ strerr_die6sys(111,FATAL,"unable to move ",fntemp," to ",fn,": "); ++ ++ _exit(0); ++} +diff -N -u -r publicfile-0.52.orig/httpd.c publicfile-0.52/httpd.c +--- publicfile-0.52.orig/httpd.c Mon Nov 8 23:23:46 1999 ++++ publicfile-0.52/httpd.c Wed Aug 29 21:30:34 2001 +@@ -15,6 +15,10 @@ + #include "substdio.h" + #include "error.h" + #include "getln.h" ++#include "byte.h" ++#include "cdb.h" ++#include "openreadclose.h" ++#include "env.h" + + int safewrite(int fd,char *buf,int len) + { +@@ -51,6 +55,7 @@ + stralloc host = {0}; + stralloc path = {0}; + stralloc ims = {0}; ++stralloc basic_auth = {0}; + int flagbody = 1; + + char filebuf[1024]; +@@ -75,11 +80,16 @@ + out_puts("\r\n"); + } + +-void barf(char *code,char *message) ++void barf2(char *code,char *message,char *realm) + { + if (protocolnum > 0) { + tai_now(&now); + header(code,message); ++ if(realm) { ++ out_puts("WWW-Authenticate: Basic realm=\""); ++ out_puts(realm); ++ out_puts("\"\r\n"); ++ } + out_puts("Content-Length: "); + out_put(strnum,fmt_ulong(strnum,str_len(message) + 28)); + out_puts("\r\n"); +@@ -100,8 +110,81 @@ + _exit(0); + } + ++void barf(char *code,char *message) ++{ ++ barf2(code,message,(char *)0); ++} ++ + stralloc fn = {0}; ++stralloc accessfn = {0}; + stralloc contenttype = {0}; ++stralloc realm = {0}; ++stralloc realmtxt = {0}; ++stralloc key = {0}; ++ ++void checkauth(void) ++{ ++ int len; ++ int fd; ++ int colon; ++ static struct cdb c; ++ char *x; ++ ++ len = byte_rchr(fn.s,fn.len,'/'); ++ if (!stralloc_copyb(&accessfn,fn.s,len)) _exit(21); ++ if (!stralloc_cats(&accessfn,"/.access")) _exit(21); ++ if (!stralloc_0(&accessfn)) _exit(21); ++ ++ if (openreadclose(accessfn.s,&realm,256) == 0) return; ++ if (!realm.len) _exit(23); /* no realm */ ++ realm.len = byte_chr(realm.s,realm.len,'\n'); ++ while (realm.len) { ++ if (realm.s[realm.len - 1] != ' ') ++ if (realm.s[realm.len - 1] != '\t') ++ break; ++ --realm.len; ++ } ++ colon = byte_chr(realm.s,realm.len,':'); ++ if (!colon) _exit(23); /* no realm */ ++ if (colon == realm.len) { ++ if (!stralloc_copys(&realmtxt,"restricted access")) _exit(21); ++ } else { ++ if (!stralloc_copyb(&realmtxt,realm.s+colon+1,realm.len-(colon+1))) _exit(21); ++ realm.len = colon; ++ } ++ if (!stralloc_0(&realmtxt)) _exit(21); ++ ++ fd = open_read("/access.cdb"); ++ if (fd == -1) _exit(23); ++ cdb_init(&c,fd); ++ ++ x = env_get("HTTPCLIENT"); ++ if (x) { ++ if (!stralloc_copyb(&key,"C",1)) _exit(21); ++ if (!stralloc_cat(&key,&realm)) _exit(21); ++ if (!stralloc_catb(&key,":",1)) _exit(21); ++ if (!stralloc_cats(&key,x)) _exit(21); ++ if (cdb_find(&c,key.s,key.len) == 1) goto AUTH_OK; ++ } ++ ++ if (!basic_auth.len) barf2("401 ","Authorization Required", realmtxt.s); ++ ++ if (!stralloc_copyb(&key,"U",1)) _exit(21); ++ if (!stralloc_cat(&key,&basic_auth)) _exit(21); ++ if (cdb_find(&c,key.s,key.len) != 1) ++ barf2("401 ","Authorization Required",realmtxt.s); ++ ++ if (!stralloc_copyb(&key,"R",1)) _exit(21); ++ if (!stralloc_cat(&key,&realm)) _exit(21); ++ if (!stralloc_catb(&key,":",1)) _exit(21); ++ if (!stralloc_cat(&key,&basic_auth)) _exit(21); ++ if (cdb_find(&c,key.s,key.len) != 1) barf("403 ","Forbidden"); ++ ++ AUTH_OK: ++ alloc_free(key); ++ cdb_free(&c); ++ close(fd); ++} + + void get(void) + { +@@ -124,6 +207,8 @@ + if (!stralloc_cat(&fn,&path)) _exit(21); + pathdecode(&fn); + if (!stralloc_0(&fn)) _exit(21); ++ ++ checkauth(); + + fd = file_open(fn.s,&mtime,&length,1); + if (fd == -1) +@@ -227,6 +312,7 @@ + if (!stralloc_copys(&path,"")) _exit(21); + if (!stralloc_copys(&protocol,"")) _exit(21); + if (!stralloc_copys(&ims,"")) _exit(21); ++ if (!stralloc_copys(&basic_auth,"")) _exit(21); + protocolnum = 2; + + spaces = 0; +@@ -302,6 +388,8 @@ + if (!stralloc_append(&host,&field.s[i])) _exit(21); + if (case_startb(field.s,field.len,"if-modified-since:")) + if (!stralloc_copyb(&ims,field.s + 18,field.len - 18)) _exit(21); ++ if (case_startb(field.s,field.len,"authorization: basic ")) ++ if (!stralloc_copyb(&basic_auth,field.s + 21,field.len - 21)) _exit(21); + field.len = 0; + } + if (!line.len) break; +diff -N -u -r publicfile-0.52.orig/openreadclose.c publicfile-0.52/openreadclose.c +--- publicfile-0.52.orig/openreadclose.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/openreadclose.c Wed Aug 29 14:24:21 2001 +@@ -0,0 +1,18 @@ ++/* Public domain. */ ++ ++#include "error.h" ++#include "open.h" ++#include "readclose.h" ++#include "openreadclose.h" ++ ++int openreadclose(const char *fn,stralloc *sa,unsigned int bufsize) ++{ ++ int fd; ++ fd = open_read(fn); ++ if (fd == -1) { ++ if (errno == error_noent) return 0; ++ return -1; ++ } ++ if (readclose(fd,sa,bufsize) == -1) return -1; ++ return 1; ++} +diff -N -u -r publicfile-0.52.orig/openreadclose.h publicfile-0.52/openreadclose.h +--- publicfile-0.52.orig/openreadclose.h Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/openreadclose.h Wed Aug 29 14:24:21 2001 +@@ -0,0 +1,10 @@ ++/* Public domain. */ ++ ++#ifndef OPENREADCLOSE_H ++#define OPENREADCLOSE_H ++ ++#include "stralloc.h" ++ ++extern int openreadclose(const char *,stralloc *,unsigned int); ++ ++#endif +diff -N -u -r publicfile-0.52.orig/readclose.c publicfile-0.52/readclose.c +--- publicfile-0.52.orig/readclose.c Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/readclose.c Wed Aug 29 14:30:52 2001 +@@ -0,0 +1,23 @@ ++/* Public domain. */ ++ ++#include <unistd.h> ++#include "error.h" ++#include "readclose.h" ++ ++int readclose_append(int fd,stralloc *sa,unsigned int bufsize) ++{ ++ int r; ++ for (;;) { ++ if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; } ++ r = read(fd,sa->s + sa->len,bufsize); ++ if (r == -1) if (errno == error_intr) continue; ++ if (r <= 0) { close(fd); return r; } ++ sa->len += r; ++ } ++} ++ ++int readclose(int fd,stralloc *sa,unsigned int bufsize) ++{ ++ if (!stralloc_copys(sa,"")) { close(fd); return -1; } ++ return readclose_append(fd,sa,bufsize); ++} +diff -N -u -r publicfile-0.52.orig/readclose.h publicfile-0.52/readclose.h +--- publicfile-0.52.orig/readclose.h Wed Dec 31 16:00:00 1969 ++++ publicfile-0.52/readclose.h Wed Aug 29 14:30:52 2001 +@@ -0,0 +1,11 @@ ++/* Public domain. */ ++ ++#ifndef READCLOSE_H ++#define READCLOSE_H ++ ++#include "stralloc.h" ++ ++extern int readclose_append(int,stralloc *,unsigned int); ++extern int readclose(int,stralloc *,unsigned int); ++ ++#endif diff -ruN publicfile/files/publicfile.sslserver publicfile.new/files/publicfile.sslserver --- publicfile/files/publicfile.sslserver Wed Dec 31 16:00:00 1969 +++ publicfile.new/files/publicfile.sslserver Tue Jan 4 11:11:47 2005 @@ -0,0 +1,36 @@ +--- httpd.c.orig Tue Nov 9 02:23:46 1999 ++++ httpd.c Sun Dec 9 21:30:59 2001 +@@ -271,8 +271,16 @@ + if (!stralloc_copyb(&path,host.s + i,host.len - i)) _exit(21); + host.len = i; + } +- else +- if (!stralloc_copy(&path,&url)) _exit(21); ++ else { ++ if (case_startb(url.s,url.len,"https://")) { ++ if (!stralloc_copyb(&host,url.s + 8,url.len - 8)) _exit(21); ++ i = byte_chr(host.s,host.len,'/'); ++ if (!stralloc_copyb(&path,host.s + i,host.len - i)) _exit(21); ++ host.len = i; ++ } ++ else ++ if (!stralloc_copy(&path,&url)) _exit(21); ++ } + + if (!path.len || (path.s[path.len - 1] == '/')) + if (!stralloc_cats(&path,"index.html")) _exit(21); +--- file.c.orig Wed Dec 12 07:09:57 2001 ++++ file.c Wed Dec 12 07:09:33 2001 +@@ -15,7 +15,11 @@ + char *x; + + x = env_get("TCPREMOTEIP"); +- if (!x) x = "0"; ++ if (!x) { ++ x = env_get("SSLREMOTEIP"); ++ if (!x) ++ x = "0"; ++ } + substdio_puts(subfderr,x); + substdio_puts(subfderr,flagread ? " read ": " dir "); + diff -ruN publicfile/files/redirect-slash-patch publicfile.new/files/redirect-slash-patch --- publicfile/files/redirect-slash-patch Wed Dec 31 16:00:00 1969 +++ publicfile.new/files/redirect-slash-patch Tue Jan 4 11:17:13 2005 @@ -0,0 +1,217 @@ +From: Giles Lean <giles@nemeton.com.au> +To: publicfile@list.cr.yp.to +Subject: redirect patch for publicfile-0.52 +Date: Sun, 05 Dec 1999 08:43:14 +1100 + +------- =_aaaaaaaaaa0 +Content-Type: text/plain; charset="us-ascii" +Content-ID: <23894.944342900.1@nemeton.com.au> + +I have a patch for publicfile-0.52 that will make it send redirects +instead of "404 access denied" when directories are requested +without a trailing slash. + +Comments and suggestions are welcome, particularly if someone can +see where I've either done something wrong protocol-wise or if the +integration with Dan's code can be improved. + +This patch is only appropriate for publicfile installations where +an existing server is being replaced or where lots of third party +HTML is installed without editing. This is not the target market +Dan Bernstein claims for publicfile, but some of us will use it +anyway. (My #1 reason? The low memory requirement.) + +After this patch is applied log messages about "is a directory" +will show up if the redirect code is used: + +@4000000038490b1f26a03cac 127.0.0.1 read ./localhost.nemeton.com.au/cr.yp.to/publicfile: is a directory +@40000000384973483712ee2c 127.0.0.1 read ./localhost.nemeton.com.au/susv2: is a directory + +Regards, + +Giles + + +------- =_aaaaaaaaaa0 +Content-Type: text/plain; name="diff"; charset="us-ascii" +Content-ID: <23894.944342900.2@nemeton.com.au> + +Index: error.c +=================================================================== +RCS file: /a/CVS/net/publicfile/error.c,v +retrieving revision 1.1.1.1 +retrieving revision 1.1.1.1.2.1 +diff -c -r1.1.1.1 -r1.1.1.1.2.1 +*** error.c 1999/12/01 19:38:15 1.1.1.1 +--- error.c 1999/12/04 21:15:37 1.1.1.1.2.1 +*************** +*** 100,102 **** +--- 100,109 ---- + #else + -14; + #endif ++ ++ int error_isdir = ++ #ifdef EISDIR ++ EISDIR; ++ #else ++ -15; ++ #endif +Index: error.h +=================================================================== +RCS file: /a/CVS/net/publicfile/error.h,v +retrieving revision 1.1.1.1 +retrieving revision 1.1.1.1.2.1 +diff -c -r1.1.1.1 -r1.1.1.1.2.1 +*** error.h 1999/12/01 19:38:15 1.1.1.1 +--- error.h 1999/12/04 21:15:37 1.1.1.1.2.1 +*************** +*** 17,22 **** +--- 17,23 ---- + extern int error_perm; + extern int error_acces; + extern int error_nodevice; ++ extern int error_isdir; + + extern char *error_str(); + extern int error_temp(); +Index: error_str.c +=================================================================== +RCS file: /a/CVS/net/publicfile/error_str.c,v +retrieving revision 1.1.1.1 +retrieving revision 1.1.1.1.2.1 +diff -c -r1.1.1.1 -r1.1.1.1.2.1 +*** error_str.c 1999/12/01 19:38:15 1.1.1.1 +--- error_str.c 1999/12/04 21:15:38 1.1.1.1.2.1 +*************** +*** 21,26 **** +--- 21,27 ---- + X(error_perm,"permission denied") + X(error_acces,"access denied") + X(error_nodevice,"device not configured") ++ X(error_isdir,"is a directory") + #ifdef ESRCH + X(ESRCH,"no such process") + #endif +Index: file.c +=================================================================== +RCS file: /a/CVS/net/publicfile/file.c,v +retrieving revision 1.1.1.1 +retrieving revision 1.1.1.1.2.1 +diff -c -r1.1.1.1 -r1.1.1.1.2.1 +*** file.c 1999/12/01 19:38:14 1.1.1.1 +--- file.c 1999/12/04 21:15:38 1.1.1.1.2.1 +*************** +*** 65,77 **** + errno = error_acces; + return -1; + } +! if (flagread) +! if ((st.st_mode & S_IFMT) != S_IFREG) { + log(fn,": ","not a regular file",flagread); + close(fd); + errno = error_acces; +- return -1; + } + + log(fn,": ","success",flagread); + +--- 65,83 ---- + errno = error_acces; + return -1; + } +! if (flagread && (st.st_mode & S_IFMT) != S_IFREG) { +! if ((st.st_mode & S_IFMT) == S_IFDIR) { +! log(fn,": ",error_str(error_isdir),flagread); +! close(fd); +! errno = error_isdir; +! } +! else { + log(fn,": ","not a regular file",flagread); + close(fd); + errno = error_acces; + } ++ return -1; ++ } + + log(fn,": ","success",flagread); + +Index: httpd.c +=================================================================== +RCS file: /a/CVS/net/publicfile/httpd.c,v +retrieving revision 1.1.1.1 +retrieving revision 1.1.1.1.2.1 +diff -c -r1.1.1.1 -r1.1.1.1.2.1 +*** httpd.c 1999/12/01 19:38:14 1.1.1.1 +--- httpd.c 1999/12/04 21:15:38 1.1.1.1.2.1 +*************** +*** 103,114 **** +--- 103,142 ---- + stralloc fn = {0}; + stralloc contenttype = {0}; + ++ void redirect(void) ++ { ++ if (!stralloc_cats(&url, "/")) _exit(21); ++ if (protocolnum > 0) { ++ tai_now(&now); ++ header("301 ", "Moved Permanently"); ++ out_puts("Content-Length: "); ++ out_put(strnum,fmt_ulong(strnum,url.len * 2 + 127)); ++ out_puts("\r\nLocation: "); ++ out_put(url.s, url.len); ++ out_puts("\r\nContent-Type: text/html\r\n\r\n"); ++ } ++ if (flagbody) { ++ out_puts("<html><body>The document you requested is a directory. Try adding a trailing slash to the URL: <A HREF=\""); ++ out_put(url.s,url.len); ++ out_puts("\">"); ++ out_put(url.s,url.len); ++ out_puts("</A></body></html>\r\n"); ++ } ++ out_flush(); ++ } ++ + void get(void) + { + unsigned long length; + int fd; + int r; + ++ if (!case_startb(url.s,url.len,"http://")) { ++ if (!stralloc_copys(&url,"http://")) _exit(21); ++ if (!stralloc_cat(&url,&host)) _exit(21); ++ if (!stralloc_cat(&url,&path)) _exit(21); ++ } ++ + host.len = byte_chr(host.s,host.len,':'); + if (!host.len) { + if (protocolnum > 1) +*************** +*** 126,133 **** + if (!stralloc_0(&fn)) _exit(21); + + fd = file_open(fn.s,&mtime,&length,1); +! if (fd == -1) + barf("404 ",error_str(errno)); + + if (protocolnum > 0) { + tai_now(&now); +--- 154,167 ---- + if (!stralloc_0(&fn)) _exit(21); + + fd = file_open(fn.s,&mtime,&length,1); +! if (fd == -1) { +! if (errno == error_isdir) { +! redirect(); +! if (protocolnum < 2) _exit(0); +! return; +! } + barf("404 ",error_str(errno)); ++ } + + if (protocolnum > 0) { + tai_now(&now); + +------- =_aaaaaaaaaa0-- + diff -ruN publicfile/pkg-plist publicfile.new/pkg-plist --- publicfile/pkg-plist Fri Jan 28 08:41:09 2000 +++ publicfile.new/pkg-plist Tue Jan 4 10:28:04 2005 @@ -1,3 +1,4 @@ bin/configure bin/httpd bin/ftpd +%%BASICAUTH%%bin/htrules >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050122003947.37931.qmail>