Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/secure/ftpd.c b/secure/ftpd.c
new file mode 100644
index 0000000..749cf03
--- /dev/null
+++ b/secure/ftpd.c
@@ -0,0 +1,178 @@
+/**************************************************************************
+** ftpd.c
+** Rumata@mg
+** 13.6.1999
+**
+** Ermittlung der Zugriffsrechte aus den Userdaten.
+**
+** Dieses Objekt wird vom ftpimp aus aufgerufen, der wiederum vom master
+** aufgerufen wird, um die Zugriffsrechte zu pruefen.
+**
+** Fuktionsweise:
+** + Im Master wird vom UNIX-ftpd aus FtpAccess (/secure/master/network)
+**   aufgerufen.
+** + Dieses ruft dann, sobald ein Zugriff erkannt wird
+**   QueryRead, QueryWrite oder QueryDir auf.
+** + Diese fragen den Master, ob der Zugriff legal ist.
+** + QueryDir liefert auch gleich das Ergebnis mit.
+**
+** Um ftp-zugriffe überwachen zu können, kann der ftpd eine liste der
+** ueberwachten spieler liefern und deren Zugriffe auf dem FTP Kanal ausgeben.
+**
+** add( name, zeit ) - FTP Zugriffe des Spielers 'name' werden protokolliert.
+**                     Nach 'zeit' wird dieser Zugriff automatisch beendet.
+**                     Ist 'zeit' <= 0, wir auf ewig ueberwacht. 
+** sub( name )       - FTP Snoop fuer Spieler 'name' direkt aufheben.
+** list()            - Mapping der ueberwachten Spieler zurueckgeben.
+**
+** FILES:
+**   /secure/master/network.c
+**   /secure/ftpd.c
+**   /std/shells/filesys/ftpimp.c
+**   /secure/ARCH/ftpd.o
+**   /p/daemon/channeld.init
+**
+***************************************************************************/
+
+#include "/secure/wizlevels.h"
+#include "/sys/daemon.h"
+
+#define FTPDSAVE "/secure/ARCH/ftpd"
+#define FTPD_CH "FTP"
+#define BBMASTER "/secure/bbmaster"
+
+mapping monitored;
+// Zu jedem Spielernamen wird vermerkt, wie lange die Ueberwachung dauern soll.
+// Zahlen <= 0 bedeuten fuer immer.
+
+nomask void create() {
+  if( clonep(this_object()) ) {
+    destruct( this_object() );
+    return;
+  }
+  seteuid( getuid() );
+  if( !restore_object(FTPDSAVE) )
+    monitored = ([]);
+}
+
+nomask int player_exists( string user ) {
+  user = lower_case(user);
+  if( !stringp( user ) || sizeof( user ) < 1 ) return 0;
+  return file_size( "/save/"+user[0..0]+"/"+user+".o" ) > 0;
+}
+
+nomask varargs int add( string user, int timeout ) {
+  if( !ARCH_SECURITY ) return -1;
+  if( !player_exists(user) ) return -2;
+  monitored[user] = timeout;
+  save_object( FTPDSAVE );
+  return 0;
+}
+
+nomask int sub( string user ) {
+  if( !ARCH_SECURITY ) return -1;
+  if( !player_exists(user) ) return -2;
+  monitored -= ([ user ]);
+  save_object( FTPDSAVE );
+  return 0;
+}
+
+nomask mixed list() {
+  if( !ARCH_SECURITY ) return -1;
+  return deep_copy(monitored);
+}
+
+#define NEWIMP "yes"
+
+private object findFtpImpFor( string user ) {
+#ifdef NEWIMP
+  return "/secure/impfetch"->impFor( lower_case(user) );
+#else
+  object imp;
+  string fname;
+
+  user = lower_case( user );
+  fname = "/ftpimp:" + user;
+  imp = find_object( fname );
+  if( !objectp(imp) ) {
+    imp = clone_object( "secure/ftpimp" );
+    imp->SetUser(user);
+    rename_object( imp, fname );
+  }
+  return imp;
+#endif
+}
+
+private nomask void msg( string user, string m ) {
+  int timeout;
+  object r;
+
+  if( !stringp(user) ) return;
+  m += "\n";
+  if( (r=find_player("rumata")) && user=="atamur" ) {
+     timeout = CHMASTER->send(FTPD_CH,findFtpImpFor(user), m );
+     tell_object( r, sprintf("%O\n", findFtpImpFor(user) ) );
+  }
+  BBMASTER->ftpbb(user,m);
+  if( !member(monitored,user) ) return;
+  timeout = monitored[user];
+  if( timeout > 0 && timeout < time() ) {
+    sub( user );
+    return;
+  }
+  CHMASTER->send(FTPD_CH,findFtpImpFor(user), m );
+}
+
+nomask int secure() {
+  return previous_object()==find_object(MASTER);
+}
+
+nomask mixed QueryRead( string user, string file ) {
+  if( !secure() ) return -1;
+  if( (IS_WIZARD(user) || file[0..4]=="/open")
+      && file[0] == '/'
+      && MASTER->valid_read(file, user, "read_file", 0)
+      ) {
+    msg( user, "read " + file );
+    return "OK";
+  } else {
+    return "FAIL";
+  }
+}
+
+nomask mixed QueryWrite( string user, string file ) {
+  if( !secure() ) return -1;
+  if( file[0] == '/'
+      && MASTER->valid_write( file, user, "write_file", 0)
+      ) {
+    msg( user, "write " + file );
+    return "OK";
+  } else {
+    return "FAIL";
+  }
+}
+
+#define DBG(x) if(find_player("rumata")){tell_object(find_player("rumata"),"FTPD:"+x+"\n");}
+
+//nomask mixed QueryDir( string user, string file ) {
+//  string reply;
+//  object imp;
+//
+//  if( !secure() ) return -1;
+//  reply = QueryRead( user, file );
+//  if( reply=="FAIL" ) return -1;
+//
+//  imp = findFtpImpFor( user );
+//  if( !objectp(imp) ) return -1; // should never happen
+//
+//  return imp->GetDir( file );
+//}
+
+nomask mixed QueryDir( string user, string file ) {
+  if( !secure() ) return -1;
+  if( file[0] == '/'
+      && MASTER->valid_read( file+"/*", user, "get_dir", 0))
+      return "OK";
+  else 
+    return "FAIL";
+}