💾 Archived View for tozip.chickenkiller.com › 2022-06-27-nofer-ann.gmi captured on 2022-07-16 at 13:55:07. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Created 2022-06-27
Gopher is OK, but it's an awkward protocol to write for. It has its quirks, to say the least. I do, however, particularly like seeing gopher pages that are left-and-right aligned. There's something just so neat about them.
I had been working on a Perl script called "nofer" ("no gopher") to work in conjunction with inetd on FreeBSD. It serves gmi pages as gopher pages, so if you have a Gemini capscule, you should be pretty much good to go. It is actually a shame that gopher has a weird layout. With the benefit of hindsight, we didn't really want to do it that way.
Without further ado, here's my nofer script:
#!/usr/bin/env perl #toy gopher server - from gemini # for setup on FreeBSD, see nopher.md # settings that you may need to change my $HOME = "/home/gemini"; my $LOG = "$HOME/tmp/nofer.log"; my $HOST = "\ttozip.chickenkiller.com\t70"; my $SRCROOT = "$HOME/repos/cerbo/website/gemini"; #use boolean; use Cwd; #use File::Spec; my $request = <>; $request =~ s/\r//g; $request =~ s/\n//g; if($request eq "") { $request = "index.gmi"; } if($request eq "/") { $request = "index.gmi"; } # check that client is not trying to snoop around our filesystem my $path1 = "$SRCROOT/$request"; #my $can_path = File::Spec->canonpath($requested_path); my $can_path = Cwd::abs_path($path1); my $rascal = substr($can_path, 0, length($SRCROOT)) ne $SRCROOT; if( $rascal || ! (-e $can_path)) { print "Error: File or directory not found!\n"; exit 1; } open(FH, "<", "$can_path"); sub handle_mapfile { while(<FH>) { my $input = $_; $input =~ chomp $input; if( $_ =~ /^=>\s+(\S+)\s+(.*)/) { my ($link, $text) = ($1, $2); my $prefix = ($link =~ /.*\.gmi$/) ? "1" : "0"; # should probably need to classify link type my $outtext = "$prefix$text\t/$link$HOST\r\n"; print $outtext; } else { print "i$input\t\tnull.host\t1\r\n"; } } } sub handle_nonmapfile { while(<FH>) { print "$_"; } } if($request =~ m/\.gmi$/) { handle_mapfile ; } else { handle_nonmapfile; } close FH; open(FH, ">>", $LOG); #my $dt = DateTime->now; my $dt = localtime(); print FH "$dt:Request \"$request\"\n"; close FH; #print $response;
It's not perfect by a long shot, but it's not so bad. It does the wrong thing when serving things like http and image requests. It also serves only static pages. Still, meh, it works well enough for me right now.
I have written some installation notes for FreeBSD:
# nofer setup on FreeBSD Perform static test: ./nofer / Install packages: pkg install inetd pkg install gopher In /etc/services, add: gopher7000 7000/tcp gopher7000 7000/udp In /etc/inetd.conf, add: gopher stream tcp nowait gemini /home/gemini/repos/cerbo/website/nofer nofer gopher7000 stream tcp nowait gemini /home/gemini/repos/cerbo/website/nofer nofer Activate inetd temporarily: service inetd onestart Test basic configuration: gopher gopher://localhost:7000 gopher gopher://tozip.chickenkiller.com:7000 gopher gopher://localhost:70 gopher gopher://tozip.chickenkiller.com:70 This seems to work on port 70, which is a little odd, because I thought non-root users cannot use low port numbers. Configure your router to redirect port 70 to your server. Enable inetd permanently: in /etc/rc.conf, add: inetd_enable="YES"
You'll need to adapt it to Linux, or whatever system it is you're using.
I have set it up on my machine, and seems to work:
gopher://tozip.chickenkiller.com/
Hope that was of use.
So who wins the smallweb wars: gopher, or gemini?