gurba-0.40/
gurba-0.40/bin/
gurba-0.40/lib/
gurba-0.40/lib/cmds/guild/fighter/
gurba-0.40/lib/cmds/monster/
gurba-0.40/lib/cmds/race/catfolk/
gurba-0.40/lib/cmds/race/dwarf/
gurba-0.40/lib/cmds/verb/
gurba-0.40/lib/daemons/data/
gurba-0.40/lib/data/boards/
gurba-0.40/lib/data/messages/
gurba-0.40/lib/data/players/
gurba-0.40/lib/design/
gurba-0.40/lib/domains/gurba/
gurba-0.40/lib/domains/gurba/guilds/fighter/
gurba-0.40/lib/domains/gurba/monsters/
gurba-0.40/lib/domains/gurba/objects/armor/
gurba-0.40/lib/domains/gurba/objects/clothing/
gurba-0.40/lib/domains/gurba/objects/weapons/
gurba-0.40/lib/domains/gurba/vendors/
gurba-0.40/lib/kernel/cmds/admin/
gurba-0.40/lib/kernel/daemons/
gurba-0.40/lib/kernel/include/
gurba-0.40/lib/kernel/lib/
gurba-0.40/lib/kernel/net/
gurba-0.40/lib/kernel/sys/
gurba-0.40/lib/logs/
gurba-0.40/lib/pub/
gurba-0.40/lib/std/modules/languages/
gurba-0.40/lib/std/races/
gurba-0.40/lib/std/races/monsters/
gurba-0.40/lib/wiz/fudge/
gurba-0.40/lib/wiz/spud/
gurba-0.40/src/host/beos/
gurba-0.40/src/host/pc/res/
gurba-0.40/src/kfun/
gurba-0.40/src/lpc/
gurba-0.40/src/parser/
gurba-0.40/tmp/
int timeout_handle;
string name;
string password;
private mapping cmds;
int connected;
string cwd;
int priv;
int binary;

void open( void ) {
  send_message( "220-GurbaLib FTP daemon v0.01 ready.\n" );
  send_message( "220 Use your mud name as login.\n" );
  cmds = ([
	   "user" : "FTP_CMD_user",
	   "pass" : "FTP_CMD_pass",
	   "retr" : "FTP_CMD_retr",
	   "stor" : "FTP_CMD_stor",
	   "nlst" : "FTP_CMD_nlst",
	   "list" : "FTP_CMD_list",
	   "pwd"  : "FTP_CMD_pwd",
	   "cdup" : "FTP_CMD_cdup",
	   "cwd"  : "FTP_CMD_cwd",
	   "quit" : "FTP_CMD_quit",
	   "type" : "FTP_CMD_type",
	   "mkd"  : "FTP_CMD_mkd",
	   "port" : "FTP_CMD_port",
	   "noop" : "FTP_CMD_noop",
	   "dele" : "FTP_CMD_dele",
	   "syst" : "FTP_CMD_syst",
	   ]);
  connected = 0;
  name = "";
  timeout_handle = call_out( "login_timeout", 120 );
}

void FTPLOG( string str ) {
  write_file( "/logs/errors/ftpd", ctime( time() ) + " : " + str );
}

void FTP_CMD_user( string arg ) {
  arg = lowercase(arg);
  if(connected) {
      send_message("530 User " + arg + " access denied.\n");
      return;
  }
  name = arg;

  if(name == "ftp" || name == "anonymous" ) {
    send_message("331 Guest login ok, send your complete e-mail address as password.\n");
    return;
  }

  send_message("331 Password required for " + arg + ".\n");
  return;
}

