Network Utilities #72

Parent #1Owner #2Flags readSource RPG Core/rpgcore-patched.db

Aliases: Network Utilities

25 verbs · 27 properties · 0 children

Verbs

VerbSpecFlagsDefinerLines
parse_addressthis none thisrxd#726
local_domainthis none thisrxd#7228
openthis none thisrxd#7224
closethis none thisrxd#7212
sendmailany none nonerxd#7217
trustthis none thisrxd#721
init_for_corethis none thisrxd#7217
raw_sendmailany none nonerxd#7269
invalid_email_addressthis none thisrxd#7220
invalid_hostnamethis none thisrxd#721
email_will_failthis none thisrxd#7229
readthis none thisrxd#7210
is_openthis none thisrxd#724
incoming_connectionthis none thisrxd#7217
return_address_forthis none thisrxd#727
server_startedthis none thisrxd#725
is_outgoing_connectionthis none thisrxd#721
notifythis none thisrxd#729
suspend_if_neededthis none thisrxd#725
errorthis none thisrxd#7211
help_msgthis none thisrxd#722
adjust_postmaster_for_passwordthis none thisrxd#7210
add_queued_mailthis none thisrxd#7214
send_queued_mailthis none thisrxd#7211
tcp_waitthis none thisrxd#7218

Properties

PropertyDefinerFlagsOwnerValue
site#72r#2"yoursite"
large_domains#72r#2{}
connect_connections_to#72#2{}
postmaster#72rc#2"postmastername@yourhost"
port#72rc#27777
MOO_name#72rc#2"YourMOO"
valid_host_regexp#72rc#2"^%([-_a-z0-9]+%.%)+%(gov%|edu%|com%|org%|int%|mil%|net%|%nato%|arpa%|[a-z][a-z]%)$"
maildrop#72rc#2"localhost"
trusts#72r#2{#36}
reply_address#72rc#2"moomailreplyto@yourhost"
active#72rc#20
valid_email_regexp#72rc#2"^[-a-z0-9_!.%+$'=/]*[-a-z0-9_!%+$'=]$"
invalid_userids#72rc#2{"", "sysadmin", "root", "postmaster", "system", "operator", "bin"}
debugging#72rc#20
errors_to_address#72rc#2"moomailerrors@yourhost"
suspicious_userids#72rc#2
list of 12{"", "sysadmin", "root", "postmaster", "bin", "SYSTEM", "OPERATOR", "guest", "me", "mailer-daemon", "webmaster", "sysop"}
usual_postmaster#72rc#2"postmastername@yourhost"
password_postmaster#72rc#2"postmastername@yourhost"
queued_mail#72#36
list of 1{{-1165412055, {"grhager@zubi.com", "Date: Thu Mar 4 16:54:01 1999 ", "From: 2@beel.wskcc.com (Wizard)", "To: grhager@zubi.com", "Subject: Your nefandous character, Titus_Crowe", "Errors-to: moomailerrors@yourhost", "X-Mail-Agent: nefandous (beel.wskcc.com 5050)", "Reply-to: ", "From Wizard@nefandous:", "A character has been created, with name \"Titus_Crowe\" and password \"veNyz\".", "Passwords are case sensitive, which means you have to type it exactly as", "it appears here, including capital and lowercase letters.", "So, to log in, you would type:", " Connect Titus_Crowe veNyz"}}}
queued_mail_task#72r#3668853779
envelope_from#72rc#2"postmastername@yourhost"
blank_envelope#72rc#20
key#1c#20
aliases#1rc#2{"Network Utilities"}
description#1rc#2
list of 74{"Utilities for dealing with network connections", "---------------", "Creating & tracking hosts:", "", ":open(host, port [, connect-connection-to]) => connection", " open a network connection (using open_network_connection).", " If 'connect-connection-to' is a player object, the", " connection will be connected to that object when it", " gets the first line of input.", "", ":close(connection)", " closes the connection & cleans up data", "", "------------------", "Parsing network things:", "", ":invalid_email_address(email)", " return \"\" or string saying why 'email' is invalid.", " uses .valid_email_regexp", "", ":invalid_hostname(host)", " return \"\" or string saying why 'host' doesn't look", " like a valid internet host name", "", ":local_domain(host)", " returns the 'important' part of a host name, e.g.", " golden.parc.xerox.com => parc.xerox.com", "", "-------------------", "Sending mail", "", ":sendmail(to, subject, @lines)", " send mail to the email address 'to' with indicated subject.", " header fields like 'from', 'date', etc. are filled in.", " lines can start with additional header lines.", "", ":raw_sendmail(to, @lines)", " used by :sendmail. Send mail to given user at host, just", " as specified, no error checking.", "", "================================================================", "Parameters:", "", ".active If 0, disabled sending of mail.", "", ".site Where does this MOO run?", " (Maybe MOOnet will use it later).", "", ".port The network port this MOO listens on.", "", ".large_domains ", " A list of sites where more than 2 levels of host name are", " significant, e.g., if you want 'parc.xerox.com' to be", " different than 'cinops.xerox.com', put \"xerox.com\" as an", " element in .large_domains.", "", ".postmaster", " Email address to which problems with MOO mail should", " go. This should be a real email address that someone reads.", "", ".maildrop", " Hostname to connect to for dropping off mail. Usually can", " just be \"localhost\".", "", ".reply_address", " If a MOO character sends email, where does a reply go?", " Inserted in 'From:' for mail from characters without", " registration addresses. ", "", ".trusts", " List of (non-wizard) programmers who can call", " :open, :sendmail, :close", "", " "}
object_size#1r#36{26956, -1090650497}
html#1rc#2<clear>

