tmi2_fluffos_v2/
tmi2_fluffos_v2/bin/
tmi2_fluffos_v2/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/ChangeLog.old/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/Win32/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/compat/simuls/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/clone/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/command/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/data/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/etc/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/include/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/inherit/master/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/log/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/compiler/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/efuns/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/single/tests/operators/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/testsuite/u/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/tmp/
tmi2_fluffos_v2/fluffos-2.7-ds2.018/windows/
tmi2_fluffos_v2/lib/
tmi2_fluffos_v2/lib/adm/
tmi2_fluffos_v2/lib/adm/daemons/languages/
tmi2_fluffos_v2/lib/adm/daemons/network/I3/
tmi2_fluffos_v2/lib/adm/daemons/virtual/
tmi2_fluffos_v2/lib/adm/daemons/virtual/template/
tmi2_fluffos_v2/lib/adm/news/
tmi2_fluffos_v2/lib/adm/obj/
tmi2_fluffos_v2/lib/adm/obj/master/
tmi2_fluffos_v2/lib/adm/priv/
tmi2_fluffos_v2/lib/adm/shell/
tmi2_fluffos_v2/lib/adm/tmp/
tmi2_fluffos_v2/lib/cmds/
tmi2_fluffos_v2/lib/d/
tmi2_fluffos_v2/lib/d/Conf/
tmi2_fluffos_v2/lib/d/Conf/adm/
tmi2_fluffos_v2/lib/d/Conf/boards/
tmi2_fluffos_v2/lib/d/Conf/cmds/
tmi2_fluffos_v2/lib/d/Conf/data/
tmi2_fluffos_v2/lib/d/Conf/logs/
tmi2_fluffos_v2/lib/d/Conf/obj/
tmi2_fluffos_v2/lib/d/Conf/text/help/
tmi2_fluffos_v2/lib/d/Fooland/adm/
tmi2_fluffos_v2/lib/d/Fooland/data/
tmi2_fluffos_v2/lib/d/Fooland/data/attic/
tmi2_fluffos_v2/lib/d/Fooland/items/
tmi2_fluffos_v2/lib/d/TMI/
tmi2_fluffos_v2/lib/d/TMI/adm/
tmi2_fluffos_v2/lib/d/TMI/boards/
tmi2_fluffos_v2/lib/d/TMI/data/
tmi2_fluffos_v2/lib/d/TMI/rooms/
tmi2_fluffos_v2/lib/d/grid/
tmi2_fluffos_v2/lib/d/grid/adm/
tmi2_fluffos_v2/lib/d/grid/data/
tmi2_fluffos_v2/lib/d/std/
tmi2_fluffos_v2/lib/d/std/adm/
tmi2_fluffos_v2/lib/data/adm/
tmi2_fluffos_v2/lib/data/adm/daemons/
tmi2_fluffos_v2/lib/data/adm/daemons/doc_d/
tmi2_fluffos_v2/lib/data/adm/daemons/emoted/
tmi2_fluffos_v2/lib/data/adm/daemons/network/http/
tmi2_fluffos_v2/lib/data/adm/daemons/network/services/mail_q/
tmi2_fluffos_v2/lib/data/adm/daemons/network/smtp/
tmi2_fluffos_v2/lib/data/adm/daemons/news/archives/
tmi2_fluffos_v2/lib/data/attic/connection/
tmi2_fluffos_v2/lib/data/attic/user/
tmi2_fluffos_v2/lib/data/std/connection/b/
tmi2_fluffos_v2/lib/data/std/connection/l/
tmi2_fluffos_v2/lib/data/std/user/a/
tmi2_fluffos_v2/lib/data/std/user/b/
tmi2_fluffos_v2/lib/data/std/user/d/
tmi2_fluffos_v2/lib/data/std/user/f/
tmi2_fluffos_v2/lib/data/std/user/l/
tmi2_fluffos_v2/lib/data/std/user/x/
tmi2_fluffos_v2/lib/data/u/d/dm/working/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/doc_d/
tmi2_fluffos_v2/lib/data/u/l/leto/smtp/
tmi2_fluffos_v2/lib/doc/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/
tmi2_fluffos_v2/lib/doc/driverdoc/applies/interactive/
tmi2_fluffos_v2/lib/doc/driverdoc/concepts/
tmi2_fluffos_v2/lib/doc/driverdoc/driver/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/arrays/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/buffers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/compile/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/ed/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/filesystem/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/floats/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/functions/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/general/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/mappings/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/numbers/
tmi2_fluffos_v2/lib/doc/driverdoc/efuns/parsing/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/constructs/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/preprocessor/
tmi2_fluffos_v2/lib/doc/driverdoc/lpc/types/
tmi2_fluffos_v2/lib/doc/driverdoc/platforms/
tmi2_fluffos_v2/lib/doc/mudlib/
tmi2_fluffos_v2/lib/ftp/
tmi2_fluffos_v2/lib/include/driver/
tmi2_fluffos_v2/lib/log/
tmi2_fluffos_v2/lib/log/driver/
tmi2_fluffos_v2/lib/obj/net/
tmi2_fluffos_v2/lib/obj/shells/
tmi2_fluffos_v2/lib/obj/tools/
tmi2_fluffos_v2/lib/std/adt/
tmi2_fluffos_v2/lib/std/board/
tmi2_fluffos_v2/lib/std/body/
tmi2_fluffos_v2/lib/std/fun/
tmi2_fluffos_v2/lib/std/living/
tmi2_fluffos_v2/lib/std/object/
tmi2_fluffos_v2/lib/std/shop/
tmi2_fluffos_v2/lib/std/socket/
tmi2_fluffos_v2/lib/std/user/
tmi2_fluffos_v2/lib/std/virtual/
tmi2_fluffos_v2/lib/student/
tmi2_fluffos_v2/lib/student/kalypso/
tmi2_fluffos_v2/lib/student/kalypso/armor/
tmi2_fluffos_v2/lib/student/kalypso/rooms/
tmi2_fluffos_v2/lib/student/kalypso/weapons/
tmi2_fluffos_v2/lib/u/l/leto/
tmi2_fluffos_v2/lib/u/l/leto/cmds/
tmi2_fluffos_v2/lib/www/errors/
tmi2_fluffos_v2/lib/www/gateways/
tmi2_fluffos_v2/lib/www/images/
tmi2_fluffos_v2/old/
tmi2_fluffos_v2/win32/
/* ftpdsupp.h: ftpd support _code_ */

