URI: 
       umnlisting.dcgi - geomyidae - A small C-based gopherd.
  HTML git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
       umnlisting.dcgi (5552B)
       ---
            1 #!/usr/bin/env python
            2 # coding=utf-8
            3 #
            4 # Dir listing like in UMN gopher.
            5 #
            6 # Files: .abstract, .names, .cap/$file, .Links
            7 # Entries: Name=, Type=, Path=, Host=, Port=, Abstract=, Admin=, URL=,
            8 #          TTL=
            9 #
           10 
           11 import os
           12 import sys
           13 
           14 def dcgifilterprint(lines):
           15         for line in lines:
           16                 line = line.strip()
           17                 if line[0] == 't':
           18                         print("t%s" % (line))
           19                 else:
           20                         print("%s" % (line))
           21 
           22 def parselinksfile(filepath, link={}):
           23         fd = open(filepath, "r")
           24         links = {}
           25         while 1:
           26                 line = fd.readline()
           27                 if not line:
           28                         if "path" in link:
           29                                 links[link["path"]] = link
           30                                 link = {}
           31                         break
           32                 line = line.strip()
           33                 if len(line) == 0 or line.startswith("#"):
           34                         if "path" in link:
           35                                 links[link["path"]] = link
           36                                 link = {}
           37                         continue
           38                 elif line.startswith("Type="):
           39                         link["type"] = line.split("=", 1)[1]
           40                 elif line.startswith("Name="):
           41                         link["name"] = line.split("=", 1)[1]
           42                 elif line.startswith("Path="):
           43                         link["path"] = line.split("=", 1)[1]
           44                 elif line.startswith("Host="):
           45                         link["host"] = line.split("=", 1)[1]
           46                 elif line.startswith("Port="):
           47                         link["port"] = line.split("=", 1)[1]
           48                 elif line.startswith("Numb="):
           49                         try:
           50                                 link["number"] = int(line.split("=", 1)[1])
           51                         except ValueError:
           52                                 pass
           53                 elif line.startswith("Abstract="):
           54                         link["abstract"] = line.split("=", 1)[1]
           55                         while link["abstract"][-1] == "\\":
           56                                 link["abstract"] = link["abstract"][:-1]
           57                                 link["abstract"] += "\n"
           58                                 link["abstract"] += fd.readline().strip()
           59 
           60                         # Undefined case in UMN. Handle it nicely.
           61                         if link["abstract"][-1] == "\\":
           62                                 link["abstract"][-1] = "\n"
           63                 elif line.startswith("Admin="):
           64                         link["admin"] = line.split("=", 1)[1]
           65                 elif line.startswith("URL="):
           66                         link["url"] = line.split("=", 1)[1]
           67                 elif line.startswith("TTL="):
           68                         link["ttl"] = line.split("=", 1)[1]
           69         fd.close()
           70 
           71         return links
           72 
           73 def usage(app):
           74         print("usage: %s search arguments host port" % (app),
           75                         file=sys.stderr)
           76         sys.exit(1)
           77 
           78 def main(args):
           79         scriptname = os.path.basename(args[0])
           80         if len(args) < 5:
           81                 usage(scriptname)
           82         search = args[1]
           83         arguments = args[2]
           84         host = args[3]
           85         port = args[4]
           86 
           87         basedir = "."
           88         if len(arguments) > 0 and arguments[0] == "/":
           89                 basedir = arguments[0].split("?")[0]
           90 
           91         # First print every .abstract file content.
           92         abstractpath = "%s/.abstract" % (basedir)
           93         if os.path.exists(abstractpath):
           94                 fd = open(abstractpath, "r")
           95                 dcgifilterprint(fd.readlines())
           96                 fd.close()
           97 
           98         outputlinks = {}
           99         numblinks = {}
          100 
          101         linkspath = "%s/.Links" % (basedir)
          102         if os.path.exists(linkspath):
          103                 linkslinks = parselinksfile(linkspath)
          104                 for linkkey in linkslinks.keys():
          105                         outputlinks[linkkey]  = linkslinks[linkkey]
          106                         if "number" in linkslinks[linkkey]:
          107                                 numblinks[linkkey] = linkslinks[linkkey]
          108 
          109         entries = os.listdir(basedir)
          110         for entry in entries:
          111                 entrylink = {}
          112                 entrylink["type"] = "9"
          113                 if os.path.isdir(entry):
          114                         entrylink["type"] = "1"
          115 
          116                 entrylink["path"] = "./%s" % (entry)
          117                 entrylink["name"] = entry
          118                 capspath = "%s/.cap/%s" % (basedir, entry)
          119                 if os.path.exists(capspath):
          120                         caplink = parselinksfile(capspath, entrylink)
          121                 outputlinks[entrylink["path"]] = entrylink
          122                 if "number" in entrylink:
          123                         numblinks[entrylink["path"]] = entrylink
          124 
          125         namespath = "%s/.names" % (basedir)
          126         if os.path.exists(namespath):
          127                 nameslinks = parselinksfile(namespath)
          128                 for namekey in nameslinks.keys():
          129                         namelink = nameslinks[namekey]
          130                         if namekey in outputlinks.keys():
          131                                 for key in namelink:
          132                                         outputlinks[namekey][key] = \
          133                                                 namelink[key]
          134                         else:
          135                                 outputlinks[namekey] = nameslinks[namekey]
          136                         if "number" in outputlinks[namekey]:
          137                                 numblinks[namekey] = outputlinks[namekey]
          138 
          139         displaylinks = {}
          140         for link in outputlinks.keys():
          141                 if "name" in outputlinks[link]:
          142                         displaylinks[outputlinks[link]["name"]] = link
          143                 elif "path" in outputlinks[link]:
          144                         if outputlinks[link]["path"].startswith("./"):
          145                                 displaylinks[outputlinks[link]["path"][2:]] = \
          146                                         link
          147                         else:
          148                                 displaylinks[outputlinks[link]["path"]] = \
          149                                         link
          150                 else:
          151                         displaylinks[link] = link
          152 
          153         displaykeys = sorted(displaylinks)
          154         for dotfile in [".Links", ".names", ".cap", ".abstract"]:
          155                 try:
          156                         displaykeys.remove(dotfile)
          157                 except ValueError:
          158                         pass
          159 
          160         # This is why the UMN format really sucks.
          161         numbers = {}
          162         for numb in numblinks.keys():
          163                 link = outputlinks[numb]
          164                 numbers[link["number"]] = outputlinks[numb]
          165                 if "name" in link:
          166                         displaykeys.remove(link["name"])
          167                 elif "path" in link:
          168                         if link["path"].startswith("./"):
          169                                 displaykeys.remove(link["path"][2:])
          170                         else:
          171                                 displaykeys.remove(link["path"])
          172 
          173         curnumber = 1
          174         while 1:
          175                 if curnumber in numbers.keys():
          176                         path = numbers[curnumber]["path"]
          177                         numbers.pop(curnumber)
          178                 else:
          179                         key = displaykeys.pop()
          180                         path = displaylinks[key]
          181 
          182                 # Work on the rest of the numbered links, when no display
          183                 # entries are left.
          184                 if len(displaykeys) == 0:
          185                         if len(numbers) == 0:
          186                                 break
          187                         randnumb = numbers.pop()
          188                         path = randnumb["path"]
          189 
          190                 link = outputlinks[path]
          191                 if "port" not in link:
          192                         link["port"] = "port"
          193                 if "host" not in link:
          194                         link["host"] = "server"
          195                 if "name" not in link:
          196                         if link["path"].startswith("./"):
          197                                 link["name"] = link["path"][2:]
          198                         else:
          199                                 link["name"] = link["path"]
          200                 if "type" not in link:
          201                         link["type"] = "9"
          202 
          203                 # dcgi escaping.
          204                 link["name"].replace("|", "\\|")
          205 
          206                 print("[%s|%s|%s|%s|%s]" % (link["type"][0],\
          207                         link["name"], link["path"], link["host"],\
          208                         link["port"]))
          209 
          210                 if "abstract" in link:
          211                         dcgifilterprint(link["abstract"].split("\n"))
          212 
          213                 curnumber += 1
          214 
          215         return 0
          216 
          217 if __name__ == "__main__":
          218         sys.exit(main(sys.argv))
          219