Add TLS to client.
[newgopher.git] / gopher.pl
blob0b9c210be5118160249d53e80c7eeacdc610c86c
1 #!/usr/bin/perl
3 use File::MimeInfo; # CPAN
4 use TLSGopher;
6 # EVIL HAS NEVER BEEN SO VILE BEFORE:
7 $share_dir = './public_gopher/';
9 # Assume TLS is handled 'upstream';
10 # stdin is request in plain-text new gopher
11 # and stdout is response in plain-text new gopher
13 # Simple request
14 $request_str = <stdin>;
15 $post_size = 0;
17 # Complex request
18 if ($request_str =~ /\t/) {
19 $size_str = <stdin>;
20 chomp($size_str); $size_str =~ s/\r$//;
21 $post_size = sprintf('%d', $size_str);
22 # Hack -- making socket non-blocking
23 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
24 $flags = fcntl(STDIN, F_GETFL, 0);
25 $flags = fcntl(STDIN, F_SETFL, $flags | O_NONBLOCK);
26 $data_read = read(STDIN, $data, $post_size);
27 undef $size_str;
30 chomp($request_str); $request_str =~ s/\r//;
31 ($selector, $search) = split(/\t/, $request_str);
33 # Make selector 'safe' :(
34 $selector = '/'.$selector;
35 $selector =~ s/\/\.+//;
36 $selector =~ s/\.\///;
37 $selector =~ s/^\/+//;
38 $selector =~ s/\/$//;
40 $path = $share_dir.$selector;
41 # Fetch file by selector
42 if (-e $path && !-r $path) {
43 die ng_error_access_denied();
46 if (-f $path) {
47 if (-x $path) {
48 # CGI script
49 $ENV{"SELECTOR"} = $selector;
50 $ENV{"SEARCH"} = $search;
51 $ENV{'DATA_SIZE'} = $post_size;
52 $tmp_file = "/tmp/post.txt";
53 open(FILE, '>'.$tmp_file);
54 #binmode(FILE);
55 #while (<STDIN>) { print FILE $_; }
56 print FILE $data;
57 close(FILE);
58 exec $path . ' <'.$tmp_file;
59 } else {
60 # FS file
61 $size = -s $path;
62 $mimetype = mimetype $path;
63 print $size."\t".$mimetype."\r\n";
64 # "cat" file.. (is there a better way?)
65 open(FILE, $path);
66 binmode(FILE);
67 while (<FILE>) { print; }
68 close(FILE);
70 exit 0;
72 if (-d $path) {
73 print ng_response( ng_menu_from_dir($path) );
74 exit 0;
77 die ng_error_not_found();
79 sub stdout_to_file {
82 sub file_to_stdin {
86 sub ng_response {
87 my $data = $_[0];
88 my $mimetype = $_[1] || 'text/x-menu';
89 my $header = length ($data) . "\t" . $mimetype. "\r\n";
90 return $header . $data;
93 sub ng_error {
94 return ng_response("e\t". $_[0] . "\terror\t\t\r\n", "text/x-menu");
97 sub ng_error_access_denied {
98 return ng_error "Access denied";
100 sub ng_error_not_found {
101 return ng_error ("File not found [".$path."]");
104 sub ng_menu_from_dir($path) {
105 $buf = "";
106 $path =~ s/\/$//;
107 @files = glob $path."/*";
108 $buf .= "i\tListing [".$path."]\r\n";
109 $buf .= "m\t..\t..\r\n";
110 $l = length $path;
111 $sl = length $share_dir;
112 foreach $file (@files) {
113 $name = substr($file, $l + 1);
114 $selector = substr($file, $sl);
115 $type = 'b';
116 if (-x $file) { $type = 's'; }
117 if (-d $file) { $type = 'm'; }
118 $buf .= $type."\t".$name."\t".$selector."\r\n";
120 return $buf;