예제 #1
0
int ftp_process_request(struct ftp_session* session, char *buf)
{
	int  fd;
	struct timeval tv;
	fd_set readfds;
	char filename[256];
	int  numbytes;
	char *sbuf;
	char *parameter_ptr, *ptr;
	rt_uint32_t addr_len = sizeof(struct sockaddr_in);
	struct sockaddr_in local, pasvremote;

	sbuf =(char *)rt_malloc(FTP_BUFFER_SIZE);

	tv.tv_sec=3, tv.tv_usec=0;
	local.sin_family=PF_INET;
	local.sin_addr.s_addr=INADDR_ANY;

	/* remove \r\n */
	ptr = buf;
	while (*ptr) {
		if (*ptr == '\r' || *ptr == '\n') *ptr = 0;
		ptr ++;
	}

	/* get request parameter */
	parameter_ptr = strchr(buf, ' ');
	if (parameter_ptr != NULL) parameter_ptr ++;

	// debug:
	rt_kprintf("%s requested: \"%s\"\n", inet_ntoa(session->remote.sin_addr), buf);

	//
	//-----------------------
	if(str_begin_with(buf, "USER")==0) {
		rt_kprintf("%s sent login \"%s\"\n", inet_ntoa(session->remote.sin_addr), parameter_ptr);
		// login correct
		if(strcmp(parameter_ptr, "anonymous") == 0) {
			session->is_anonymous = RT_TRUE;
			rt_sprintf(sbuf, "331 Anonymous login OK send e-mail address for password.\r\n", parameter_ptr);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		} else if (strcmp(parameter_ptr, FTP_USER) == 0) {
			session->is_anonymous = RT_FALSE;
			rt_sprintf(sbuf, "331 Password required for %s\r\n", parameter_ptr);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		} else {
			// incorrect login
			rt_sprintf(sbuf, "530 Login incorrect. Bye.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return -1;
		}
		return 0;
	} else if(str_begin_with(buf, "PASS")==0) {
		rt_kprintf("%s sent password \"%s\"\n", inet_ntoa(session->remote.sin_addr), parameter_ptr);
		if (strcmp(parameter_ptr, FTP_PASSWORD)==0 ||
			session->is_anonymous == RT_TRUE) {
			// password correct
			rt_sprintf(sbuf, "230 User logged in\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return 0;
		}

		// incorrect password
		rt_sprintf(sbuf, "530 Login or Password incorrect. Bye!\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		rt_free(sbuf);
		return -1;
	} else if(str_begin_with(buf, "LIST")==0  ) {
		memset(sbuf,0,FTP_BUFFER_SIZE);
		rt_sprintf(sbuf, "150 Opening Binary mode connection for file list.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		do_list(session->currentdir, session->pasv_sockfd);
		closesocket(session->pasv_sockfd);
		session->pasv_active = 0;
		rt_sprintf(sbuf, "226 Transfert Complete.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "NLST")==0 ) {
		memset(sbuf, 0, FTP_BUFFER_SIZE);
		rt_sprintf(sbuf, "150 Opening Binary mode connection for file list.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		do_simple_list(session->currentdir, session->pasv_sockfd);
		closesocket(session->pasv_sockfd);
		session->pasv_active = 0;
		rt_sprintf(sbuf, "226 Transfert Complete.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "PWD")==0 || str_begin_with(buf, "XPWD")==0) {
		rt_sprintf(sbuf, "257 \"%s\" is current directory.\r\n", session->currentdir);
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "TYPE")==0) {
		// Ignore it
		if(strcmp(parameter_ptr, "I")==0) {
			rt_sprintf(sbuf, "200 Type set to binary.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		} else {
			rt_sprintf(sbuf, "200 Type set to ascii.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		}
	} else if(str_begin_with(buf, "PASV")==0) {
		int dig1, dig2;
		int sockfd;
		char optval='1';

		session->pasv_port = 10000;
		session->pasv_active = 1;
		local.sin_port=htons(session->pasv_port);
		local.sin_addr.s_addr=INADDR_ANY;

		dig1 = (int)(session->pasv_port/256);
		dig2 = session->pasv_port % 256;

		FD_ZERO(&readfds);
		if((sockfd=socket(PF_INET, SOCK_STREAM, 0))==-1) {
			rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			goto err1;
		}
		if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))==-1) {
			rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			goto err1;
		}
		if(bind(sockfd, (struct sockaddr *)&local, addr_len)==-1) {
			rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			goto err1;
		}
		if(listen(sockfd, 1)==-1) {
			rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			goto err1;
		}
		rt_kprintf("Listening %d seconds @ port %d\n", tv.tv_sec, session->pasv_port);
		rt_sprintf(sbuf, "227 Entering passive mode (%d,%d,%d,%d,%d,%d)\r\n", 127, 0, 0, 1, dig1, dig2);
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		FD_SET(sockfd, &readfds);
		select(0, &readfds, 0, 0, &tv);
		if(FD_ISSET(sockfd, &readfds)) {
			if((session->pasv_sockfd = accept(sockfd, (struct sockaddr*)&pasvremote, &addr_len))==-1) {
				rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
				send(session->sockfd, sbuf, strlen(sbuf), 0);
				goto err1;
			} else {
				rt_kprintf("Got Data(PASV) connection from %s\n", inet_ntoa(pasvremote.sin_addr));
				session->pasv_active = 1;
				closesocket(sockfd);
			}
		} else {
err1:
			closesocket(session->pasv_sockfd);
			session->pasv_active = 0;
			rt_free(sbuf);
			return 0;
		}
	} else if (str_begin_with(buf, "RETR")==0) {
		int file_size;

		strcpy(filename, buf + 5);

		build_full_path(session, parameter_ptr, filename, 256);
		file_size = ftp_get_filesize(filename);
		if (file_size == -1) {
			rt_sprintf(sbuf, "550 \"%s\" : not a regular file\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			session->offset=0;
			rt_free(sbuf);
			return 0;
		}

		fd = open(filename, O_RDONLY, 0);
		if (fd < 0) {
			rt_free(sbuf);
			return 0;
		}

		if(session->offset>0 && session->offset < file_size) {
			lseek(fd, session->offset, SEEK_SET);
			rt_sprintf(sbuf, "150 Opening binary mode data connection for partial \"%s\" (%d/%d bytes).\r\n",
					   filename, file_size - session->offset, file_size);
		} else {
			rt_sprintf(sbuf, "150 Opening binary mode data connection for \"%s\" (%d bytes).\r\n", filename, file_size);
		}
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		while((numbytes = read(fd, sbuf, FTP_BUFFER_SIZE))>0) {
			send(session->pasv_sockfd, sbuf, numbytes, 0);
		}
		rt_sprintf(sbuf, "226 Finished.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		close(fd);
		closesocket(session->pasv_sockfd);
	} else if (str_begin_with(buf, "STOR")==0) {
		if(session->is_anonymous == RT_TRUE) {
			rt_sprintf(sbuf, "550 Permission denied.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return 0;
		}

		build_full_path(session, parameter_ptr, filename, 256);

		fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0);
		if(fd < 0) {
			rt_sprintf(sbuf, "550 Cannot open \"%s\" for writing.\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return 0;
		}
		rt_sprintf(sbuf, "150 Opening binary mode data connection for \"%s\".\r\n", filename);
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		FD_ZERO(&readfds);
		FD_SET(session->pasv_sockfd, &readfds);
		rt_kprintf("Waiting %d seconds for data...\n", tv.tv_sec);
		while(select(session->pasv_sockfd+1, &readfds, 0, 0, &tv)>0 ) {
			if((numbytes=recv(session->pasv_sockfd, sbuf, FTP_BUFFER_SIZE, 0))>0) {
				write(fd, sbuf, numbytes);
			} else if(numbytes==0) {
				close(fd);
				closesocket(session->pasv_sockfd);
				rt_sprintf(sbuf, "226 Finished.\r\n");
				send(session->sockfd, sbuf, strlen(sbuf), 0);
				break;
			} else if(numbytes==-1) {
				close(fd);
				closesocket(session->pasv_sockfd);
				rt_free(sbuf);
				return -1;
			}
		}
		closesocket(session->pasv_sockfd);
	} else if(str_begin_with(buf, "SIZE")==0) {
		int file_size;

		build_full_path(session, parameter_ptr, filename, 256);

		file_size = ftp_get_filesize(filename);
		if( file_size == -1) {
			rt_sprintf(sbuf, "550 \"%s\" : not a regular file\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		} else {
			rt_sprintf(sbuf, "213 %d\r\n", file_size);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		}
	} else if(str_begin_with(buf, "MDTM")==0) {
		rt_sprintf(sbuf, "550 \"/\" : not a regular file\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "SYST")==0) {
		rt_sprintf(sbuf, "215 %s\r\n", "RT-Thread RTOS");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "CWD")==0) {
		build_full_path(session, parameter_ptr, filename, 256);

		rt_sprintf(sbuf, "250 Changed to directory \"%s\"\r\n", filename);
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		strcpy(session->currentdir, filename);
		rt_kprintf("Changed to directory %s", filename);
	} else if(str_begin_with(buf, "CDUP")==0) {
		rt_sprintf(filename, "%s/%s", session->currentdir, "..");

		rt_sprintf(sbuf, "250 Changed to directory \"%s\"\r\n", filename);
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		strcpy(session->currentdir, filename);
		rt_kprintf("Changed to directory %s", filename);
	} else if(str_begin_with(buf, "PORT")==0) {
		int i;
		int portcom[6];
		char tmpip[100];

		i=0;
		portcom[i++]=atoi(strtok(parameter_ptr, ".,;()"));
		for(; i<6; i++)
			portcom[i]=atoi(strtok(0, ".,;()"));
		rt_sprintf(tmpip, "%d.%d.%d.%d", portcom[0], portcom[1], portcom[2], portcom[3]);

		FD_ZERO(&readfds);
		if((session->pasv_sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1) {
			rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			closesocket(session->pasv_sockfd);
			session->pasv_active = 0;
			rt_free(sbuf);
			return 0;
		}
		pasvremote.sin_addr.s_addr=inet_addr(tmpip);
		pasvremote.sin_port=htons(portcom[4] * 256 + portcom[5]);
		pasvremote.sin_family=PF_INET;
		if(connect(session->pasv_sockfd, (struct sockaddr *)&pasvremote, addr_len)==-1) {
			// is it only local address?try using gloal ip addr
			pasvremote.sin_addr=session->remote.sin_addr;
			if(connect(session->pasv_sockfd, (struct sockaddr *)&pasvremote, addr_len)==-1) {
				rt_sprintf(sbuf, "425 Can't open data connection.\r\n");
				send(session->sockfd, sbuf, strlen(sbuf), 0);
				closesocket(session->pasv_sockfd);
				rt_free(sbuf);
				return 0;
			}
		}
		session->pasv_active=1;
		session->pasv_port = portcom[4] * 256 + portcom[5];
		rt_kprintf("Connected to Data(PORT) %s @ %d\n", tmpip, portcom[4] * 256 + portcom[5]);
		rt_sprintf(sbuf, "200 Port Command Successful.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "REST")==0) {
		if(atoi(parameter_ptr)>=0) {
			session->offset=atoi(parameter_ptr);
			rt_sprintf(sbuf, "350 Send RETR or STOR to start transfert.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		}
	} else if(str_begin_with(buf, "MKD")==0) {
		if (session->is_anonymous == RT_TRUE) {
			rt_sprintf(sbuf, "550 Permission denied.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return 0;
		}

		build_full_path(session, parameter_ptr, filename, 256);

		if(mkdir(filename, 0) == -1) {
			rt_sprintf(sbuf, "550 File \"%s\" exists.\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		} else {
			rt_sprintf(sbuf, "257 directory \"%s\" successfully created.\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		}
	} else if(str_begin_with(buf, "DELE")==0) {
		if (session->is_anonymous == RT_TRUE) {
			rt_sprintf(sbuf, "550 Permission denied.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return 0;
		}

		build_full_path(session, parameter_ptr, filename, 256);

		if(unlink(filename)==0)
			rt_sprintf(sbuf, "250 Successfully deleted file \"%s\".\r\n", filename);
		else {
			rt_sprintf(sbuf, "550 Not such file or directory: %s.\r\n", filename);
		}
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	} else if(str_begin_with(buf, "RMD")==0) {
		if (session->is_anonymous == RT_TRUE) {
			rt_sprintf(sbuf, "550 Permission denied.\r\n");
			send(session->sockfd, sbuf, strlen(sbuf), 0);
			rt_free(sbuf);
			return 0;
		}
		build_full_path(session, parameter_ptr, filename, 256);

		if(unlink(filename) == -1) {
			rt_sprintf(sbuf, "550 Directory \"%s\" doesn't exist.\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		} else {
			rt_sprintf(sbuf, "257 directory \"%s\" successfully deleted.\r\n", filename);
			send(session->sockfd, sbuf, strlen(sbuf), 0);
		}
	}

	else if(str_begin_with(buf, "QUIT")==0) {
		rt_sprintf(sbuf, "221 Bye!\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
		rt_free(sbuf);
		return -1;
	} else {
		rt_sprintf(sbuf, "502 Not Implemented.\r\n");
		send(session->sockfd, sbuf, strlen(sbuf), 0);
	}
	rt_free(sbuf);
	return 0;
}
예제 #2
0
파일: HC_main.cpp 프로젝트: 299299/NagaGame
int havok_convert_main(bx::CommandLine* cmdline)
{
#ifdef HAVOK_COMPILE
    uint32_t timeMS = GetTickCount();

    int err = kErrorSuccess;
    LOG_INIT("HavokConverterLog.html", "Havok Converter");
    MemoryConfig cfg;
    memset(&cfg, 0, sizeof(cfg));
    cfg.m_debugMemSize = SIZE_MB(2);
    cfg.m_initHavok = true;
    cfg.m_havokFrameMemSize = 0;
    cfg.m_havokMonitorMemSize = 0;
    g_memoryMgr.init(cfg);

#ifdef HC_DUMP_PROFILE
    g_profiler.init(64);
#endif

    register_engine_factories();

    g_hc_config = new HC_Config;
    g_hc_config->m_packNormal = cmdline->hasArg("packnormal");
    g_hc_config->m_packUV = cmdline->hasArg("packuv");
    g_hc_config->m_slient = cmdline->hasArg("slient");
    g_hc_config->m_verbose = cmdline->hasArg("verbose");
    g_hc_config->m_merge = !cmdline->hasArg('b');

    Actor_Config config;
    ActorConverter* converter = 0;
    const char* mode = cmdline->findOption('m');
    if(!mode)
        mode = "model";

    const char* class_name = cmdline->findOption('c');
    if(!class_name)
        class_name = "level_geometry";

    const char* input = cmdline->findOption('f');
    const char* output = cmdline->findOption('o');
    if(!input)
    {
        g_hc_config->m_error.add_error("havok convert must specific f args!");
        err = kErrorArg;
        goto error_exit;
    }

    config.m_exportMode = mode;
    config.m_input = input;
    config.m_exportName = getFileName(input);
    config.m_exportFolder = "";
    config.m_rootPath = "";
    config.m_exportClass = class_name;

    if(output)
    {
        std::string output_path = output;
        string_replace(output_path, "\\", "/");
        if (str_begin_with(output_path, "./"))
        {
            output_path = output_path.substr(2, output_path.length() - 2);
        }
        if(!str_begin_with(output_path, INTERMEDIATE_PATH))
            config.m_exportFolder = std::string(INTERMEDIATE_PATH) + output_path;
        else
            config.m_exportFolder = output_path;
        add_trailing_slash(config.m_exportFolder);
        std::string path = config.m_exportFolder;
        string_replace(path, INTERMEDIATE_PATH, "");
        config.m_rootPath = path;
        LOGD("export-folder=%s *********** root-folder=%s", config.m_exportFolder.c_str(), config.m_rootPath.c_str());
    }
    else
    {
        config.m_exportFolder = TEMP_PATH;
    }
    config.m_output = config.m_exportFolder + config.m_exportName + "." + std::string(EngineNames::ACTOR);

    config.m_loader = new hkLoader;
    hkRootLevelContainer* rlc = config.m_loader->load(config.m_input.c_str());
    if (!rlc)
    {
        g_hc_config->m_error.add_error("can not load input havok file %s", config.m_input.c_str());
        err = kErrorLoadHavok;
        goto error_exit;
    }

    config.m_rlc = rlc;
    create_folder(config.m_exportFolder);
    hkxEnvironment* env = LOAD_OBJECT(rlc, hkxEnvironment);
    if(env)
    {
        hkStringBuf env_str;
        env->convertToString(env_str);
        LOGI(env_str.cString());
        config.m_assetFolder = env->getVariableValue("assetFolder");
        config.m_assetPath = env->getVariableValue("assetPath");
    }

    hkaAnimationContainer* ac = LOAD_OBJECT(rlc, hkaAnimationContainer);
    hkxScene* scene = LOAD_OBJECT(rlc,hkxScene);
    hkpPhysicsData* data = LOAD_OBJECT(rlc, hkpPhysicsData);

    config.m_scene = scene;
    config.m_animation = ac;
    config.m_physics = data;

    if(config.m_exportMode == "model")
    {
        if(!scene || !scene->m_rootNode)
        {
            g_hc_config->m_error.add_error("hkx file do not has root scene node.");
            goto error_exit;
        }
        converter = new StaticModelConverter;
        converter->setClass(config.m_exportClass);
    }
    else if(config.m_exportMode == "skin")
    {
        converter = new CharacterConverter;
        converter->setClass("character");
    }
    else if(config.m_exportMode == "level")
    {
        converter = new LevelConverter;
        config.m_output = config.m_exportFolder + config.m_exportName + "." + std::string(EngineNames::LEVEL);
    }
    else if(config.m_exportMode == "animation")
    {
        converter = new AnimationConverter;
        config.m_output = config.m_exportFolder + config.m_exportName + "." + std::string(EngineNames::ANIMATION);
    }
    if(!converter)
    {
        g_hc_config->m_error.add_error("havok converter export mode error.");
        err = kErrorArg;
        goto error_exit;
    }

    converter->m_config = &config;
    converter->setName(config.m_exportName);
    if(config.m_exportMode == "skin")
    {
        converter->process(ac);
    }
    else if(config.m_exportMode == "animation")
    {
        converter->process(ac);
    }
    else
    {
        converter->process(scene);
    }
    converter->postProcess();
    converter->serializeToFile(config.m_output.c_str());

error_exit:
    SAFE_REMOVEREF(converter);
    SAFE_REMOVEREF(config.m_loader);
    if(!g_hc_config->m_slient)
        g_hc_config->m_error.show_error();
    SAFE_DELETE(g_hc_config);

#ifdef HC_DUMP_PROFILE
    g_profiler.dump_to_file("havokconverter_profile.txt", true, true);
    g_profiler.shutdown();
#endif

    g_memoryMgr.shutdown();

    timeMS = GetTickCount() - timeMS;
    LOGD("******************************************************");
    LOGD("******************************************************");
    LOGD("* TOTAL TIME COST = %d[MS]", timeMS);
    LOGD("******************************************************");
    LOGD("******************************************************");

    LOG_TERM();
#endif
	return kErrorSuccess;
}