geomyidae

A small C-based gopherd. (gopher://bitreich.org/1/scm/geomyidae)
git clone git://r-36.net/geomyidae
Log | Files | Refs | README | LICENSE

commit a541c4f4710d4e11847d082a623e11ab8fca6c31
parent 27c94c92d5fdf7294ee1905c381d0ce2f4ccebca
Author: Christoph Lohmann <20h@r-36.net>
Date:   Sun,  3 Apr 2022 12:22:57 +0200

Add UMN .Links etc. directory parsing example.

Reduce dirlisting.dcgi to bare example.

Diffstat:
cgi-examples/dirlisting.dcgi | 22+---------------------
cgi-examples/umnlisting.dcgi | 181+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 182 insertions(+), 21 deletions(-)

diff --git a/cgi-examples/dirlisting.dcgi b/cgi-examples/dirlisting.dcgi @@ -2,11 +2,6 @@ # # Dir listing example. # -# Entry definition in .Links, .cap/$file or .names: -# Name=, Type=, Path=, Host=, Port=, Numb=, Abstract=, Admin=, URL=, TTL= -# - -[ -f .abstract ] && cat .abstract | sed 's/^t/&&/' find . -maxdepth 1 \ | sort -r \ @@ -14,26 +9,11 @@ find . -maxdepth 1 \ | grep -v "^\." \ | while read -r entry; do - [ "${entry}" == ".cap" ] && continue - [ "${entry}" == ".Links" ] && continue - [ "${entry}" == ".names" ] && continue - entrytype="9" [ -d "${entry}" ] && entrytype="1" - entryserver="server" - entryport="port" - entryname="%f" - if [ -f ".cap/$entry" ]; - then - entryname="$(cat ".cap/$entry" \ - | grep "^Name=" \ - | cut -d'=' -f 2-)" - fi - [ -z "${entryname}" ] && entryname="%f" - find "${entry}" \ -maxdepth 0 \ - -printf "[${entrytype}|%TY-%Tm-%Td ${entryname}|%f|${entryserver}|${entryport}]\r\n" + -printf "[${entrytype}|%TY-%Tm-%Td %f|%f|server|port]\r\n" done diff --git a/cgi-examples/umnlisting.dcgi b/cgi-examples/umnlisting.dcgi @@ -0,0 +1,181 @@ +#!/usr/bin/env python +# coding=utf-8 +# +# Dir listing like in UMN gopher. +# +# Files: .abstract, .names, .cap/$file, .Links +# Entries: Name=, Type=, Path=, Host=, Port=, Abstract=, Admin=, URL=, +# TTL= +# + +import os +import sys + +def dcgifilterprint(lines): + for line in lines: + line = line.strip() + if line[0] == 't': + print("t%s" % (line)) + else: + print("%s" % (line)) + +def parselinksfile(filepath, link={}): + fd = open(filepath, "r") + links = {} + while 1: + line = fd.readline() + if not line: + if "path" in link: + links[link["path"]] = link + link = {} + break + line = line.strip() + if len(line) == 0 or line.startswith("#"): + if "path" in link: + links[link["path"]] = link + link = {} + continue + elif line.startswith("Type="): + link["type"] = line.split("=", 1)[1] + elif line.startswith("Name="): + link["name"] = line.split("=", 1)[1] + elif line.startswith("Path="): + link["path"] = line.split("=", 1)[1] + elif line.startswith("Host="): + link["host"] = line.split("=", 1)[1] + elif line.startswith("Port="): + link["port"] = line.split("=", 1)[1] + elif line.startswith("Numb="): + try: + link["number"] = int(line.split("=", 1)[1]) + except ValueError: + pass + elif line.startswith("Abstract="): + link["abstract"] = line.split("=", 1)[1] + while link["abstract"][-1] == "\\": + link["abstract"] = link["abstract"][:-1] + link["abstract"] += "\n" + link["abstract"] += fd.readline().strip() + + # Undefined case in UMN. Handle it nicely. + if link["abstract"][-1] == "\\": + link["abstract"][-1] = "\n" + elif line.startswith("Admin="): + link["admin"] = line.split("=", 1)[1] + elif line.startswith("URL="): + link["url"] = line.split("=", 1)[1] + elif line.startswith("TTL="): + link["ttl"] = line.split("=", 1)[1] + fd.close() + + return links + +def usage(app): + print("usage: %s search arguments host port" % (app), + file=sys.stderr) + sys.exit(1) + +def main(args): + scriptname = os.path.basename(args[0]) + if len(args) < 5: + usage(scriptname) + search = args[1] + arguments = args[2] + host = args[3] + port = args[4] + + basedir = "." + if len(arguments) > 0 and arguments[0] == "/": + basedir = arguments[0].split("?")[0] + + # First print every .abstract file content. + abstractpath = "%s/.abstract" % (basedir) + if os.path.exists(abstractpath): + fd = open(abstractpath, "r") + dcgifilterprint(fd.readlines()) + fd.close() + + outputlinks = {} + + linkspath = "%s/.Links" % (basedir) + if os.path.exists(linkspath): + linkslinks = parselinksfile(linkspath) + for linkkey in linkslinks.keys(): + outputlinks[linkkey] = linkslinks[linkkey] + + entries = os.listdir(basedir) + for entry in entries: + entrylink = {} + entrylink["type"] = "9" + if os.path.isdir(entry): + entrylink["type"] = "1" + + entrylink["path"] = "./%s" % (entry) + entrylink["name"] = entry + capspath = "%s/.cap/%s" % (basedir, entry) + if os.path.exists(capspath): + caplink = parselinksfile(capspath, entrylink) + outputlinks[entrylink["path"]] = entrylink + + namespath = "%s/.names" % (basedir) + if os.path.exists(namespath): + nameslinks = parselinksfile(namespath) + for namekey in nameslinks.keys(): + namelink = nameslinks[namekey] + if namekey in outputlinks.keys(): + for key in namelink: + outputlinks[namekey][key] = \ + namelink[key] + else: + outputlinks[namekey] = nameslinks[namekey] + displaylinks = {} + for link in outputlinks.keys(): + if "name" in outputlinks[link]: + displaylinks[outputlinks[link]["name"]] = link + elif "path" in outputlinks[link]: + if outputlinks[link]["path"].startswith("./"): + displaylinks[outputlinks[link]["path"][2:]] = \ + link + else: + displaylinks[outputlinks[link]["path"]] = \ + link + else: + displaylinks[link] = link + + displaykeys = sorted(displaylinks) + for key in displaykeys: + path = displaylinks[key] + if path == "./.Links" or \ + path == "./.cap" or \ + path == "./.names" or \ + path == "./.abstract": + continue + + link = outputlinks[path] + if "port" not in link: + link["port"] = "port" + if "host" not in link: + link["host"] = "server" + if "name" not in link: + if link["path"].startswith("./"): + link["name"] = link["path"][2:] + else: + link["name"] = link["path"] + if "type" not in link: + link["type"] = "9" + + # dcgi escaping. + link["name"].replace("|", "\\|") + + print("[%s|%s|%s|%s|%s]" % (link["type"][0],\ + link["name"], link["path"], link["host"],\ + link["port"])) + + if "abstract" in link: + dcgifilterprint(link["abstract"].split("\n")) + + return 0 + +if __name__ == "__main__": + sys.exit(main(sys.argv)) +