void FTP_CMD_pass( string arg ) {

  object player;

  if( name == "" ) {
    send_message( "530 Login with USER first.\n" );
    return;
  }

  if( name == "ftp" || name == "anonymous" ) {
    send_message("230 guest login ok, access restrictions apply.\n");
    connected = 1;
    priv = 0;
    cwd = "/pub";
    FTPLOG("Anomymous login (" + arg + ")\n" );
    return;
   }
  password = crypt( arg, "gurba" );
  player = clone_object( "/std/player" );
  player->set_name( name );
  player->restore_me();
  if( password != player->query_password() ) {
    send_message( "530 Login incorrect.\n" );
    return;
  }
  destruct_object( player );
  send_message( "230 User " + name + " logged in.\n" );
  priv = SECURE_D->query_priv( name );
  FTPLOG( name + " logged in.\n" );
  connected = 1;
  cwd = "/";
}

void FTP_CMD_retr( string arg ) {

}

void FTP_CMD_stor( string arg ) {

}

void FTP_CMD_nlst( string arg ) {

}

void FTP_CMD_pwd( string arg ) {
  send_message( "257 \"" + cwd + "\" is current directory.\n" ); 
}

void FTP_CMD_cdup( string arg ) {

}

void FTP_CMD_cwd( string arg ) {

}

void FTP_CMD_quit( string arg ) {
  send_message( "221 Goodbye.\n" );
  FTPLOG( name + " quit.\n" );
  destruct_object( this_object() );
}

void FTP_CMD_type( string arg ) {
  switch(arg) {
  case "a":
  case "A":
    binary = 0;
    send_message("200 Type set to A.\n");
    return;
  case "i":
  case "I":
    binary = 1;
    send_message("200 Type set to I.\n");
    return;
  default:
    send_message("550 Unknown file type.\n");
    return;
  }
}

void FTP_CMD_mkd( string arg ) {

}

void FTP_CMD_port( string arg ) {
  string ip;
  string *parts;
  int    port;
  
  parts = explode( arg, "," );
  if( sizeof( parts ) != 6 ) {
    send_message("550 Failed command.\n");
    return;
  }
  ip = implode( parts[0..3], "." );

  /* Make a 16 bit port # out of two 8 bit values. */
  port = (str2val(parts[4]) << 8) + str2val(parts[5]);
  switch(info->binary) {
  case 0:
    break;
  case 1:
    break;
  default:
    return;
  }
  send_message("200 PORT command successful.\n");
  return;
}

void FTP_CMD_noop( string arg ) {
  send_message("221 NOOP command successful.\n");
}

void FTP_CMD_dele( string arg ) {

}

void FTP_CMD_syst( string arg ) {
  send_message( "215 UNIX Mud name: Gurba\n" );
}

void FTP_write( void ) {
  send_message( "226 Transfer complete.\n" );
}

void receive_message( string message ) {
  string cmd, arg;
  string func;

  if( message != "" && strlen(message) >= 2 ) {
    if( message[strlen(message)-1] == '\n' ) {
      message = message[..strlen(message)-2];
    }
  }

  if( message != "" && strlen(message) >= 2 ) {
    if( message[strlen(message)-1] == '\r' ) {
      message = message[..strlen(message)-2];
    }
  }

  arg = "";
  if( sscanf( message, "%s %s", cmd, arg ) != 2 ) {
    cmd = message;
  }

  cmd = lowercase( cmd );

  FTPLOG( "Got: " + message + "\n" );

  if( connected == 0 ) {
    /* Only allow these commands if not connected */
    switch( cmd ) {
    case "user" : 
      FTP_CMD_user( arg );
      return;
    case "pass":
      FTP_CMD_pass( arg );
      return;
    case "quit":
      FTP_CMD_quit( arg );
      return;
    case "noop":
      FTP_CMD_noop( arg );
      return;
    default:
      send_message("503 Log in with USER first.\n");
      return;
    }
  }
  func = cmds[cmd];
  if (!func)
    {
      /* Log command so we know what clients are trying to use */
      send_message( "502 Unknown command " + cmd + "\n" );
      return;
    }
  if(catch(call_other(this_object(), func, arg))) {
    FTPLOG(name + " caused a FAILURE with command '" + message + "'.\n" );
    send_message("550 Unknown failure.  Please report what you were doing to the mud admin.\n");
  }
  return;
}


void login_timeout( void ) {
  send_message( "220 Timed out.\n" );
  destruct_object( this_object() );
}