#!/usr/bin/perl # yuno2.pl - Don Yang (uguu.org) # # 07/31/05 use strict; use Socket; use CGI ':standard'; my ($CHARSET, $MAXPOSTSIZE, $INTSIZE); my ($Port, $Posts); local (*SERVER, *CLIENT, *SERVER_PIPE, *CLIENT_PIPE); $CHARSET = 'Shift_JIS'; $MAXPOSTSIZE = 0x20000; $INTSIZE = length(pack 'I', 0); sub ProcessRequest() { my ($request, $data, $headersize, $rsize); $request = ''; while( defined(recv(CLIENT, $data, 1024, 0)) ) { $request .= $data; if( ($headersize = index($request, "\r\n\r\n")) > 0 ) { $headersize += 4; last; } if( ($headersize = index($request, "\n\n")) > 0 ) { $headersize += 2; last; } } if( $request =~ /^POST / ) { $rsize = ($request =~ /content-length:\s*(\d+)/i) ? $1 : $MAXPOSTSIZE; $rsize -= length($request) - $headersize; while( $rsize > 0 && defined(recv(CLIENT, $data, $rsize, 0)) ) { $request .= $data; $rsize -= length($data); } print (('-' x 32), "\n", $request, "\n"); my ($post, $query); $post = substr($request, $headersize); $query = new CGI($post); $post = $query->param('x'); return if( $query->param('f') eq 'reload' ); $post =~ s/\r\n/\n/g; if( $query->param('f') ne 'raw' ) { $post =~ s/&/&/g; $post =~ s//>/g; if( $query->param('f') eq 'post' ) { $post =~ s/\n/
/g; } else { $post = "
\n$post
"; } } $post .= '

' . (scalar localtime); $Posts = "\n


\n$post$Posts"; $post = (pack 'I', length($post)) . $post; print CLIENT_PIPE $post; } else { print (('-' x 32), "\n", $request, "\n"); } my ($reply); $reply = <<"EOT"; Yuno


$Posts EOT $reply = "HTTP/1.0 200 OK\r\n" . "Content-Type: text/html\r\n" . "Server: Yuno\r\n" . "Connection: close\r\n" . "Content-Length: " . length($reply) . "\r\n\r\n" . $reply; send(CLIENT, $reply, 0); close CLIENT; close CLIENT_PIPE; exit 0; } $Port = ($#ARGV >= 0 ? $ARGV[0] : 80); $Posts = ''; my ($rin, $rout); unless( socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) ) { die "socket: $!\n"; } unless( bind(SERVER, sockaddr_in($Port, INADDR_ANY)) ) { die "bind: $!\n"; } unless( listen(SERVER, 5) ) { die "listen: $!\n"; } unless( pipe SERVER_PIPE, CLIENT_PIPE ) { die "pipe: $!\n"; } binmode(SERVER); binmode(SERVER_PIPE); binmode(CLIENT_PIPE); $rin = ''; vec($rin, fileno(SERVER), 1) = 1; vec($rin, fileno(SERVER_PIPE), 1) = 1; print "listening on $Port\n"; while( select($rout = $rin, undef, undef, undef) ) { if( vec($rout, fileno(SERVER), 1) ) { accept(CLIENT, SERVER); if( fork ) { close(CLIENT); } else { close(SERVER_PIPE); binmode(CLIENT); ProcessRequest(); } } if( vec($rout, fileno(SERVER_PIPE), 1) ) { my ($data, $entry, $size); $entry = ''; if( read(SERVER_PIPE, $data, $INTSIZE, 0) ) { $size = unpack 'I', $data; while( read(SERVER_PIPE, $data, $size, 0) ) { $entry .= $data; $size -= length($data); last if( $size <= 0 ); } $Posts = "\n
\n$entry$Posts"; } } } die "select: $!\n";