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";
+}