|
|
umnlisting.dcgi - geomyidae - A small C-based gopherd. |
|
|
 |
git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/geomyidae/ (git://bitreich.org) |
|
|
 |
Log |
|
|
 |
Files |
|
|
 |
Refs |
|
|
 |
Tags |
|
|
 |
README |
|
|
 |
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 |
|