Fehlende Files fuer Mailsystem ergaenzt.
Change-Id: Ia51a607d71ac86a12e957ae0f2c604f190581314
diff --git a/mail/mailer.c b/mail/mailer.c
new file mode 100644
index 0000000..77bac9f
--- /dev/null
+++ b/mail/mailer.c
@@ -0,0 +1,1366 @@
+/* =========================================================================
+
+ Ein Mailobjekt fuer Morgengrauen.
+ (C) 1993-97 Loco@MG. Unter Verwendung des std/post-codes von Jof
+
+ Verwendung ausserhalb von Morgengrauen ist gestattet unter folgenden
+ Bedingungen:
+ - Benutzung erfolgt auf eigene Gefahr. Jegliche Verantwortung wird
+ abgelehnt.
+ - Auch in veraenderten oder abgeleiteten Objekten muss ein Hinweis auf
+ die Herkunft erhalten bleiben.
+ - Bitte Loco Bescheid sagen.
+ Ein Update-Service besteht nicht. Diese Lizenz kann jederzeit
+ zurueckgezogen werden.
+
+ Letzte Aenderungen:
+ 190494 [Loco] mail <spieler> fuehrt nicht ins mailmenue anschliessend.
+ 280494 [Loco] .mailrc
+ 020594 [Loco] system.mailrc, aliase anzeigen, Text retten, selfdestruct
+ in reset() im Fehlerfall, kleinere bugfixes
+ 070794 [Loco] Kleinigkeiten (bugfixes und Optimierungen), '+'
+ 231195 [Loco] Bereiche bei Speichern und Loeschen
+ 171295 [Loco] Bereiche bei forward. Stapelweise Kleinigkeiten.
+ 191295 [Loco] Kleinere Zeitoptimierungen, teilweise schiefgelaufen und
+ deswegen doch nicht, minor bugfixes.
+ 190295 [Loco] keine folderlist beim hochstarten
+ 110696 [Loco] Forwardserver-Unterstuetzung (.forward-aehnlich)
+ 031296 [Loco] major update:
+ Erlaube in der Blueprint nichtinteraktives Versenden
+ vorbereiteter mails (z.B. fuer mpa: versende artikel);
+ Zeitoptimierungen durch effektiveres caching;
+ '-';
+ Einige optische Aenderungen;
+ Warnung bei grossen mailfiles;
+ Unterstuetzung von bcc's;
+ d,m,f,s erlauben Listen;
+ Abkuerzungen und '-' bei Folderargumenten
+ 080297 [Loco] Zeitoptimierungen, interne Aenderungen, Bugfixes
+ 280103 [Muadib]Silentflag
+ 020304 [Vanion]In do_mail() wird jetzt M_NOCHECK gemovet, sonst hat ein
+ Mailer eines Spielers, der voll ist, kein Environment.
+ 100105 [Zook] Magier mit Level >= 26 bekommen erst spaeter eine
+ Mitteilung (Gebietswartung insb. f. Regionsmagier
+ erfordert schlicht ein groesseres Postfach).
+
+----------------------------------------------------------------------------
+
+Aufrufe von aussen zur Benutzung:
+
+a) im geklonten Objekt:
+ obj->do_mail() interaktives Mailmenue
+ obj->do_mail(empf) 'halbinteraktiv': _eine_ mail, an Empfaenger str
+ Objekt zerstoert sich nach Gebrauch selbst.
+ Bei obj->do_mail("-silent") wird der Inhalt des Mailfolders nicht
+ aufgelistet. Ansonsten wie obj->do_mail()
+
+b) in der blueprint: nur non-interactive
+ obj->do_mail(empf,titel,text)
+ sendet mail mit Titel titel und Inhalt text an Empfaenger empf.
+ Aliase etc. werden von this_interactive() genommen.
+ Nur fuer 'trusted objects' zugelassen, siehe #define TRUSTED
+
+=========================================================================== */
+
+#include "post.h"
+
+inherit "std/thing";
+//inherit "std/more"; // wird vom nedit inherited
+inherit NEDIT;
+
+#include <properties.h>
+#include <language.h>
+#include <config.h>
+#include <mail.h>
+#include <wizlevels.h>
+#include <moving.h>
+#include <defines.h>
+#include <input_to.h>
+
+#undef DEBUG
+
+#define TRUSTED(o) (objectp(o) && BLUE_NAME(o)=="/obj/mpa")
+// (geteuid(o)=="p:service"|| \
+// geteuid(o)==geteuid(this_interactive())))
+
+#define MAILFILE(name) ("/"+MAILPATH+name[0..0]+"/"+name)
+#define MAILFILEO(name) (MAILFILE(name)+".o")
+#define MAILDEMON0297 // Maildemon-Version 8.Feb.97 vorhanden?
+
+#define IS_NUMBER(n) (stringp(n) && sizeof(n) && n[0]>='0' && n[0]<='9')
+
+#ifdef DEBUG
+#define DEBUGVAR(x) if(find_player("tiamak")) tell_object(find_player("tiamak"),sprintf("Value of x is %O\n",x))
+#else
+#define DEBUGVAR(x)
+#endif
+
+// Zaehlung: akt_nr ab 1, akt_folder ab 0
+
+static string subject, message, receiver, sender, *carbon;
+#ifdef MAIL_SUPPORT_BCC
+static string* blindcarbon;
+#endif
+static string name, office_name;
+static int done, akt_folder, i, akt_nr, directflag;
+static int folder_size,folder_date; // cacheverwaltung
+static mapping aliases;
+
+mixed *folders;
+
+// Prototypen, die nun mal gebraucht werden
+
+static varargs void SendMail(string text,int flag);
+static void input();
+static mixed process_names(mixed s);
+static void get_carbon_copy(string str);
+static varargs string* send_mail(mixed back);
+string * unify_array(string * a);
+static mapping Read_mailrc(string file);
+static varargs void update(int directflag,int nocondflag);
+static varargs void ListContent();
+string GetFolderName(mixed fol);
+static void LagWarning();
+string GetReTitle(string s);
+static string Message2string(int nr);
+int * GetNumbers(mixed s);
+
+void create() {
+ (::create());
+ seteuid(getuid());
+ SetProp(P_IDS,({"mailer"}));
+ SetProp(P_NAME,"mailer");
+ office_name="Morgengrauens Post";
+ akt_folder=-1;
+ folder_size=folder_date=-42;
+ SetProp(P_NODROP,1);
+ SetProp(P_SHORT,0);
+ SetProp(P_WEIGHT,0);
+}
+
+
+void init() {
+ (::init());
+ init_rescue();
+ add_action("postneustart","post");
+ add_action("postneustart","mail");
+}
+
+
+void reset() {
+ object pl;
+ (::reset());
+ if (!name) {remove();return;}
+ pl=find_player(name);
+ if (!pl || environment()!=pl) {remove();return;}
+ if (nedittext && !query_input_pending(pl)) {
+ tell_object(pl,"\
+*** Hoppla! Du hast noch einen nicht fertiggeschriebenen Brief!\n\
+*** Mit ~r kannst Du weiterschreiben.\n");
+ return;
+ }
+ if (query_input_pending(pl)!=this_object())
+ {remove();return;}
+}
+
+
+mixed postneustart() {
+ if (!this_interactive() || name!=geteuid(this_interactive())
+ || query_input_pending(this_interactive())
+ || this_interactive()!=this_player()) return 0;
+ write("Und weiter gehts...\n");
+ if (nedittext) return RescueText();
+ return input();
+}
+
+
+string SetOfficeName(string n) {
+ return office_name=n;
+}
+
+
+static varargs void write_mail(mixed str, string std_subject, string text) {
+ string str2;
+ int h;
+
+ carbon=process_names(str);
+ if (!sizeof(carbon)) {
+ write("Kein Empfaenger angegeben!\n"),(directflag?remove():input());
+ return;
+ }
+ write("Empfaenger: "+implode(map(carbon,#'capitalize/*'*/),", ")+"\n");
+ str=carbon[0];
+ if (sizeof(carbon)>=2) carbon=carbon[1..<1];
+ else carbon=0;
+ if ((str2=str) && str2!="" && str2[0]=='\\') str2=str2[1..];
+ if (!str) { write("WEM willst Du schreiben?\n"),(directflag?remove():input()); return;
+ }
+ if (!master()->find_userinfo(str2) && member(str2,'@')==-1)
+ {
+ write("Mit dem Namen gibt es hier niemanden.\n"),(directflag?remove():input());
+ return;
+ }
+
+ receiver=str;
+
+ if (text) {
+ subject=std_subject;
+ return SendMail(text,1); // flag 1: keine CC's bitte.
+ }
+
+ //write("Titel");
+ //if (std_subject) write(" ("+std_subject+")");
+ //write(": ");
+ string pr;
+ if (std_subject) pr = "Titel ("+std_subject+"): ";
+ else pr = "Titel: ";
+ subject=std_subject;
+ input_to("get_subject",INPUT_PROMPT,pr);
+ return;
+}
+
+
+static varargs void get_subject(string str,string pretext) {
+ DEBUGVAR(str);
+ DEBUGVAR(subject);
+ if ((!str||str=="") && !subject)
+ {
+ input_to("get_subject",INPUT_PROMPT,"Titel (Abbrechen mit ~q): ");
+ return;
+ }
+ if (str=="~q"||str=="~Q") return SendMail(0); // entspricht Abbruch im Editor.
+ if (str && str!="") subject=str;
+ write("Bitte gib jetzt Deine Nachricht an:\n\
+** oder . wenn fertig, ~q fuer Abbruch, ~h fuer eine Hilfsseite\n");
+ nedit("SendMail",pretext);
+}
+
+
+static varargs void SendMail(string text,int flag) {
+ // flag: 1 = keine CC abfragen.
+ if (!text) {
+ write("Abbruch! Brief landet im Reisswolf.\n");
+ if (directflag) {remove(); return;
+ }
+
+ subject=receiver=carbon=message=0;
+ return input();
+ }
+ message=text;
+ if (flag) return get_carbon_copy(0);
+ //write("Cc: ");
+ input_to("get_carbon_copy",INPUT_PROMPT, "Cc: ");
+ return;
+}
+
+
+static void get_carbon_copy(string str) { // Aufruf mit 0, wenn keine cc gewuenscht.
+ int i,j;
+ object p;
+ string *oldcarbons,*h,*receivers;
+ mapping orignames;
+
+ oldcarbons=carbon;
+ if (str=="~q") return SendMail(0); // Abbruch, entspricht Abbruch im Editor
+ if (!str || str=="") carbon=0;
+ else carbon=process_names(str);
+ carbon=(oldcarbons ? oldcarbons : ({}))+(carbon ? carbon : ({}));
+
+#ifdef MAIL_SUPPORT_BCC
+ blindcarbon=filter(carbon,
+ function status (string x)
+ {if (x[0]=='-') return(1);
+ return(0);});
+ carbon-=blindcarbon;
+ blindcarbon=map(blindcarbon,
+ function string (string x)
+ {return(x[1..]);} );
+#endif
+
+#ifdef MAIL_SUPPORT_BCC
+ oldcarbons=({receiver})+carbon+blindcarbon; // speichere alle Originaladressen
+#else
+ oldcarbons=({receiver})+carbon;
+#endif
+
+ /* Forwards auswerten, dabei werden auch ungueltige Adressen gefiltert */
+ /* orignames speichert die Zuordnung Zieladressen -> Originaladressen */
+
+ orignames=([]);
+ h=explode(FWSERV->QueryForward(receiver),",");
+
+ DEBUGVAR(h);
+ for (j=sizeof(h);j--;)
+ orignames[(h[j][0]=='\\'?h[j][1..]:h[j])]=({receiver[0]=='\\'?receiver[1..]:receiver});
+ receiver=h[0];
+ receivers=h[1..]; // Missbrauch dieser Variable!
+
+ DEBUGVAR(orignames);
+
+ for (i=sizeof(carbon);i--;) {
+ h=explode(FWSERV->QueryForward(carbon[i])||"",",");
+ for (j=sizeof(h);j--;) {
+ h[j]=(h[j][0]=='\\'?h[j][1..]:h[j]);
+ orignames[h[j]]=(orignames[h[j]]||({}))+({carbon[i][0]=='\\'?carbon[i][1..]:carbon[i]});
+ receivers+=h;
+ }
+ }
+ carbon=receivers;
+
+#ifdef MAIL_SUPPORT_BCC
+ receivers=({});
+ for (i=sizeof(blindcarbon)-1;i>=0;i--) {
+ h=old_explode(FWSERV->QueryForward(blindcarbon[i]),",");
+ for (j=sizeof(h)-1;j>=0;j--) {
+ h[j]=(h[j][0]=='\\'?h[j][1..]:h[j]);
+ orignames[h[j]]=(orignames[h[j]]||({}))+({blindcarbon[i][0]=='\\'?blindcarbon[i][1..]:blindcarbon[i]});
+ receivers+=h;
+ }
+ }
+ blindcarbon=receivers;
+#endif
+
+ carbon=send_mail();
+ receivers=({});
+
+ if (!pointerp(carbon) || !sizeof(carbon)){
+ write("Brief NICHT verschickt, da keine Empfaenger gefunden!\n");
+ } else {
+ string *a;
+ DEBUGVAR(orignames);
+ for (i=0;i<sizeof(carbon);i++){
+ DEBUGVAR(carbon[i]);
+ /* evtl. abfragen nach query_editing und/oder query_input_to */
+ /* Benachrichtige Spieler, die ein forward gesetzt haben */
+ a=orignames[carbon[i]];
+ if (pointerp(a))
+ {
+ a=a-({carbon[i]});
+ for (j=sizeof(a);j--;)
+ if (p=find_player(a[j]))
+ tell_object(p,"Ein Postreiter ruft Dir aus einiger Entfernung zu, dass Du neue Post hast!\nDer Brief wurde wunschgemaess weitergeleitet.\n");
+ }
+ /* Benachrichtige Empfaenger */
+#ifndef MAILDEMON0297
+ if (p=find_player(carbon[i]))
+ tell_object(p,"Ein Postreiter ruft Dir aus einiger Entfernung zu, dass Du neue Post hast!\n");
+#endif
+ receivers+=orignames[carbon[i]]||orignames["\\"+carbon[i]]||({});
+ }
+ DEBUGVAR(carbon);
+ write("Abgesandt an: "+implode(unify_array(map(receivers,#'capitalize)),", ")+"\n");//')));
+ }
+ for (i=sizeof(oldcarbons);i--;)
+ if (oldcarbons[i][0]=='\\')
+ oldcarbons[i]=oldcarbons[i][1..];
+ oldcarbons=oldcarbons-receivers;
+ if (sizeof(oldcarbons)) {
+ write("Empfaenger unbekannt: "+implode(map(oldcarbons,#'capitalize),", ")+"\nIrgendjemand wirft Dir den zurueckgekommenen Brief zu.\n");//')))
+ send_mail(oldcarbons);
+ }
+
+ message=receiver=carbon=subject=0;
+ if (directflag) {
+ if (directflag==1) remove(); // 1: Direktmodus, 2: non-interactive
+ return;
+ }
+ return input();
+}
+
+
+static varargs string* send_mail(mixed back) {
+ mixed *mail;
+
+ mail=allocate(9);
+
+#ifdef DEBUG
+ DEBUGVAR(receiver);
+ DEBUGVAR(carbon);
+#endif
+
+ if (!pointerp(carbon) || !sizeof(carbon)) carbon=0;
+ mail[MSG_FROM]=this_player()->query_real_name();
+ mail[MSG_SENDER]=office_name;
+ mail[MSG_RECIPIENT]=(back ? mail[MSG_FROM] : receiver);
+ mail[MSG_CC]=(back ? 0 : carbon);
+#ifdef MAIL_SUPPORT_BCC
+ mail[MSG_BCC]=blindcarbon;
+#else
+ mail[MSG_BCC]=0;
+#endif
+
+ mail[MSG_SUBJECT]=(back ? "Zurueck! Empfaenger unbekannt: "+implode(back,", ") : subject);
+ mail[MSG_DATE]=ctime(time());
+ mail[MSG_ID]="MorgenGrauen:"+time();
+ mail[MSG_BODY]=message;
+ return MAILDEMON->DeliverMail(mail,NO_SYSTEM_ALIASES|NO_USER_ALIASES);
+}
+
+
+varargs void do_mail(mixed str,string titel,string text) {
+ // text und titel angegeben: versende Text, keine weiteren Taetigkeiten.
+
+ mixed i;
+ int silent;
+
+ if (name) return; /* security flag :-) */
+ if (!this_interactive()) return;
+ if (!text) {
+ name=geteuid(this_interactive());
+ move(this_interactive(),M_NOCHECK);
+ if (!name) remove();
+ }
+ aliases=Read_mailrc(ALIASFILE(geteuid(this_interactive())))+
+ Read_mailrc(SYSALIAS);
+// akt_folder=member_array("newmail",folders[0]);
+// if (akt_folder==-1) akt_folder=0;
+ if (str) {
+ str=lower_case(str);
+
+ if(regreplace(regreplace(str," ","",1),"\t","",1)=="-silent")
+ {
+ silent=1;
+ }
+ else
+ {
+ directflag=1;
+ if (text) {
+ if (this_interactive()!=this_player()) return 0;
+ if (!TRUSTED(previous_object())) return
+ write(break_string("WARNUNG!!! Objekt "+object_name(previous_object())+
+ " versucht, Mail mit Deinem Absender zu versenden! "
+ "Bitte Erzmagier oder Loco verstaendigen.",78)+
+ "\n");
+ directflag=2;
+ return write_mail(str,titel,text);
+ }
+ directflag=1;
+ return write_mail(str);
+ }
+ }
+
+ update(0,1);
+ if (!pointerp(folders) || sizeof(folders)!=2 || sizeof(folders[0])==0) {
+ write("Du hast im Moment keine Post !\n");
+ folders=({({}),({})});
+ }
+ write("Du hast "+sizeof(folders[0])+" Ordner, Liste mit 'i'.\n");
+
+ if(!silent)
+ {
+ ListContent();
+ }
+
+ write("Gesamtgroesse Deines Postfachs: "+
+ (i=(file_size(MAILFILEO(name))+512)/1024)+" KB.\n");
+ // Kleiner Hack als Uebergangsloesung, weil ich die dumme Warnung
+ // nicht mehr sehen kann. ;^)
+ // 22.10.2000, Tiamak
+ if(IS_ARCH(this_interactive())) i=0;
+
+ //
+ // Kleiner Hack, damit Regionsmitarbeiter und groessere Magier
+ // bei ihren Gebietswartungen nicht staendig mit nervigen
+ // Meldungen belaestigt werden:
+ //
+ // 2005-01-10, Zook
+ if (query_wiz_level(this_interactive()) > DOMAINMEMBER_LVL) {
+ if (i>700)
+ write("*************************************************************\n"
+ "* Dein Postfach ist zu gross! Bitte versuche aufzuraeumen *\n"
+ "* und damit die Groesse zu reduzieren. Grosse Postfaecher *\n"
+ "* verursachen unnoetiges Lag fuer die Spieler. *\n"
+ "*************************************************************\n");
+ i=0;
+ }
+
+ if (i>500) // Extra-Warnung fuer Catweazle
+ // man koennte natuerlich auch eine Channel-Meldung ausspucken
+ // mit dem Hinweis, wer das aktuelle Lag verursacht... vielleicht
+ // ab 800 KB? ;-)
+ write("*****************************************************************\n"
+ "* Dein Postfach hat eine absolut unakzeptable Groesse erreicht. *\n"
+ "* Uebergrosse Postfaecher verursachen unnoetiges Lag fuer alle! *\n"
+ "* Bitte raeume es dringend auf, d.h. loesche alle Briefe, die *\n"
+ "* Du nicht _unbedingt_ benoetigst, oder lager sie aus und *\n"
+ "* loesche sie anschliessend. Hauptsache, weg damit. *\n"
+ "*****************************************************************\n");
+ else if (i>300) // Warnung fuer bestimmte Magier und Seher ab 300 KB
+ write("WARNUNG! Dein Postfach hat eine bedenkliche Groesse erreicht.\n"
+ "Beachte, dass uebergrosse Postfaecher nicht nur unnoetig Speicher, sondern\n"
+ "insbesondere auch Rechenzeit verbrauchen und damit groesseres Lag verursachen\n"
+ "koennen. Du solltest also dringend aufraeumen und alle nicht unbedingt\n"
+ "notwendigen Briefe loeschen (evtl. natuerlich vorher auslagern.\n");
+ else if (i>200) // Hinweis fuer andere.
+ write("Der Postbeamte macht dich darauf aufmerksam, dass Dein Postfach bereits\n"
+ "ziemlich voll ist und Du dringend einmal aufraeumen solltest.\n");
+ else if (i>100) // Hinweis fuer andere.
+ write("Der Postbeamte macht dich darauf aufmerksam, dass Dein Postfach\n"
+ "relativ voll ist.\n");
+
+
+ if ((i=FWSERV->QueryForward(name))!=name)
+ write("Du hast einen Nachsendeauftrag gestellt, Deine Post wird an\n"
+ +i+" weitergeleitet.\n");
+ return input();
+}
+
+
+static void MediumHelpPage() {
+ if (sizeof(folders[0]))
+ write("Aktueller Ordner ist \""+folders[0][akt_folder]+"\"\n");
+ write("\n\
+Brief <nr> lesen '<nr>' (lies <nr>)\n\
+Aktueller / naechster / letzter Brief '.' / '+' / '-'\n\
+Brief schreiben 'm <name>' (schreibe)\n\
+Brief beantworten 'r [nr]' (beantworte)\n\
+Gruppenantwort an alle Empfaenger 'g [nr]' (gruppe)\n\
+Brief(e) loeschen 'd [nummern]' (loesche)\n\
+Brief(e) weitersenden 'f [nummern] <name>' (weiter)\n\
+Weitersenden plus eigenen Text 'F [nr] <name>' (Weiter)\n\
+Brief(e) in anderen Ordner verschieben 'v [nummern] <ordner>' (verschiebe)\n\
+Mails in diesem Ordner listen 'l' (oder nichts) (anzeigen)\n\
+Aktuellen Ordner wechseln 'c <ordner>' (oeffne)\n\
+Neuen Ordner anlegen 'n <ordnername>' (erzeuge)\n\
+Leeren Ordner loeschen 'e <ordner>' (entferne)\n\
+Alle Ordner anzeigen 'i' (ordner)\n\
+"+ (IS_WIZARD(this_player()) ? "\
+Brief(e) speichern in Datei 's [nummern]' (speichere)\n\
+ "+SAVEFILENAME+"\n" : "")+ "\
+Mailaliase anzeigen 'a' (aliase)\n\
+Verfuegbare Kommandos zeigen '?' oder 'h'\n\
+Postmenue verlassen 'q'\n\
+Kommando <cmd> ausfuehren '!<cmd>'\n\
+[nummern] bedeutet: [nr|nr-nr [nr|nr-nr ...]]. (Liste von Nr und Bereichen)\n\
+Bei der Langform reicht es, die ersten 4 Zeichen eines Kommandos anzugeben.\n\
+Falls ein Befehl (z.B. \'v\' nicht funktioniert, pruefe bitte, ob dies ein \n\
+clientseitiges Makro bei Dir ist.\n\
+");
+ return input();
+}
+
+static varargs int GetFolders(int nocondflag) {
+// nocondflag: no condition, unbedingt neuladen
+
+// Cache-Verwaltung endlich funktionsfaehig [251196]
+// IDEE: Uhrzeit & Groesse untersuchen, ausserdem nach Verschieben neuladen.
+// Auch nach automatischem Verschieben (unread -> newmail)!
+
+
+// write("DEBUG: GetFolders called, old date "+folder_date+", old size "+folder_size+", nocondflag="+nocondflag+"\n");
+ if (!nocondflag &&
+ file_time(MAILFILEO(name))==folder_date &&
+ file_size(MAILFILEO(name))==folder_size) return 0;
+
+ if (!restore_object(MAILFILE(name))) folders=({({}),({})});
+ folder_date=file_time(MAILFILEO(name));
+ folder_size=file_size(MAILFILEO(name));
+ if (!pointerp(folders) || sizeof(folders)!=2) folders=({({}),({})});
+// write("DEBUG: GetFolders finished, new date "+folder_date+", new size "+folder_size+"\n");
+ return 1;
+}
+
+static varargs void update(int directflag,int nocondflag) {
+ // directflag: Mailer wird im Direktmodus betrieben
+ // nocondflag: Unbedingt neuladen
+
+ int i,j,k,newletters;
+ mixed *ignored;
+
+ if (!GetFolders(nocondflag)) return; // es hat sich nix getan
+
+ if (akt_nr<1) akt_nr=1;
+
+ DEBUGVAR(akt_folder);
+
+ if (akt_folder>=sizeof(folders[0]) || akt_folder<0) {
+ akt_folder=member(folders[0], "newmail");
+ if (akt_folder==-1) {
+ MAILDEMON->MakeFolder("newmail",name);
+ GetFolders(1);
+ DEBUGVAR(folders[0]);
+ akt_folder=member(folders[0], "newmail");
+ }
+ if (!directflag && akt_folder!=-1) write("Ordner 'newmail' aufgeschlagen.\n");
+ }
+
+// if (!pointerp(folders)) return write("ERROR: folders no array in update\n"); // Kann eigentlich nicht vorkommen
+ if (sizeof(folders[0]) && akt_nr>sizeof(folders[1][akt_folder]))
+ akt_nr=sizeof(folders[1][akt_folder]);
+ j=member(folders[0], "unread");
+ if (j==-1) return;
+ newletters=0;
+
+ // Testweise eine neue Version, die aber voraussetzt, dass die Position von
+ // unread in der Folderliste von /secure/mail waehrend der Aktion
+ // nicht veraendert wird.
+ // alt ausgeklammert, ausserdem ueberall 0 statt k
+ // k=0;
+ // Neue Version wieder testweise drin
+
+ // while (j != -1 && pointerp(folders[1][j]) && sizeof(folders[1][j])>0) {
+ for (k=0;k<sizeof(folders[1][j]);k++) {
+
+ // write("DEBUG: j="+j+"\n");
+
+ if (pointerp(ignored=this_player()->QueryProp(P_IGNORE)) &&
+ member(ignored, lower_case(folders[1][j][k][MSG_FROM]+".mail"))>=0) {
+ mixed msg;
+ msg=folders[1][j][k];
+ write("Du laesst einen Brief von "+capitalize(msg[MSG_FROM])+
+ " unbesehen zurueckgehen.\n");
+ msg[MSG_BODY]=this_player()->name()+" \
+hat diesen Brief ungeoeffnet an Dich zurueckgehen lassen\n\
+und moechte nicht mehr von Deinen Briefen belaestigt werden.\n\
+Titel: "+msg[MSG_SUBJECT]+"\n\
+------ Inhalt: ------------------------\n"+
+ msg[MSG_BODY];
+ msg[MSG_RECIPIENT]=msg[MSG_FROM];
+ msg[MSG_SUBJECT]="Annahme verweigert - zurueck an Absender";
+ msg[MSG_CC]=0;
+ msg[MSG_BCC]=0;
+ MAILDEMON->DeliverMail(msg,NO_SYSTEM_ALIASES|NO_USER_ALIASES);
+ if (find_player(msg[MSG_RECIPIENT]))
+ tell_object(find_player(msg[MSG_RECIPIENT]),
+ "Ein Postreiter ruft Dir aus einiger Entfernung leicht sauer zu, dass er einen\nzurueckgekommenen Brief fuer Dich hat.\n");
+ MAILDEMON->RemoveMsg(0,j,name);
+ } else {
+ // Testweise durch DeleteUnreadFolder ersetzt (080297)
+#ifndef MAILDEMON0297
+ MAILDEMON->MoveMsg(0, j, "newmail", name);
+#endif
+ newletters++;
+ }
+ // GetFolders(1);
+ // j=member_array("unread",folders[0]);
+ // Letzte 2 Zeilen in "neuer" Version ersatzlos gestrichen
+ }
+
+#ifdef MAILDEMON0297
+ MAILDEMON->DeleteUnreadFolder(name);
+#else
+ MAILDEMON->RemoveFolder("unread",name);
+#endif
+ if (newletters) {
+ if (office_name=="mpa Kurierdienst")
+ write(break_string("Ein Kurier sagt \"Tach, Post!\", drueckt Dir "+
+ ((newletters==1) ? "einen neuen Brief" : newletters+" neue Briefe")
+ +" in die Hand und verschwindet wieder.\n",78));
+ else
+ write("Du siehst, wie ein Postbeamter "+
+ ((newletters==1) ? "einen neuen Brief" : newletters+" neue Briefe")
+ +" in Dein Fach legt.\n");
+ }
+ GetFolders(1); // jetzt ohne unread, damit im endgueltigen Zustand.
+ while (akt_folder>=sizeof(folders[0])) akt_folder--;
+ if ((!akt_nr)&&sizeof(folders[1][akt_folder])) akt_nr=1;
+}
+
+
+static varargs void ListContent() {
+ int i;
+ update();
+// DEBUGVAR(folders[0]);
+// DEBUGVAR(folders[1]);
+ DEBUGVAR(akt_folder);
+ if (!pointerp(folders)||sizeof(folders)!=2||
+ !pointerp(folders[0])||!sizeof(folders[0])) {
+ write("Du hast keinen einzigen Ordner!\n");
+ return;
+ }
+ write("Ordner "+folders[0][akt_folder]+": ");
+ if (!pointerp(folders[1]) || akt_folder>=sizeof(folders[1]) ||
+ !pointerp(folders[1][akt_folder])) {
+ write("Dieser Ordner ist leer.\n");
+ return;
+ }
+ write(sizeof(folders[1][akt_folder])+" Brief"+
+ ((sizeof(folders[1][akt_folder])!=1)?"e\n":"\n"));
+ for (i=0;i<sizeof(folders[1][akt_folder]);i++){
+ write(((i+1==akt_nr) ? "->" : " ")+
+ sprintf("%3d: (%12s, %s) ",i+1,capitalize(folders[1][akt_folder][i][MSG_FROM]),
+ folders[1][akt_folder][i][MSG_DATE][5..11])+
+ folders[1][akt_folder][i][MSG_SUBJECT]+"\n");
+ }
+ return;
+}
+
+
+static void ChangeFolder(mixed x) {
+ if (!(x=GetFolderName(x))) return;
+ akt_folder=member(folders[0],x);
+ write("Du oeffnest den Ordner '"+x+"'.\n");
+ if (akt_nr<=0) akt_nr=1;
+ if (akt_nr>=sizeof(folders[1][akt_folder]))
+ akt_nr=sizeof(folders[1][akt_folder]);
+ ListContent();
+}
+
+
+static void ListFolders() {
+ int i;
+ update();
+ write("Du hast "+sizeof(folders[0])+" Ordner:\n");
+ for (i=0;i<sizeof(folders[0]);i++)
+ write(sprintf("%2s%3d: %-20s(%3d Briefe)\n",
+ ((i==akt_folder)?"->":" "),
+ i+1,folders[0][i],sizeof(folders[1][i])));
+ write("Gesamtgroesse Deines Postfachs: "+
+ ((file_size(MAILFILEO(name))+512)/1024)+" KB.\n");
+}
+
+
+static void MakeFolder(string s) {
+ int ret;
+ if (sscanf(s,"%d",ret)||s[0]<'a'||s[0]>'z') return
+ write("Um Probleme zu vermeiden, duerfen Ordner nicht mit Nummern oder Sonderzeichen\nbezeichnet werden.\n");
+ if (s=="newmail"||s=="unread") return
+ write("Die Ordnernamen 'newmail' und 'unread' sind reserviert.\n");
+ ret=MAILDEMON->MakeFolder(s, name);
+ if (ret==1) write("Ok, neuer Ordner mit Namen "+s+" angelegt.\n");
+ else write("Ein Ordner mit dem Namen existiert bereits.\n");
+ return;
+}
+
+
+static int RemoveFolder(string x) {
+ int ret;
+ if (!x) return -42; // folder existiert nicht, Fehlermeldung bereits geg.
+// if (intp(x)) x=folders[0][x];
+
+ if (x=="newmail") return
+ write("Der Ordnername 'newmail' ist reserviert.\nDieser Ordner darf nicht geloescht werden.\n"),-43;
+
+ ret=MAILDEMON->RemoveFolder(x, name);
+ switch (ret) {
+ case 1: write("Ordner "+x+" geloescht.\n"); break;
+ case -1: write("Kein solcher Ordner.\n"); break;
+ case 0: write("Der Ordner war nicht leer - nicht geloescht.\n"); break;
+ default: write("Fehler Nummer "+ret+" - was auch immer das heisst...\n"); break;
+ }
+ return ret;
+}
+
+
+static varargs int DeleteMessage(int *nrs) {
+ int ret,x;
+ mixed m;
+ if ( sizeof(nrs) > 15 ) LagWarning();
+
+ for (x=sizeof(nrs)-1;x>=0;x--) {
+ write("Loesche Brief "+(nrs[x]+1)+": ");
+ ret=MAILDEMON->RemoveMsg(nrs[x], akt_folder, name);
+ switch(ret) {
+ case 1: write("Ok.\n"); break;
+ case 0: write("Kein solcher Brief im aktuellen Ordner.\n"); break;
+ case -1:write("Kein aktueller Ordner.\n"); update(); return ret;
+ default: write("MAILDEMON: Interner Fehler Nummer "+ret+"!\n"); break;
+ }
+ }
+
+ return ret;
+}
+
+//"
+
+static int MoveMessage(mixed msg,mixed fol) {
+ int ret,i;
+
+ for (i=0;i<sizeof(msg);i++) {
+ ret=MAILDEMON->MoveMsg(msg[i]-i, akt_folder, fol, name);
+ switch(ret) {
+ case 1:
+ write("Brief "+(msg[i]+1)+" verschoben nach "+fol+".\n");
+ break;
+ case 0:
+ write("So viele Briefe sind nicht im aktuellen Ordner.\n"); return 0;
+ case -1:
+ write("Seltsamer Fehler - duerfte eigentlich nicht passieren:\n'Kein aktueller Ordner.'\n"); return -1;
+ case -3:
+ write("Den Zielordner "+fol+" gibt es nicht!\n"); return ret;
+ default:
+ write("MAILDEMON: MoveMsg Interner Fehler "+ret+". Bitte Erzmagier verstaendigen.\n"); return ret;
+ }
+ }
+ if (akt_nr>=sizeof(folders[1][akt_folder]))
+ akt_nr=sizeof(folders[1][akt_folder])-1;
+
+ return ret;
+}
+
+
+static varargs int Reply(int nr,int group) {
+ mixed to,dummy;
+ if (!pointerp(folders)||!pointerp(folders[0])||
+ sizeof(folders[0])<=akt_folder) {
+ write("Seltsamer Fehler: Kein aktueller Ordner!\n");
+ return 0;
+ }
+ if (nr<0 || !pointerp(folders[1][akt_folder]) ||
+ sizeof(folders[1][akt_folder])<=nr){
+ write("Einen Brief mit Nummer "+(nr+1)+" gibt es in diesem Ordner nicht!\n");
+ return 0;
+ }
+
+ if (sscanf("\n"+lower_case(folders[1][akt_folder][nr][MSG_BODY]),
+ "%s\nreply-to:%s\n",dummy,to)==2) { // Reply-to gesetzt
+ while (to[0]==' ') to=to[1..]; // ueberschuessige Leerzeichen entfernen
+ while (to[<1]==' ') to=to[0..<2];
+ }
+ else
+ to=folders[1][akt_folder][nr][MSG_FROM];
+ if (group) // Gruppenantwort
+ to=({to,
+ folders[1][akt_folder][nr][MSG_RECIPIENT]})+
+ (pointerp(folders[1][akt_folder][nr][MSG_CC]) ? folders[1][akt_folder][nr][MSG_CC] : ({}))
+ -({name});
+#ifdef DEBUG
+ DEBUGVAR(name);
+ DEBUGVAR(to);
+#endif
+ write_mail(to,GetReTitle(folders[1][akt_folder][nr][MSG_SUBJECT]));
+ return 1;
+}
+
+
+static varargs int Forward(mixed to,mixed nr,int appendflag) {
+ mixed msg;
+ if (!pointerp(folders)||!pointerp(folders[0])||
+ sizeof(folders[0])<=akt_folder) {
+ write("Seltsamer Fehler: Kein aktueller Ordner!\n");
+ return 0;
+ }
+ if (nr<0 || !pointerp(folders[1][akt_folder]) ||
+ sizeof(folders[1][akt_folder])<=nr){
+ write("Nicht so viele Briefe in diesem Ordner!\n");
+ return 0;
+ }
+ to=process_names(to);
+ receiver=to[0];
+ carbon=to[1..];
+ subject="Fw: "+folders[1][akt_folder][nr][MSG_SUBJECT];
+ message="Weitergesendeter Brief, urspruenglich von: "+
+ folders[1][akt_folder][nr][MSG_FROM]+"\n\
+-----------------------------\n\
+"+folders[1][akt_folder][nr][MSG_BODY]+"\
+-----------------------------\n";
+ if (!appendflag) return get_carbon_copy(0),1;
+ else {
+ write("Text kann angehaengt werden\n");
+ get_subject(subject,message);
+ }
+ return 1;
+}
+
+
+
+static int ForwardArea(mixed to,int * nrs) {
+ mixed msg;
+
+ if (!sizeof(nrs)) return 0;
+ if (sizeof(nrs)==1) return Forward(to,nrs[0]);
+ if (sizeof(nrs)>15) LagWarning();
+
+ to=process_names(to);
+ receiver=to[0];
+ carbon=to[1..];
+ subject="Fw: Gesammelte Briefe ("+dtime(time())[5..23]+")";
+ message="";
+ for (i=0;i<sizeof(nrs);i++) {
+ write("Brief "+(nrs[i]+1)+": ");
+ message+=Message2string(nrs[i])+
+ "----------------------------------------------------------------------\n";
+ write("Angehaengt.\n");
+ }
+/*
+ if (!appendflag) {
+*/
+ return get_carbon_copy(0),1;
+/* }
+ else {
+ write("Text kann angehaengt werden\n");
+ get_subject(subject,message);
+ }
+ return 1;
+*/
+}
+
+//----------
+
+
+static int ReadMessage(int nr) {
+ if (nr<sizeof(folders[1][akt_folder]) && nr>=0)
+ akt_nr=nr+1;
+ message=Message2string(nr);
+ if (!message) return 0;
+ this_player()->More(message,0,#'input); //')
+ return 1;
+}
+
+
+static string Message2string(int nr) {
+ mixed letter;
+ string message;
+ int x;
+ if (!pointerp(folders)||!pointerp(folders[0])||
+ sizeof(folders[0])<=akt_folder){
+ write("Seltsamer Fehler: Kein aktueller Ordner!\n");
+ return 0;
+ }
+ if (!pointerp(folders[1][akt_folder]) ||
+ sizeof(folders[1][akt_folder])<=nr ||
+ nr<0) {
+ write("Diese Nummer gibt es in diesem Ordner nicht!\n");
+ return 0;
+ }
+ letter=folders[1][akt_folder][nr];
+ message=
+ "Absender: "+capitalize(letter[MSG_FROM])+"\n"+
+ ((letter[MSG_FROM]==letter[MSG_SENDER]) ? "" :
+ "Abgesandt aber von: "+capitalize(letter[MSG_SENDER])+"\n") +
+ "An: "+capitalize(letter[MSG_RECIPIENT]);
+ if (stringp(letter[MSG_CC]) && letter[MSG_CC]!="" ||
+ pointerp(letter[MSG_CC]) && sizeof(letter[MSG_CC])) {
+ message+="\nCc: ";
+ if (!pointerp(letter[MSG_CC])) message+=capitalize(letter[MSG_CC]);
+ else message+=implode(map(letter[MSG_CC],#'capitalize),", ");//'))
+ }
+ message+="\nDatum: "+letter[MSG_DATE]+"\n"+
+/* Sinnlos, oder? "Id: "+letter[MSG_ID]+"\n"+ */
+ "Titel: "+letter[MSG_SUBJECT]+"\n\n"+
+ letter[MSG_BODY]+"\n\n";
+ return message;
+}
+
+
+static void LagWarning() {
+ write("\
+WARNUNG!!! Diese Aktion kann sehr lange benoetigen. Bitte sparsam verwenden,\n\
+ um das Lag fuer alle ertraeglich zu halten. Falls die Aktion mit einem\n\
+ Fehler abbricht, waren es wahrscheinlich zu viele Briefe auf einmal.\n\
+ Dann kannst Du mit \"mail\" wieder in das Mailmenu einsteigen und solltest\n\
+ es mit weniger Briefen versuchen.\n");
+}
+
+
+static varargs int SaveMessage(int * nrs) {
+ int x,nr;
+ string rest;
+ mixed letter;
+
+ if (!IS_WIZARD(this_player())) {
+ write("Das koennen nur Magier!\n");
+ return 0;
+ }
+ if (!sizeof(nrs)) {
+ write("Speichere nichts.\n");
+ return 1;
+ }
+
+ if ( sizeof(nrs) > 15 ) LagWarning();
+
+ for (nr=0;nr<sizeof(nrs);nr++) {
+ write("Speichere Brief "+(nrs[nr]+1)+": ");
+ letter=Message2string(nrs[nr]);
+ letter+="----------------------------------------------------------------------\n";
+ if (!letter) {
+ write("Speichern unmoeglich.\n");
+ return 0;
+ }
+ if (!write_file(SAVEFILENAME, letter))
+ write("Brief zu lang!\n");
+ else
+ write("Ok.\n");
+ }
+ write("Speichern nach "+SAVEFILENAME+" fertig.\nBitte denk dran, diese Datei wieder zu loeschen!\n");
+ return 1;
+}
+
+// {'}
+
+static void ListAliases() {
+ mixed a;
+ int i;
+ string s;
+ a=sort_array(m_indices(aliases),#'>); // ');
+ s=( "Definierte Aliase:\n"
+ "d.xyz = Alle Mitarbeiter der Domain xyz\n"
+ "freunde = Deine Freunde (entsprechend Freundschaftsband)\n"
+ "me = "+(this_player()->QueryProp(P_MAILADDR))+"\n");
+ for (i=0;i<sizeof(a);i++)
+ if (strstr(aliases[a[i]],"@")==-1) s+=sprintf("%-12s = %s\n",a[i],aliases[a[i]]);
+ write(s);
+}
+
+
+
+/* ------ Das Mailmenue --------------------------------------------------*/
+
+
+static void mail_cmds(string str) {
+
+ string *strargs;
+ int i,nrargs;
+
+ update();
+
+ if (!str || str=="" || !(nrargs=sizeof(strargs=old_explode(str[0..0]+lower_case(str[1..])," ")))) {
+ ListContent();
+ return input();
+ }
+ strargs[0]=strargs[0][0..3];
+ if (IS_NUMBER(strargs[0])) {
+ strargs=({"lies",strargs[0]});
+ nrargs=2;
+ }
+ DEBUGVAR(strargs);
+ switch (strargs[0]) {
+ case "q": // quit
+ case "quit":
+ remove(); return;
+ case "?": // Hilfeseite
+ case "hilf":
+ case "h":
+ MediumHelpPage();
+ return;
+ case "oeff": // change folder
+ case "c":
+ if (nrargs<2) {
+ write("Welchen Ordner willst Du oeffnen (Name, Nummer, +, -)?\n");
+ break;
+ }
+ ChangeFolder(strargs[1]);
+ break;
+ case "ordn": // list folders
+ case "i":
+ ListFolders();
+ break;
+ case "anze": // list content
+ case "l":
+ ListContent();
+ break;
+ case "alia": // list aliases
+ case "a":
+ ListAliases();
+ break;
+ case "erze": // make new folder
+ case "n":
+ if (nrargs<2) {
+ write("Bitte als Argument einen Namen fuer den neuen Ordner angeben!\n");
+ break;
+ }
+ MakeFolder(lower_case(strargs[1]));
+ break;
+ case "entf": // delete folder
+ case "e":
+ if (nrargs<2) {
+ write("Bitte als Argument Name oder Nummer des zu loeschenden Ordners angeben.\n");
+ break;
+ }
+ RemoveFolder(GetFolderName(strargs[1]));
+ break;
+ case "loes": // delete message
+ case "d":
+ if (nrargs==1) DeleteMessage(({akt_nr-1}));
+ else DeleteMessage(GetNumbers(strargs[1..]));
+ break;
+ case "schr": // write mail
+ case "m":
+ if (nrargs<2) {
+ write("Bitte Empfaenger als Argument angeben!\n");
+ break;
+ }
+ write_mail(strargs[1..]);
+ return;
+ case "vers": // move message to other folder
+ case "verl":
+ case "v":
+ if (nrargs<2 || (nrargs>2 && !IS_NUMBER(strargs[1]))) {
+ write("Syntax: v [nr|nr-nr [nr|nr-nr ...]] <ordnername>|<ordnernr>|+|-\n");
+ break;
+ }
+ if (nrargs==2) MoveMessage(({akt_nr-1}),GetFolderName(strargs[1]));
+ else MoveMessage(GetNumbers(strargs[1..<2]),GetFolderName(strargs[<1]));
+ update(0,1); // unbedingt neuladen.
+ break;
+ case "bean":
+ case "r":
+ case "grup":
+ case "g":
+ if (nrargs<2) {
+ if (Reply(akt_nr-1,(strargs[0][0]=='g'))) return;
+ break;
+ }
+ if (!IS_NUMBER(strargs[1])) {
+ write("Argumentfehler: Bitte Nummer des Briefes angeben, auf den sich die Antwort\n"
+ "beziehen soll. Ohne Argument bezieht sie sich auf den aktuellen Brief.\n");
+ break;
+ }
+ if (nrargs>2) {
+ write("Zu viele Argumente. Eine Antwort darf sich nur auf einen Brief beziehen!\n");
+ break;
+ }
+ if (Reply(to_int(strargs[1])-1,(strargs[0][0]=='g'))) return;
+ break;
+ case "weit":
+ case "f":
+ if (nrargs<2 ||
+ (IS_NUMBER(strargs[nrargs-1])&&sizeof(old_explode(strargs[nrargs-1],"@"))==1)) {
+ write("Syntax: f [nr|nr-nr [nr|nr-nr ...]] empfaenger [empf2 ...]\n");
+ break;
+ }
+ if (!IS_NUMBER(strargs[1])) {
+ if (Forward(strargs[1..],akt_nr-1)) return;
+ } // return, nicht break: input() wird von get_carbon_copy() aufger.
+ else {
+ int pos; // letzte Position, an der eine Nummer steht
+
+ for (pos=nrargs-1;pos>1&&!IS_NUMBER(strargs[pos]);pos--);
+ if (ForwardArea(strargs[(pos+1)..],GetNumbers(strargs[1..pos])))
+ return;
+ }
+ break;
+ case "Weit":
+ case "F":
+ if (nrargs<2 || (nrargs==2 && IS_NUMBER(strargs[1]))) {
+ write("Haeh? Bitte so: F [nr] empfaenger\n");
+ break;
+ }
+ if (!IS_NUMBER(strargs[1])) {
+ if (Forward(strargs[1..],akt_nr-1,1)) return;
+ break;
+ }
+ if (IS_NUMBER(strargs[2])||member(strargs[1],'-')>=0) {
+ write("Argumentfehler: Wenn Du eigenen Text anhaengen willst, darfst Du nur einen\n"
+ "Brief angeben, nicht mehrere.\n");
+ break;
+ }
+ if (Forward(strargs[2..],to_int(strargs[1])-1,1)) return;
+ break;
+ case "lies":
+ if (nrargs<2) { if (ReadMessage(akt_nr-1)) return; } else
+ if (ReadMessage(to_int(strargs[1])-1)) return;
+ break;
+ case ".":
+ if (ReadMessage(akt_nr-1)) return;
+ break;
+ case "+":
+ if (akt_nr==sizeof(folders[1][akt_folder]))
+ write("Noch weiter vorwaerts gehts nicht!\nMit 'c +' kannst Du den naechsten Ordner oeffnen.\n");
+ else if (ReadMessage(akt_nr)) return;
+ break;
+ case "-":
+ if (akt_nr==1)
+ write("Noch weiter zurueck gehts nicht!\nMit 'c -' kannst Du den vorhergehenden Ordner oeffnen.\n");
+ else if (ReadMessage(akt_nr-2)) return;
+ break;
+ case "spei":
+ case "s":
+ if ((nrargs==2 && !IS_NUMBER(strargs[1]))) {
+ write("Syntax: s [nr|nr-nr [nr|nr-nr ...]]\n");
+ break;
+ }
+ if (nrargs==1) (SaveMessage(({akt_nr-1})));
+ else (SaveMessage(GetNumbers(strargs[1..])));
+ break;
+ default:
+ write("Kommando nicht verstanden. Eine Hilfsseite bekommst Du mit 'h'.\n");
+ break;
+ }
+ return input();
+}
+
+
+/*------------------------------------------------------------------------*/
+
+static string prompt() {
+ string path;
+
+ update();
+ if (!pointerp(folders)||!pointerp(folders[0])||
+ sizeof(folders[0])<=akt_folder)
+ path="(kein Ordner)";
+ else
+ path= "(" + folders[0][akt_folder] + ":" +
+ ( sizeof(folders[1][akt_folder]) ?
+ akt_nr + "/" + sizeof(folders[1][akt_folder]) :
+ "leer") + ")";
+ return(path + " [Hilfe mit h] => ");
+}
+
+
+static void input() {
+ //prompt();
+ input_to("mail_cmds", INPUT_PROMPT, prompt());
+ return;
+}
+
+
+static mixed GetAlias(mixed a);
+
+#ifdef MAIL_SUPPORT_BCC
+static mixed RecurseProcessNames(mixed a);
+#endif
+
+
+static mixed process_names(mixed s) {
+ mixed a1,a2,h;
+ int i;
+ string domain;
+
+ if (stringp(s)) {
+ a1=explode(regreplace(lower_case(s),","," ",1)," ")-({""});
+ }
+ else a1=s;
+ a2=({});
+ foreach(string str: a1)
+ a2+=explode(str,",");
+
+ a1=({});
+
+// printf("DEBUG ANFANG: %O\n",a2);
+
+ foreach(string str: a2) {
+ if( !sizeof(str) ) continue;
+ if (sscanf(str,"d.%s",domain)) {
+ h=(get_dir("/d/"+domain+"/*")||({}))-({".",".."});
+ // h immer ein Array
+ h=filter(h,#'query_wiz_level);
+ if (sizeof(h))
+ a1+=h;
+ else
+ a1+=({"d."+domain});
+ }
+ else if (str=="freunde")
+ a1+=("/p/service/tiamak/obj/fbmaster"->get_friends(getuid(this_player()), 8));
+ else if (str=="me")
+ a1+=({this_player()->QueryProp(P_MAILADDR)});
+ else if (aliases[str])
+ a1+=GetAlias(str);
+#ifdef MAIL_SUPPORT_BCC
+ else if (str[0]=='-')
+ a1+=map(RecurseProcessNames(str[1..]), function string (string x) {
+ return("-"+x);});
+#endif
+ else if ( (str[0]>='a' && str[0]<='z')
+ || (sscanf(str,"%s@%s",domain,domain))
+ || str[0]=='\\')
+ a1+=({str});
+ }
+
+// printf("DEBUG ENDE: %O\n",a1);
+
+ a1=filter(a1,function int (string x)
+ { return(sizeof(x)>1); } );
+
+ return(map(a1,#'lower_case));
+}
+
+
+static mixed GetAlias(mixed a) { return process_names(aliases[a]); }
+#ifdef MAIL_SUPPORT_BCC
+static mixed RecurseProcessNames(mixed a) { return process_names(a); }
+#endif
+
+
+static mapping Read_mailrc(string file) {
+ mapping al;
+ int i;
+ mixed ar;
+ string s1,s2;
+
+ if (!(ar=read_file(file))) {
+// write(file+" not readable\n");
+ return ([]);
+ }
+ al=([]);
+ ar=explode(ar,"\n");
+ for (i=sizeof(ar)-1;i>=0;i--)
+ if (sscanf(ar[i],"%s %s",s1,s2)==2)
+ al+=([s1:s2]);
+// printf("Got aliases %O",al);
+ return al;
+}
+
+
+string * unify_array(string * a) {
+// int i;
+// for (i=sizeof(a)-1;i>=0;i--) a=a-({a[i]})+({a[i]});
+// Rikus 14.02.2001
+ a=m_indices(mkmapping(a));
+ return a;
+}
+
+
+string GetReTitle(string s) {
+ int nr,s2;
+
+ if (!s) s="";
+ if (s[0..7]=="Re: Re: ") return "Re^3: "+s[8..];
+ else if (sscanf(s,"Re^%d: %s",nr,s2))
+ return "Re^"+(nr+1)+": "+s2;
+ else return "Re: "+s;
+}
+
+
+int * GetNumbers(mixed s) {
+ int i,h1,h2;
+ mixed ret;
+
+ if (intp(s)) return ({s-1});
+ if (stringp(s)) s=({s-1});
+ if (!pointerp(s)) return 0;
+
+ ret=({});
+
+ for (i=sizeof(s)-1;i>=0;i--) {
+ if (sscanf(s[i],"%d-%d",h1,h2)==2) {
+ if (h2-h1>100) {
+ write("Nicht so viele auf einmal, bitte.\n");
+ return ({});
+ }
+ for (h1--;h1<h2;h1++) ret=ret-({h1})+({h1});
+ }
+ else
+ ret=ret-({h1=to_int(s[i])-1})+({h1});
+ }
+ ret=sort_array(ret,#'>); //')
+ DEBUGVAR(ret);
+ if (ret[0]<0) {
+ write("Illegale Nummer: "+(ret[0]+1)+", nichts unter 1 bitte!\n");
+ return ({});
+ }
+ if (ret[<1]>=sizeof(folders[1][akt_folder])) {
+ write("Illegale Nummer: "+(ret[<1]+1)+", so gross ist dieser Ordner nicht!\n");
+ return ({});
+ }
+ return ret;
+}
+
+
+/*
+int is_number(string s) {
+ return (s[0]>='0'&&s[0]<='9');
+}
+*/
+
+
+string GetFolderName(mixed fol) { // int oder string. alles andere -> Fehler!
+ mixed h;
+
+ if (fol=="+") fol=akt_folder+1;
+ if (fol=="-") fol=akt_folder-1;
+ if ((!fol)||(intp(fol))||(IS_NUMBER(fol))) {
+ if (!intp(fol)) fol=to_int(fol)-1;
+ if (fol<0||fol>=sizeof(folders[0]))
+ return write("Einen Ordner mit Nummer "+(fol+1)+" gibt es nicht.\n"),0;
+ return folders[0][fol];
+ }
+ fol=lower_case(fol);
+ if (sizeof(h=regexp(folders[0],"^"+fol))==1) return h[0];
+ if (member(folders[0],fol)==-1)
+ return write("Einen Ordner mit Namen "+fol+" hast Du nicht.\n"),0;
+ return fol;
+}
+
+int query_prevent_shadow() { return 1; }