Zesstra | 25387d9 | 2017-02-03 20:20:56 +0100 | [diff] [blame] | 1 | /* ========================================================================= |
| 2 | |
| 3 | Ein Mailobjekt fuer Morgengrauen. |
| 4 | (C) 1993-97 Loco@MG. Unter Verwendung des std/post-codes von Jof |
| 5 | |
| 6 | Verwendung ausserhalb von Morgengrauen ist gestattet unter folgenden |
| 7 | Bedingungen: |
| 8 | - Benutzung erfolgt auf eigene Gefahr. Jegliche Verantwortung wird |
| 9 | abgelehnt. |
| 10 | - Auch in veraenderten oder abgeleiteten Objekten muss ein Hinweis auf |
| 11 | die Herkunft erhalten bleiben. |
| 12 | - Bitte Loco Bescheid sagen. |
| 13 | Ein Update-Service besteht nicht. Diese Lizenz kann jederzeit |
| 14 | zurueckgezogen werden. |
| 15 | |
| 16 | Letzte Aenderungen: |
| 17 | 190494 [Loco] mail <spieler> fuehrt nicht ins mailmenue anschliessend. |
| 18 | 280494 [Loco] .mailrc |
| 19 | 020594 [Loco] system.mailrc, aliase anzeigen, Text retten, selfdestruct |
| 20 | in reset() im Fehlerfall, kleinere bugfixes |
| 21 | 070794 [Loco] Kleinigkeiten (bugfixes und Optimierungen), '+' |
| 22 | 231195 [Loco] Bereiche bei Speichern und Loeschen |
| 23 | 171295 [Loco] Bereiche bei forward. Stapelweise Kleinigkeiten. |
| 24 | 191295 [Loco] Kleinere Zeitoptimierungen, teilweise schiefgelaufen und |
| 25 | deswegen doch nicht, minor bugfixes. |
| 26 | 190295 [Loco] keine folderlist beim hochstarten |
| 27 | 110696 [Loco] Forwardserver-Unterstuetzung (.forward-aehnlich) |
| 28 | 031296 [Loco] major update: |
| 29 | Erlaube in der Blueprint nichtinteraktives Versenden |
| 30 | vorbereiteter mails (z.B. fuer mpa: versende artikel); |
| 31 | Zeitoptimierungen durch effektiveres caching; |
| 32 | '-'; |
| 33 | Einige optische Aenderungen; |
| 34 | Warnung bei grossen mailfiles; |
| 35 | Unterstuetzung von bcc's; |
| 36 | d,m,f,s erlauben Listen; |
| 37 | Abkuerzungen und '-' bei Folderargumenten |
| 38 | 080297 [Loco] Zeitoptimierungen, interne Aenderungen, Bugfixes |
| 39 | 280103 [Muadib]Silentflag |
| 40 | 020304 [Vanion]In do_mail() wird jetzt M_NOCHECK gemovet, sonst hat ein |
| 41 | Mailer eines Spielers, der voll ist, kein Environment. |
| 42 | 100105 [Zook] Magier mit Level >= 26 bekommen erst spaeter eine |
| 43 | Mitteilung (Gebietswartung insb. f. Regionsmagier |
| 44 | erfordert schlicht ein groesseres Postfach). |
| 45 | |
| 46 | ---------------------------------------------------------------------------- |
| 47 | |
| 48 | Aufrufe von aussen zur Benutzung: |
| 49 | |
| 50 | a) im geklonten Objekt: |
| 51 | obj->do_mail() interaktives Mailmenue |
| 52 | obj->do_mail(empf) 'halbinteraktiv': _eine_ mail, an Empfaenger str |
| 53 | Objekt zerstoert sich nach Gebrauch selbst. |
| 54 | Bei obj->do_mail("-silent") wird der Inhalt des Mailfolders nicht |
| 55 | aufgelistet. Ansonsten wie obj->do_mail() |
| 56 | |
| 57 | b) in der blueprint: nur non-interactive |
| 58 | obj->do_mail(empf,titel,text) |
| 59 | sendet mail mit Titel titel und Inhalt text an Empfaenger empf. |
| 60 | Aliase etc. werden von this_interactive() genommen. |
| 61 | Nur fuer 'trusted objects' zugelassen, siehe #define TRUSTED |
| 62 | |
| 63 | =========================================================================== */ |
| 64 | |
| 65 | #include "post.h" |
| 66 | |
Zesstra | afd72e0 | 2017-02-03 20:32:56 +0100 | [diff] [blame^] | 67 | inherit "/std/thing"; |
Zesstra | 25387d9 | 2017-02-03 20:20:56 +0100 | [diff] [blame] | 68 | //inherit "std/more"; // wird vom nedit inherited |
| 69 | inherit NEDIT; |
| 70 | |
| 71 | #include <properties.h> |
| 72 | #include <language.h> |
| 73 | #include <config.h> |
| 74 | #include <mail.h> |
| 75 | #include <wizlevels.h> |
| 76 | #include <moving.h> |
| 77 | #include <defines.h> |
| 78 | #include <input_to.h> |
| 79 | |
| 80 | #undef DEBUG |
| 81 | |
| 82 | #define TRUSTED(o) (objectp(o) && BLUE_NAME(o)=="/obj/mpa") |
| 83 | // (geteuid(o)=="p:service"|| \ |
| 84 | // geteuid(o)==geteuid(this_interactive()))) |
| 85 | |
Zesstra | afd72e0 | 2017-02-03 20:32:56 +0100 | [diff] [blame^] | 86 | #define MAILFILE(name) (MAILPATH+name[0..0]+"/"+name) |
Zesstra | 25387d9 | 2017-02-03 20:20:56 +0100 | [diff] [blame] | 87 | #define MAILFILEO(name) (MAILFILE(name)+".o") |
| 88 | #define MAILDEMON0297 // Maildemon-Version 8.Feb.97 vorhanden? |
| 89 | |
| 90 | #define IS_NUMBER(n) (stringp(n) && sizeof(n) && n[0]>='0' && n[0]<='9') |
| 91 | |
| 92 | #ifdef DEBUG |
| 93 | #define DEBUGVAR(x) if(find_player("tiamak")) tell_object(find_player("tiamak"),sprintf("Value of x is %O\n",x)) |
| 94 | #else |
| 95 | #define DEBUGVAR(x) |
| 96 | #endif |
| 97 | |
| 98 | // Zaehlung: akt_nr ab 1, akt_folder ab 0 |
| 99 | |
| 100 | static string subject, message, receiver, sender, *carbon; |
| 101 | #ifdef MAIL_SUPPORT_BCC |
| 102 | static string* blindcarbon; |
| 103 | #endif |
| 104 | static string name, office_name; |
| 105 | static int done, akt_folder, i, akt_nr, directflag; |
| 106 | static int folder_size,folder_date; // cacheverwaltung |
| 107 | static mapping aliases; |
| 108 | |
| 109 | mixed *folders; |
| 110 | |
| 111 | // Prototypen, die nun mal gebraucht werden |
| 112 | |
| 113 | static varargs void SendMail(string text,int flag); |
| 114 | static void input(); |
| 115 | static mixed process_names(mixed s); |
| 116 | static void get_carbon_copy(string str); |
| 117 | static varargs string* send_mail(mixed back); |
| 118 | string * unify_array(string * a); |
| 119 | static mapping Read_mailrc(string file); |
| 120 | static varargs void update(int directflag,int nocondflag); |
| 121 | static varargs void ListContent(); |
| 122 | string GetFolderName(mixed fol); |
| 123 | static void LagWarning(); |
| 124 | string GetReTitle(string s); |
| 125 | static string Message2string(int nr); |
| 126 | int * GetNumbers(mixed s); |
| 127 | |
| 128 | void create() { |
| 129 | (::create()); |
| 130 | seteuid(getuid()); |
| 131 | SetProp(P_IDS,({"mailer"})); |
| 132 | SetProp(P_NAME,"mailer"); |
| 133 | office_name="Morgengrauens Post"; |
| 134 | akt_folder=-1; |
| 135 | folder_size=folder_date=-42; |
| 136 | SetProp(P_NODROP,1); |
| 137 | SetProp(P_SHORT,0); |
| 138 | SetProp(P_WEIGHT,0); |
| 139 | } |
| 140 | |
| 141 | |
| 142 | void init() { |
| 143 | (::init()); |
| 144 | init_rescue(); |
| 145 | add_action("postneustart","post"); |
| 146 | add_action("postneustart","mail"); |
| 147 | } |
| 148 | |
| 149 | |
| 150 | void reset() { |
| 151 | object pl; |
| 152 | (::reset()); |
| 153 | if (!name) {remove();return;} |
| 154 | pl=find_player(name); |
| 155 | if (!pl || environment()!=pl) {remove();return;} |
| 156 | if (nedittext && !query_input_pending(pl)) { |
| 157 | tell_object(pl,"\ |
| 158 | *** Hoppla! Du hast noch einen nicht fertiggeschriebenen Brief!\n\ |
| 159 | *** Mit ~r kannst Du weiterschreiben.\n"); |
| 160 | return; |
| 161 | } |
| 162 | if (query_input_pending(pl)!=this_object()) |
| 163 | {remove();return;} |
| 164 | } |
| 165 | |
| 166 | |
| 167 | mixed postneustart() { |
| 168 | if (!this_interactive() || name!=geteuid(this_interactive()) |
| 169 | || query_input_pending(this_interactive()) |
| 170 | || this_interactive()!=this_player()) return 0; |
| 171 | write("Und weiter gehts...\n"); |
| 172 | if (nedittext) return RescueText(); |
| 173 | return input(); |
| 174 | } |
| 175 | |
| 176 | |
| 177 | string SetOfficeName(string n) { |
| 178 | return office_name=n; |
| 179 | } |
| 180 | |
| 181 | |
| 182 | static varargs void write_mail(mixed str, string std_subject, string text) { |
| 183 | string str2; |
| 184 | int h; |
| 185 | |
| 186 | carbon=process_names(str); |
| 187 | if (!sizeof(carbon)) { |
| 188 | write("Kein Empfaenger angegeben!\n"),(directflag?remove():input()); |
| 189 | return; |
| 190 | } |
| 191 | write("Empfaenger: "+implode(map(carbon,#'capitalize/*'*/),", ")+"\n"); |
| 192 | str=carbon[0]; |
| 193 | if (sizeof(carbon)>=2) carbon=carbon[1..<1]; |
| 194 | else carbon=0; |
| 195 | if ((str2=str) && str2!="" && str2[0]=='\\') str2=str2[1..]; |
| 196 | if (!str) { write("WEM willst Du schreiben?\n"),(directflag?remove():input()); return; |
| 197 | } |
| 198 | if (!master()->find_userinfo(str2) && member(str2,'@')==-1) |
| 199 | { |
| 200 | write("Mit dem Namen gibt es hier niemanden.\n"),(directflag?remove():input()); |
| 201 | return; |
| 202 | } |
| 203 | |
| 204 | receiver=str; |
| 205 | |
| 206 | if (text) { |
| 207 | subject=std_subject; |
| 208 | return SendMail(text,1); // flag 1: keine CC's bitte. |
| 209 | } |
| 210 | |
| 211 | //write("Titel"); |
| 212 | //if (std_subject) write(" ("+std_subject+")"); |
| 213 | //write(": "); |
| 214 | string pr; |
| 215 | if (std_subject) pr = "Titel ("+std_subject+"): "; |
| 216 | else pr = "Titel: "; |
| 217 | subject=std_subject; |
| 218 | input_to("get_subject",INPUT_PROMPT,pr); |
| 219 | return; |
| 220 | } |
| 221 | |
| 222 | |
| 223 | static varargs void get_subject(string str,string pretext) { |
| 224 | DEBUGVAR(str); |
| 225 | DEBUGVAR(subject); |
| 226 | if ((!str||str=="") && !subject) |
| 227 | { |
| 228 | input_to("get_subject",INPUT_PROMPT,"Titel (Abbrechen mit ~q): "); |
| 229 | return; |
| 230 | } |
| 231 | if (str=="~q"||str=="~Q") return SendMail(0); // entspricht Abbruch im Editor. |
| 232 | if (str && str!="") subject=str; |
| 233 | write("Bitte gib jetzt Deine Nachricht an:\n\ |
| 234 | ** oder . wenn fertig, ~q fuer Abbruch, ~h fuer eine Hilfsseite\n"); |
| 235 | nedit("SendMail",pretext); |
| 236 | } |
| 237 | |
| 238 | |
| 239 | static varargs void SendMail(string text,int flag) { |
| 240 | // flag: 1 = keine CC abfragen. |
| 241 | if (!text) { |
| 242 | write("Abbruch! Brief landet im Reisswolf.\n"); |
| 243 | if (directflag) {remove(); return; |
| 244 | } |
| 245 | |
| 246 | subject=receiver=carbon=message=0; |
| 247 | return input(); |
| 248 | } |
| 249 | message=text; |
| 250 | if (flag) return get_carbon_copy(0); |
| 251 | //write("Cc: "); |
| 252 | input_to("get_carbon_copy",INPUT_PROMPT, "Cc: "); |
| 253 | return; |
| 254 | } |
| 255 | |
| 256 | |
| 257 | static void get_carbon_copy(string str) { // Aufruf mit 0, wenn keine cc gewuenscht. |
| 258 | int i,j; |
| 259 | object p; |
| 260 | string *oldcarbons,*h,*receivers; |
| 261 | mapping orignames; |
| 262 | |
| 263 | oldcarbons=carbon; |
| 264 | if (str=="~q") return SendMail(0); // Abbruch, entspricht Abbruch im Editor |
| 265 | if (!str || str=="") carbon=0; |
| 266 | else carbon=process_names(str); |
| 267 | carbon=(oldcarbons ? oldcarbons : ({}))+(carbon ? carbon : ({})); |
| 268 | |
| 269 | #ifdef MAIL_SUPPORT_BCC |
| 270 | blindcarbon=filter(carbon, |
| 271 | function status (string x) |
| 272 | {if (x[0]=='-') return(1); |
| 273 | return(0);}); |
| 274 | carbon-=blindcarbon; |
| 275 | blindcarbon=map(blindcarbon, |
| 276 | function string (string x) |
| 277 | {return(x[1..]);} ); |
| 278 | #endif |
| 279 | |
| 280 | #ifdef MAIL_SUPPORT_BCC |
| 281 | oldcarbons=({receiver})+carbon+blindcarbon; // speichere alle Originaladressen |
| 282 | #else |
| 283 | oldcarbons=({receiver})+carbon; |
| 284 | #endif |
| 285 | |
| 286 | /* Forwards auswerten, dabei werden auch ungueltige Adressen gefiltert */ |
| 287 | /* orignames speichert die Zuordnung Zieladressen -> Originaladressen */ |
| 288 | |
| 289 | orignames=([]); |
| 290 | h=explode(FWSERV->QueryForward(receiver),","); |
| 291 | |
| 292 | DEBUGVAR(h); |
| 293 | for (j=sizeof(h);j--;) |
| 294 | orignames[(h[j][0]=='\\'?h[j][1..]:h[j])]=({receiver[0]=='\\'?receiver[1..]:receiver}); |
| 295 | receiver=h[0]; |
| 296 | receivers=h[1..]; // Missbrauch dieser Variable! |
| 297 | |
| 298 | DEBUGVAR(orignames); |
| 299 | |
| 300 | for (i=sizeof(carbon);i--;) { |
| 301 | h=explode(FWSERV->QueryForward(carbon[i])||"",","); |
| 302 | for (j=sizeof(h);j--;) { |
| 303 | h[j]=(h[j][0]=='\\'?h[j][1..]:h[j]); |
| 304 | orignames[h[j]]=(orignames[h[j]]||({}))+({carbon[i][0]=='\\'?carbon[i][1..]:carbon[i]}); |
| 305 | receivers+=h; |
| 306 | } |
| 307 | } |
| 308 | carbon=receivers; |
| 309 | |
| 310 | #ifdef MAIL_SUPPORT_BCC |
| 311 | receivers=({}); |
| 312 | for (i=sizeof(blindcarbon)-1;i>=0;i--) { |
| 313 | h=old_explode(FWSERV->QueryForward(blindcarbon[i]),","); |
| 314 | for (j=sizeof(h)-1;j>=0;j--) { |
| 315 | h[j]=(h[j][0]=='\\'?h[j][1..]:h[j]); |
| 316 | orignames[h[j]]=(orignames[h[j]]||({}))+({blindcarbon[i][0]=='\\'?blindcarbon[i][1..]:blindcarbon[i]}); |
| 317 | receivers+=h; |
| 318 | } |
| 319 | } |
| 320 | blindcarbon=receivers; |
| 321 | #endif |
| 322 | |
| 323 | carbon=send_mail(); |
| 324 | receivers=({}); |
| 325 | |
| 326 | if (!pointerp(carbon) || !sizeof(carbon)){ |
| 327 | write("Brief NICHT verschickt, da keine Empfaenger gefunden!\n"); |
| 328 | } else { |
| 329 | string *a; |
| 330 | DEBUGVAR(orignames); |
| 331 | for (i=0;i<sizeof(carbon);i++){ |
| 332 | DEBUGVAR(carbon[i]); |
| 333 | /* evtl. abfragen nach query_editing und/oder query_input_to */ |
| 334 | /* Benachrichtige Spieler, die ein forward gesetzt haben */ |
| 335 | a=orignames[carbon[i]]; |
| 336 | if (pointerp(a)) |
| 337 | { |
| 338 | a=a-({carbon[i]}); |
| 339 | for (j=sizeof(a);j--;) |
| 340 | if (p=find_player(a[j])) |
| 341 | tell_object(p,"Ein Postreiter ruft Dir aus einiger Entfernung zu, dass Du neue Post hast!\nDer Brief wurde wunschgemaess weitergeleitet.\n"); |
| 342 | } |
| 343 | /* Benachrichtige Empfaenger */ |
| 344 | #ifndef MAILDEMON0297 |
| 345 | if (p=find_player(carbon[i])) |
| 346 | tell_object(p,"Ein Postreiter ruft Dir aus einiger Entfernung zu, dass Du neue Post hast!\n"); |
| 347 | #endif |
| 348 | receivers+=orignames[carbon[i]]||orignames["\\"+carbon[i]]||({}); |
| 349 | } |
| 350 | DEBUGVAR(carbon); |
| 351 | write("Abgesandt an: "+implode(unify_array(map(receivers,#'capitalize)),", ")+"\n");//'))); |
| 352 | } |
| 353 | for (i=sizeof(oldcarbons);i--;) |
| 354 | if (oldcarbons[i][0]=='\\') |
| 355 | oldcarbons[i]=oldcarbons[i][1..]; |
| 356 | oldcarbons=oldcarbons-receivers; |
| 357 | if (sizeof(oldcarbons)) { |
| 358 | write("Empfaenger unbekannt: "+implode(map(oldcarbons,#'capitalize),", ")+"\nIrgendjemand wirft Dir den zurueckgekommenen Brief zu.\n");//'))) |
| 359 | send_mail(oldcarbons); |
| 360 | } |
| 361 | |
| 362 | message=receiver=carbon=subject=0; |
| 363 | if (directflag) { |
| 364 | if (directflag==1) remove(); // 1: Direktmodus, 2: non-interactive |
| 365 | return; |
| 366 | } |
| 367 | return input(); |
| 368 | } |
| 369 | |
| 370 | |
| 371 | static varargs string* send_mail(mixed back) { |
| 372 | mixed *mail; |
| 373 | |
| 374 | mail=allocate(9); |
| 375 | |
| 376 | #ifdef DEBUG |
| 377 | DEBUGVAR(receiver); |
| 378 | DEBUGVAR(carbon); |
| 379 | #endif |
| 380 | |
| 381 | if (!pointerp(carbon) || !sizeof(carbon)) carbon=0; |
| 382 | mail[MSG_FROM]=this_player()->query_real_name(); |
| 383 | mail[MSG_SENDER]=office_name; |
| 384 | mail[MSG_RECIPIENT]=(back ? mail[MSG_FROM] : receiver); |
| 385 | mail[MSG_CC]=(back ? 0 : carbon); |
| 386 | #ifdef MAIL_SUPPORT_BCC |
| 387 | mail[MSG_BCC]=blindcarbon; |
| 388 | #else |
| 389 | mail[MSG_BCC]=0; |
| 390 | #endif |
| 391 | |
| 392 | mail[MSG_SUBJECT]=(back ? "Zurueck! Empfaenger unbekannt: "+implode(back,", ") : subject); |
| 393 | mail[MSG_DATE]=ctime(time()); |
| 394 | mail[MSG_ID]="MorgenGrauen:"+time(); |
| 395 | mail[MSG_BODY]=message; |
| 396 | return MAILDEMON->DeliverMail(mail,NO_SYSTEM_ALIASES|NO_USER_ALIASES); |
| 397 | } |
| 398 | |
| 399 | |
| 400 | varargs void do_mail(mixed str,string titel,string text) { |
| 401 | // text und titel angegeben: versende Text, keine weiteren Taetigkeiten. |
| 402 | |
| 403 | mixed i; |
| 404 | int silent; |
| 405 | |
| 406 | if (name) return; /* security flag :-) */ |
| 407 | if (!this_interactive()) return; |
| 408 | if (!text) { |
| 409 | name=geteuid(this_interactive()); |
| 410 | move(this_interactive(),M_NOCHECK); |
| 411 | if (!name) remove(); |
| 412 | } |
| 413 | aliases=Read_mailrc(ALIASFILE(geteuid(this_interactive())))+ |
| 414 | Read_mailrc(SYSALIAS); |
| 415 | // akt_folder=member_array("newmail",folders[0]); |
| 416 | // if (akt_folder==-1) akt_folder=0; |
| 417 | if (str) { |
| 418 | str=lower_case(str); |
| 419 | |
| 420 | if(regreplace(regreplace(str," ","",1),"\t","",1)=="-silent") |
| 421 | { |
| 422 | silent=1; |
| 423 | } |
| 424 | else |
| 425 | { |
| 426 | directflag=1; |
| 427 | if (text) { |
| 428 | if (this_interactive()!=this_player()) return 0; |
| 429 | if (!TRUSTED(previous_object())) return |
| 430 | write(break_string("WARNUNG!!! Objekt "+object_name(previous_object())+ |
| 431 | " versucht, Mail mit Deinem Absender zu versenden! " |
| 432 | "Bitte Erzmagier oder Loco verstaendigen.",78)+ |
| 433 | "\n"); |
| 434 | directflag=2; |
| 435 | return write_mail(str,titel,text); |
| 436 | } |
| 437 | directflag=1; |
| 438 | return write_mail(str); |
| 439 | } |
| 440 | } |
| 441 | |
| 442 | update(0,1); |
| 443 | if (!pointerp(folders) || sizeof(folders)!=2 || sizeof(folders[0])==0) { |
| 444 | write("Du hast im Moment keine Post !\n"); |
| 445 | folders=({({}),({})}); |
| 446 | } |
| 447 | write("Du hast "+sizeof(folders[0])+" Ordner, Liste mit 'i'.\n"); |
| 448 | |
| 449 | if(!silent) |
| 450 | { |
| 451 | ListContent(); |
| 452 | } |
| 453 | |
| 454 | write("Gesamtgroesse Deines Postfachs: "+ |
| 455 | (i=(file_size(MAILFILEO(name))+512)/1024)+" KB.\n"); |
| 456 | // Kleiner Hack als Uebergangsloesung, weil ich die dumme Warnung |
| 457 | // nicht mehr sehen kann. ;^) |
| 458 | // 22.10.2000, Tiamak |
| 459 | if(IS_ARCH(this_interactive())) i=0; |
| 460 | |
| 461 | // |
| 462 | // Kleiner Hack, damit Regionsmitarbeiter und groessere Magier |
| 463 | // bei ihren Gebietswartungen nicht staendig mit nervigen |
| 464 | // Meldungen belaestigt werden: |
| 465 | // |
| 466 | // 2005-01-10, Zook |
| 467 | if (query_wiz_level(this_interactive()) > DOMAINMEMBER_LVL) { |
| 468 | if (i>700) |
| 469 | write("*************************************************************\n" |
| 470 | "* Dein Postfach ist zu gross! Bitte versuche aufzuraeumen *\n" |
| 471 | "* und damit die Groesse zu reduzieren. Grosse Postfaecher *\n" |
| 472 | "* verursachen unnoetiges Lag fuer die Spieler. *\n" |
| 473 | "*************************************************************\n"); |
| 474 | i=0; |
| 475 | } |
| 476 | |
| 477 | if (i>500) // Extra-Warnung fuer Catweazle |
| 478 | // man koennte natuerlich auch eine Channel-Meldung ausspucken |
| 479 | // mit dem Hinweis, wer das aktuelle Lag verursacht... vielleicht |
| 480 | // ab 800 KB? ;-) |
| 481 | write("*****************************************************************\n" |
| 482 | "* Dein Postfach hat eine absolut unakzeptable Groesse erreicht. *\n" |
| 483 | "* Uebergrosse Postfaecher verursachen unnoetiges Lag fuer alle! *\n" |
| 484 | "* Bitte raeume es dringend auf, d.h. loesche alle Briefe, die *\n" |
| 485 | "* Du nicht _unbedingt_ benoetigst, oder lager sie aus und *\n" |
| 486 | "* loesche sie anschliessend. Hauptsache, weg damit. *\n" |
| 487 | "*****************************************************************\n"); |
| 488 | else if (i>300) // Warnung fuer bestimmte Magier und Seher ab 300 KB |
| 489 | write("WARNUNG! Dein Postfach hat eine bedenkliche Groesse erreicht.\n" |
| 490 | "Beachte, dass uebergrosse Postfaecher nicht nur unnoetig Speicher, sondern\n" |
| 491 | "insbesondere auch Rechenzeit verbrauchen und damit groesseres Lag verursachen\n" |
| 492 | "koennen. Du solltest also dringend aufraeumen und alle nicht unbedingt\n" |
| 493 | "notwendigen Briefe loeschen (evtl. natuerlich vorher auslagern.\n"); |
| 494 | else if (i>200) // Hinweis fuer andere. |
| 495 | write("Der Postbeamte macht dich darauf aufmerksam, dass Dein Postfach bereits\n" |
| 496 | "ziemlich voll ist und Du dringend einmal aufraeumen solltest.\n"); |
| 497 | else if (i>100) // Hinweis fuer andere. |
| 498 | write("Der Postbeamte macht dich darauf aufmerksam, dass Dein Postfach\n" |
| 499 | "relativ voll ist.\n"); |
| 500 | |
| 501 | |
| 502 | if ((i=FWSERV->QueryForward(name))!=name) |
| 503 | write("Du hast einen Nachsendeauftrag gestellt, Deine Post wird an\n" |
| 504 | +i+" weitergeleitet.\n"); |
| 505 | return input(); |
| 506 | } |
| 507 | |
| 508 | |
| 509 | static void MediumHelpPage() { |
| 510 | if (sizeof(folders[0])) |
| 511 | write("Aktueller Ordner ist \""+folders[0][akt_folder]+"\"\n"); |
| 512 | write("\n\ |
| 513 | Brief <nr> lesen '<nr>' (lies <nr>)\n\ |
| 514 | Aktueller / naechster / letzter Brief '.' / '+' / '-'\n\ |
| 515 | Brief schreiben 'm <name>' (schreibe)\n\ |
| 516 | Brief beantworten 'r [nr]' (beantworte)\n\ |
| 517 | Gruppenantwort an alle Empfaenger 'g [nr]' (gruppe)\n\ |
| 518 | Brief(e) loeschen 'd [nummern]' (loesche)\n\ |
| 519 | Brief(e) weitersenden 'f [nummern] <name>' (weiter)\n\ |
| 520 | Weitersenden plus eigenen Text 'F [nr] <name>' (Weiter)\n\ |
| 521 | Brief(e) in anderen Ordner verschieben 'v [nummern] <ordner>' (verschiebe)\n\ |
| 522 | Mails in diesem Ordner listen 'l' (oder nichts) (anzeigen)\n\ |
| 523 | Aktuellen Ordner wechseln 'c <ordner>' (oeffne)\n\ |
| 524 | Neuen Ordner anlegen 'n <ordnername>' (erzeuge)\n\ |
| 525 | Leeren Ordner loeschen 'e <ordner>' (entferne)\n\ |
| 526 | Alle Ordner anzeigen 'i' (ordner)\n\ |
| 527 | "+ (IS_WIZARD(this_player()) ? "\ |
| 528 | Brief(e) speichern in Datei 's [nummern]' (speichere)\n\ |
| 529 | "+SAVEFILENAME+"\n" : "")+ "\ |
| 530 | Mailaliase anzeigen 'a' (aliase)\n\ |
| 531 | Verfuegbare Kommandos zeigen '?' oder 'h'\n\ |
| 532 | Postmenue verlassen 'q'\n\ |
| 533 | Kommando <cmd> ausfuehren '!<cmd>'\n\ |
| 534 | [nummern] bedeutet: [nr|nr-nr [nr|nr-nr ...]]. (Liste von Nr und Bereichen)\n\ |
| 535 | Bei der Langform reicht es, die ersten 4 Zeichen eines Kommandos anzugeben.\n\ |
| 536 | Falls ein Befehl (z.B. \'v\' nicht funktioniert, pruefe bitte, ob dies ein \n\ |
| 537 | clientseitiges Makro bei Dir ist.\n\ |
| 538 | "); |
| 539 | return input(); |
| 540 | } |
| 541 | |
| 542 | static varargs int GetFolders(int nocondflag) { |
| 543 | // nocondflag: no condition, unbedingt neuladen |
| 544 | |
| 545 | // Cache-Verwaltung endlich funktionsfaehig [251196] |
| 546 | // IDEE: Uhrzeit & Groesse untersuchen, ausserdem nach Verschieben neuladen. |
| 547 | // Auch nach automatischem Verschieben (unread -> newmail)! |
| 548 | |
| 549 | |
| 550 | // write("DEBUG: GetFolders called, old date "+folder_date+", old size "+folder_size+", nocondflag="+nocondflag+"\n"); |
| 551 | if (!nocondflag && |
| 552 | file_time(MAILFILEO(name))==folder_date && |
| 553 | file_size(MAILFILEO(name))==folder_size) return 0; |
| 554 | |
| 555 | if (!restore_object(MAILFILE(name))) folders=({({}),({})}); |
| 556 | folder_date=file_time(MAILFILEO(name)); |
| 557 | folder_size=file_size(MAILFILEO(name)); |
| 558 | if (!pointerp(folders) || sizeof(folders)!=2) folders=({({}),({})}); |
| 559 | // write("DEBUG: GetFolders finished, new date "+folder_date+", new size "+folder_size+"\n"); |
| 560 | return 1; |
| 561 | } |
| 562 | |
| 563 | static varargs void update(int directflag,int nocondflag) { |
| 564 | // directflag: Mailer wird im Direktmodus betrieben |
| 565 | // nocondflag: Unbedingt neuladen |
| 566 | |
| 567 | int i,j,k,newletters; |
| 568 | mixed *ignored; |
| 569 | |
| 570 | if (!GetFolders(nocondflag)) return; // es hat sich nix getan |
| 571 | |
| 572 | if (akt_nr<1) akt_nr=1; |
| 573 | |
| 574 | DEBUGVAR(akt_folder); |
| 575 | |
| 576 | if (akt_folder>=sizeof(folders[0]) || akt_folder<0) { |
| 577 | akt_folder=member(folders[0], "newmail"); |
| 578 | if (akt_folder==-1) { |
| 579 | MAILDEMON->MakeFolder("newmail",name); |
| 580 | GetFolders(1); |
| 581 | DEBUGVAR(folders[0]); |
| 582 | akt_folder=member(folders[0], "newmail"); |
| 583 | } |
| 584 | if (!directflag && akt_folder!=-1) write("Ordner 'newmail' aufgeschlagen.\n"); |
| 585 | } |
| 586 | |
| 587 | // if (!pointerp(folders)) return write("ERROR: folders no array in update\n"); // Kann eigentlich nicht vorkommen |
| 588 | if (sizeof(folders[0]) && akt_nr>sizeof(folders[1][akt_folder])) |
| 589 | akt_nr=sizeof(folders[1][akt_folder]); |
| 590 | j=member(folders[0], "unread"); |
| 591 | if (j==-1) return; |
| 592 | newletters=0; |
| 593 | |
| 594 | // Testweise eine neue Version, die aber voraussetzt, dass die Position von |
| 595 | // unread in der Folderliste von /secure/mail waehrend der Aktion |
| 596 | // nicht veraendert wird. |
| 597 | // alt ausgeklammert, ausserdem ueberall 0 statt k |
| 598 | // k=0; |
| 599 | // Neue Version wieder testweise drin |
| 600 | |
| 601 | // while (j != -1 && pointerp(folders[1][j]) && sizeof(folders[1][j])>0) { |
| 602 | for (k=0;k<sizeof(folders[1][j]);k++) { |
| 603 | |
| 604 | // write("DEBUG: j="+j+"\n"); |
| 605 | |
| 606 | if (pointerp(ignored=this_player()->QueryProp(P_IGNORE)) && |
| 607 | member(ignored, lower_case(folders[1][j][k][MSG_FROM]+".mail"))>=0) { |
| 608 | mixed msg; |
| 609 | msg=folders[1][j][k]; |
| 610 | write("Du laesst einen Brief von "+capitalize(msg[MSG_FROM])+ |
| 611 | " unbesehen zurueckgehen.\n"); |
| 612 | msg[MSG_BODY]=this_player()->name()+" \ |
| 613 | hat diesen Brief ungeoeffnet an Dich zurueckgehen lassen\n\ |
| 614 | und moechte nicht mehr von Deinen Briefen belaestigt werden.\n\ |
| 615 | Titel: "+msg[MSG_SUBJECT]+"\n\ |
| 616 | ------ Inhalt: ------------------------\n"+ |
| 617 | msg[MSG_BODY]; |
| 618 | msg[MSG_RECIPIENT]=msg[MSG_FROM]; |
| 619 | msg[MSG_SUBJECT]="Annahme verweigert - zurueck an Absender"; |
| 620 | msg[MSG_CC]=0; |
| 621 | msg[MSG_BCC]=0; |
| 622 | MAILDEMON->DeliverMail(msg,NO_SYSTEM_ALIASES|NO_USER_ALIASES); |
| 623 | if (find_player(msg[MSG_RECIPIENT])) |
| 624 | tell_object(find_player(msg[MSG_RECIPIENT]), |
| 625 | "Ein Postreiter ruft Dir aus einiger Entfernung leicht sauer zu, dass er einen\nzurueckgekommenen Brief fuer Dich hat.\n"); |
| 626 | MAILDEMON->RemoveMsg(0,j,name); |
| 627 | } else { |
| 628 | // Testweise durch DeleteUnreadFolder ersetzt (080297) |
| 629 | #ifndef MAILDEMON0297 |
| 630 | MAILDEMON->MoveMsg(0, j, "newmail", name); |
| 631 | #endif |
| 632 | newletters++; |
| 633 | } |
| 634 | // GetFolders(1); |
| 635 | // j=member_array("unread",folders[0]); |
| 636 | // Letzte 2 Zeilen in "neuer" Version ersatzlos gestrichen |
| 637 | } |
| 638 | |
| 639 | #ifdef MAILDEMON0297 |
| 640 | MAILDEMON->DeleteUnreadFolder(name); |
| 641 | #else |
| 642 | MAILDEMON->RemoveFolder("unread",name); |
| 643 | #endif |
| 644 | if (newletters) { |
| 645 | if (office_name=="mpa Kurierdienst") |
| 646 | write(break_string("Ein Kurier sagt \"Tach, Post!\", drueckt Dir "+ |
| 647 | ((newletters==1) ? "einen neuen Brief" : newletters+" neue Briefe") |
| 648 | +" in die Hand und verschwindet wieder.\n",78)); |
| 649 | else |
| 650 | write("Du siehst, wie ein Postbeamter "+ |
| 651 | ((newletters==1) ? "einen neuen Brief" : newletters+" neue Briefe") |
| 652 | +" in Dein Fach legt.\n"); |
| 653 | } |
| 654 | GetFolders(1); // jetzt ohne unread, damit im endgueltigen Zustand. |
| 655 | while (akt_folder>=sizeof(folders[0])) akt_folder--; |
| 656 | if ((!akt_nr)&&sizeof(folders[1][akt_folder])) akt_nr=1; |
| 657 | } |
| 658 | |
| 659 | |
| 660 | static varargs void ListContent() { |
| 661 | int i; |
| 662 | update(); |
| 663 | // DEBUGVAR(folders[0]); |
| 664 | // DEBUGVAR(folders[1]); |
| 665 | DEBUGVAR(akt_folder); |
| 666 | if (!pointerp(folders)||sizeof(folders)!=2|| |
| 667 | !pointerp(folders[0])||!sizeof(folders[0])) { |
| 668 | write("Du hast keinen einzigen Ordner!\n"); |
| 669 | return; |
| 670 | } |
| 671 | write("Ordner "+folders[0][akt_folder]+": "); |
| 672 | if (!pointerp(folders[1]) || akt_folder>=sizeof(folders[1]) || |
| 673 | !pointerp(folders[1][akt_folder])) { |
| 674 | write("Dieser Ordner ist leer.\n"); |
| 675 | return; |
| 676 | } |
| 677 | write(sizeof(folders[1][akt_folder])+" Brief"+ |
| 678 | ((sizeof(folders[1][akt_folder])!=1)?"e\n":"\n")); |
| 679 | for (i=0;i<sizeof(folders[1][akt_folder]);i++){ |
| 680 | write(((i+1==akt_nr) ? "->" : " ")+ |
| 681 | sprintf("%3d: (%12s, %s) ",i+1,capitalize(folders[1][akt_folder][i][MSG_FROM]), |
| 682 | folders[1][akt_folder][i][MSG_DATE][5..11])+ |
| 683 | folders[1][akt_folder][i][MSG_SUBJECT]+"\n"); |
| 684 | } |
| 685 | return; |
| 686 | } |
| 687 | |
| 688 | |
| 689 | static void ChangeFolder(mixed x) { |
| 690 | if (!(x=GetFolderName(x))) return; |
| 691 | akt_folder=member(folders[0],x); |
| 692 | write("Du oeffnest den Ordner '"+x+"'.\n"); |
| 693 | if (akt_nr<=0) akt_nr=1; |
| 694 | if (akt_nr>=sizeof(folders[1][akt_folder])) |
| 695 | akt_nr=sizeof(folders[1][akt_folder]); |
| 696 | ListContent(); |
| 697 | } |
| 698 | |
| 699 | |
| 700 | static void ListFolders() { |
| 701 | int i; |
| 702 | update(); |
| 703 | write("Du hast "+sizeof(folders[0])+" Ordner:\n"); |
| 704 | for (i=0;i<sizeof(folders[0]);i++) |
| 705 | write(sprintf("%2s%3d: %-20s(%3d Briefe)\n", |
| 706 | ((i==akt_folder)?"->":" "), |
| 707 | i+1,folders[0][i],sizeof(folders[1][i]))); |
| 708 | write("Gesamtgroesse Deines Postfachs: "+ |
| 709 | ((file_size(MAILFILEO(name))+512)/1024)+" KB.\n"); |
| 710 | } |
| 711 | |
| 712 | |
| 713 | static void MakeFolder(string s) { |
| 714 | int ret; |
| 715 | if (sscanf(s,"%d",ret)||s[0]<'a'||s[0]>'z') return |
| 716 | write("Um Probleme zu vermeiden, duerfen Ordner nicht mit Nummern oder Sonderzeichen\nbezeichnet werden.\n"); |
| 717 | if (s=="newmail"||s=="unread") return |
| 718 | write("Die Ordnernamen 'newmail' und 'unread' sind reserviert.\n"); |
| 719 | ret=MAILDEMON->MakeFolder(s, name); |
| 720 | if (ret==1) write("Ok, neuer Ordner mit Namen "+s+" angelegt.\n"); |
| 721 | else write("Ein Ordner mit dem Namen existiert bereits.\n"); |
| 722 | return; |
| 723 | } |
| 724 | |
| 725 | |
| 726 | static int RemoveFolder(string x) { |
| 727 | int ret; |
| 728 | if (!x) return -42; // folder existiert nicht, Fehlermeldung bereits geg. |
| 729 | // if (intp(x)) x=folders[0][x]; |
| 730 | |
| 731 | if (x=="newmail") return |
| 732 | write("Der Ordnername 'newmail' ist reserviert.\nDieser Ordner darf nicht geloescht werden.\n"),-43; |
| 733 | |
| 734 | ret=MAILDEMON->RemoveFolder(x, name); |
| 735 | switch (ret) { |
| 736 | case 1: write("Ordner "+x+" geloescht.\n"); break; |
| 737 | case -1: write("Kein solcher Ordner.\n"); break; |
| 738 | case 0: write("Der Ordner war nicht leer - nicht geloescht.\n"); break; |
| 739 | default: write("Fehler Nummer "+ret+" - was auch immer das heisst...\n"); break; |
| 740 | } |
| 741 | return ret; |
| 742 | } |
| 743 | |
| 744 | |
| 745 | static varargs int DeleteMessage(int *nrs) { |
| 746 | int ret,x; |
| 747 | mixed m; |
| 748 | if ( sizeof(nrs) > 15 ) LagWarning(); |
| 749 | |
| 750 | for (x=sizeof(nrs)-1;x>=0;x--) { |
| 751 | write("Loesche Brief "+(nrs[x]+1)+": "); |
| 752 | ret=MAILDEMON->RemoveMsg(nrs[x], akt_folder, name); |
| 753 | switch(ret) { |
| 754 | case 1: write("Ok.\n"); break; |
| 755 | case 0: write("Kein solcher Brief im aktuellen Ordner.\n"); break; |
| 756 | case -1:write("Kein aktueller Ordner.\n"); update(); return ret; |
| 757 | default: write("MAILDEMON: Interner Fehler Nummer "+ret+"!\n"); break; |
| 758 | } |
| 759 | } |
| 760 | |
| 761 | return ret; |
| 762 | } |
| 763 | |
| 764 | //" |
| 765 | |
| 766 | static int MoveMessage(mixed msg,mixed fol) { |
| 767 | int ret,i; |
| 768 | |
| 769 | for (i=0;i<sizeof(msg);i++) { |
| 770 | ret=MAILDEMON->MoveMsg(msg[i]-i, akt_folder, fol, name); |
| 771 | switch(ret) { |
| 772 | case 1: |
| 773 | write("Brief "+(msg[i]+1)+" verschoben nach "+fol+".\n"); |
| 774 | break; |
| 775 | case 0: |
| 776 | write("So viele Briefe sind nicht im aktuellen Ordner.\n"); return 0; |
| 777 | case -1: |
| 778 | write("Seltsamer Fehler - duerfte eigentlich nicht passieren:\n'Kein aktueller Ordner.'\n"); return -1; |
| 779 | case -3: |
| 780 | write("Den Zielordner "+fol+" gibt es nicht!\n"); return ret; |
| 781 | default: |
| 782 | write("MAILDEMON: MoveMsg Interner Fehler "+ret+". Bitte Erzmagier verstaendigen.\n"); return ret; |
| 783 | } |
| 784 | } |
| 785 | if (akt_nr>=sizeof(folders[1][akt_folder])) |
| 786 | akt_nr=sizeof(folders[1][akt_folder])-1; |
| 787 | |
| 788 | return ret; |
| 789 | } |
| 790 | |
| 791 | |
| 792 | static varargs int Reply(int nr,int group) { |
| 793 | mixed to,dummy; |
| 794 | if (!pointerp(folders)||!pointerp(folders[0])|| |
| 795 | sizeof(folders[0])<=akt_folder) { |
| 796 | write("Seltsamer Fehler: Kein aktueller Ordner!\n"); |
| 797 | return 0; |
| 798 | } |
| 799 | if (nr<0 || !pointerp(folders[1][akt_folder]) || |
| 800 | sizeof(folders[1][akt_folder])<=nr){ |
| 801 | write("Einen Brief mit Nummer "+(nr+1)+" gibt es in diesem Ordner nicht!\n"); |
| 802 | return 0; |
| 803 | } |
| 804 | |
| 805 | if (sscanf("\n"+lower_case(folders[1][akt_folder][nr][MSG_BODY]), |
| 806 | "%s\nreply-to:%s\n",dummy,to)==2) { // Reply-to gesetzt |
| 807 | while (to[0]==' ') to=to[1..]; // ueberschuessige Leerzeichen entfernen |
| 808 | while (to[<1]==' ') to=to[0..<2]; |
| 809 | } |
| 810 | else |
| 811 | to=folders[1][akt_folder][nr][MSG_FROM]; |
| 812 | if (group) // Gruppenantwort |
| 813 | to=({to, |
| 814 | folders[1][akt_folder][nr][MSG_RECIPIENT]})+ |
| 815 | (pointerp(folders[1][akt_folder][nr][MSG_CC]) ? folders[1][akt_folder][nr][MSG_CC] : ({})) |
| 816 | -({name}); |
| 817 | #ifdef DEBUG |
| 818 | DEBUGVAR(name); |
| 819 | DEBUGVAR(to); |
| 820 | #endif |
| 821 | write_mail(to,GetReTitle(folders[1][akt_folder][nr][MSG_SUBJECT])); |
| 822 | return 1; |
| 823 | } |
| 824 | |
| 825 | |
| 826 | static varargs int Forward(mixed to,mixed nr,int appendflag) { |
| 827 | mixed msg; |
| 828 | if (!pointerp(folders)||!pointerp(folders[0])|| |
| 829 | sizeof(folders[0])<=akt_folder) { |
| 830 | write("Seltsamer Fehler: Kein aktueller Ordner!\n"); |
| 831 | return 0; |
| 832 | } |
| 833 | if (nr<0 || !pointerp(folders[1][akt_folder]) || |
| 834 | sizeof(folders[1][akt_folder])<=nr){ |
| 835 | write("Nicht so viele Briefe in diesem Ordner!\n"); |
| 836 | return 0; |
| 837 | } |
| 838 | to=process_names(to); |
| 839 | receiver=to[0]; |
| 840 | carbon=to[1..]; |
| 841 | subject="Fw: "+folders[1][akt_folder][nr][MSG_SUBJECT]; |
| 842 | message="Weitergesendeter Brief, urspruenglich von: "+ |
| 843 | folders[1][akt_folder][nr][MSG_FROM]+"\n\ |
| 844 | -----------------------------\n\ |
| 845 | "+folders[1][akt_folder][nr][MSG_BODY]+"\ |
| 846 | -----------------------------\n"; |
| 847 | if (!appendflag) return get_carbon_copy(0),1; |
| 848 | else { |
| 849 | write("Text kann angehaengt werden\n"); |
| 850 | get_subject(subject,message); |
| 851 | } |
| 852 | return 1; |
| 853 | } |
| 854 | |
| 855 | |
| 856 | |
| 857 | static int ForwardArea(mixed to,int * nrs) { |
| 858 | mixed msg; |
| 859 | |
| 860 | if (!sizeof(nrs)) return 0; |
| 861 | if (sizeof(nrs)==1) return Forward(to,nrs[0]); |
| 862 | if (sizeof(nrs)>15) LagWarning(); |
| 863 | |
| 864 | to=process_names(to); |
| 865 | receiver=to[0]; |
| 866 | carbon=to[1..]; |
| 867 | subject="Fw: Gesammelte Briefe ("+dtime(time())[5..23]+")"; |
| 868 | message=""; |
| 869 | for (i=0;i<sizeof(nrs);i++) { |
| 870 | write("Brief "+(nrs[i]+1)+": "); |
| 871 | message+=Message2string(nrs[i])+ |
| 872 | "----------------------------------------------------------------------\n"; |
| 873 | write("Angehaengt.\n"); |
| 874 | } |
| 875 | /* |
| 876 | if (!appendflag) { |
| 877 | */ |
| 878 | return get_carbon_copy(0),1; |
| 879 | /* } |
| 880 | else { |
| 881 | write("Text kann angehaengt werden\n"); |
| 882 | get_subject(subject,message); |
| 883 | } |
| 884 | return 1; |
| 885 | */ |
| 886 | } |
| 887 | |
| 888 | //---------- |
| 889 | |
| 890 | |
| 891 | static int ReadMessage(int nr) { |
| 892 | if (nr<sizeof(folders[1][akt_folder]) && nr>=0) |
| 893 | akt_nr=nr+1; |
| 894 | message=Message2string(nr); |
| 895 | if (!message) return 0; |
| 896 | this_player()->More(message,0,#'input); //') |
| 897 | return 1; |
| 898 | } |
| 899 | |
| 900 | |
| 901 | static string Message2string(int nr) { |
| 902 | mixed letter; |
| 903 | string message; |
| 904 | int x; |
| 905 | if (!pointerp(folders)||!pointerp(folders[0])|| |
| 906 | sizeof(folders[0])<=akt_folder){ |
| 907 | write("Seltsamer Fehler: Kein aktueller Ordner!\n"); |
| 908 | return 0; |
| 909 | } |
| 910 | if (!pointerp(folders[1][akt_folder]) || |
| 911 | sizeof(folders[1][akt_folder])<=nr || |
| 912 | nr<0) { |
| 913 | write("Diese Nummer gibt es in diesem Ordner nicht!\n"); |
| 914 | return 0; |
| 915 | } |
| 916 | letter=folders[1][akt_folder][nr]; |
| 917 | message= |
| 918 | "Absender: "+capitalize(letter[MSG_FROM])+"\n"+ |
| 919 | ((letter[MSG_FROM]==letter[MSG_SENDER]) ? "" : |
| 920 | "Abgesandt aber von: "+capitalize(letter[MSG_SENDER])+"\n") + |
| 921 | "An: "+capitalize(letter[MSG_RECIPIENT]); |
| 922 | if (stringp(letter[MSG_CC]) && letter[MSG_CC]!="" || |
| 923 | pointerp(letter[MSG_CC]) && sizeof(letter[MSG_CC])) { |
| 924 | message+="\nCc: "; |
| 925 | if (!pointerp(letter[MSG_CC])) message+=capitalize(letter[MSG_CC]); |
| 926 | else message+=implode(map(letter[MSG_CC],#'capitalize),", ");//')) |
| 927 | } |
| 928 | message+="\nDatum: "+letter[MSG_DATE]+"\n"+ |
| 929 | /* Sinnlos, oder? "Id: "+letter[MSG_ID]+"\n"+ */ |
| 930 | "Titel: "+letter[MSG_SUBJECT]+"\n\n"+ |
| 931 | letter[MSG_BODY]+"\n\n"; |
| 932 | return message; |
| 933 | } |
| 934 | |
| 935 | |
| 936 | static void LagWarning() { |
| 937 | write("\ |
| 938 | WARNUNG!!! Diese Aktion kann sehr lange benoetigen. Bitte sparsam verwenden,\n\ |
| 939 | um das Lag fuer alle ertraeglich zu halten. Falls die Aktion mit einem\n\ |
| 940 | Fehler abbricht, waren es wahrscheinlich zu viele Briefe auf einmal.\n\ |
| 941 | Dann kannst Du mit \"mail\" wieder in das Mailmenu einsteigen und solltest\n\ |
| 942 | es mit weniger Briefen versuchen.\n"); |
| 943 | } |
| 944 | |
| 945 | |
| 946 | static varargs int SaveMessage(int * nrs) { |
| 947 | int x,nr; |
| 948 | string rest; |
| 949 | mixed letter; |
| 950 | |
| 951 | if (!IS_WIZARD(this_player())) { |
| 952 | write("Das koennen nur Magier!\n"); |
| 953 | return 0; |
| 954 | } |
| 955 | if (!sizeof(nrs)) { |
| 956 | write("Speichere nichts.\n"); |
| 957 | return 1; |
| 958 | } |
| 959 | |
| 960 | if ( sizeof(nrs) > 15 ) LagWarning(); |
| 961 | |
| 962 | for (nr=0;nr<sizeof(nrs);nr++) { |
| 963 | write("Speichere Brief "+(nrs[nr]+1)+": "); |
| 964 | letter=Message2string(nrs[nr]); |
| 965 | letter+="----------------------------------------------------------------------\n"; |
| 966 | if (!letter) { |
| 967 | write("Speichern unmoeglich.\n"); |
| 968 | return 0; |
| 969 | } |
| 970 | if (!write_file(SAVEFILENAME, letter)) |
| 971 | write("Brief zu lang!\n"); |
| 972 | else |
| 973 | write("Ok.\n"); |
| 974 | } |
| 975 | write("Speichern nach "+SAVEFILENAME+" fertig.\nBitte denk dran, diese Datei wieder zu loeschen!\n"); |
| 976 | return 1; |
| 977 | } |
| 978 | |
| 979 | // {'} |
| 980 | |
| 981 | static void ListAliases() { |
| 982 | mixed a; |
| 983 | int i; |
| 984 | string s; |
| 985 | a=sort_array(m_indices(aliases),#'>); // '); |
| 986 | s=( "Definierte Aliase:\n" |
| 987 | "d.xyz = Alle Mitarbeiter der Domain xyz\n" |
| 988 | "freunde = Deine Freunde (entsprechend Freundschaftsband)\n" |
| 989 | "me = "+(this_player()->QueryProp(P_MAILADDR))+"\n"); |
| 990 | for (i=0;i<sizeof(a);i++) |
| 991 | if (strstr(aliases[a[i]],"@")==-1) s+=sprintf("%-12s = %s\n",a[i],aliases[a[i]]); |
| 992 | write(s); |
| 993 | } |
| 994 | |
| 995 | |
| 996 | |
| 997 | /* ------ Das Mailmenue --------------------------------------------------*/ |
| 998 | |
| 999 | |
| 1000 | static void mail_cmds(string str) { |
| 1001 | |
| 1002 | string *strargs; |
| 1003 | int i,nrargs; |
| 1004 | |
| 1005 | update(); |
| 1006 | |
| 1007 | if (!str || str=="" || !(nrargs=sizeof(strargs=old_explode(str[0..0]+lower_case(str[1..])," ")))) { |
| 1008 | ListContent(); |
| 1009 | return input(); |
| 1010 | } |
| 1011 | strargs[0]=strargs[0][0..3]; |
| 1012 | if (IS_NUMBER(strargs[0])) { |
| 1013 | strargs=({"lies",strargs[0]}); |
| 1014 | nrargs=2; |
| 1015 | } |
| 1016 | DEBUGVAR(strargs); |
| 1017 | switch (strargs[0]) { |
| 1018 | case "q": // quit |
| 1019 | case "quit": |
| 1020 | remove(); return; |
| 1021 | case "?": // Hilfeseite |
| 1022 | case "hilf": |
| 1023 | case "h": |
| 1024 | MediumHelpPage(); |
| 1025 | return; |
| 1026 | case "oeff": // change folder |
| 1027 | case "c": |
| 1028 | if (nrargs<2) { |
| 1029 | write("Welchen Ordner willst Du oeffnen (Name, Nummer, +, -)?\n"); |
| 1030 | break; |
| 1031 | } |
| 1032 | ChangeFolder(strargs[1]); |
| 1033 | break; |
| 1034 | case "ordn": // list folders |
| 1035 | case "i": |
| 1036 | ListFolders(); |
| 1037 | break; |
| 1038 | case "anze": // list content |
| 1039 | case "l": |
| 1040 | ListContent(); |
| 1041 | break; |
| 1042 | case "alia": // list aliases |
| 1043 | case "a": |
| 1044 | ListAliases(); |
| 1045 | break; |
| 1046 | case "erze": // make new folder |
| 1047 | case "n": |
| 1048 | if (nrargs<2) { |
| 1049 | write("Bitte als Argument einen Namen fuer den neuen Ordner angeben!\n"); |
| 1050 | break; |
| 1051 | } |
| 1052 | MakeFolder(lower_case(strargs[1])); |
| 1053 | break; |
| 1054 | case "entf": // delete folder |
| 1055 | case "e": |
| 1056 | if (nrargs<2) { |
| 1057 | write("Bitte als Argument Name oder Nummer des zu loeschenden Ordners angeben.\n"); |
| 1058 | break; |
| 1059 | } |
| 1060 | RemoveFolder(GetFolderName(strargs[1])); |
| 1061 | break; |
| 1062 | case "loes": // delete message |
| 1063 | case "d": |
| 1064 | if (nrargs==1) DeleteMessage(({akt_nr-1})); |
| 1065 | else DeleteMessage(GetNumbers(strargs[1..])); |
| 1066 | break; |
| 1067 | case "schr": // write mail |
| 1068 | case "m": |
| 1069 | if (nrargs<2) { |
| 1070 | write("Bitte Empfaenger als Argument angeben!\n"); |
| 1071 | break; |
| 1072 | } |
| 1073 | write_mail(strargs[1..]); |
| 1074 | return; |
| 1075 | case "vers": // move message to other folder |
| 1076 | case "verl": |
| 1077 | case "v": |
| 1078 | if (nrargs<2 || (nrargs>2 && !IS_NUMBER(strargs[1]))) { |
| 1079 | write("Syntax: v [nr|nr-nr [nr|nr-nr ...]] <ordnername>|<ordnernr>|+|-\n"); |
| 1080 | break; |
| 1081 | } |
| 1082 | if (nrargs==2) MoveMessage(({akt_nr-1}),GetFolderName(strargs[1])); |
| 1083 | else MoveMessage(GetNumbers(strargs[1..<2]),GetFolderName(strargs[<1])); |
| 1084 | update(0,1); // unbedingt neuladen. |
| 1085 | break; |
| 1086 | case "bean": |
| 1087 | case "r": |
| 1088 | case "grup": |
| 1089 | case "g": |
| 1090 | if (nrargs<2) { |
| 1091 | if (Reply(akt_nr-1,(strargs[0][0]=='g'))) return; |
| 1092 | break; |
| 1093 | } |
| 1094 | if (!IS_NUMBER(strargs[1])) { |
| 1095 | write("Argumentfehler: Bitte Nummer des Briefes angeben, auf den sich die Antwort\n" |
| 1096 | "beziehen soll. Ohne Argument bezieht sie sich auf den aktuellen Brief.\n"); |
| 1097 | break; |
| 1098 | } |
| 1099 | if (nrargs>2) { |
| 1100 | write("Zu viele Argumente. Eine Antwort darf sich nur auf einen Brief beziehen!\n"); |
| 1101 | break; |
| 1102 | } |
| 1103 | if (Reply(to_int(strargs[1])-1,(strargs[0][0]=='g'))) return; |
| 1104 | break; |
| 1105 | case "weit": |
| 1106 | case "f": |
| 1107 | if (nrargs<2 || |
| 1108 | (IS_NUMBER(strargs[nrargs-1])&&sizeof(old_explode(strargs[nrargs-1],"@"))==1)) { |
| 1109 | write("Syntax: f [nr|nr-nr [nr|nr-nr ...]] empfaenger [empf2 ...]\n"); |
| 1110 | break; |
| 1111 | } |
| 1112 | if (!IS_NUMBER(strargs[1])) { |
| 1113 | if (Forward(strargs[1..],akt_nr-1)) return; |
| 1114 | } // return, nicht break: input() wird von get_carbon_copy() aufger. |
| 1115 | else { |
| 1116 | int pos; // letzte Position, an der eine Nummer steht |
| 1117 | |
| 1118 | for (pos=nrargs-1;pos>1&&!IS_NUMBER(strargs[pos]);pos--); |
| 1119 | if (ForwardArea(strargs[(pos+1)..],GetNumbers(strargs[1..pos]))) |
| 1120 | return; |
| 1121 | } |
| 1122 | break; |
| 1123 | case "Weit": |
| 1124 | case "F": |
| 1125 | if (nrargs<2 || (nrargs==2 && IS_NUMBER(strargs[1]))) { |
| 1126 | write("Haeh? Bitte so: F [nr] empfaenger\n"); |
| 1127 | break; |
| 1128 | } |
| 1129 | if (!IS_NUMBER(strargs[1])) { |
| 1130 | if (Forward(strargs[1..],akt_nr-1,1)) return; |
| 1131 | break; |
| 1132 | } |
| 1133 | if (IS_NUMBER(strargs[2])||member(strargs[1],'-')>=0) { |
| 1134 | write("Argumentfehler: Wenn Du eigenen Text anhaengen willst, darfst Du nur einen\n" |
| 1135 | "Brief angeben, nicht mehrere.\n"); |
| 1136 | break; |
| 1137 | } |
| 1138 | if (Forward(strargs[2..],to_int(strargs[1])-1,1)) return; |
| 1139 | break; |
| 1140 | case "lies": |
| 1141 | if (nrargs<2) { if (ReadMessage(akt_nr-1)) return; } else |
| 1142 | if (ReadMessage(to_int(strargs[1])-1)) return; |
| 1143 | break; |
| 1144 | case ".": |
| 1145 | if (ReadMessage(akt_nr-1)) return; |
| 1146 | break; |
| 1147 | case "+": |
| 1148 | if (akt_nr==sizeof(folders[1][akt_folder])) |
| 1149 | write("Noch weiter vorwaerts gehts nicht!\nMit 'c +' kannst Du den naechsten Ordner oeffnen.\n"); |
| 1150 | else if (ReadMessage(akt_nr)) return; |
| 1151 | break; |
| 1152 | case "-": |
| 1153 | if (akt_nr==1) |
| 1154 | write("Noch weiter zurueck gehts nicht!\nMit 'c -' kannst Du den vorhergehenden Ordner oeffnen.\n"); |
| 1155 | else if (ReadMessage(akt_nr-2)) return; |
| 1156 | break; |
| 1157 | case "spei": |
| 1158 | case "s": |
| 1159 | if ((nrargs==2 && !IS_NUMBER(strargs[1]))) { |
| 1160 | write("Syntax: s [nr|nr-nr [nr|nr-nr ...]]\n"); |
| 1161 | break; |
| 1162 | } |
| 1163 | if (nrargs==1) (SaveMessage(({akt_nr-1}))); |
| 1164 | else (SaveMessage(GetNumbers(strargs[1..]))); |
| 1165 | break; |
| 1166 | default: |
| 1167 | write("Kommando nicht verstanden. Eine Hilfsseite bekommst Du mit 'h'.\n"); |
| 1168 | break; |
| 1169 | } |
| 1170 | return input(); |
| 1171 | } |
| 1172 | |
| 1173 | |
| 1174 | /*------------------------------------------------------------------------*/ |
| 1175 | |
| 1176 | static string prompt() { |
| 1177 | string path; |
| 1178 | |
| 1179 | update(); |
| 1180 | if (!pointerp(folders)||!pointerp(folders[0])|| |
| 1181 | sizeof(folders[0])<=akt_folder) |
| 1182 | path="(kein Ordner)"; |
| 1183 | else |
| 1184 | path= "(" + folders[0][akt_folder] + ":" + |
| 1185 | ( sizeof(folders[1][akt_folder]) ? |
| 1186 | akt_nr + "/" + sizeof(folders[1][akt_folder]) : |
| 1187 | "leer") + ")"; |
| 1188 | return(path + " [Hilfe mit h] => "); |
| 1189 | } |
| 1190 | |
| 1191 | |
| 1192 | static void input() { |
| 1193 | //prompt(); |
| 1194 | input_to("mail_cmds", INPUT_PROMPT, prompt()); |
| 1195 | return; |
| 1196 | } |
| 1197 | |
| 1198 | |
| 1199 | static mixed GetAlias(mixed a); |
| 1200 | |
| 1201 | #ifdef MAIL_SUPPORT_BCC |
| 1202 | static mixed RecurseProcessNames(mixed a); |
| 1203 | #endif |
| 1204 | |
| 1205 | |
| 1206 | static mixed process_names(mixed s) { |
| 1207 | mixed a1,a2,h; |
| 1208 | int i; |
| 1209 | string domain; |
| 1210 | |
| 1211 | if (stringp(s)) { |
| 1212 | a1=explode(regreplace(lower_case(s),","," ",1)," ")-({""}); |
| 1213 | } |
| 1214 | else a1=s; |
| 1215 | a2=({}); |
| 1216 | foreach(string str: a1) |
| 1217 | a2+=explode(str,","); |
| 1218 | |
| 1219 | a1=({}); |
| 1220 | |
| 1221 | // printf("DEBUG ANFANG: %O\n",a2); |
| 1222 | |
| 1223 | foreach(string str: a2) { |
| 1224 | if( !sizeof(str) ) continue; |
| 1225 | if (sscanf(str,"d.%s",domain)) { |
| 1226 | h=(get_dir("/d/"+domain+"/*")||({}))-({".",".."}); |
| 1227 | // h immer ein Array |
| 1228 | h=filter(h,#'query_wiz_level); |
| 1229 | if (sizeof(h)) |
| 1230 | a1+=h; |
| 1231 | else |
| 1232 | a1+=({"d."+domain}); |
| 1233 | } |
| 1234 | else if (str=="freunde") |
| 1235 | a1+=("/p/service/tiamak/obj/fbmaster"->get_friends(getuid(this_player()), 8)); |
| 1236 | else if (str=="me") |
| 1237 | a1+=({this_player()->QueryProp(P_MAILADDR)}); |
| 1238 | else if (aliases[str]) |
| 1239 | a1+=GetAlias(str); |
| 1240 | #ifdef MAIL_SUPPORT_BCC |
| 1241 | else if (str[0]=='-') |
| 1242 | a1+=map(RecurseProcessNames(str[1..]), function string (string x) { |
| 1243 | return("-"+x);}); |
| 1244 | #endif |
| 1245 | else if ( (str[0]>='a' && str[0]<='z') |
| 1246 | || (sscanf(str,"%s@%s",domain,domain)) |
| 1247 | || str[0]=='\\') |
| 1248 | a1+=({str}); |
| 1249 | } |
| 1250 | |
| 1251 | // printf("DEBUG ENDE: %O\n",a1); |
| 1252 | |
| 1253 | a1=filter(a1,function int (string x) |
| 1254 | { return(sizeof(x)>1); } ); |
| 1255 | |
| 1256 | return(map(a1,#'lower_case)); |
| 1257 | } |
| 1258 | |
| 1259 | |
| 1260 | static mixed GetAlias(mixed a) { return process_names(aliases[a]); } |
| 1261 | #ifdef MAIL_SUPPORT_BCC |
| 1262 | static mixed RecurseProcessNames(mixed a) { return process_names(a); } |
| 1263 | #endif |
| 1264 | |
| 1265 | |
| 1266 | static mapping Read_mailrc(string file) { |
| 1267 | mapping al; |
| 1268 | int i; |
| 1269 | mixed ar; |
| 1270 | string s1,s2; |
| 1271 | |
| 1272 | if (!(ar=read_file(file))) { |
| 1273 | // write(file+" not readable\n"); |
| 1274 | return ([]); |
| 1275 | } |
| 1276 | al=([]); |
| 1277 | ar=explode(ar,"\n"); |
| 1278 | for (i=sizeof(ar)-1;i>=0;i--) |
| 1279 | if (sscanf(ar[i],"%s %s",s1,s2)==2) |
| 1280 | al+=([s1:s2]); |
| 1281 | // printf("Got aliases %O",al); |
| 1282 | return al; |
| 1283 | } |
| 1284 | |
| 1285 | |
| 1286 | string * unify_array(string * a) { |
| 1287 | // int i; |
| 1288 | // for (i=sizeof(a)-1;i>=0;i--) a=a-({a[i]})+({a[i]}); |
| 1289 | // Rikus 14.02.2001 |
| 1290 | a=m_indices(mkmapping(a)); |
| 1291 | return a; |
| 1292 | } |
| 1293 | |
| 1294 | |
| 1295 | string GetReTitle(string s) { |
| 1296 | int nr,s2; |
| 1297 | |
| 1298 | if (!s) s=""; |
| 1299 | if (s[0..7]=="Re: Re: ") return "Re^3: "+s[8..]; |
| 1300 | else if (sscanf(s,"Re^%d: %s",nr,s2)) |
| 1301 | return "Re^"+(nr+1)+": "+s2; |
| 1302 | else return "Re: "+s; |
| 1303 | } |
| 1304 | |
| 1305 | |
| 1306 | int * GetNumbers(mixed s) { |
| 1307 | int i,h1,h2; |
| 1308 | mixed ret; |
| 1309 | |
| 1310 | if (intp(s)) return ({s-1}); |
| 1311 | if (stringp(s)) s=({s-1}); |
| 1312 | if (!pointerp(s)) return 0; |
| 1313 | |
| 1314 | ret=({}); |
| 1315 | |
| 1316 | for (i=sizeof(s)-1;i>=0;i--) { |
| 1317 | if (sscanf(s[i],"%d-%d",h1,h2)==2) { |
| 1318 | if (h2-h1>100) { |
| 1319 | write("Nicht so viele auf einmal, bitte.\n"); |
| 1320 | return ({}); |
| 1321 | } |
| 1322 | for (h1--;h1<h2;h1++) ret=ret-({h1})+({h1}); |
| 1323 | } |
| 1324 | else |
| 1325 | ret=ret-({h1=to_int(s[i])-1})+({h1}); |
| 1326 | } |
| 1327 | ret=sort_array(ret,#'>); //') |
| 1328 | DEBUGVAR(ret); |
| 1329 | if (ret[0]<0) { |
| 1330 | write("Illegale Nummer: "+(ret[0]+1)+", nichts unter 1 bitte!\n"); |
| 1331 | return ({}); |
| 1332 | } |
| 1333 | if (ret[<1]>=sizeof(folders[1][akt_folder])) { |
| 1334 | write("Illegale Nummer: "+(ret[<1]+1)+", so gross ist dieser Ordner nicht!\n"); |
| 1335 | return ({}); |
| 1336 | } |
| 1337 | return ret; |
| 1338 | } |
| 1339 | |
| 1340 | |
| 1341 | /* |
| 1342 | int is_number(string s) { |
| 1343 | return (s[0]>='0'&&s[0]<='9'); |
| 1344 | } |
| 1345 | */ |
| 1346 | |
| 1347 | |
| 1348 | string GetFolderName(mixed fol) { // int oder string. alles andere -> Fehler! |
| 1349 | mixed h; |
| 1350 | |
| 1351 | if (fol=="+") fol=akt_folder+1; |
| 1352 | if (fol=="-") fol=akt_folder-1; |
| 1353 | if ((!fol)||(intp(fol))||(IS_NUMBER(fol))) { |
| 1354 | if (!intp(fol)) fol=to_int(fol)-1; |
| 1355 | if (fol<0||fol>=sizeof(folders[0])) |
| 1356 | return write("Einen Ordner mit Nummer "+(fol+1)+" gibt es nicht.\n"),0; |
| 1357 | return folders[0][fol]; |
| 1358 | } |
| 1359 | fol=lower_case(fol); |
| 1360 | if (sizeof(h=regexp(folders[0],"^"+fol))==1) return h[0]; |
| 1361 | if (member(folders[0],fol)==-1) |
| 1362 | return write("Einen Ordner mit Namen "+fol+" hast Du nicht.\n"),0; |
| 1363 | return fol; |
| 1364 | } |
| 1365 | |
| 1366 | int query_prevent_shadow() { return 1; } |