Ancestry

Ancestors (nearest first): #1 Root Class

Children: none

Call graph

calls n72_2 #72:open n72_5 #72:trust n72_2->n72_5 n42_0 #42:controls n72_2->n42_0 n72_3 #72:close n72_3->n72_5 n55_18 #55:iassoc n72_3->n55_18 n72_4 #72:sendmail n72_4->n72_5 n72_8 #72:invalid_email_address n72_4->n72_8 n72_7 #72:raw_sendmail n72_4->n72_7 n72_14 #72:return_address_for n72_4->n72_14 n72_7->n72_2 n72_7->n72_3 n72_18 #72:suspend_if_needed n72_7->n72_18 n72_24 #72:tcp_wait n72_7->n72_24 n72_6 #72:init_for_core n1_28 #1:init_for_core n72_6->n1_28 n56_7 #56:running_out_of_time n72_18->n56_7 n56_8 #56:suspend_if_needed n72_18->n56_8 n72_10 #72:email_will_fail n72_10->n72_8 n6_18 #6:tell n72_10->n6_18 n72_0 #72:parse_address n72_10->n72_0 n72_11 #72:read n72_11->n72_5 n72_13 #72:incoming_connection n55_17 #55:assoc n72_13->n55_17 n72_17 #72:notify n72_17->n72_5 n72_16 #72:is_outgoing_connection n72_17->n72_16 n72_20 #72:help_msg n1_9 #1:description n72_20->n1_9 n72_22 #72:add_queued_mail n59_37 #59:task_valid n72_22->n59_37 n72_23 #72:send_queued_mail n72_22->n72_23 n72_23->n72_7

Source

parse_address

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"Given an email address, return {userid, site}.";
2"Valid addresses are of the form `userid[@site]'.";
3"At least for now, if [@site] is left out, site will be returned as blank.";
4"Should be a default address site, or something, somewhere.";
5address = args[1];
6return (at = index(address, "@")) ? {address[1..at - 1], address[at + 1..$]} | {address, ""};

local_domain

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"given a site, try to figure out what the `local' domain is.";
2"if site has a @ or a % in it, give up and return E_INVARG.";
3"blank site is returned as is; try this:local_domain(this.localhost) for the answer you probably want.";
4site = args[1];
5if (index(site, "@") || index(site, "%"))
6return E_INVARG;
7elseif (match(site, "^[0-9.]+$"))
8return E_INVARG;
9elseif (!site)
10return "";
11elseif (!(dot = rindex(site, ".")))
12dot = rindex(site = this.site, ".");
13endif
14if ((!dot) || (!(dot = rindex(site[1..dot - 1], "."))))
15return site;
16else
17domain = site[dot + 1..$];
18site = site[1..dot - 1];
19while (site && (domain in this.large_domains))
20if (dot = rindex(site, "."))
21domain = tostr(site[dot + 1..$], ".", domain);
22site = site[1..dot - 1];
23else
24return tostr(site, ".", domain);
25endif
26endwhile
27return domain;
28endif

