@create $container named email handler:email handler,emh @prop emh."messages" {} "" @prop emh."conn" #-1 rc @prop emh."address" {} rc ;emh.("address") = {"localhost", 110} @prop emh."account" {} "" ;emh.("account") = {"userid", "password"} @prop emh."lines" {} "" ;emh.("lines") = {"+OK Pop server at bioinformatics signing off."} @prop emh."emailnote" #1206 rc @prop emh."on" 0 rc @prop emh."controllers" {} rc ;emh.("controllers") = {#2} @prop emh."task" -1 rc @prop emh."scheduler" #1116 rc ;emh.("aliases") = {"email handler", "emh"} ;emh.("description") = "A mailbox that receives email sent to a given email address, when active." ;emh.("unique") = 1 @verb emh:"check_mail" this none this rx @program emh:check_mail set_task_perms(caller_perms()); if (this:check_status()) return 1; endif conn = $network:open(@this.address); if (typeof(conn) == ERR) return 1; endif this.conn = conn; this:send("user " + this.account[1]); this:get(("+OK Password required for " + this.account[1]) + "."); this:send("pass " + this.account[2]); res = this:get("+OK " + this.account[1], "-ERR"); if (res[1] == 2) this:send("quit"); this.conn = #-1; return 1; endif delims = match(res[2], "has %([0-9]*%) message(s)")[3][1]; mssgs = tonum(res[2][delims[1]..delims[2]]); for msg in [1..mssgs] smsg = tostr(msg); message = {}; this:send("retr " + smsg); res = this:get(".", ("-ERR Message " + smsg) + " has been deleted.", ("-ERR Message " + smsg) + " does not exist."); if (res[1] in {0, 1}) fork (msg) this:newmessage(msg, res[2..length(res) - 1]); endfork else "handle non-existent message"; endif this:send("dele " + smsg); this:get(("+OK Message " + smsg) + " has been deleted.", ("-ERR Message " + smsg) + " has been deleted.", ("-ERR Message " + smsg) + " does not exist."); endfor this:send("quit"); $network:close(conn); this.conn = #-1; return mssgs; . @verb emh:"check_status" this none this rx @program emh:check_status return typeof(idle_seconds(this.conn)) != ERR; . @verb emh:"notify" this none this rx @program emh:notify return; . @verb emh:"send" this none this rx @program emh:send set_task_perms(caller_perms()); if (this:check_status()) notify(this.conn, tostr(args[1])); endif . @verb emh:"get" this none this rx @program emh:get set_task_perms(caller_perms()); lines = {}; while (this:check_status()) line = read(this.conn); if (typeof(line) == STR) lines = {@lines, line}; for pos in [1..length(args)] if (index(line, args[pos]) == 1) return {pos, @lines}; endif endfor endif endwhile return {0, @lines}; . @verb emh:"newmessage" this none this rx @program emh:newmessage if (caller != this) return E_PERM; endif number = args[1]; text = args[2..length(args)]; if (!text) return E_ARGS; endif note = $recycler:_create(this.emailnote); if (typeof(note) == OBJ) note.r = 1; note:set_text(@text); note:set_name(ctime()); move(note, this); this.location:announce_all(this:namec(1), " emits a ", (number == 1) ? "" | ($string_utils:english_ordinal(number) + " "), "'ping!'"); note:analyze(); else this.messages = {@this.messages, args}; endif . @verb emh:"turn" this any none r @program emh:turn if (!(player in this.controllers)) player:tell("You can't control ", this:name(1), "."); return E_PERM; elseif ((prepstr == "on") && (!this.on)) this.on = 1; this.location:announce_all(player.name, " turns ", this:name(1), " on."); this.task = this.scheduler:schedule_every(300, this, "check_mail", {}); elseif ((prepstr == "off") && this.on) this.on = 0; this.location:announce_all(player.name, " turns ", this:name(1), " off."); this.scheduler:kill_task(this.task); this.task = -1; else player:tell("Do what?"); endif . "***finished*** @create $note named generic external email:generic external email,gee @prop gee."headers" {} "" ;gee.("aliases") = {"generic external email", "gee"} ;gee.("description") = "A simple, unobtrusive sheet of paper." ;gee.("adj") = "note from" @verb gee:"analyze" this none this rx @program gee:analyze if (!$perm_utils:controls(caller_perms(), this)) return E_PERM; endif start = "" in (text = this:text()); if (!start) "can't find empty line dividing headers from body - what's going on?"; return E_ARGS; endif size = match(text[1], "+OK %([0-9]*%) octets")[3][1]; if ((typeof(size) == LIST) && (length(size) > 1)) size = text[1][size[1]..size[2]]; endif headers = text[2..start - 1]; text = text[start + 1..length(text)]; for header in (headers) res = match(header, "^%([^ :]*%):"); if (res) pos = res[3][1][2]; this.headers = {@this.headers, {header[1..pos], header[pos + 3..length(header)]}}; else this.headers[length(this.headers)][2] = this.headers[length(this.headers)][2] + header; endif endfor if (text) line = text[1]; while ((!line) && text) text = text[2..length(text)]; line = text[1]; endwhile if (text) line = text[length(text)]; while ((!line) && text) text = text[1..l = length(text) - 1]; line = text[l]; endwhile endif this:set_text(text); endif "Last modified Wed Aug 10 17:22:36 1994 IDT by Gustavo (#2)."; . @verb gee:"headers" this none none rxd @program gee:headers $focus_utils:set_focus(player, this); if (!this:is_readable_by((caller_perms() != #-1) ? caller_perms() | player)) player:tell("Sorry, but it seems to be written in some code that you can't read."); else this:look_self(); player:tell(); headers = this:get_headers(); for item in [1..length(headers)] headers[item] = (headers[item][1] + ": ") + headers[item][2]; endfor player:tell_lines(headers); player:tell(); player:tell("(You finish reading.)"); endif . @verb gee:"get_headers" this none this @program gee:get_headers cp = caller_perms(); if ($perm_utils:controls(cp, this) || this:is_readable_by(cp)) return this.headers; else return E_PERM; endif . "***finished***