Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/secure/master/network.c b/secure/master/network.c
new file mode 100644
index 0000000..e681f82
--- /dev/null
+++ b/secure/master/network.c
@@ -0,0 +1,431 @@
+// MorgenGrauen MUDlib
+//
+// master/network.c - UDP-Handling
+//
+// $Id: network.c 8934 2014-09-10 21:57:12Z Zesstra $
+
+#pragma strict_types
+
+#include "/secure/master.h"
+#define BBMASTER "/secure/bbmaster"
+
+/*
+#undef DEBUG
+#define DEBUG(x) if (call_sefun("find_player","zesstra")) \
+                 tell_object(call_sefun("find_player","zesstra"),x);
+*/
+
+//ich will hieraus momentan kein Debug, ist zuviel. Zesstra
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+#define DEBUG(x)
+
+nosave int mails_last_hour;
+
+static string mail_normalize( string str )
+{
+    str = regreplace( str, "[^<]*<(.*)>[^>]*", "\\1", 0);
+    return regreplace( str, " *([^ ][^ ]*).*", "\\1", 0);
+}
+
+
+static string *mk_rec_list( string str )
+{
+    return map( explode( lower_case(str), "," ) - ({""}),
+                      "mail_normalize", this_object() );
+}
+
+
+static int CheckPasswd( string name, string passwd ) {
+    mixed *uinf;
+
+    if (!stringp(passwd) || !sizeof(passwd))
+ return 0;
+    if ( sizeof(uinf = get_full_userinfo(name)) < 2 )
+        return 0;
+
+    string pwhash = uinf[USER_PASSWORD+1];
+    if (sizeof(pwhash) > 13) {
+ // MD5-Hash
+ passwd = md5_crypt(passwd, pwhash);
+    }
+    else if (sizeof(pwhash) > 2) {
+ // Crypt-Hash
+ passwd = crypt(passwd, pwhash[0..1]);
+    }
+    else return 0;
+
+    return (passwd == pwhash);
+}
+
+
+static void FtpAccess( string host, string message, int port )
+{
+    string *comp, reply, head;
+#if __EFUN_DEFINED__(send_udp)
+    comp = efun::explode( message, "\t" );
+#define FTP_ID   0
+#define FTP_SEQ  1
+#define FTP_TAG  2
+#define FTP_CMD  3
+#define FTP_ARG1 4
+#define FTP_ARG2 5
+#define FTP_ARG3 6
+
+  if ( sizeof(comp) <= FTP_CMD || lower_case(comp[FTP_TAG]) != "req" ){
+      log_file( "IMP_MSGS", "Host: " + host + ":" + port + " - '" +
+                message + "'\n" );
+      return;
+  }
+
+  reply = "INVALID";
+
+  head = sprintf( "%s\t%s\tRPLY\t%s\t",
+                  comp[FTP_ID], comp[FTP_SEQ], comp[FTP_CMD] );
+
+  switch ( lower_case(comp[FTP_CMD]) ){
+  case "user":
+      if ( sizeof(comp) <= FTP_ARG1 )
+          break;
+
+      if ( IS_LEARNER(lower_case(comp[FTP_ARG1])) )
+          reply = "/players/" + lower_case(comp[FTP_ARG1]);
+      else
+          reply = "NONE";
+      break;
+
+  case "pass":
+      if ( sizeof(comp) <= FTP_ARG2 )
+          break;
+
+      comp[FTP_ARG1] = lower_case(comp[FTP_ARG1]);
+
+      if ( IS_LEARNER(comp[FTP_ARG1]) &&
+           !"/secure/master"->QueryTBanished(comp[FTP_ARG1]) ){
+          if ( CheckPasswd( comp[FTP_ARG1], comp[FTP_ARG2] ) )
+              reply = "OK";
+          else {
+              if ( get_wiz_level( comp[FTP_ARG1] ) < ARCH_LVL )
+                  log_file( "LOGINFAIL",
+                            sprintf( "PASSWORD:      (FTP)     %s %s\n",
+                                     comp[FTP_ARG1],
+                                     ctime(time()) ) );
+              else
+                  log_file( "ARCH/LOGINFAIL",
+                            sprintf( "PASSWORD:      (FTP)     %s %s\n",
+                                     comp[FTP_ARG1],
+                                     ctime(time()) ) );
+          }
+      }
+      else
+          reply = "FAIL";
+      break;
+
+  case "read":
+DEBUG("-FtpAccess----\nHost:"+host+"Message:\n"+message+"\n--------------\n");
+      if ( sizeof(comp) <= FTP_ARG2 )
+          break;
+
+      if ( comp[FTP_ARG2][0] == '/' &&
+           valid_read( comp[FTP_ARG2], lower_case(comp[FTP_ARG1]),
+                       "read_file", 0 ) ){
+
+          BBMASTER->ftpbb( lower_case(comp[FTP_ARG1]),
+                           "read " + comp[FTP_ARG2] + "\n" );
+          reply = "OK";
+          }
+      else
+          reply = "FAIL";
+      break;
+
+  case "writ":
+DEBUG("-FtpAccess----\nHost:"+host+"Message:\n"+message+"\n--------------\n");
+      if ( sizeof(comp) <= FTP_ARG2 )
+          break;
+
+      if ( comp[FTP_ARG2][0] == '/' &&
+           valid_write( comp[FTP_ARG2], lower_case(comp[FTP_ARG1]),
+                       "write_file", 0 ) ){
+
+          BBMASTER->ftpbb( lower_case(comp[FTP_ARG1]),
+                           "write " + comp[FTP_ARG2] + "\n" );
+          reply = "OK";
+          }
+       else
+          reply = "FAIL";
+      break;
+
+  case "list":
+DEBUG("-FtpAccess----\nHost:"+host+"Message:\n"+message+"\n--------------\n");
+      if ( sizeof(comp) <= FTP_ARG2 )
+          break;
+
+      if ( comp[FTP_ARG2][0] == '/' &&
+           valid_read( comp[FTP_ARG2], lower_case(comp[FTP_ARG1]),
+                       "read_file", 0 ) )
+          reply = "OK";
+      else
+          reply = "FAIL";
+      break;
+
+  default:
+DEBUG("-FtpAccess----\nHost:"+host+"Message:\n"+message+"\n--------------\n");
+      log_file( "IMP_MSGS", "Host: " + host + ":" + port + " - '" +
+                message + "'\n" );
+      break;
+  }
+
+  send_udp( host, port, head+reply );
+#endif
+}
+
+
+static int doReadMail( string file )
+{
+    string str, *lines, *parts, *tmp;
+    mixed *message;
+    int i, j;
+
+    if ( (i = file_size(file)) > 50000 || i < 5 ){
+        rm(file);
+        DEBUG( "Mail size invalid\n" );
+        return -1;
+    }
+
+    if ( !(str = read_bytes( file, 0, 50000 )) )
+        return -1;
+
+    if ( !(j = sizeof(lines = explode( str, "\n" ))) )
+        return -2;
+
+    i = 0;
+
+    while ( i < j && lines[i] != "" )
+        i++;
+
+    if ( i == j )
+        return -2;
+
+ DEBUG( sprintf( "Have %d headerlines:\n", i ) );
+
+    message= allocate(9);
+    message[MSG_CC] = ({});
+    message[MSG_BCC] = ({});
+    message[MSG_BODY] = implode( lines[i..], "\n" );
+
+    for ( j = 0; j < i; j++ ){
+        parts = explode( lines[j], ":" );
+
+        if ( sizeof(parts) > 1 ){
+            str = lower_case(parts[0]);
+            parts[0] = implode( parts[1..], ":" );
+
+            switch (str){
+            case "subject":
+                message[MSG_SUBJECT] = parts[0];
+                break;
+
+            case "from":
+                DEBUG( "Found from\n" );
+                DEBUG( sprintf( "PARTS[0]=%s\n", parts[0] ) );
+                message[MSG_FROM] = mail_normalize(parts[0]);
+                message[MSG_SENDER] = parts[0];
+                DEBUG( sprintf( "FROM: %s\nSENDER: %s\n",
+                                message[MSG_FROM],
+                                message[MSG_SENDER] ) );
+                break;
+
+            case "cc":
+                DEBUG( sprintf("FOUND CC: %O\n", parts[0]) );
+                message[MSG_CC] += mk_rec_list(parts[0]);
+                break;
+
+            case "bcc":
+                DEBUG( sprintf("FOUND BCC: %O\n", parts[0]) );
+                message[MSG_BCC] += mk_rec_list(parts[0]);
+                break;
+
+            case "to":
+                DEBUG( sprintf("FOUND TO: %O\n", parts[0]) );
+                tmp = mk_rec_list(parts[0]);
+
+                if ( !message[MSG_RECIPIENT] )
+                    message[MSG_RECIPIENT] = tmp[0];
+
+                message[MSG_CC] += tmp;
+                break;
+
+            // Das MUD-TO: wird vom Perlskript als erste Headerzeile eingefuegt
+            case "mud-to":
+                DEBUG( sprintf("FOUND MUD-TO: %O\n", parts[0]) );
+                message[MSG_RECIPIENT] = mail_normalize(lower_case(parts[0]));
+                break;
+            }
+        }
+    }
+
+    // Eigentlichen Empfaenger aus CC: loeschen
+    message[MSG_CC] -= ({ message[MSG_RECIPIENT],
+                          message[MSG_RECIPIENT]+"@mg.mud.de",
+                          message[MSG_RECIPIENT]+"@morgengrauen.mud.de" });
+
+
+ DEBUG( sprintf( "TO: %O\n", message[MSG_RECIPIENT] ) );
+    DEBUG( sprintf( "CC: %O\n", message[MSG_CC] ) );
+    DEBUG( sprintf( "BCC: %O\n", message[MSG_BCC] ) );
+
+    if ( !stringp(message[MSG_FROM]) )
+        return -2;
+
+    if ( !stringp(message[MSG_RECIPIENT]) ){
+        str = explode( file, "/" )[<1];
+        i = 0;
+        j = sizeof(str);
+
+        while ( i < j && str[i] <= '9' && str[i] >= '0' )
+            i++;
+
+        if ( i >= j )
+            return -2;
+        
+        message[MSG_RECIPIENT] = str[i..];
+  DEBUG( sprintf( "EMERGENCY RECIPIENT=%s\n", str[i..] ) );
+    }
+
+    rm(file);
+
+    // Da vom Master besser nichts von ausserhalb /secure #include't wird,
+    // direkt die '5'. Normalerweise hiesse der Aufruf:
+    // DeliverMail( message, NO_USER_ALIASES|NO_CARBON_COPIES );
+    "/secure/mailer"->DeliverMail( message, 5 );
+    return 1;
+}
+
+
+public void mailread()
+{
+    string *files;
+    int i;
+
+    DEBUG( "mailread called\n" );
+
+    if ( mails_last_hour >= MAX_MAILS_PER_HOUR )
+        return;
+
+    files = (get_dir( "/mail/inbound/*" )||({})) - ({ "..", "." });
+    i = sizeof(files);
+
+    while ( i-- && mails_last_hour < MAX_MAILS_PER_HOUR ){
+        DEBUG( "FOUND FILE \"" + files[i] + "\" ...\n" );
+        mails_last_hour++;
+
+        if ( doReadMail( "/mail/inbound/" + files[i]) < -1 ){
+            mixed message;
+
+            message = allocate(9);
+            mails_last_hour++;
+            rename( "/mail/inbound/" + files[i],
+                    "/secure/ARCH/MAIL/" + files[i] );
+            message[MSG_SENDER] = geteuid();
+            message[MSG_FROM] = getuid();
+            message[MSG_SUBJECT] = "Fehlerhafte Mail: /secure/ARCH/MAIL/" +
+                files[i];
+            message[MSG_RECIPIENT] = "mud@mg.mud.de";
+            message[MSG_BODY] = "Bitte Ueberpruefen!\n";
+            // NO_SYSTEM_ALIASES|NO_USER_ALIASES == 3
+            "/secure/mailer"->DeliverMail( message, 3 );
+        }
+    }
+}
+
+
+static void udp_query( string query, string host, int port )
+{
+#if __EFUN_DEFINED__(send_udp)
+    string *mess;
+    mixed *data;
+    int i, j;
+
+    mess = explode( query, " " );
+    
+    switch ( mess[1] ){
+    case "wholist":
+    case "who":
+        data = (string *)"/obj/werliste"->QueryWhoListe();
+        break;
+
+    case "uptime":
+        data = ({ call_sefun("uptime") });
+        break;
+
+    case "finger":
+        if ( sizeof(mess) < 3 )
+            data = ({ "Error: Wen soll ich fingern ?" });
+        else
+            data = explode( (string)"p/daemon/finger"->
+                            finger_single( lower_case(mess[2]), 0 ), "\n" );
+        break;
+
+    case "mailread":
+        data = ({ "Okay" });
+        mailread();
+        break;
+
+    default:
+        data = ({ "Error: unknown request " + mess[1] + "\n" });
+    }
+
+
+    send_udp( host, port, sprintf( "%s 0 %d", mess[0], sizeof(data) ) );
+
+    for ( i = 0, j = sizeof(data); i < j; i++ )
+        send_udp( host, port, sprintf( "%s %d %s", mess[0], i+1, data[i] ) );
+#endif
+}
+
+#define UDP_DEBUG(x) 
+//#define UDP_DEBUG(x) (write_file("/log/ARCH/udp.log",(x)))
+
+void receive_udp(string host, string message, int port)
+{
+  mixed *tmp;
+  UDP_DEBUG(sprintf("%s %s:%d: %s\n",strftime(),host,port,message));
+
+  if (message[0..6]=="EXTREQ:"
+  	|| message[0..5]=="IPNAME"
+  	|| message[0..3]=="AUTH"
+  ) {	
+    return;
+  }
+
+  if( message[0..8]=="IPLOOKUP\n" ) {
+    "/p/daemon/iplookup"->update( message );
+    return;
+  }
+
+  if( message[0..9]=="DNSLOOKUP\n" ) {
+    "/p/daemon/dnslookup"->update( message );
+    return;
+  }
+
+  if (message[0..4]=="NFTPD") {
+#if __HOST_NAME__==MUDHOST
+    if (host!=FTPD_IP) {
+      DEBUG(sprintf("INVALID HOST: %s\n",host));
+      return;
+    }
+#endif
+    FtpAccess(host,message,port);
+    return;
+  }
+
+  if (message[0..9]=="udp_query:") {
+    return udp_query(message[10..],host,port);
+  }
+
+  "secure/inetd"->_receive_udp(host, message);
+}
+
+