Skip to content
Snippets Groups Projects
ftpsrvr.c 81.5 KiB
Newer Older
	status("Initializing");

	lprintf("Synchronet FTP Server Version %s%s"
		,FTP_VERSION
#ifdef _DEBUG
		," Debug"
#else
		,""
#endif
		);

#if defined(__BORLANDC__)
	sprintf(compiler,"BCC %X.%02X"
		,__BORLANDC__>>8
		,__BORLANDC__&0xff);
#elif defined(_MSC_VER)
	sprintf(compiler,"MSC %u", _MSC_VER);
#else
	strcpy(compiler,"UNKNOWN COMPILER");
#endif

	lprintf("Compiled %s %s with %s", __DATE__, __TIME__, compiler);

	srand(time(NULL));

	if(PUTENV("TZ=UCT0"))
		lprintf("!putenv() FAILED");

	tzset();

	if((t=checktime())!=0) {   /* Check binary time */
		lprintf("!TIME PROBLEM (%08lx)",t);
		cleanup(1);
		return;
    }

	if(!winsock_startup()) {
		cleanup(1);
		return;
	}

    if((socket_mutex=CreateMutex(NULL,FALSE,NULL))==NULL) {
    	lprintf("!ERROR %d creating socket_mutex", GetLastError());
		cleanup(1);
        return;
    }

	/* Initial configuration and load from CNF files */
    memset(&scfg, 0, sizeof(scfg));
    sprintf(scfg.ctrl_dir, "%.*s", sizeof(scfg.ctrl_dir)-1
    	,startup->ctrl_dir);
    lprintf("Loading configuration files from %s", scfg.ctrl_dir);
	if(!load_cfg(&scfg, NULL)) {
		lprintf("!Failed to load configuration files");
		cleanup(1);
		return;
	}

	if(!startup->max_clients) {
		startup->max_clients=scfg.sys_nodes;
		if(startup->max_clients<10)
			startup->max_clients=10;
	}
	lprintf("Maximum clients: %d",startup->max_clients);

	if(!startup->max_inactivity) 
		startup->max_inactivity=300; /* seconds */

	lprintf("Maximum inactivity: %d seconds",startup->max_inactivity);

	active_clients=0;
	update_clients();

	strlwr(scfg.sys_id); /* Use lower-case unix-looking System ID for group name */

	for(i=0;i<scfg.total_libs;i++) {
		strlwr(scfg.lib[i]->sname);
		dotname(scfg.lib[i]->sname,scfg.lib[i]->sname);
	}

	for(i=0;i<scfg.total_dirs;i++) 
		strlwr(scfg.dir[i]->code);


    /* open a socket and wait for a client */

    if((server_socket=open_socket(SOCK_STREAM))==INVALID_SOCKET) {
		lprintf("!ERROR %d opening socket", ERROR_VALUE);
		cleanup(1);
		return;
	}

    lprintf("FTP socket %d opened",server_socket);

#if 1
	linger.l_onoff=TRUE;
    linger.l_linger=5;	/* seconds */

	if((result=setsockopt(server_socket, SOL_SOCKET, SO_LINGER
    	,(char *)&linger, sizeof(linger)))!=0) {
		lprintf ("!ERROR %d (%d) setting socket options.", result, ERROR_VALUE);
		cleanup(1);
		return;
	}
#endif

	/*****************************/
	/* Listen for incoming calls */
	/*****************************/
    memset(&server_addr, 0, sizeof(server_addr));

	server_addr.sin_addr.S_un.S_addr = htonl(startup->interface_addr);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port   = htons(startup->port);

    if((result=bind(server_socket, (struct sockaddr *) &server_addr
    	,sizeof(server_addr)))!=0) {
		lprintf("!ERROR %d (%d) binding socket to port %d"
			,result, ERROR_VALUE,startup->port);
		cleanup(1);
		return;
	}

    if((result=listen(server_socket, 1))!= 0) {
		lprintf("!ERROR %d (%d) listening on socket", result, ERROR_VALUE);
		cleanup(1);
		return;
	}

	/* signal caller that we've started up successfully */
    if(startup->started!=NULL)
    	startup->started();

	lprintf("FTP Server thread started on port %d",startup->port);
	status(STATUS_WFC);

	while(server_socket!=INVALID_SOCKET) {

		/* now wait for connection */

		client_addr_len = sizeof(client_addr);
		client_socket = accept(server_socket, (struct sockaddr *)&client_addr
        	,&client_addr_len);

		if(client_socket == INVALID_SOCKET)
		{
rswindell's avatar
rswindell committed
			if(ERROR_VALUE == ENOTSOCK || ERROR_VALUE == EINTR)
            	lprintf ("FTP socket closed while listening");
            else
				lprintf ("!ERROR %d accept failed", ERROR_VALUE);
			break;
		}
		if(startup->socket_open!=NULL)
			startup->socket_open(TRUE);
		sockets++;

		if(active_clients>=startup->max_clients) {
			lprintf("!MAXMIMUM CLIENTS (%d) reached, access denied",startup->max_clients);
			sockprintf(client_socket,"421 Maximum active clients reached, please try again later.");
			Sleep(3000);
			close_socket(&client_socket,__LINE__);
			continue;
		}

		if((ftp=malloc(sizeof(ftp_t)))==NULL) {
			lprintf("!ERROR allocating %d bytes of memory for ftp_t",sizeof(ftp_t));
			sockprintf(client_socket,"421 System error, please try again later.");
			Sleep(3000);
			close_socket(&client_socket,__LINE__);
			continue;
		}

		ftp->socket=client_socket;
		ftp->client_addr=client_addr;

		_beginthread (ctrl_thread, 0, ftp);
	}

	if(active_clients) {
		lprintf("Waiting for %d active clients to disconnect...", active_clients);
		start=time(NULL);
		while(active_clients) {
			if(time(NULL)-start>TIMEOUT_THREAD_WAIT) {
				lprintf("!TIMEOUT waiting for %d active clients ",active_clients);
				break;
			}
			Sleep(100);
		}
	}

	cleanup(0);
}