ms.c
来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 339 行
C
339 行
/* * Intermud mail server, used by Huthar's mailer daemon * Original author: Huthar * Rewritten to conform to new socket efun specs, Blackthorn (10/31/92) * Small patches for TMI-2 mudlib, Buddha (11/6/92) * * Cleaned up 930413 by Zak - enhanced to use new mapping format for mail. * Zak, 930604 fixed up writing to remote mud, auto-format our mud * name into one w/o spaces, etc. * Zak, 930606 noted a potential security hole. (find the `XXX' * comment referring to ``enable for debugging only'') * Grendel, 930904 Fixed a bug in mailing to remote groups */ #include <config.h>#include <mailer.h>#include <daemons.h>#include <net/daemons.h>#include <uid.h> #define log(x) log_file("MS", x)#define MS_SAVE "mail-queue"#define FLUSH_TIME 86400#define AGE_TIME 604800#define EOF "%EOF%"#define EOT "%EOT%" nosave mapping sockets;nosave mixed mqi, outgoing;nosave string mname; mixed mail_queue;int date_last_flushed; void flush_mail_queue();void dump_mailq(); voidcreate(){ seteuid(ROOT_UID); mail_queue = ([ ]); sockets = ([ ]); mqi = ({ }); restore_object(MAILDIR + MS_SAVE); mqi = keys(mail_queue); mname = lower_case(replace_string(THIS_MUD, " ", ".")); flush_mail_queue();} // create stringconvert_name(string lname, string lmud){ string tmp, tmpaddr; if (!lname) return "_unknown_@" + mname;// if (sscanf(lname, "%s@%s", tmp, tmpaddr)==0) return lname; if (sscanf(lname, "%s@%s", tmp, tmpaddr) != 2) { tmp = lname; tmpaddr = lmud; } if (!tmp || tmp == "") tmp = "_unknown_"; if (!tmpaddr || tmpaddr == "") tmpaddr = mname; if (tmpaddr != mname) return tmp + "@" + tmpaddr; return tmp;} // convert_name voidremote_mail(string own, string mud, mapping outmsg){ string *tmp; if (file_name(previous_object()) != MAILER_D) return;//printf("remote mail to: %s@%s, subj: %s\n", own, mud, outmsg["To"]); if (! outmsg["message"]) outmsg["message"] = "\n"; else outmsg["message"] += "\n"; outmsg["message"] = replace_string( outmsg["message"], EOF + "\n", EOF + ".\n" ); outmsg["message"] = replace_string( outmsg["message"], EOT + "\n", EOT + ".\n" ); if (!mail_queue[mud]) mail_queue[mud] = ({ }); outmsg["recipient"] = own;// printf("before: mq[mud] %s\n", dump_variable(mail_queue[mud])); mail_queue[mud] += ({ copy(outmsg) });// printf("after: mq[mud] %s\n", dump_variable(mail_queue[mud]));// printf("mud is %s\n", mud); save_object(MAILDIR + MS_SAVE); mqi += ({ mud });} // remote_mailvoiddump_mailq(){ mixed *mk; int i, j; mk = keys(mail_queue); i = sizeof(mk); while (i--) { printf("Mud: %s\n", mk[i]); j = sizeof(mail_queue[mk[i]]); printf("%d: %s\n\t%s\n", i, dump_variable(mk[i]), dump_variable(mail_queue[mk[i]])); }} // dump_mailq // ZAKNOTE: what uses this???voidbad_port(string lmud, string lfrom, string msg){ object ob; ob = find_player(lfrom); if (!ob) return; tell_object(ob, "The mud " + lmud + " doesn't exist or has a bad port address.\n" + "If the mud should exist, notify your local admins.\n"); tell_object(ob, "Saving letter in: " + TMP_DIR + "/" + lfrom + ".dead.letter\n"); write_file(TMP_DIR + "/" + lfrom + ".dead.letter", msg); mail_queue[lmud] = 0;} // bad_port voidremove(){ destruct(this_object()); } // remove #if 1 // XXX: enable for debugging only - Zakvoid set_mqi(mixed m) { mqi = m; }string *query_mqi() { return mqi; }void set_mail_queue(mixed a) { mail_queue = a; }mapping query_mail_queue() { return mail_queue; } voidclear_mail_queue() { mail_queue = ([ ]); save_object(MAILDIR + MS_SAVE);} // clear_mail_queue#endif voidage_queue(){ int i, j; string *key; mixed tmp; key = keys(mail_queue); i = sizeof(key); while (i--) { tmp = mail_queue[key[i]]; j = sizeof(tmp); while (j--) { if (time() - tmp[j]["date"] > AGE_TIME) { log("Aging mail from: " + tmp[j]["from"] + ", dated: " + tmp[j]["date"] + "\n");// ZAKNOTE: this is effectively a null statement... why???// exclude_array(tmp, j); } } }} // age_queuevoidreset(){ if ((time() - date_last_flushed) > FLUSH_TIME) { mqi = keys(mail_queue); flush_mail_queue(); date_last_flushed = time(); } age_queue();} // reset voidclose_callback(int id){ map_delete(sockets, id); return;} // close_callback voidservice_request(int id){ sockets[id] = ([ "msg" : "" ]);} // service_request voidprocess_message(int id){ mapping inmsg; mixed tmp, tmp2; int i, j, res, max; string receiver, mud, grp; sscanf(sockets[id]["msg"], "%s\n%s", mud, tmp); sockets[id]["msg"] = tmp; tmp = explode(sockets[id]["msg"], EOF); tmp = tmp[0..sizeof(tmp)-2]; tmp2 = allocate(sizeof(tmp)); inmsg = ([ ]); max = sizeof(tmp); for (i = 0; i < max; i++) { tmp2[i] = explode(tmp[i], "\n"); } max = sizeof(tmp2); for (i = 0; i < max; i++) { receiver = convert_name(tmp2[i][0], mname); inmsg["to"] = explode(tmp2[i][1], " "); j = sizeof(inmsg["to"]); while (j--) inmsg["to"][j] = convert_name(inmsg["to"][j], mud); inmsg["cc"] = explode(tmp2[i][2], " "); if (inmsg["cc"][0]) { j = sizeof(inmsg["cc"]); while (j--) inmsg["cc"][j] = convert_name(inmsg["cc"][j], mud); } else inmsg["cc"] = ({ }); inmsg["from"] = convert_name(tmp2[i][3], mud); inmsg["subject"] = tmp2[i][4]; sscanf(tmp2[i][5], "%d", inmsg["date"]); inmsg["message"] = implode(tmp2[i][6..sizeof(tmp2[i]) - 1], "\n"); res = 0; if(sscanf(receiver, "(%s)", grp)) // do remote group mail { string grparr; grparr = ((mapping)GROUP_OB->query_groups())[grp]; j = sizeof(grparr); while(j--) { res += (int)MAILER_D->add_message(grparr[j], inmsg); } } else res = (int)MAILER_D->add_message(receiver, inmsg); if (!res) { MAILER_D->add_message(inmsg["from"], ([ "to" : ({ inmsg["from"] }), "cc" : ({ }), "from" : "MS@" + mname, "subject" : "`" + capitalize(receiver) + "' does not exists at this site. (MAIL BOUNCE)", "date": time(), "message" : "BODY OF MESSAGE FOLLOWS:\n\n" + inmsg["message"] ])); // XXX: rework the line below - it's ugly... -Zak if (sizeof(explode(inmsg["from"], "@")) == 1) { MAILER_D->biff(inmsg["from"], "MS", capitalize(receiver) + " does not at exist at this site. (MAIL BOUNCE)"); MAILER_D->flush_files(); } else call_out("flush_mail_queue", 30); return; } MAILER_D->biff(receiver, inmsg["from"], inmsg["subject"]); MAILER_D->flush_files(); } // for} // process_messagevoidread_callback(int id, string data){ if (data == (EOT + "\n")) { sockets[id]["msg"] += data; process_message(id); return; } sockets[id]["msg"] += data;} // read_callback voidflush_mail_queue(){ string *muds, address, port; string tmp; int id; if (!sizeof(mqi)) return; outgoing = mail_queue[mqi[0]]; id = INETD->open_service(mqi[0], "mail"); if (id < 0) { log("flush_mail_queue: open_service: " + socket_error(id) + "\n"); mqi -= ({ mqi[0] }); flush_mail_queue(); } // we need some sort of time out here} // flush_mail_queue voidservice_callback(int id){ int i, max; string str; string to, cc; INETD->write_socket(id, mname + "\n"); max = sizeof(outgoing); for (i = 0; i < max; i++) { to = pointerp(outgoing[i]["to"]) ? implode(outgoing[i]["to"], " ") : ""; cc = pointerp(outgoing[i]["cc"]) ? implode(outgoing[i]["cc"], " ") : ""; INETD->write_socket(id, sprintf("%s\n%s\n%s\n%s\n%s\n%d\n", outgoing[i]["recipient"], to, cc, outgoing[i]["from"], outgoing[i]["subject"], outgoing[i]["date"])); INETD->write_socket(id, sprintf("%s\n%s\n", outgoing[i]["message"], EOF)); } INETD->write_socket(id, EOT + "\n"); INETD->close_socket(id); map_delete(mail_queue, mqi[0]); mqi -= ({ mqi[0] }); save_object(MAILDIR + MS_SAVE); call_out("flush_mail_queue", 60);} // service_callback
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?