コード例 #1
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
void command_pasv(char *foo)
{
	int a1, a2, a3, a4;
   socklen_t namelen;
	struct sockaddr_in localsock;
    if (epsvall) {
        control_printf(SL_FAILURE, "500 EPSV ALL has been called.");
        return;
    }
	pasvsock = socket(AF_INET, SOCK_STREAM, 0);
	sa.sin_addr.s_addr = INADDR_ANY;
	sa.sin_family = AF_INET;

    if (!config_getoption("PASSIVE_PORTS") || !strlen(config_getoption("PASSIVE_PORTS"))) {
        /* bind to any port */
        sa.sin_port = 0;
        if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
            control_printf(SL_FAILURE, "425-Error: Unable to bind data socket.\r\n425 %s", strerror(errno));
            return;
        }
	} else {
        int i = 0, success = 0, port;
        for (;;) {
            port = int_from_list(config_getoption("PASSIVE_PORTS"), i++);
            if (port < 0)
                break;
            sa.sin_port = htons(port);
            if (bind(pasvsock, (struct sockaddr *) &sa, sizeof(sa)) == 0) {
                success = 1;
#ifdef DEBUG
//                bftpd_log("Passive mode: Successfully bound port %d\n", port);
#endif
                break;
            }
        }
        if (!success) {
            control_printf(SL_FAILURE, "425 Error: Unable to bind data socket.");
            return;
        }
        prepare_sock(pasvsock);
    }       

	if (listen(pasvsock, 1)) {
		control_printf(SL_FAILURE, "425-Error: Unable to make socket listen.\r\n425 %s",
				 strerror(errno));
		return;
	}
	namelen = sizeof(localsock);
	getsockname(pasvsock, (struct sockaddr *) &localsock, (int *) &namelen);
	sscanf((char *) inet_ntoa(name.sin_addr), "%i.%i.%i.%i",
		   &a1, &a2, &a3, &a4);
	control_printf(SL_SUCCESS, "227 Entering Passive Mode (%i,%i,%i,%i,%i,%i)", a1, a2, a3, a4,
			 ntohs(localsock.sin_port) >> 8, ntohs(localsock.sin_port) & 0xFF);
	pasv = 1;
}
コード例 #2
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
int dataconn()
{
	struct sockaddr foo;
	struct sockaddr_in local;
	size_t namelen = sizeof(foo);
    // brcm int curuid = geteuid();

	memset(&foo, 0, sizeof(foo));
	memset(&local, 0, sizeof(local));

	if (pasv) {
		sock = accept(pasvsock, (struct sockaddr *) &foo, &namelen);
		if (sock == -1) {
            control_printf(SL_FAILURE, "425-Unable to accept data connection.\r\n425 %s.",
                     strerror(errno));
			return 1;
		}
        close(pasvsock);
        prepare_sock(sock);
	} else {
		sock = socket(AF_INET, SOCK_STREAM, 0);
        prepare_sock(sock);
		local.sin_addr.s_addr = name.sin_addr.s_addr;
		local.sin_family = AF_INET;
#if 0 //brcm
        if (!strcasecmp(config_getoption("DATAPORT20"), "yes")) {
            seteuid(0);
            local.sin_port = htons(20);
        }
#endif //brcm
		if (bind(sock, (struct sockaddr *) &local, sizeof(local)) < 0) {
			control_printf(SL_FAILURE, "425-Unable to bind data socket.\r\n425 %s.",
					strerror(errno));
			return 1;
		}
#if 0 //brcm
        if (!strcasecmp(config_getoption("DATAPORT20"), "yes"))
            seteuid(curuid);
#endif //brcm
		sa.sin_family = AF_INET;
		if (connect(sock, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
			control_printf(SL_FAILURE, "425-Unable to establish data connection.\r\n"
                    "425 %s.", strerror(errno));
			return 1;
		}
	}
	control_printf(SL_SUCCESS, "150 %s data connection established.",
	               xfertype == TYPE_BINARY ? "BINARY" : "ASCII");
	return 0;
}
コード例 #3
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
int checkpass(char *password)
{
    if (!getpwnam(user))
		return 1;
#if 0 //brcm
    if (!strcasecmp(config_getoption("ANONYMOUS_USER"), "yes"))
		return 0;
#endif //brcm
#ifdef WANT_PAM
	if (!strcasecmp(config_getoption("AUTH"), "pam"))
		return checkpass_pam(password);
	else
#endif
	return checkpass_pwd(password);
}
コード例 #4
0
ファイル: bftpdutmp.c プロジェクト: Nymphetaminer/dsl-n55u
void bftpdutmp_init()
{
#ifdef TC_REMOVE
	char *filename = strdup(config_getoption("PATH_BFTPDUTMP"));

        if (! filename)
            return;

	if ((!strcasecmp(filename, "none")) || (!filename[0]))
		return;
    /* First we have to create the file if it doesn't exist */

    bftpdutmp = fopen(filename, "a");
    if (bftpdutmp)
        fclose(bftpdutmp);
    /* Then we can open it for reading and writing */
    if (!(bftpdutmp = fopen(filename, "r+"))) {
        bftpd_log("Could not open log file %s.", filename);
        control_printf(SL_FAILURE, "421-Could not open file %s\r\n"
                 "421 Server disabled for security reasons.", filename);
        exit(1);
    }
    rewind(bftpdutmp);
    // clean up memory
    free(filename);
#endif    
}
コード例 #5
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
int checkshell()
{
#ifdef HAVE_GETUSERSHELL
	char *cp;
	struct passwd *pwd;
#if 0 //brcm
    if (!strcasecmp(config_getoption("AUTH_ETCSHELLS"), "no"))
        return 0;
#endif //brcm    
	pwd = getpwnam(user);

	while ((cp = getusershell()))
		if (!strcmp(cp, pwd->pw_shell))
			break;
	endusershell();

	if (!cp)
		return 1;
	else
		return 0;
#else
    return 0;
#   warning "Your system doesn't have getusershell(). You can not"
#   warning "use /etc/shells authentication with bftpd."
#endif
}
コード例 #6
0
void command_adminlogin(char *params)
{
    char adminpass[31];
    char rootpass[31];
    char buffer[256];
    char *realadminpass = config_getoption("ADMIN_PASS");
    if (sscanf(params, "%30s %30s", adminpass, rootpass) < 2)
        loginfailed();
    if (!realadminpass[0])
        loginfailed();
    if (strcmp(crypt(adminpass, realadminpass), realadminpass))
        loginfailed();
    /* Admin password is right */
    strcpy(user, "root");
    init_userinfo();
    if (checkpass(rootpass))
        loginfailed();
    /* Root password is right as well */
    signal(SIGALRM, SIG_IGN);
    control_printf(SL_SUCCESS, "230 Administrative login successful.");
    bftpd_log("Administrative login SUCCESSFUL\n");
    while (fgets(buffer, sizeof(buffer), stdin)) {
        admin_parsecmd(buffer);
    }
    exit(0);
}
コード例 #7
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
void wtmp_init()
{
	if (strcasecmp(config_getoption("LOG_WTMP"), "no")) {
		if (!((wtmp = fopen(_PATH_WTMP, "a"))))
			bftpd_log("Warning: Unable to open %s.\n", _PATH_WTMP);
	}
}
コード例 #8
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
void new_umask()
{
    int um;
    char *foo = config_getoption("UMASK");
    if (!foo[0])
        um = 022;
    else
        um = strtoul(foo, NULL, 8);
    umask(um);
}
コード例 #9
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
int bftpd_setuid(uid_t uid)
{
#if 0 //brcm
    /* If we must open the data connections from port 20,
     * we have to keep the possibility to regain root privileges */
    if (!strcasecmp(config_getoption("DATAPORT20"), "yes"))
        return seteuid(uid);
    else
#endif //brcm
        return setuid(uid);
}
コード例 #10
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
void login_init()
{
    char *foo = config_getoption("INITIAL_CHROOT");
#ifdef HAVE_UTMP_H
	wtmp_init();
#endif
    if (foo[0]) { /* Initial chroot */
        if (chroot(foo) == -1) {
            control_printf(SL_FAILURE, "421 Initial chroot to '%s' failed.\r\n%s.",
                    foo, strerror(errno));
            exit(1);
        }
    }
}
コード例 #11
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
void command_user(char *username)
{

//printf("In command_user username=%s\n", username); // brcm

	// brcm char *alias;
	if (state) {
		control_printf(SL_FAILURE, "503 Username already given.");
		return;
	}
	mystrncpy(user, username, sizeof(user) - 1);
    userinfo_set = 1; /* Dirty! */
#if 0 // brcm 	
    alias = (char *) config_getoption("ALIAS");
    userinfo_set = 0;
	if (alias[0] != '\0')
		mystrncpy(user, alias, sizeof(user) - 1);
#endif //brcm
    init_userinfo();
#ifdef DEBUG
//	bftpd_log("Trying to log in as %s.\n", user);
#endif
#if 0 //brcm
    expand_groups();
	if (!strcasecmp(config_getoption("ANONYMOUS_USER"), "yes"))
		bftpd_login("");
	else {
		state = STATE_USER;
		control_printf(SL_SUCCESS, "331 Password please.");
	}
#endif //brcm
    state = STATE_USER; //brcm
	control_printf(SL_SUCCESS, "331 Password please."); //brcm

//printf("Done command_user username=%s\n", username); // brcm
}
コード例 #12
0
ファイル: dirlist.c プロジェクト: TheTypoMaster/AH4222
void hidegroups_init()
{
    char *foo = strdup(config_getoption("HIDE_GROUP"));
	char *foo_save = foo;
    char *bar;
    struct group *tmpgrp;
    while ((bar = strtok(foo, ","))) {
        foo = NULL; /* strtok requirement */
        if ((strcmp(bar, "0")) && (!strtoul(bar, NULL, 10))) {
            /* bar is not numeric */
            if ((tmpgrp = getgrnam(bar)))
                add_to_hidegroups(tmpgrp->gr_gid);
        } else
            if (strtoul(bar, NULL, 10))
                add_to_hidegroups(strtoul(bar, NULL, 10));
    }
	free(foo_save);
}
コード例 #13
0
ファイル: logging.c プロジェクト: gamman/bftpd
void log_init()
{
    char *foo = config_getoption("LOGFILE");
#ifdef HAVE_SYSLOG_H
	if (!strcasecmp(foo, "syslog")) {
        log_syslog = 1;
		openlog(global_argv[0], LOG_PID, LOG_DAEMON);
	} else
#endif
    if (foo[0])
        if (!(logfile = fopen(foo, "a"))) {
    		control_printf(SL_FAILURE, "421-Could not open log file.\r\n"
    		         "421 Server disabled for security reasons.");
    		exit(1);
    	}
    statuslog = fopen(PATH_STATUSLOG, "a");
    /* This one is for the admin code. */
    statuslogforreading = fopen(PATH_STATUSLOG, "r");
}
コード例 #14
0
ファイル: logging.c プロジェクト: gamman/bftpd
/*
 * This function opens the log file which keeps track of the amount
 * of data sent or received.
*/
int Open_Send_Receive_Log()
{
    char *foldername, *filename, *my_date;

    foldername = config_getoption("BANDWIDTH");
    if (! foldername[0])
       return 1;

    my_date = Current_Date();
    filename = (char *) calloc( strlen(foldername) + strlen(my_date) + 16, sizeof(char) );
    if (! filename)
       return 0;

    sprintf(filename, "%s/%s.txt", foldername, my_date);
    send_receive_file = fopen(filename, "a");
    free(filename);
    if (! send_receive_file)
       return 0;
    else
       return 1;
}
コード例 #15
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
void command_port(char *params) {
  unsigned long a0, a1, a2, a3, p0, p1, addr;
  if (epsvall) {
      control_printf(SL_FAILURE, "500 EPSV ALL has been called.");
      return;
  }
  sscanf(params, "%lu,%lu,%lu,%lu,%lu,%lu", &a0, &a1, &a2, &a3, &p0, &p1);
  addr = htonl((a0 << 24) + (a1 << 16) + (a2 << 8) + a3);
#if 0 //brcm
  if((addr != remotename.sin_addr.s_addr) &&( strncasecmp(config_getoption("ALLOW_FXP"), "yes", 3))) {
      control_printf(SL_FAILURE, "500 The given address is not yours.");
      return;
  }
#endif //brcm
  sa.sin_addr.s_addr = addr;
  sa.sin_port = htons((p0 << 8) + p1);
  if (pasv) {
    close(sock);
    pasv = 0;
  }
  control_printf(SL_SUCCESS, "200 PORT %lu.%lu.%lu.%lu:%lu OK",
           a0, a1, a2, a3, (p0 << 8) + p1);
}
コード例 #16
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
int checkuser()
{
#if 0 //brcm 
	FILE *fd;
	char *p;
	char line[256];

	if ((fd = fopen(config_getoption("PATH_FTPUSERS"), "r"))) {
		while (fgets(line, sizeof(line), fd))
			if ((p = strchr(line, '\n'))) {
				*p = '\0';
				if (line[0] == '#')
					continue;
				if (!strcasecmp(line, user)) {
					fclose(fd);
					return 1;
				}
			}
		fclose(fd);
	}
#endif //brcm 
	return 0;
}
コード例 #17
0
ファイル: commands.c プロジェクト: patrick-ken/bipac-7800nl
void command_eprt(char *params) {
    char delim;
    int af;
    char addr[51];
    char foo[20];
    int port;
    if (epsvall) {
        control_printf(SL_FAILURE, "500 EPSV ALL has been called.");
        return;
    }
    if (strlen(params) < 5) {
        control_printf(SL_FAILURE, "500 Syntax error.");
        return;
    }
    delim = params[0];
    sprintf(foo, "%c%%i%c%%50[^%c]%c%%i%c", delim, delim, delim, delim, delim);
    if (sscanf(params, foo, &af, addr, &port) < 3) {
        control_printf(SL_FAILURE, "500 Syntax error.");
        return;
    }
    if (af != 1) {
        control_printf(SL_FAILURE, "522 Protocol unsupported, use (1)");
        return;
    }
    sa.sin_addr.s_addr = inet_addr(addr);
    if ((sa.sin_addr.s_addr != remotename.sin_addr.s_addr) && (strncasecmp(config_getoption("ALLOW_FXP"), "yes", 3))) {
        control_printf(SL_FAILURE, "500 The given address is not yours.");
        return;
    }
    sa.sin_port = htons(port);
    if (pasv) {
        close(sock);
        pasv = 0;
    }
    control_printf(SL_FAILURE, "200 EPRT %s:%i OK", addr, port);
}
コード例 #18
0
void dirlist(char *name, FILE * client, char verbose,int bshow_hiden_files)
{
	DIR *directory;
    FILE *can_see_file;
    int show_nonreadable_files = FALSE;
    char *local_cwd = NULL;
    int i;
    int show_hidden_files = FALSE;
    glob_t globbuf;

     // 0.不支持配置文件配置,直接设置成显示所有文件包括隐藏文件
#if 0       
    if (! strcasecmp( config_getoption("SHOW_HIDDEN_FILES"), "yes") )
#endif
       show_hidden_files = bshow_hiden_files;

    if (! strcasecmp( config_getoption("SHOW_NONREADABLE_FILES"), "yes") )
       show_nonreadable_files = TRUE;

    if ((strstr(name, "/.")) && strchr(name, '*'))
        return; /* DoS protection */

	if ((directory = opendir(name))) 
        {
	     closedir(directory);
             local_cwd = bftpd_cwd_getcwd();
             chdir(name);
             glob("*", 0, NULL, &globbuf);
             if (show_hidden_files)
                 glob(".*", GLOB_APPEND, NULL, &globbuf);
	 } 
        else
        {
    	     if ( (name[0] == '*') && (show_hidden_files) )
             {
                glob(name, 0, NULL, &globbuf);
                glob(".*", GLOB_APPEND, NULL, &globbuf);
             }
             else
                glob(name, 0, NULL, &globbuf);
        }

	for (i = 0; i < globbuf.gl_pathc; i++)
        {
            if (! show_nonreadable_files) 
            {
               if ( (can_see_file = fopen(globbuf.gl_pathv[i], "r") ) == NULL)
                   continue;
               else
                   fclose(can_see_file);
            }

            dirlist_one_file(globbuf.gl_pathv[i], client, verbose);
        }

	globfree(&globbuf);
	if (local_cwd) {
		chdir(local_cwd);
		free(local_cwd);
	}
}
コード例 #19
0
ファイル: login.c プロジェクト: TheTypoMaster/AH4222
int bftpd_login(char *password)
{
#if 0	// brcm 
    char str[256];
	char *foo;
	int maxusers;
#endif //brcm
//printf("In bftpd_login password=%s, user=%s\n", password, user); // brcm
	if (!getpwnam(user)) {
        control_printf(SL_FAILURE, "421 Login incorrect.");
		return 1;
    }
    // brcm add local/remote login check
    if ((glbAccessMode == CLI_ACCESS_LOCAL && (strcmp(user, "user") && strcmp(user, "root"))) ||
        (glbAccessMode == CLI_ACCESS_REMOTE && strcmp(user, "support")))
    {
        control_printf(SL_FAILURE, "421 Login incorrect.");
	    return 1;
    }
#if 0 //brcm
	if (strncasecmp(foo = config_getoption("DENY_LOGIN"), "no", 2)) {
		if (foo[0] != '\0') {
			if (strncasecmp(foo, "yes", 3))
				control_printf(SL_FAILURE, "421-Server disabled.\r\n421 Reason: %s", foo);
			else
				control_printf(SL_FAILURE, "421 Login incorrect.");
			bftpd_log("Login as user '%s' failed: Server disabled.\n", user);
			exit(0);
		}
	}
	maxusers = strtoul(config_getoption("USERLIMIT_GLOBAL"), NULL, 10);
	if ((maxusers) && (maxusers == bftpdutmp_usercount("*"))) {
		control_printf(SL_FAILURE, "421 There are already %i users logged in.", maxusers);
		exit(0);
	}
	maxusers = strtoul(config_getoption("USERLIMIT_SINGLEUSER"), NULL, 10);
	if ((maxusers) && (maxusers == bftpdutmp_usercount(user))) {
		control_printf(SL_FAILURE, "421 User %s is already logged in %i times.", user, maxusers);
		exit(0);
	}
#endif //brcm

    if(checkuser() || checkshell()) {
		control_printf(SL_FAILURE, "421 Login incorrect.");
		exit(0);
	}
	if (checkpass(password))
		return 1;
#if 0 //brcm
	if (strcasecmp((char *) config_getoption("RATIO"), "none")) {
		sscanf((char *) config_getoption("RATIO"), "%i/%i",
			   &ratio_send, &ratio_recv);
	}
	strcpy(str, config_getoption("ROOTDIR"));
	if (!str[0])
		strcpy(str, "%h");
	replace(str, "%u", userinfo.pw_name);
	replace(str, "%h", userinfo.pw_dir);
	if (!strcasecmp(config_getoption("RESOLVE_UIDS"), "yes")) {
		passwdfile = fopen("/etc/passwd", "r");
		groupfile = fopen("/etc/group", "r");
	}
#endif //brcm
	setgid(userinfo.pw_gid);

	initgroups(userinfo.pw_name, userinfo.pw_gid);
#if 0 //brcm
	if (strcasecmp(config_getoption("DO_CHROOT"), "no")) {
		if (chroot(str)) {
			control_printf(SL_FAILURE, "421 Unable to change root directory.\r\n%s.",
					strerror(errno));
			exit(0);
		}
		if (bftpd_setuid(userinfo.pw_uid)) {
			control_printf(SL_FAILURE, "421 Unable to change uid.");
			exit(0);
		}
		if (chdir("/")) {
			control_printf(SL_FAILURE, "421 Unable to change working directory.\r\n%s.",
					 strerror(errno));
			exit(0);
		}
	} else {
		if (bftpd_setuid(userinfo.pw_uid)) {
			control_printf(SL_FAILURE, "421 Unable to change uid.");
			exit(0);
		}
		if (chdir(str)) {
			control_printf(SL_FAILURE, "230 Couldn't change cwd to '%s': %s.", str,
					 strerror(errno));
			chdir("/");
		}
	}
    new_umask();
	print_file(230, config_getoption("MOTD_USER"));
#endif //brcm
	
    control_printf(SL_SUCCESS, "230 User logged in.");

#ifdef HAVE_UTMP_H
	bftpd_logwtmp(1);
#endif
#if 0 //brcm
    bftpdutmp_log(1);
	bftpd_log("Successfully logged in as user '%s'.\n", user);

    if (config_getoption("AUTO_CHDIR")[0])
        chdir(config_getoption("AUTO_CHDIR"));
#endif //brcm        
	state = STATE_AUTHENTICATED;
//brcm	bftpd_cwd_init();

	return 0;
}
コード例 #20
0
ファイル: options.c プロジェクト: earthGavinLee/hg556a_source
/*
This function opens the config file and
tries to reset some of the option values
in memory.
-- Jesse
*/
void Reread_Config_File()
{
    char *line;     // line in config file
    char *config_value;    // value stored in memory
    char *new_value;
    FILE *config_file;
    int xfer_delay;
    int section = 0;     // where are we in the config file
    unsigned long get_value;

    // open config file
    config_file = fopen(configpath, "r");
    if (! config_file)
       return;

    /* read a line from the config file */
    line = config_read_line(config_file);
    while ( line )
    {
       if ( strchr(line, '{') )
          section++;

       /* look for reconized option name */
       if ( strstr(line, "HELLO_STRING") )
          config_value = config_getoption_reread("HELLO_STRING");
       else if ( strstr(line, "QUIT_MSG") )
          config_value = config_getoption_reread("QUIT_MSG");
       else if ( strstr(line, "XFERBUFSIZE") )
          config_value = config_getoption_reread("XFERBUFSIZE");
       else if ( strstr(line, "DATA_TIMEOUT") )
          config_value = config_getoption_reread("DATA_TIMEOUT");
       else if ( strstr(line, "CONTROL_TIMEOUT") )
          config_value = config_getoption_reread("CONTROL_TIMEOUT");
       else if ( strstr(line, "USERLIMIT_GLOBAL") )
          config_value = config_getoption_reread("USERLIMIT_GLOBAL");
       else if ( strstr(line, "USERLIMIT_SINGLEUSER") )
          config_value = config_getoption_reread("USERLIMIT_SINGLEUSER");
       else if ( strstr(line, "USERLIMIT_HOST") )
          config_value = config_getoption_reread("USERLIMIT_HOST");
       else if ( strstr(line, "DENY_LOGIN") )
          config_value = config_getoption_reread("DENY_LOGIN");
       else if ( strstr(line, "XFER_DELAY") )
          config_value = config_getoption_reread("XFER_DELAY");
       else if ( strstr(line, "GZ_UPLOAD") )
          config_value = config_getoption_reread("GZ_UPLOAD");
       else
          config_value = NULL;

       /* get new value from input */
       new_value = strchr(line, '"') ;
       if (new_value)
       {
           char *temp;
           new_value++;      // go to first character after quote
           temp = strchr(new_value, '"');  
           if (temp)
              temp[0] = '\0';    // null terminal string
       }

       /* set value of option */
       if ( (config_value) && (new_value) && (section == 1) )
       {
           // make sure it will fit.
           if ( strlen(new_value) < 256) 
              strcpy(config_value, new_value);
       }

       line = config_read_line(config_file);
    }       /* while not end of file */

    fclose(config_file);

    /* reset numeric values */
    get_value = strtoul( config_getoption("XFERBUFSIZE"), NULL, 0 );
    if (get_value <= INT_MAX)
       xfer_bufsize = get_value;
    else
       xfer_bufsize = XFER_BUFSIZE;

    if (! xfer_bufsize )
       xfer_bufsize = XFER_BUFSIZE;

    control_timeout = atoi( config_getoption("CONTROL_TIMEOUT") );
    if (! control_timeout)
       control_timeout = CONTROL_TIMEOUT;

    data_timeout = atoi( config_getoption("DATA_TIMEOUT") );
    if (! data_timeout)
       data_timeout = DATA_TIMEOUT;

    xfer_delay = atoi( config_getoption("XFER_DELAY") );
}