#ifndef _FTPDSUPP_H
#define _FTPDSUPP_H

/*
 * debugging macros
 */
#ifdef DEBUG
#define TP(STR) if ( find_player( TP_CRE ) ) \
                    tell_object( find_player( TP_CRE ), STR )
#define DEBUG_SEND   /* define to debug data_write_callback() */
#else
#define TP(STR)
#define DEBUG_SEND
#endif /* DEBUG */

#define CHECK_LOGIN() \
    if ( !socket_info[ fd ][ LOGGED_IN ] ) { \
        socket_write( fd, "530 Please login with USER and PASS.\n" ); \
        break; \
    }

#define CHECK_CMD(x) \
    if ( sizeof(command) == x) { \
        socket_write( fd, sprintf("500 '%s': command not understood.\n", \
              command[ 0 ]) ); \
        break; \
    }
   
/*
 * check_access determines who is allowed to use ftp (assuming the correct
 * password is known).  if check_access() returns 0 then the user is
 * disallowed even if the user knows the password.
 */
int
check_access(string name)
{
  string file;

#ifdef FTP_USERS
    if (!sizeof(FTP_USERS))
        return 0;
    return (member_array(name, FTP_USERS) != -1) ? 1 : 0;
#else

#ifdef ANONYMOUS_FTP
    if ( member_array(name, ANONYMOUS_FTP) != -1)
        return 1;
#endif /* ANONYMOUS_FTP */

#ifdef GUEST_WIZARD_FTP
    // TMI-2 allows those wizards w/o directories to log in
    file = PDATA_DIR + name[0..0] + "/" + name + __SAVE_EXTENSION__;
    return ( file_exists( file ) &&
           ( sscanf( read_file( file ), "%*swizard 1%*s" ) == 2 ) );
#else
    // This is if you require users to have a home directory
    //  in order to use ftp.
    return directory_exists(HOME_DIR(name)); /* tmi-2 simul_efun */
#endif

#endif /* FTP_USERS */
}

/*
 * return 1 if user named 'name' has password of 'plaintext'
 */
int
check_password(string name, string plaintext)
{
    string fancytext, cpass;
    object login_ob;

#ifdef ANONYMOUS_FTP
    if ( name == "anonymous" ) {
        // Currently guest's email address is not verified from USITE;
        // consider supporting:
        //   name@some.ip.dot.address (from USITE and/or socket_address(fd))
        //   name@some.domain.name (from USITE)
        //   name@some-mud (reverse DNS lookup)
        if (!plaintext || plaintext == "")
            return 0;
        else if (member_array(plaintext, ({ "none", "guest", "anon",
              "anonymous", "none@none"}) ) != -1)
            return 0;
        else
            return 1;
    }
#endif /* ANONYMOUS_FTP */

    /*
     * This is a good example of differences in mudlib design
     *   1) export_uid() vs creator_file() on setting a new object's uid
     *   2) query_password() vs query("password")
     */
#if 0
    seteuid(name)
    login_ob = new(PLAYER_OB);
    seteuid(getuid());

    login_ob->load_me(name);
    fancytext = (string)login_ob->query_password();
#else
    seteuid(getuid());
    login_ob = new(CONNECTION);

    // set login object's uid
    seteuid(name);
    export_uid(login_ob);

    // now set login object's name
    seteuid( getuid() );
    login_ob->set("name", name);

    // get login object's password
    login_ob->restore();
    fancytext = (string)login_ob->query("password");
#endif

    reload_object(login_ob);
    destruct(login_ob);

    if (!fancytext || !plaintext) {
        return 0;
    }

    cpass = crypt(plaintext, fancytext);

    return (cpass == fancytext);
}