open

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1":open(address, port, [connect-connection-to])";
2"Open a network connection to address/port.  If the connect-connection-to is passed, then the connection will be connected to that object when $login gets ahold of it.  If not, then the connection is just ignored by $login, i.e. not bothered by it with $welcome_message etc.";
3"The object specified by connect-connection-to has to be a player (though it need not be a $player).";
4"Returns the (initial) connection or an error, as in open_network_connection";
5if (!this:trust(caller_perms()))
6return E_PERM;
7endif
8address = args[1];
9port = args[2];
10if (length(args) < 3)
11connect_to = $nothing;
12elseif ((typeof(connect_to = args[3]) == OBJ) && (valid(connect_to) && is_player(connect_to)))
13if (!$perm_utils:controls(caller_perms(), connect_to))
14return E_PERM;
15endif
16else
17return E_INVARG;
18endif
19if (typeof(connection = `open_network_connection(address, port) ! ANY') != ERR)
20if (valid(connect_to))
21this.connect_connections_to = {@this.connect_connections_to, {connection, connect_to}};
22endif
23endif
24return connection;

close

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1if (!this:trust(caller_perms()))
2return E_PERM;
3endif
4con = args[1];
5if (!index(`connection_name(con) ! ANY => ""', " to "))
6return E_INVARG;
7endif
8boot_player(con);
9if (i = $list_utils:iassoc(con, $network.connect_connections_to))
10$network.connect_connections_to = listdelete($network.connect_connections_to, i);
11endif
12return 1;

sendmail

Spec any none noneFlags rxdOwner #2Definer #72

Referenced by

Source

1"sendmail(to, subject, line1, line2, ...)";
2"  sends mail to internet address 'to', with given subject.";
3"  It fills in various fields, such as date, from (from player), etc.";
4"  the rest of the arguments are remaining lines of the message, and may begin with additional header fields.";
5"  (must match RFC822 specification).";
6"Requires $network.trust to call (no anonymous mail from MOO).";
7"Returns 0 if successful, or else error condition or string saying why not.";
8if (!this:trust(caller_perms()))
9return E_PERM;
10endif
11mooname = this.MOO_name;
12mooinfo = tostr(mooname, " (", this.site, " ", this.port, ")");
13if (reason = this:invalid_email_address(to = args[1]))
14return reason;
15endif
16"took out Envelope-from:  + this.errors_to_address";
17return this:raw_sendmail(to, "Date: " + ctime(), "From: " + this:return_address_for(player), "To: " + to, "Subject: " + args[2], "Errors-to: " + this.errors_to_address, "X-Mail-Agent: " + mooinfo, @args[3..$]);

trust

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1return (who = args[1]).wizard || (who in this.trusts);

init_for_core

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

none

Source

1if (caller_perms().wizard)
2pass(@args);
3this.active = 0;
4this.errors_to_address = "moomailerrors@yourhost";
5this.site = "yoursite";
6this.postmaster = "postmastername@yourhost";
7this.usual_postmaster = "postmastername@yourhost";
8this.password_postmaster = "postmastername@yourhost";
9this.envelope_from = "postmastername@yourhost";
10this.blank_envelope = 0;
11this.MOO_name = "YourMOO";
12this.maildrop = "localhost";
13this.port = 7777;
14this.large_domains = {};
15this.trusts = {$hacker};
16this.connect_connections_to = {};
17endif

raw_sendmail

Spec any none noneFlags rxdOwner #2Definer #72

Referenced by

Source

1"Copied from sendmail fix (#88079):raw_sendmail by Lineman (#108318) Mon Feb  1 19:29:43 1999 PST";
2"rawsendmail(to, @lines)";
3"sends mail without processing. Returns 0 if successful, or else reason why not.";
4if (!caller_perms().wizard)
5return E_PERM;
6endif
7if (!this.active)
8return "Networking is disabled.";
9endif
10if (typeof(this.debugging) == LIST)
11"who to notify";
12debugging = this.debugging;
13else
14"notify this owner";
15debugging = this.debugging && {this.owner};
16endif
17address = args[1];
18body = listdelete(args, 1);
19data = {"HELO " + this.site, ("MAIL FROM:<" + this.postmaster) + ">", ("RCPT TO:<" + address) + ">", "DATA"};
20blank = 0;
21for x in (body)
22this:suspend_if_needed(0);
23if (!(blank || match(x, "[a-z0-9-]*: ")))
24if (x)
25data = {@data, ""};
26endif
27blank = 1;
28endif
29data = {@data, (x && (x[1] == ".")) ? "." + x | x};
30endfor
31data = {@data, ".", "QUIT", ""};
32suspend(0);
33target = $network:open(this.maildrop, 25);
34if (typeof(target) == ERR)
35return tostr("Cannot open connection to maildrop ", this.maildrop, ": ", target);
36endif
37set_connection_option(target, "hold-input", 1);
38blast = 0;
39msg = 0;
40expects = {"220", "250", "250", "250%|251", "354", "250", "221"};
41for line in (data)
42if (!blast)
43reply = this:tcp_wait(target);
44if (typeof(reply) == ERR)
45msg = "Connection dropped or timed out.";
46break;
47elseif (!match(reply[1..3], expects[1]))
48msg = (("Expected " + expects[1]) + " but got ") + reply;
49break;
50endif
51debugging && notify(debugging[1], "GET: " + reply);
52expects[1..1] = {};
53if (reply[1..3] == "221")
54"Service closing transmission channel";
55break;
56elseif (reply[1..3] == "354")
57"Start mail input; end with <CRLF>.<CRLF>";
58blast = 1;
59endif
60elseif (line == ".")
61blast = 0;
62endif
63debugging && notify(debugging[1], "SEND:" + line);
64notify(target, line);
65((ticks_left() < 4000) || (seconds_left() < 2)) && suspend(0);
66endfor
67$network:close(target);
68debugging && notify(debugging[1], "EXIT:" + (msg || "Mail sent successfully."));
69return msg;

invalid_email_address

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"invalid_email_address(email) -- check to see if email looks like a valid email address. Return reason why not.";
2address = args[1];
3if (!address)
4return "no email address supplied";
5endif
6if (!(at = rindex(address, "@")))
7return ("'" + address) + "' doesn't look like a valid internet email address";
8endif
9name = address[1..at - 1];
10host = address[at + 1..$];
11if (match(name, "^in%%") || match(name, "^smtp%%"))
12return tostr("'", name, "' doesn't look like a valid username (try removing the 'in%' or 'smtp%')");
13endif
14if (!match(host, $network.valid_host_regexp))
15return tostr("'", host, "' doesn't look like a valid internet host");
16endif
17if (!match(name, $network.valid_email_regexp))
18return tostr("'", name, "' doesn't look like a valid user name for internet mail");
19endif
20return "";

invalid_hostname

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

none

Source

1return match(args[1], this.valid_host_regexp) ? "" | tostr("'", args[1], "' doesn't look like a valid internet host name");

email_will_fail

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1":email_will_fail(email-address[, display?]) => Makes sure the email-address is one that can actually be used by $network:sendmail().";
2{email, ?display = 0} = args;
3reason = this:invalid_email_address(email);
4if (reason && display)
5player:tell("Invalid email address: ", reason);
6endif
7return reason;
8"following is code from OpalMOO, not used here";
9"Possible situations where the address would be unusable are when the address is invalid or we can't connect to the site to send mail.";
10"If <display> is true, error messages are displayed to the player and 1 is returned when address is unuable.  If <display> is false and address is unusable, the error message is returned.  If the address is usable, 0 is always returned.";
11if (!this:approved_for_network(caller_perms()))
12return E_PERM;
13endif
14if (!this:valid_email_address(email))
15msg = tostr("Your email address (", email, ") is not a usable account.");
16elseif ((result = this:verify_email_address(email)) == E_INVARG)
17msg = tostr("Unable to connect to ", this:parse_address(email)[2], ".");
18elseif (typeof(result) == STR)
19msg = tostr("The site ", (parse = this:parse_address(email))[2], " does not recognize ", parse[1], " as a valid account.");
20else
21return 0;
22endif
23if (display)
24player:tell(msg);
25return 1;
26else
27return msg;
28endif
29"Last modified Tue Jun 15 00:19:01 1993 EDT by Ranma (#200).";

read

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"for trusted players, they can read from objects they own or open connections";
2if (!this:trust(caller_perms()))
3return E_PERM;
4elseif (valid(x = args[1]))
5if ((x.owner == x) || (x.owner != caller_perms()))
6return E_INVARG;
7endif
8"elseif (!this:is_outgoing_connection(x) return E_PERM";
9endif
10return `read(@args) ! ANY';

is_open

Spec this none thisFlags rxdOwner #36Definer #72

Referenced by

Source

1":is_open(object)";
2"return true if the object is somehow connected, false otherwise.";
3return typeof(`idle_seconds(@args) ! ANY') == INT;
4"Relies on test in idle_seconds, and the error catching";

incoming_connection

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"Peer at an incoming connection.  Decide if it should be connected to something, return that object. If it should be ignored (outbound connection), return 1. Called only by #0:do_login_command";
2if (caller != #0)
3return;
4endif
5what = args[1];
6"this code for unix servers >= 1.7.5 only";
7if (index(`connection_name(what) ! ANY => ""', " to "))
8"outbound connection";
9if (ct = $list_utils:assoc(what, this.connect_connections_to))
10this.connect_connections_to = setremove(this.connect_connections_to, ct);
11return ct[2];
12else
13return 1;
14endif
15else
16return 0;
17endif

return_address_for

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1":return_address_for(player) => string of 'return address'. Currently inbound mail doesn't work, so this is a bogus address.";
2who = args[1];
3if (valid(who) && is_player(who))
4return tostr(toint(who), "@", this.site, " (", who.name, ")");
5else
6return tostr($login.registration_address, " (non-player ", who, ")");
7endif

server_started

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"called when restarting to clean out state.";
2if (caller != #0)
3return E_PERM;
4endif
5this.connect_connections_to = {};

is_outgoing_connection

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1return index(`connection_name(args[1]) ! ANY => ""', " to ");

notify

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"for trusted players, they can write to connections";
2if (!this:trust(caller_perms()))
3return E_PERM;
4elseif (valid(x = args[1]))
5return E_INVARG;
6elseif (!this:is_outgoing_connection(x))
7return E_PERM;
8endif
9return notify(x, args[2]);

suspend_if_needed

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"$command_utils:suspend_if_needed but chowned to player";
2if ($command_utils:running_out_of_time())
3set_task_perms(caller_perms().wizard ? player | caller_perms());
4return $command_utils:suspend_if_needed(@args);
5endif

error

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

none

Source

1":error(ERN, host, port) interpret open_network_connection(host, port) error";
2{msg, host, port} = args;
3if (msg == E_PERM)
4return "Networking not enabled in server, or else user doesn't have permission to call o_n_c();";
5elseif (msg == E_INVARG)
6return tostr("The host/port ", toliteral(host), "/", toliteral(port), " is invalid or is not responding.");
7elseif (msg == E_QUOTA)
8return tostr("The connection to ", toliteral(host), "/", toliteral(port), " cannot be made at this time.");
9else
10return tostr("Unusual error: ", toliteral(msg));
11endif

help_msg

Spec this none thisFlags rxdOwner #36Definer #72

Referenced by

none

Source

1"'cause this doesn't have a $_utils name";
2return this:description();

adjust_postmaster_for_password

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"adjust_postmaster_for_password(enter_or_exit): permits the MOO to have two different postmasters for different kinds of bounces.  If entering password (argument \"enter\"), change to $network.password_postmaster, else (argument \"exit\") change to $network.usual_postmaster.";
2if (args[1] == "enter")
3$network.postmaster = $network.password_postmaster;
4$network.errors_to_address = $network.password_postmaster;
5$network.envelope_from = $network.password_postmaster;
6else
7$network.postmaster = $network.usual_postmaster;
8$network.errors_to_address = $network.usual_postmaster;
9$network.envelope_from = $network.blank_envelope ? "" | $network.usual_postmaster;
10endif

add_queued_mail

Spec this none thisFlags rxdOwner #36Definer #72

Referenced by

none

Source

1"$network:add_queued_mail( mail message )";
2"  -- where `mail message' is in the same format as passed to :raw_sendmail";
3if (caller == this)
4this.queued_mail = {@this.queued_mail, {time(), args}};
5if (!$code_utils:task_valid(this.queued_mail_task))
6fork fid (3600)
7this:send_queued_mail();
8endfork
9this.queued_mail_task = fid;
10endif
11return 1;
12else
13return E_PERM;
14endif

send_queued_mail

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"$network:send_queued_mail()";
2"  -- tries to send the mail stored in the .queued_mail property";
3while (queued_mail = this.queued_mail)
4message = queued_mail[1];
5if (!this:raw_sendmail(@message[2]))
6this.queued_mail = setremove(this.queued_mail, message);
7else
8"wait an hour";
9suspend(3600);
10endif
11endwhile

tcp_wait

Spec this none thisFlags rxdOwner #2Definer #72

Referenced by

Source

1"Copied from sendmail fix (#88079):tcp_wait by Lineman (#108318) Mon Feb  1 19:28:18 1999 PST";
2{conn, ?timeout = 0} = args;
3if (!caller_perms().wizard)
4return E_PERM;
5elseif (timeout)
6fork task (timeout)
7boot_player(conn);
8endfork
9endif
10while (1)
11if (typeof(line = `read(conn) ! ANY') == ERR)
12break;
13elseif (match(line, "^[0-9][0-9][0-9] "))
14timeout && `kill_task(task) ! ANY';
15break;
16endif
17endwhile
18return line;