Gopher utilities #75
Aliases: Gopher utilities
17 verbs · 10 properties · 0 children
Verbs
| Verb | Spec | Flags | Definer | Lines |
|---|---|---|---|---|
get_now | this none this | rxd | #75 | 40 |
parse | this none this | rxd | #75 | 21 |
show_text | this none this | rxd | #75 | 31 |
type | this none this | rxd | #75 | 26 |
summary | this none this | rxd | #75 | 29 |
get | this none this | rxd | #75 | 33 |
clear_cache | this none this | rxd | #75 | 10 |
unparse | this none this | rxd | #75 | 7 |
interpret_error | this none this | rxd | #75 | 11 |
trusted | this none this | rxd | #75 | 2 |
_textp | this none this | rxd | #75 | 3 |
_mail_text | this none this | rxd | #75 | 14 |
init_for_core | this none this | rxd | #75 | 4 |
display_cache | this none none | rxd | #75 | 25 |
get_cache | this none this | rxd | #75 | 9 |
cache_entry | this none this | rxd | #75 | 8 |
help_msg | this none this | rxd | #75 | 1 |
Properties
| Property | Definer | Flags | Owner | Value |
|---|---|---|---|---|
cache_requests | #75 | r | #2 | {} |
cache_times | #75 | r | #2 | {} |
cache_values | #75 | r | #2 | {} |
limit | #75 | rc | #2 | 2000 |
cache_timeout | #75 | r | #2 | 900 |
key | #1 | c | #2 | 0 |
aliases | #1 | rc | #2 | {"Gopher utilities"} |
description | #1 | rc | #2 | list of 30{"An interface to Gopher internet services.", "Copyright (c) 1992,1993 Grump,JoeFeedback@LambdaMOO.", "", "This object contains just the raw verbs for getting data from gopher servers and parsing the results. Look at #50122 (Generic Gopher Slate) on LambdaMOO for one example of a user interface. ", "", ":get(site, port, selection)", " Get data from gopher server: returns a list of strings, or an error if it couldn't connect. Results are cached.", "", ":get_now(site, port, selection)", " Used by $gopher:get. Arguments are the same: this actually gets the ", " data without checking the cache. (Don't call this, since the", " caching is important to reduce lag.)", " ", ":show_text(who, start, end, site, port, selection)", " Requires wiz-perms to call.", " like who:notify_lines($gopher:get(..node..)[start..end])", "", ":clear_cache()", " Erase the gopher cache.", "", ":parse(string)", " Takes a directory line as returned by $gopher:get, and return a list", " {host, port, selector, label}", " host, port, and selector are what you send to :get.", " label is a string, where the first character is the type code.", "", ":type(char)", " returns the name of the gopher type indicated by the character, e.g.", " $gopher:type(\"I\") => \"image\"", ""} |
object_size | #1 | r | #36 | {14657, -1090650497} |
html | #1 | rc | #2 | <clear> |
Ancestry
Ancestors (nearest first): #1 Root Class
Children: none
Call graph
Source
get_now
Referenced by
- #75:get line 28:
this:get_now
Source
1"Usage: get_now(site, port, message)"; 2"Returns a list of strings, or an error if we couldn't connect."; 3{host, port, message, ?extra = {0}} = args; 4if (!this:trusted(caller_perms())) 5return E_PERM; 6elseif ((!match(host, $network.valid_host_regexp)) && (!match(host, "[0-9]+%.[0-9]+%.[0-9]+%.[0-9]+"))) 7"allow either welformed internet hosts or explicit IP addresses."; 8return E_INVARG; 9elseif ((port < 100) && (!(port in {70, 80, 81, 79}))) 10"disallow connections to low number ports; necessary?"; 11return E_INVARG; 12endif 13opentime = time(); 14con = $network:open(host, port); 15opentime = time() - opentime; 16if (typeof(con) == ERR) 17return con; 18endif 19notify(con, message); 20results = {}; 21count = this.limit; 22"perhaps this isn't necessary, but if a gopher source is slowly spewing things, perhaps we don't want to hang forever -- perhaps this should just fork a process to close the connection instead?"; 23now = time(); 24timeout = 30; 25end = "^%.$"; 26if (extra[1] == "2") 27end = "^[2-9]"; 28endif 29while ((((typeof(string = `read(con) ! ANY') == STR) && (!match(string, end))) && ((count = count - 1) > 0)) && ((now + timeout) > (now = time()))) 30if (string && (string[1] == ".")) 31string = string[2..$]; 32endif 33results = {@results, string}; 34endwhile 35$network:close(con); 36if (opentime > 0) 37"This is to keep repeated calls to $network:open to 'slow responding hosts' from totally spamming."; 38suspend(0); 39endif 40return results;
parse
Referenced by
- #75:summary line 3:
this:parse - #75:_mail_text line 9:
$gopher:parse
Source
1"parse gopher result line:"; 2"return {host, port, tag, label}"; 3"host/port/tag are what you send to the gopher server to get that line"; 4"label is <type>/human readable entry"; 5{string} = args; 6tab = index(string, " "); 7label = string[1..tab - 1]; 8string = string[tab + 1..$]; 9tab = index(string, " "); 10tag = string[1..tab - 1]; 11string = string[tab + 1..$]; 12tab = index(string, " "); 13host = string[1..tab - 1]; 14if (host[$] == ".") 15host = host[1..$ - 1]; 16endif 17string = string[tab + 1..$]; 18tab = index(string, " "); 19port = toint(tab ? string[1..tab - 1] | string); 20return {host, port, tag, label}; 21"ignore extra material after port, if any";
show_text
Referenced by
none
Source
1"$gopher:show_text(who, start, end, ..node..)"; 2"like who:notify_lines($gopher:get(..node..)[start..end]), but pipelined"; 3if (!caller_perms().wizard) 4return E_PERM; 5endif 6{who, start, end, @args} = args; 7con = $network:open(who, start); 8if (typeof(con) == ERR) 9player:tell("Sorry, can't get this information now."); 10return; 11endif 12notify(con, end); 13line = 0; 14sent = 0; 15end = end || this.limit; 16while (((string = `read(con) ! ANY') != ".") && (typeof(string) == STR)) 17line = line + 1; 18if ((line >= start) && ((!end) || (line <= end))) 19sent = sent + 1; 20if (valid(who)) 21if (string && (string[1] == ".")) 22string = string[2..$]; 23endif 24who:notify(string); 25else 26notify(who, string); 27endif 28endif 29endwhile 30$network:close(con); 31return sent;
type
Referenced by
- #75:summary line 11:
$gopher:type
Source
1type = args[1]; 2if (type == "1") 3return "menu"; 4elseif (type == "?") 5return "menu?"; 6elseif (type == "0") 7return "text"; 8elseif (type == "7") 9return "search"; 10elseif (type == "9") 11return "binary"; 12elseif (type == "2") 13return "phone directory"; 14elseif (type == "4") 15return "binhex"; 16elseif (type == "8") 17return "telnet"; 18elseif (type == "I") 19return "image"; 20elseif (type == " ") 21"not actually gopher protocol: used by 'goto'"; 22return ""; 23else 24return "unknown"; 25endif 26"not done, need to fill out";
summary
Referenced by
none
Source
1"return a 'nice' string showing the information in a gopher node"; 2if (typeof(parse = args[1]) == STR) 3parse = this:parse(parse); 4endif 5if (parse[1] == "!") 6return {"[remembered set]", "", ""}; 7endif 8if (length(parse) > 3) 9label = parse[4]; 10if (label) 11type = $gopher:type(label[1]); 12label = label[2..$]; 13if (type == "menu") 14elseif (type == "search") 15label = (("<" + parse[3][rindex(parse[3], " ") + 1..$]) + "> ") + label; 16else 17label = (type + ": ") + label; 18endif 19else 20label = "(top)"; 21endif 22else 23label = parse[3] + " (top)"; 24endif 25port = ""; 26if (parse[2] != 70) 27port = tostr(" ", parse[2]); 28endif 29return {tostr("[", parse[1], port, "]"), label, parse[3]};
get
Referenced by
- #75:_mail_text line 5:
$gopher:get - #75:_mail_text line 8:
$gopher:get - #88:check_dictionary line 5:
$gopher:get
Source
1"Usage: get(site, port, selection)"; 2"returns a list of strings, or an error if it couldn't connect. Results are cached."; 3request = args[1..3]; 4while ((index = request in this.cache_requests) && (this.cache_times[index] > time())) 5if (typeof(result = this.cache_values[index]) != INT) 6return result; 7endif 8if ($code_utils:task_valid(result)) 9"spin, let other process getting same data win, or timeout"; 10suspend(1); 11else 12"well, other process crashed, or terminated, or whatever."; 13this.cache_times[index] = 0; 14endif 15endwhile 16if (!this:trusted(caller_perms())) 17return E_PERM; 18endif 19while (this.cache_times && (this.cache_times[1] < time())) 20((ticks_left() < 4000) || (seconds_left() < 2)) && suspend(0); 21this.cache_times = listdelete(this.cache_times, 1); 22this.cache_values = listdelete(this.cache_values, 1); 23this.cache_requests = listdelete(this.cache_requests, 1); 24"caution: don't want to suspend between test and removal"; 25endwhile 26((ticks_left() < 4000) || (seconds_left() < 2)) && suspend(0); 27this:cache_entry(@request); 28value = this:get_now(@args); 29((ticks_left() < 4000) || (seconds_left() < 2)) && suspend(0); 30index = this:cache_entry(@request); 31this.cache_times[index] = time() + ((typeof(value) == ERR) ? 120 | 1800); 32this.cache_values[index] = value; 33return value;
clear_cache
Referenced by
- #75:init_for_core line 2:
this:clear_cache
Source
1if (!this:trusted(caller_perms())) 2return E_PERM; 3endif 4if (!args) 5this.cache_values = this.cache_times = this.cache_requests = {}; 6elseif (index = args[1..3] in this.cache_requests) 7this.cache_requests = listdelete(this.cache_requests, index); 8this.cache_times = listdelete(this.cache_times, index); 9this.cache_values = listdelete(this.cache_values, index); 10endif
unparse
Referenced by
none
Source
1"unparse(host, port, tag, label) => string"; 2{host, port, tag, label} = args; 3if (tab = index(tag, " ")) 4"remove search terms from search nodes"; 5tag = tag[1..tab - 1]; 6endif 7return tostr(label, " ", tag, " ", host, " ", port);
interpret_error
Referenced by
none
Source
1"return an explanation for a 'false' $gopher:get result"; 2value = args[1]; 3if (value == E_INVARG) 4return "That gopher server is not reachable or is not responding."; 5elseif (value == E_QUOTA) 6return "Gopher connections cannot be made at this time because of system resource limitations!"; 7elseif (typeof(value) == ERR) 8return tostr("The gopher request results in an error: ", value); 9else 10return "The gopher request has no results."; 11endif
trusted
Referenced by
- #75:get_now line 4:
this:trusted - #75:get line 16:
this:trusted - #75:clear_cache line 1:
this:trusted
Source
1"default -- gopher trusts everybody"; 2return 1;
_textp
Referenced by
- #75:_mail_text line 4:
this:_textp
Source
1"_textp(parsed node)"; 2"Return true iff the parsed info points to a text node."; 3return index("02", args[1][4][1]);
_mail_text
Referenced by
none
Source
1"_mail_text(parsed node)"; 2"Return the text to be mailed out for the given node."; 3where = args[1]; 4if (this:_textp(where)) 5return $gopher:get(@where); 6else 7text = {}; 8for x in ($gopher:get(@where)) 9parse = $gopher:parse(x); 10sel = parse[4]; 11text = {@text, "Type=" + sel[1], "Name=" + sel[2..$], "Path=" + parse[3], "Host=" + parse[1], "Port=" + tostr(parse[2]), "#"}; 12endfor 13return text; 14endif
init_for_core
Referenced by
none
Source
1if (caller_perms().wizard) 2this:clear_cache(); 3pass(@args); 4endif
display_cache
Referenced by
none
Source
1"Just for debugging -- shows what's in the gopher cache"; 2req = this.cache_requests; 3tim = this.cache_times; 4val = this.cache_values; 5"save values in case cache changes while printing"; 6player:tell("size -- expires -- host (port) ------ selector ------------"); 7for i in [1..length(req)] 8re = req[i]; 9host = $string_utils:left(re[1] + ((re[2] == 70) ? "" | tostr(" (", re[2], ")")), 24); 10expires = $string_utils:right($time_utils:dhms(tim[i] - time()), 8); 11va = val[i]; 12if (typeof(va) == LIST) 13va = length(va); 14elseif (typeof(va) == ERR) 15va = toliteral(va); 16else 17va = tostr(va); 18endif 19selector = re[3]; 20if (length(selector) > 40) 21selector = "..." + selector[$ - 37..$]; 22endif 23player:tell($string_utils:right(va, 8), expires, " ", host, selector); 24endfor 25player:tell("--- end cache display -------------------------------------");
get_cache
Referenced by
none
Source
1"Usage: get_cache(site, port, selection)"; 2"return current cache"; 3request = args[1..3]; 4if (index = request in this.cache_requests) 5if (this.cache_times[index] > now) 6return this.cache_values[index]; 7endif 8endif 9return 0;
cache_entry
Referenced by
Source
1if (index = args in this.cache_requests) 2return index; 3else 4this.cache_times = {@this.cache_times, time() + 240}; 5this.cache_values = {@this.cache_values, task_id()}; 6this.cache_requests = {@this.cache_requests, args}; 7return length(this.cache_requests); 8endif
help_msg
Referenced by
none
Source
1return this:description();