/*
 * determines if "who" is allowed to connect from this site
 * by using the same args used by the user in his/her .login file for
 * the sitecheck command
 */
#ifdef CHECK_SITE
/*
 * compare dot portions (address components) of ip number (dotted decimal/
 * dotted quad) with an ip number pattern (ie containing wildcard(s))
 * - returns 1 if a match, 0 otherwise
 */
static int dot_match(string *site, string *pattern, int flag) {
    int i, j;

    j = sizeof(pattern);
    if (j != 4)
        return 0;

    while (j--) {
        if (flag) {
            /*
             * match any octect
             */
            if (pattern[j] == "*")
                continue;
        } else {
            /*
             * be strict (last octect only)
             */
            if (j == 3 && pattern[3] == "*")
                continue;
        }

        /*
         * component doesn't match
         */
        if (site[j] != pattern[j])
            return 0;
    }

    /*
     * by process of elimination...it must match
     */
    return 1;
}

int check_site(string who, int fd) {
    int wildcard_flag;
    string site, site_num;
    string arg;
    string *sites;
    object ob;
    int i, s, l1, l2;
    string *site_dots, *match_dots;

    site = USITE;

    /*
     * get site list (if any)
     */
    if (site && site != "" && file_size(HOME_DIR(who)) == -2 &&
          file_size(HOME_DIR(who) + ".login") > 0) {
        arg = read_file(HOME_DIR(who) + ".login");
        if (arg && strlen(arg)) {
            sites = explode(arg, "\n");
            sites = regexp(sites, "^sitecheck ");
            if (sites && sizeof(sites)) {
                arg = sites[0][10..<1];
                
                /*
                 * parse command line args
                 */
                arg = replace_string(arg, ",", " ");
                sites = explode(lower_case(arg), " ");

                /*
                 * check for options
                 */
                if (sites[0][0] == '-') {
                    // at the moment, we don't respect the presence of
                    // the -t (test) flag (ie allow the user to login
                    // anyways), and we don't respect the absense of the
                    // -d (destruct) flag, choosing to always drop the
                    // connection if the site check fails

                    if (strsrch(sites[0], 'w') != -1)
                        wildcard_flag = 1;
                }

                /*
                 * check list of accepted sites
                 *   1) check for perfect match
                 */
                site = lower_case(site);
                if (member_array(site, sites) != -1)
                    return 1;

                /*
                 *   2) check ip number (from ip name)
                 */
                if (sscanf(site, "%*d.%*d.%*d.%*d") != 4) {
                    site_num = socket_address(fd);
                    sscanf( site_num, "%s %*s", site_num );
                    if (member_array(site_num, sites) != -1)
                        return 1;
                } else {
                    site_num = site;
                    site = 0;
                }

                /*
                 * LAST: loop through wildcards in sites[]
                 *   Note: sites[] is altered
                 */
                if (strsrch(arg, '*') != -1) {
                    /*
                     * here's a quick filter :)
                     */
                    sites = regexp(sites, "\\*");
                    if (sites && (s = sizeof(sites))) {
                        /*
                         * check site ip name;
                         * default only allows '*' as a prefix,
                         *   ie "*.domain.name"
                         */
                        if (site) {
                            l1 = strlen(site);
                            i = s;
                            while (i--) {
                                l2 = strlen(sites[i]) - 1;
                                if (l2 > 1 && l1 > l2 &&
                                      sites[i][0..1] == "*." &&
                                      strcmp(site[l1-l2..<1],
                                      sites[i][1..<1]) == 0)
                                    return 1;
                            }

                            if (wildcard_flag) {
                                /*
                                 * handle '*' as suffix
                                 */
                                 i = s;
                                 while (i--) {
                                     l2 = strlen(sites[i]) - 2;
                                     if (l2 > 0 && l1 > l2 &&
                                          sites[i][l2..<1] == ".*" &&
                                          strcmp(site[0..l2],
                                          sites[i][0..l2]) == 0)
                                        return 1;
                                 }
                            }
                        }

                        /*
                         * check site ip number
                         */
                        if (site_num) {
                            site_dots = explode(site_num, ".");
                            i = s;
                            while (i--) {
                                match_dots = explode(sites[i], ".");
                                if (dot_match(site_dots, match_dots,
                                      wildcard_flag))
                                    return 1;
                            }
                        }
                    }
                }

                return 0;
            }
        }
    }

    return 1;
}
#endif /* SITE_CHECK */

#endif /* _FTPDSUPP_H */