// /adm/daemon/postal_d.c // from the Nightmare Mudlib // the postal daemon... handles all mail sending and receiving // "radix", // Added retire_user and age_mail : Radix - March 6, 1997 #include <post.h> mapping *box_info; mapping my_groups; static mapping mud_groups; static string file; string *expand_list(string *who); string *expand_group(string grp); void add_post(string *local, mapping borg); void notify_online(string *who, string from, string sub); int get_post_number(string id); void remove_post(string, string); void retire_user(string); void age_mail(string); void create() { seteuid("Root"); box_info = ({}); my_groups = ([]); mud_groups = ([ "gods" : ({ "baldrick", "benedick", "asmodean" }), "mudlib" : ({ "baldrick", "benedick", "asmodean" }), "thanes" : ({ "baldrick", "benedick", "asmodean", }), "bugs" : ({ "baldrick", "benedick", "asmodean", }), ]); // catch(mud_groups["patrons"] = "/d/aprior/master"->query_patrons()); // the above commented out by Randor cause there's no /d/aprior here // so far - 19-mar-98 } int valid_access(string func) { if(geteuid(previous_object()) == "Root") return 1; if(member_array(base_name(previous_object()), TRUSTED_MAILERS) != -1) return 1; log_file("illegal", "attempt to access postal daemon function "+func+" by "+ (this_player() ? this_player()->query_name() : getuid(previous_object()))+ " from file "+file_name(previous_object())+"\n"); log_file("illegal", ctime(time())+"\n"); return 0; } void update_post_box(string who) { if(file == DIR_POSTAL+"/"+who) return; if(file && file != "") { if(!sizeof(box_info) && !sizeof(my_groups)) rm(file+".o"); else save_object(file); } box_info = ({}); my_groups = ([]); file = DIR_POSTAL+"/" +who; restore_object(file); } // Radix : March 5, 1997 void retire_user(string who) { mapping m; if(!who) return; who = lower_case(who); // if(this_player() && !this_player()->query_lord() && // this_player()->query_name() != who) ///return; update_post_box(who); if(find_player(who)) tell_object(find_player(who),"Removing your mail.\n"); foreach(m in box_info) remove_post(who, m["id"]); return; } string *post_mail(mapping borg) { string *local, *remote; if(!valid_access("post mail")) return ({}); if(!borg["from"]) return ({}); update_post_box(borg["from"]); local = uniq_array(expand_list(borg["to"])+expand_list(borg["cc"])); if(!sizeof(local -= (remote=filter_array(local, "remote_mail",this_object(), borg)))) return remote; add_post(local, borg); notify_online(local, borg["from"], borg["subject"]); return local+remote; } int remote_mail(string who, mapping borg) { string pl, mud; if(sscanf(who, "%s@%s", pl, mud) != 2) return 0; MAIL_S->remote_mail(pl, mud, borg); return 1; } string *expand_list(string *who) { string *full; string a,b; int i; full = ({}); if(!(i=sizeof(who))) return ({}); while(i--) { if(!who[i] || who[i] == "" || !stringp(who[i])) continue; if(sscanf((who[i]=lower_case(who[i])), "%s@%s", a, b) == 2) full += ({ who[i] }); else if(user_exists(who[i])) full += ({ who[i] }); else if(mud_groups[who[i]] || my_groups[who[i]]) full += expand_group(who[i]); else write("No such user or group: "+capitalize(who[i])+".\n"); } return full; } string *expand_group(string grp) { string *ret, *g; string a, b; int i; if(mud_groups[grp]) g = mud_groups[grp]; else if(my_groups[grp]) g = my_groups[grp]; else return ({}); i = sizeof(g); ret = ({}); while(i--) { if(sscanf(g[i], "%s@%s", a, b) ==2) ret += ({ g[i] }); else if(user_exists(g[i])) ret += ({ g[i] }); else write("No such user: "+capitalize(g[i])+".\n"); } return ret; } void add_post(string *local, mapping borg) { string *tmp; int i, max; if(!valid_access("add post")) return; if(!(i=sizeof(local))) return; borg["id"] = (string)LETTER_D->create_message(borg["message"],local); borg["read"] = 0; map_delete(borg, "message"); while(i--) { update_post_box(local[i]); box_info += ({ borg }); } } void remove_post(string who, string id) { int x; if(!valid_access("remove post")) return; update_post_box(who = lower_case(who)); if((x=get_post_number(id)) == -1) return; LETTER_D->delete_message(id, who); box_info = exclude_array(box_info, x); } static int get_post_number(string id) { int i; i = sizeof(box_info); while(i--) if(box_info[i]["id"] == id) return i; return -1; } mapping mail_status(string who) { int un, tot, i; update_post_box(who = lower_case(who)); i = sizeof(box_info); while(i--) { tot++; if(!box_info[i]["read"]) un++; } return ([ "unread":un, "total":tot ]); } void notify_online(string *who, string from, string sub) { object ob, mail; string str; int i; i = sizeof(who); while(i--) { if(!(ob = find_player(who[i])) || ((str=(string)ob->getenv("MAIL_MSG")) == "ignore")) continue; if(!str || str == "") str = " New mail has arrived from $N\n Subject: $S"; str = replace_string(str, "$N", capitalize(from)); str = replace_string(str, "$S", sub); //tell_object(ob,str); tell_object(ob,wrap(str,(int)ob->query_cols()) ); //tell_object(ob, wrap(str, (int)ob->getenv("screen"))); if(mail=present(POST_ID, ob)) mail->reset_post(); } } mapping add_group(string who, string group, string *in_group) { string a, b; int i; if(!valid_access("add group")) return ([]); update_post_box(who = lower_case(who)); if(!my_groups) my_groups = ([]); if(!my_groups[group]) my_groups[group] = ({}); i = sizeof(in_group); while(i--) { if(user_exists(in_group[i] = lower_case(in_group[i]))) my_groups[group] += ({ in_group[i] }); if(sscanf(in_group[i], "%s@%s", a, b) == 2) my_groups[group] += ({ in_group[i] }); } return my_groups; } mapping remove_group(string who, string group, string *out_group) { int i; if(!valid_access("remove group")) return ([]); update_post_box(who = lower_case(who)); if(!my_groups) return ([]); if(!my_groups[group]) return my_groups; i = sizeof(my_groups[group]); while(i--) my_groups[group] -= ({ my_groups[group][i] }); if(!sizeof(my_groups)) map_delete(my_groups, group); return my_groups; } void mark_read(string who, string id) { int i; if(!valid_access("mark read")) return; update_post_box(who = lower_case(who)); i = sizeof(box_info); while(i--) if(id == box_info[i]["id"]) box_info[i]["read"] = 1; } // Radix : March 7, 1997 void age_mail(string who) { int low, high; mapping m; if(!valid_access("age mail")) return; update_post_box(who); foreach(m in box_info) if(m["date"] + AGED < time()) { high = get_post_number(m["id"]); if(!low) low = high; remove_post(who, m["id"]); } if(low) { if(low == high) tell_object(find_player(who),"Aged letter #"+low+"\n"); else if(low + 1 == high) tell_object(find_player(who),"Aged letters #"+low+" and " "#"+high+"\n"); else tell_object(find_player(who),"Aged letters #"+low+" through" " #"+high+"\n"); } return; } mapping query_mud_groups() { return mud_groups; } int query_mailing_list(string which) { if(!which) return 1; if(mud_groups[which]) return 1; return 0; } void flush_files() { if(!sizeof(box_info) && !sizeof(my_groups)) rm(file+".o"); else save_object(file); } string read_sig(string who) { if(file_exists("/w/"+who+"/.sig")) return read_file("/w/"+who+"/.sig"); else return ""; } int valid_shadow() { return 1; }