Fehlende Files fuer Mailsystem ergaenzt.

Change-Id: Ia51a607d71ac86a12e957ae0f2c604f190581314
diff --git a/p/service/loco/obj/fwsaveserv.c b/p/service/loco/obj/fwsaveserv.c
new file mode 100644
index 0000000..a228994
--- /dev/null
+++ b/p/service/loco/obj/fwsaveserv.c
@@ -0,0 +1,35 @@
+/***************************************************************************
+
+ Forward-Server: Lade-/Speicherserver.
+  Dieser Teilserver hat die Aufgabe, einzelne Teile der forwardliste 
+  auf Anfrage zu laden und 
+
+ Teil des MG-Mailsystems
+ (C) 1996 Loco@Morgengrauen
+
+ Es gilt dasselbe Copyright wie fuer mailer.c, bitte dort nachlesen.
+
+***************************************************************************/
+
+#include "/mail/post.h"
+
+mixed data;
+
+create() {
+  seteuid(getuid());
+}
+
+mapping LoadData(string file) {
+  if (!stringp(file)||sizeof(file)>1||file>"z"||file<"a")
+    return 0;
+  restore_object(FWSAVEFILE(file));
+  return data;
+}
+
+int SaveData(string file, mapping what) {
+//  if (geteuid(previous_object())!=geteuid()) return 0;
+  data=what;
+  save_object(FWSAVEFILE(file));
+  data=0;
+  return 1;
+}
diff --git a/p/service/loco/obj/fwserv.c b/p/service/loco/obj/fwserv.c
new file mode 100644
index 0000000..7f27d3d
--- /dev/null
+++ b/p/service/loco/obj/fwserv.c
@@ -0,0 +1,152 @@
+/***************************************************************************
+
+ Forward-Server
+ Teil des MG-Mailsystems
+ (C) 1996 Loco@Morgengrauen
+
+ Es gilt dasselbe Copyright wie fuer mailer.c, bitte dort nachlesen.
+
+***************************************************************************/
+/* 24.03.2008, Arathorn
+   - Auch Erzmagier duerfen jetzt Eintraege aendern (Aenderung an Security())
+ */
+
+#include <properties.h>
+#include "/secure/config.h"
+#include "/mail/post.h"
+#include <wizlevels.h>
+
+#define LOG "/p/service/loco/save/FWLOG"
+
+static int Security(string name);
+
+static mixed forwarddata;
+mixed properties;
+
+
+create() {
+  seteuid(getuid());
+  forwarddata=([]);
+}
+
+
+LoadFile(s) {
+  if (!forwarddata[s])
+    forwarddata[s]=FWSAVESERV->LoadData(s);
+  if (!forwarddata[s])
+    forwarddata[s]=([]);
+}
+
+
+string QueryForward(string adr) {
+/* Setze eine Adresse um. Rueckgabe: Forwardadresse oder Name, wenn keine
+   gesetzt ist. Externe Adressen werden nicht umgesetzt. */
+  string s, res;
+  object player;
+  int i;
+
+  if (member(adr, '@')>=0) return adr; /* Externe Adresse */
+
+  for (i=sizeof(adr)-1;i>=1;i--) {
+    if (adr[i]>'z'||adr[i]<'a')
+      return "*UNGUELTIGER NAME: "+adr+" *";
+  }
+  if (adr[0]=='\\')
+    return adr;
+  
+  if (adr[0]>'z'||adr[0]<'a') 
+    return "*UNGUELTIGER NAME: "+adr+" *";
+
+
+  s=adr[0..0];
+  LoadFile(s);
+  
+  if (!member(forwarddata[s],adr)) return adr;
+
+  /* Achtung, ab hier wechselt Variable s z.T. ihre Bedeutung */
+
+  if (player=find_player(adr)) 
+    s=player->QueryProp(P_MAILADDR);
+  else {
+    /* Gibts den Spieler? */
+    if (!master()->find_userinfo(adr))
+        return 0;
+    /* hol die Daten */
+    restore_object(SAVEPATH+s+"/"+adr);
+    s=properties[P_MAILADDR];
+    properties=0;
+  }    
+
+  s=lower_case(s);
+  if (!s || !sizeof(s) ||
+      s=="none")
+    return adr;  /* keine sinnvolle Zieladresse: nicht umsetzen */
+
+  // jetzt noch pruefen, ob s eine fuer den MAILDEMON gueltige adresse ist.
+  if (MAILDEMON->query_recipient_ok(s))
+    return s;
+
+  return adr; // offenbar keine gueltige Adresse.
+}
+
+
+string AddForward(string name) {
+  string s;
+
+  name=lower_case(name);
+  s=name[0..0];
+
+  if (!Security(name)) 
+    return "Nachsendeauftrag abgelehnt, bitte EM oder Loco benachrichtigen.";
+
+  LoadFile(s);
+  
+  if (member(forwarddata[s],name))
+    return "Nachsendeauftrag war bereits gestellt worden.";
+
+  forwarddata[s]+=([name]);
+  FWSAVESERV->SaveData(s,forwarddata[s]);
+
+  write_file(LOG,ctime()+": ADD "+name+"\n");
+  
+  return "Nachsendeauftrag angenommen. Die Adresse lautet:\n  "+
+    QueryForward(name)+
+      "\nFalls diese falsch ist, bitte augenblicklich die email aendern!\n";
+
+}
+
+
+string DeleteForward(string name) {
+  string s;
+
+  name=lower_case(name);
+  s=name[0..0];
+
+  if (!Security(name)) 
+    return "Loeschen des Nachsendeauftrags ist nicht erlaubt,\n  bitte EM oder Loco benachrichtigen.";
+
+  LoadFile(s);
+  
+  if (!member(forwarddata[s],name))
+    return "Es war kein Nachsendeauftrag gestellt worden.";
+
+  forwarddata[s]-=([name]);
+  FWSAVESERV->SaveData(s,forwarddata[s]);
+  
+  write_file(LOG,ctime()+": DEL "+name+"\n");
+
+  return "Nachsendeauftrag geloescht, Post wird wieder direkt ausgeliefert.\n";
+}
+
+
+
+static int Security(string name) {
+  if (geteuid(this_interactive())==name) return 1;
+  if (geteuid()==geteuid(previous_object())) return 2;
+  if (member( ({ROOTID,MAILID}), geteuid(previous_object())) >=0 ) return 3;
+  if ( this_interactive() && IS_ARCH(this_interactive()) ) return 4;
+  return 0;
+}
+
+
+QueryForwards() { if (Security(" N I X ")) return forwarddata; }
diff --git a/p/service/loco/std/mailcabin.c b/p/service/loco/std/mailcabin.c
new file mode 100644
index 0000000..bd91261
--- /dev/null
+++ b/p/service/loco/std/mailcabin.c
@@ -0,0 +1,105 @@
+/* Eine Schreibkabine, in der man einigermassen ungestoert seine Post
+   lesen und schreiben kann.
+
+   (C) 1993/94 by Loco@Morgengrauen
+
+   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.
+   Ein Update-Service besteht nicht.
+
+   Fuer Fragen, Hinweise und Vorschlaege bitte mich in Morgengrauen oder 
+   Nightfall ansprechen.
+*/
+
+#pragma strong_types,save_types
+
+#include "/mail/post.h"
+#include <config.h>
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+
+inherit STDPOST;
+inherit "/std/thing/moving";
+inherit "/std/thing/commands";
+
+protected void create() {
+  post::create();
+  commands::create();
+  SetProp(P_NAME,"Schreibkabine");
+  SetProp(P_GENDER,FEMALE);
+  SetProp(P_SHORT,"Eine Schreibkabine");
+  SetProp(P_INT_LONG,"\
+In dieser Kabine kannst Du ungestoert Post lesen und schreiben. Niemand anders\n\
+kann hier rein, solange Du drin bist, dafuer waere die Kabine auch viel zu eng.\n\
+Tippe einfach 'post' oder 'mail', bzw 'mail <spieler>' zum Schreiben.\n\
+Mit 'raus' kommst Du wieder raus.\n");
+  SetProp(P_NOGET,"Versuch mal, eine festmontierte Kabine auszubauen!\n");
+  AddId("kabine");
+  AddId("schreibkabine");
+  AddId("postkabine");
+
+}
+
+int besetzt() {
+  mixed in,i;
+  in=all_inventory(this_object());
+  for (i=0;i<sizeof(in);i++) if (living(in[i]) && in[i]!=this_player()) return 1;
+  return 0;
+}
+
+public varargs string long() {
+  return "\
+Eine kleine Ein-Personen-Kabine, in der Du ungestoert Deine Post lesen und\n\
+schreiben kannst. Du kannst sie betreten. \n\
+"+( besetzt() ? "Diese Kabine ist allerdings besetzt.\n" : "");
+}
+
+string int_short(mixed viewer, mixed viewpoint) {
+  return (environment()->QueryProp(P_INT_SHORT))+" (Kabine)\n";
+}
+
+public varargs int move(mixed dest, int method, string dir, string textout, string textin) 
+{
+  int r;
+  r=(::move(dest,method));
+  AddExit("raus",object_name(environment()));
+  return r;
+}
+
+void init() {
+  (commands::init());
+  if (environment(this_player())==environment(this_object())) {
+    add_action("rein","betrete");
+    add_action("rein","betritt");
+    return;
+  }
+  if (besetzt()) {
+    this_player()->move(environment(this_object()),M_GO,0,"passt hier nicht mehr rein","macht die Tuer einer Kabine auf, aber die ist schon besetzt");
+    return;
+  }
+  if (environment(this_player())==this_object()) {
+    (post::init());
+    add_action("do_mail","mail");
+    add_action("do_mail","post");
+    return;
+  } 
+}
+
+int rein(string str) {
+  if (!str || !id(str)) {
+    notify_fail("Wo willst Du denn rein?\n");
+    return 0;
+  }
+  if (besetzt()) {
+    notify_fail("BESETZT!\n");
+    return 0;
+  }
+  this_player()->move(this_object(),M_GO,0,"betritt eine Schreibkabine","betritt die Kabine");
+  return 1;
+}
+
diff --git a/p/service/loco/std/post.c b/p/service/loco/std/post.c
new file mode 100644
index 0000000..47d0c43
--- /dev/null
+++ b/p/service/loco/std/post.c
@@ -0,0 +1,40 @@
+/* Neue std/post
+   (C) 1993 by Loco
+*/
+
+inherit "/std/room";
+
+#include "/mail/post.h"
+#include <properties.h>
+#include <rooms.h>
+
+void create() {
+  int i;
+  (::create());
+  SetProp(P_INT_SHORT,"Postamt");
+  SetProp(P_INT_LONG,"\
+Dies ist ein Testpostamt.\n\
+Von hier aus kannst Du Briefe an Deine Mitspieler schicken und Briefe von\n\
+ihnen lesen. Wenn Du das willst, tippe 'post' oder 'mail',\n\
+bzw. 'mail <spieler>'.\n");
+  SetProp( P_LIGHT, 1 );
+  AddCmd("post","do_mail");
+  AddCmd("mail","do_mail");
+  SetProp(P_INDOORS,1);
+  //  if (!argh) {
+  //   for (i=0;i<NRCABINS;++i) AddItem(MAILCABIN,REFRESH_REMOVE);
+  //  AddItem(COUNTER,REFRESH_REMOVE);
+  //  SetProp(P_POST,PP_ALLOWED);
+    //  }
+}
+
+int do_mail(string str) {
+  object mailer;
+  if (this_interactive()!=this_player()) return 0;
+  mailer=clone_object(MAILER);
+  mailer->SetOfficeName(short());
+  mailer->do_mail(str);
+  return 1;
+}
+
+