#!/usr/bin/perl # yuno3.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) + $headersize - length $request; while( $rsize > 0 && defined(recv CLIENT, $data, $rsize, 0) ) { $request .= $data; $rsize -= length $data; } print '-' x 32, "\n$request\n"; my ($post, $query); $query = new CGI(substr $request, $headersize); $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 send CLIENT, "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, 0; close CLIENT; close CLIENT_PIPE; exit; } $Port = (shift || 80); my ($rin, $rout); die $! unless socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp')) && bind(SERVER, sockaddr_in($Port, INADDR_ANY)) && listen(SERVER, 5) && pipe(SERVER_PIPE, CLIENT_PIPE); binmode SERVER; binmode SERVER_PIPE; binmode CLIENT_PIPE; $Posts = $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; last if ($size -= length $data) <= 0; } $Posts = "\n
\n$entry$Posts"; } } } die $!;