Introduction
Statistics
Contact
Development
Disclaimer
Help
!/usr/pkg/bin/perl
germ- let your ideas germinate.
(c) 2009--11, Wesley Teal,
[email protected]
includes code and comments by
[email protected]
distributed under the MIT/X Consortium License, see LICENSE for details
se warnings;
se strict;
se Text::Wrap;
Text::Wrap::columns=65;
se Fcntl qw(:flock);
se POSIX qw(strftime);
Nix the PATH and prevent SETUID/SETGID
ENV{PATH} = "";
> = $<;
) = $(;
=== Configurable Variables ===
The directory used in gopher links, make sure not to end with a "/"
y $base_dir ="/users/trevorb";
Full path name to the directory you store your *.post, header.txt, and div.txt
files in. Make sure not to end with a "/"
y $dir = "/ftp/pub$base_dir/dat";
The maximum number of posts you want displayed per phlog page
y $max_posts = 6;
Permalink text. Shown as a link to individual posts. It's a good idea to have
this end with something about comments so that the comment count isn't just a
random-seeming number sitting next to this link
y $permalink_text = "View Post/Comments";
This is the text that will be displayed on the main page when you use the
"--more--" tag in your posts.
y $more_text = "[Continued...]";
This is printed after every comment that is left on your gopherlog. Changing
this after you have comments will mess up comment counts, so it's best to
change it right away or not at all. This also divides tags from posts.
y $cmt_div = "---";
This scripts name, so it can get all self-referential
y $name = "germ.cgi";
The server that is hosting the script
y $server = "sdf-eu.org";
The port number the server uses; don't change this unless you know its serving
from a different port
y $port = 70;
=== End Configurable Variables ===
y $txt_string = "\tnull\ttext\t70";
y $ver = "germ 0.4.0";
y $header = "header.txt";
y $div = "div.txt";
y $footer = "i$txt_string\r\nipowered by $ver$txt_string\r\n.\r\n";
y $com_string = "\t$base_dir/$name\t$server\t$port";
y @tag_list;
check to see if the server is using cgi variables to communicate with germ
or if its passing information as arguments like Bucktooth
y $query;
f (exists $ENV{QUERY_STRING}) {
$query = $ENV{QUERY_STRING};
else {
$query = join(' ',@ARGV);
get posts
pendir(DH, $dir) || die "3Can't open $dir. $! \r\n";
y @posts = grep(/post$/, readdir(DH));
losedir(DH);
posts = sort { -M "$dir/$a" <=> -M "$dir/$b" } @posts;
print main page
f (length($query) == 0) {
if (($max_posts - 1) > $#posts) {
$max_posts = $#posts + 1;
}
&print_page (@posts[0 .. ($max_posts - 1)]);
if ($#posts > ($max_posts - 1)) {
print "1Older Posts\t$base_dir/$name?archive1\t$server\t$port\r\n";
}
show individual posts/comments
elsif ($query =~ /^\w+\.post$/) {
my $go_string = "\t$base_dir/$name?$query\t$server\t$port";
my $post = "$query";
my $cmt = "$post.cmt";
&print_file ($header);
&print_file ($div);
print "1Back to Main Page$com_string\r\n";
print "i$txt_string\r\n";
my $date = strftime ("%Y %B %d, %R", localtime((stat ("$dir/$post"))[9]));
print "i$date$txt_string\r\n";
print "i$txt_string\r\n";
&print_file ($post);
print "i$txt_string\r\n";
print "7Leave Comment$com_string\r\n";
$Text::Wrap::separator = "$txt_string\r\n";
print wrap("i", "i", "To leave comment enter \"$post\" at the prompt followe…
$Text::Wrap::separator = "\n";
if ($tag_list[0]) {
&print_tags (@tag_list);
}
&print_file ($div);
if (-e "$dir/$cmt") {
&print_file ("$cmt");
}
show archives
elsif ($query =~ /^archive\d+$/) {
my $num = $query;
$num =~ s/archive//;
my $min = $max_posts * $num;
my $max = $max_posts * $num + $max_posts - 1;
if ($max > $#posts) {
$max = $#posts;
}
&print_page (@posts[$min .. $max]);
if ($num == 1) {
print "1Newer Posts\t$base_dir/$name\t$server\t$port\r\n";
}elsif ($num > 1) {
my $prev_page = $num - 1;
print "1Newer Posts\t$base_dir/$name?archive$prev_page\t$server\t$port\r…
}
if ($#posts > $max) {
$num += 1;
print "1Older Posts\t$base_dir/$name?archive$num\t$server\t$port\r\n";
}
show files containing a specific tag
elsif ($query =~ /^tag=(\w+)/) {
my $tag = $query;
my @tag_files;
$tag =~ s/^tag=//;
$tag =~ s/_/ /g;
foreach my $file (@posts) {
open (FH, "< $dir/$file") || print "3Couldn't look for tags in $file! $!…
while (<FH>) {
if (!/^#tags/i) {
next;
} elsif ($. > 2) {
last;
} elsif (/\b$tag/i) {
push (@tag_files, $file);
last;
}
}
close (FH);
}
&print_page (@tag_files);
get comments
elsif (($query =~ /^\w+\.post\s[\w[:punct:]]+/) && (length($query) < 950)) {
my $comment = $query;
my @s_comment= (split (/ /,$comment));
my $post;
if ($s_comment[0] =~ /\w+\.post/) {
$post = $s_comment[0];
}
my $comfile = "$dir/$post.cmt";
my $tmp = "$comfile.tmp";
my $go_string = "\t$base_dir/$name?$post\t$server\t$port";
if (-e "$dir/$post") {
open(NEW, "> $tmp");
flock(NEW, LOCK_EX);
my $date = strftime ("%Y %B %d, %R", localtime((stat ($tmp))[9]));
print NEW "$date\n";
print NEW wrap ("", "", @s_comment[1..$#s_comment]), "\n";
print NEW "\n$cmt_div\n\n";
if (-e $comfile) {
open (OLD, "< $comfile");
flock (OLD, LOCK_EX);
while (my $line = <OLD>) {
print NEW $line;
}
close OLD;
}
close NEW;
rename ($tmp, $comfile) || die "Can't rename $comfile!";
chmod 0640, $comfile;
print "iYour comment has been posted.$txt_string\r\n";
print "1View your comment$go_string\r\n";
} else {
print "3Sorry, $post does not exist.\t$txt_string\r\n";
print "1Back to Main Page$com_string\r\n";
}
elsif (($query =~ /\w+\.post\s[\w[:punct:]]+/) && (length($query) > 950)) {
print "3Sorry, comment should be less than 950 characters.$txt_string\r\n";
print "1Back to Main Page$com_string\r\n";
print error page
elsif (($query !~ /\w+\.post\s[\w[:punct:]]/) && ($query !~ /archive\d/) && (l…
print "3Oh shoot, something's gone wrong.$txt_string\r\n";
print "1Back to Main Page$com_string\r\n";
rint $footer;
Here there be subroutines
print individual posts as well as header and div files
ub print_file {
my $file = "$dir/$_[0]";
if (-s $file) {
open (FH, "< $file") || print "3Can't Open $file! $! $txt_string\r\n";
if ($file =~ /txt$/) {
while (<FH>) {
chomp;
print "i$_$txt_string\r\n";
}
} else {
@tag_list = "";
while (<FH>) {
chomp;
if ($_ =~ s/^#tags\s+//i) {
@tag_list = split (/\s*,\s*/, $_);
} elsif ( $_ =~ /^[0-9ceghisIMT].+?\t/ ) {
print "$_\r\n";
} elsif ($_ =~ /^--more--$/) {
if ($query =~ /^\w+\.post$/) {
next;
} else {
print "i$more_text$txt_string\r\n";
last;
}
} else {
print "i$_$txt_string\r\n";
}
}
}
close (FH);
}
print pages of posts (main page and archive pages). Counts comments as well.
ub print_page {
my @print_list = @_;
&print_file ($header);
&print_file ($div);
foreach my $file (@print_list) {
my $cmt_count = 0;
my @p_name = split /\//, $file;
my $p = 0;
until ($p_name[$p] =~ /post$/) {
$p++;
}
my $go_string = "\t$base_dir/$name?$p_name[$p]\t$server\t$port";
my $date = strftime ("%Y %B %d, %R", localtime((stat ("$dir/$file"))[9])…
print "i$date$txt_string\r\n";
print "i$txt_string\r\n";
&print_file ($file);
if (-e "$dir/$file.cmt") {
open (FH, "< $dir/$file.cmt") || print "3Can't count comments for $f…
while (<FH>) {
chomp;
if ($_ =~ /$cmt_div/) {
$cmt_count += 1;
}
}
close (FH);
}
print "1$permalink_text($cmt_count)$go_string\r\n";
if ($tag_list[0]) {
&print_tags (@tag_list);
}
&print_file ($div);
}
print tag list
ub print_tags {
my @tags = @_;
print "i$cmt_div$txt_string\r\n";
print "iTags:$txt_string\r\n";
foreach my $tag (@tags) {
my $tag_link = $tag;
$tag_link =~ s/\s+/_/g;
print "1$tag\t$base_dir/$name?tag=$tag_link\t$server\t$port\r\n";
}