blob: 56c9b89fc75210d8715f18d1568e6c09dba6a0c9 [file] [log] [blame]
/* =========================================================================
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(int limit);
string GetFolderName(mixed fol);
static void LagWarning();
string GetReTitle(string s);
static string Message2string(int nr);
int * GetNumbers(mixed s);
protected 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);
}
public varargs void init(object origin) {
(::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.
int 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);
int display_limit;
if (str)
{
str = lower_case(str);
// Eingabestring zerlegen, um die Elemente der Reihe nach parsen zu
// koennen.
string* params = explode(str, " ");
string* recipients = ({});
/* Ueber alle Argumente laufen und auf Verwendbares pruefen.
Muss for() sein, damit wir zwischendrin mittels p++ Eintraege
ueberspringen koennen.
Gueltige Argumente sind -show [<zahl>|zeilen], -silent,
Empfaengerliste.
Wenn hinter -show irgendwas kommt, das weder Integer noch "zeilen"
ist, wird es verworfen.
Wenn irgendwelche Empfaenger angegeben sind, wird auf jeden Fall
an write_mail() weitergegeben, egal was sonst fuer Argumente
dabeiwaren. Dies ist Absicht, damit man sich z.B. ein Alias
"mail -show 20 $*" bauen kann, das ohne weitere Angaben den
Posteingang oeffnet, aber eine neue Mail erstellt, wenn man dahinter
einen Empfaenger angibt. Auf diese Weise kann man einen im Alias
eingestellten Defaultwert bei der Eingabe des Befehls immer noch
mit -silent oder einer anderen Zahl ueberschreiben. */
int p;
for(p=0; p<sizeof(params); p++)
{
// Wenn das Argument -silent ist, Flag setzen.
if (params[p] == "-silent")
{
display_limit = 0;
silent = 1;
}
// Wenn es -show ist, checken wir ob das Array noch ein weiteres
// Element enthaelt und wenn ja, werten wir es aus und
else if (params[p] == "-show")
{
// hat das Array noch ein Element nach -show?
if (sizeof(params) >= p+2)
{
// wenn ja, ist es ein String ungleich Leerstring?
if (sizeof(params[p+1]))
{
string howmany = params[p+1];
// "zeilen" zuerst checken, weil das sonst im naechsten Check
// auch zu silent = 1 fuehren wuerde.
if (howmany == "zeilen")
display_limit = this_player()->QueryProp(P_SCREENSIZE);
// Kann man es in ein Integer >0 wandeln?
// Wenn 0 rauskommt, wurde entweder "-show 0" angegeben, oder
// ein ungueltiger Parameter. Beides interpretieren wir als
// "silent".
else if (to_int(howmany) == 0)
silent = 1;
// Alle anderen Ergebnisse werden als Zeilenlimit fuer die
// Anzeige interpretiert.
else
display_limit = to_int(howmany);
}
// Argumente nach -show werden in jedem Fall nicht nochmal
// verarbeitet, d.h. ein Schleifendurchlauf wird uebersprungen.
p++;
}
}
// Alles andere duerfte dann wohl ein Adressat sein.
else
{
recipients += ({params[p]});
}
}
// Wenn wir potentielle Empfaenger identifiziert haben, bauen wir den
// Argumentstring neu zusammen, damit wir ihn spaeter an write_mail()
// uebergeben koennen.
if(sizeof(recipients))
{
str = implode(recipients, " ");
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(display_limit);
}
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;
}
// MSG_TIME enthaelt leider einen Datumsstring, so dass wir die MSG_ID
// verwenden, um die Zeit daraus zu ermitteln. Die MSG_ID hat immer das
// Format MUDNAME+":"+time().
private string msgIDtoTime(string msg_id) {
int msg_time;
string unused;
// Damit das auch dann funktioniert, wenn man die Mailfolder aus dem
// Livemud im Testmud einliest, das ja ggf. einen anderen Namen hat,
// verwenden wir einen generischen Suchstring. Das Mud sollte dann aber
// keinen : im Namen haben.
if (sscanf(msg_id, "%s:%d", unused, msg_time) == 2)
return strftime("%d.%m.%Y", msg_time);
else
return "unbekannt";
}
static varargs void ListContent(int limit) {
update();
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;
}
int mailcount = sizeof(folders[1][akt_folder]);
write(sprintf("%d Brief%s\n", mailcount, mailcount!=1 ? "e" : ""));
// Wieviele Zeichen muessen wir fuer die fortlaufenden Mail-Nummern
// reservieren? Dazu errechnen wir die Anzahl Ziffern der Arraygroesse.
int num_width = sizeof(to_string(mailcount));
// 4 Zeichen muessen reichen, damit sind immerhin 9999 Mails numerierbar.
num_width = min(4, num_width);
int sender_width;
string sender_name;
// Feldbreite fuer die Absenderangabe ermitteln. Wird weiter unten fuer
// die Anzeige der Mails benoetigt, um das Namensfeld dynamisch
// einzustellen. Dies soll helfen, mehr vom Subject anzeigen zu koennen.
// Leider muessen wir dazu einmal extra ueber die Liste laufen.
int i;
if (limit) {
limit = max(mailcount - limit, 0);
}
for (i = limit ; i < mailcount ; i++) {
sender_name = folders[1][akt_folder][i][MSG_FROM];
if (sizeof(sender_name) > sender_width)
sender_width = sizeof(sender_name);
// Wenn wir schon die max. Namenslaenge fuer Spieler erreicht haben,
// muss der Rest nicht mehr durchlaufen werden.
if (sender_width >= 11) {
// Groesse beschraenken; es kann sein, dass alte Mailboxen noch Mails
// von extern enthalten, und deren Mailadressen sprengen dann das
// Format.
sender_width = min(11, sender_width);
break;
}
}
// Subject-Breite anpassen, je nach Groesse der anderen dynamischen Felder.
// sender_width ist max 11, num_width ist max 4.
int subject_width = 46+(11-sender_width)+(4-num_width);
/* Format der Zeile. Wir bauen dynamische Feldbreiten an den Stellen ein,
wo es sinnvoll ist, und haben um den Mailzaehler herum zwei String-
Felder, die die Markierung fuer die aktuell bearbeitete Mail aufnehmen.
Absender und Betreffzeile werden durch den : im Formatcode
abgeschnitten. Es muss insbesondere beim Absender der : verwendet
werden, damit laengere Namen abgeschnitten werden, bei kuerzeren aber
korrekt mit Leerzeichen aufgefuellt wird. Verwendet man stattdessen
den ., macht sprintf() das nicht.
Beispiel einer Zeile mit markierter Mail:
[125:](Spielername, 18.12.2019) Test
^_^ ^---------^ ^--^
| | |
num_width sender_width subject_width */
string lineformat = "%s%"+num_width+"d:%s"+ // Mail-Zaehler
"(%:"+sender_width+"s, %10s) "+ // Absender + Datum
"%:-"+subject_width+"s\n"; // Betreffzeile
for (i = limit ; i < mailcount ; i++) {
// Leeres Subject wird als 0 gespeichert. Falls das zutrifft, wird das
// hier beruecksichtigt.
string subject = folders[1][akt_folder][i][MSG_SUBJECT];
if (!stringp(subject) || !sizeof(subject))
subject = "<kein Betreff>";
write(sprintf(lineformat,
(i+1==akt_nr) ? "[" : " ",
i+1,
(i+1==akt_nr) ? "]" : " ",
capitalize(folders[1][akt_folder][i][MSG_FROM]),
msgIDtoTime(folders[1][akt_folder][i][MSG_ID]),
subject
));
}
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; }