Example #1
0
int
main(int argc, char *argv[])
{
	FD	*f;
	int	fd;
	fd_set	localFDSet;
	int	ret;

	if (!netInit())
	{
		return 1;
	}
	if (!threadInit())
	{
		return 1;
	}

	fd = netListen(NULL, NULL, &mainPort);
	if (fd < 0)
	{
		fprintf(stderr, "netListen failed\n");
		return 1;
	}

	f = addFD(fd, acceptNewLogger);
	if (!f)
	{
		fprintf(stderr, "addFD failed\n");
		return 1;
	}

	while (1)
	{
		localFDSet = fdSet;
		ret = select(maxFD + 1, &localFDSet, NULL, NULL, NULL);
		if (ret == -1)
		{
			perror("select");
		}
		for (fd = 0; fd <= maxFD; fd++)
		{
			if (FD_ISSET(fd, &localFDSet))
			{
				if ((*table[fd]->handler)(fd))
				{
					for (fd = 0; fd <= maxFD; fd++)
					{
						removeFD(fd);
					}
					return 0;
				}
			}
		}
	}

	return 1;
}
Example #2
0
int main(int argc, char** argv){
	struct timespec t = {.tv_sec=0};
	struct timespec lastTime = {.tv_sec = 0, .tv_nsec = 0};
	struct timespec otherTime = {.tv_sec = 0, .tv_nsec = 0};
	SDL_Event evnt;

	if(argc < 2){
		puts("Please specify an ip.");
		return 5;
	}
	if(initView){
		puts("no SDL2 window");
		return 1;
	}
	initNetwork(argv[1], 1212);
	char test[10];
	test[0] = 0;
	sendto(sockfd, test, 10, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
	sendto(sockfd, test, 10, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
	while(running){
		netListen();
		while(SDL_PollEvent(&evnt)){
			if(evnt.type == SDL_KEYDOWN){
				if(!keyAction(evnt.key.keysym.sym, 1)){
					test[0] = 1;
					sendto(sockfd, test, 10, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
				}
			}else if(evnt.type == SDL_KEYUP){
				if(!keyAction(evnt.key.keysym.sym, 0)){
					test[0] = 1;
					sendto(sockfd, test, 10, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
				}
			}else if(evnt.type == SDL_QUIT){
				running = 0;
			}
		}
		clock_gettime(CLOCK_MONOTONIC, &otherTime);
		int32_t sleep = (int32_t)(1000000000/50) - (otherTime.tv_nsec-lastTime.tv_nsec) - 1000000001*(otherTime.tv_sec-lastTime.tv_sec);
		if(sleep > 0){
			t.tv_nsec = sleep;
			nanosleep(&t, NULL);
		}
		clock_gettime(CLOCK_MONOTONIC, &lastTime);
	}
	SDL_DestroyRenderer(render);
	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}
Example #3
0
File: net.c Project: jxva/miaoox
int netStartServer(char *err, int port, char *bindaddr) {
    int so;
    struct sockaddr_in sa;
    /*struct sockaddr_in sa;*/

    if ((so = netCreateSocket(err, AF_INET)) == -1)
        return -1;
    //netSetSocketReuse(err, so);
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bindaddr && inet_aton(bindaddr, &sa.sin_addr) == 0) {
        netPrintError(err, "invalid bind address");
        close(so);
        return -1;
    }
    if (netBind(err, so, (struct sockaddr*)&sa) == -1)
        return -1;
    if (netListen(err, so, (struct sockaddr*)&sa) == -1)
        return -1;
    return so;
}
Example #4
0
static int
readLoggerRequest(int fd)
{
	char		b[10240];
	int		bytesRead;
	int		doSuspend;
	FD		*f;
	FILE		*file;
	unsigned char	*host;
	int		i;
	char		*p;
	unsigned short	port;
	int		proxyListenFD;
	char		*resume;
	char		*str;
	char		*suspend;
	int		suspendPort;

	bytesRead = recv(fd, b, sizeof(b) - 1, 0);
	if (bytesRead < 0)
	{
		if (errno != ECONNRESET)
		{
			perror("recv");
		}
		removeFD(fd);
		return 0;
	}
	else if (!bytesRead)
	{
		removeFD(fd);
		return 0;
	}
	b[bytesRead] = 0;

	resume = "/resume";
	suspend = "/suspend";
	if (strstr(b, "/exit"))
	{
		char *goodbye =
			"HTTP/1.0 200 OK\n"
			"Content-Type: text/html\n"
			"\n"
			"Bye!"
		;
		send(fd, goodbye, strlen(goodbye), 0);
		removeFD(fd);
		return 1;
	}
	else if ((strstr(b, resume)) || (strstr(b, suspend)))
	{
		if (strstr(b, resume))
		{
			str = resume;
			doSuspend = 0;
		}
		else
		{
			str = suspend;
			doSuspend = 1;
		}
		p = strstr(b, str);
		p += strlen(str);
		if (*p != '/')
		{
			char *notOK =
				"HTTP/1.0 200 OK\n"
				"Content-Type: text/html\n"
				"\n"
				"No backslash after command!"
			;
			send(fd, notOK, strlen(notOK), 0);
			removeFD(fd);
			return 0;
		}
		sscanf(p + 1, "%d", &suspendPort);
		for (i = 0; i <= maxFD; i++)
		{
			if (table[i] && (table[i]->port == suspendPort))
			{
				table[i]->suspend = doSuspend;
				break;
			}
		}
		if (i <= maxFD)
		{
			char *ok =
				"HTTP/1.0 200 OK\n"
				"Content-Type: text/html\n"
				"\n"
				"OK!"
			;
			send(fd, ok, strlen(ok), 0);
		}
		else
		{
			char *notOK =
				"HTTP/1.0 200 OK\n"
				"Content-Type: text/html\n"
				"\n"
				"Cannot find port number in table!"
			;
			send(fd, notOK, strlen(notOK), 0);
		}
		removeFD(fd);
		return 0;
	}

	/* XXX send(1, b, bytesRead, 0); */

	file = fdopen(fd, "w");
	if (!file)
	{
		char *err = "fdopen failed\n";
		send(fd, err, strlen(err), 0);
		removeFD(fd);
		return 0;
	}
	table[fd]->logFile = file;

	port = 0;
	proxyListenFD = netListen(NULL, &host, &port);
	if (proxyListenFD < 0)
	{
		fprintf(file, "listen failed\n");
		removeFD(fd);
		fclose(file);
		return 0;
	}
	f = addFD(proxyListenFD, acceptNewClient);
	if (!f)
	{
		fprintf(file, "addFD failed\n");
		removeFD(fd);
		fclose(file);
		return 0;
	}

	fprintf(file, welcome1);
	fprintf(file, welcome2);
	fprintf(file, welcome3, host, port);
	fprintf(file, welcome4, host, mainPort, port, host, mainPort, port);
	sprintf(suspendStr, "http://%s:%d/suspend/%d", host, mainPort, port);
	free(host);
	fflush(file);
	f->logFile = file;
	table[fd]->port = port;

	return 0;
}
Example #5
0
static void handleclient(u64 conn_s_p)
{
	// todo: clean up
	
	int conn_s = (int)conn_s_p;
	int list_s_data = -1;
	int conn_s_data = -1;
	int datareq = 0;
	
	char		cwd[256];
	char		rnfr[256];
	char		filename[256];
	char		user[32];
	u32		rest = 0;
	int		authd = 0;
	int		active = 1;
	Lv2FsFile	tempfd;
	char		buf[BUFFER_SIZE];

	char	buffer[1024];
	char	client_cmd[8][128];
	ssize_t	bytes;
	
	#if LOGIN_CHECK == 1
	// load password file
	char passwordcheck[33];
						
	// check if password file exists - if not, use default password
	if(exists(PASSWORD_FPATH) == 0)
	{
		Lv2FsFile fd;
		u64 read;
		
		lv2FsOpen(PASSWORD_FPATH, LV2_O_RDONLY, &fd, 0, NULL, 0);
		lv2FsRead(fd, passwordcheck, 32, &read);
		lv2FsClose(fd);
		
		if(strlen(passwordcheck) != 32)
		{
			strcpy(passwordcheck, LOGIN_PASSWORD);
		}
	}
	else
	{
		strcpy(passwordcheck, LOGIN_PASSWORD);
	}
	#endif
	
	// start directory
	strcpy(cwd, "/");
	
	// welcome message
	swritel(conn_s, "220-OpenPS3FTP by @jjolano\r\n");
	sprintf(buffer, "220 Version %s\r\n", VERSION);
	swritel(conn_s, buffer);
	
	while(exitapp == 0 && active && (bytes = sreadl(conn_s, buffer, 1024)) > 0)
	{
		// get rid of the newline at the end of the string
		buffer[strcspn(buffer, "\n")] = '\0';
		buffer[strcspn(buffer, "\r")] = '\0';
		
		// parse received string into array
		int parameter_count = 0;
		
		char *result = strtok(buffer, " ");
		
		strcpy(client_cmd[0], result);
		
		while(parameter_count < 7 && (result = strtok(NULL, " ")) != NULL)
		{
			parameter_count++;
			strcpy(client_cmd[parameter_count], result);
		}
		
		// identify the command
		int cmd_id;
		for(cmd_id = 0; cmd_id < client_cmds_count; cmd_id++)
		{
			if(strcasecmp(client_cmd[0], client_cmds[cmd_id]) == 0)
			{
				break;
			}
		}
		
		// execute command
		if(authd == 0)
		{
			// not logged in
			
			switch(cmd_id)
			{
				case 0: // USER
					#if LOGIN_CHECK == 1
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						strcpy(user, client_cmd[1]);
						sprintf(buffer, "331 User %s OK. Password required\r\n", user);
						swritel(conn_s, buffer);
					}
					else
					{
						swritel(conn_s, "501 Please provide a username\r\n");
					}
					#else
					sprintf(buffer, "331 User %s OK. Password (not really) required\r\n", user);
					swritel(conn_s, buffer);
					#endif
					break;
				case 1: // PASS
					#if LOGIN_CHECK == 1
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						// hash the password given
						char output[33];
						md5(output, client_cmd[1]);
					
						if(strcmp(user, LOGIN_USERNAME) == 0 && strcmp(output, passwordcheck) == 0)
						{
							swritel(conn_s, "230 Successful authentication\r\n");
							authd = 1;
						}
						else
						{
							swritel(conn_s, "430 Invalid username or password - \r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Invalid username or password\r\n");
					}
					#else
					swritel(conn_s, "230 Successful authentication\r\n");
					authd = 1;
					#endif
					break;
				case 2: // QUIT
					swritel(conn_s, "221 See you later\r\n");
					active = 0;
					break;
				default: swritel(conn_s, "530 You are not logged in\r\n");
			}
		}
		else
		{
			// logged in
			
			switch(cmd_id)
			{
				case 0: // USER
				case 1: // PASS
					swritel(conn_s, "530 You are already logged in\r\n");
					break;
				case 2: // QUIT
					swritel(conn_s, "221 See you later\r\n");
					active = 0;
					break;
				case 3: // PASV
					rest = 0;
				
					netSocketInfo snf;
				
					int ret = netGetSockInfo(conn_s, &snf, 1);
				
					if(ret >= 0 && snf.local_adr.s_addr != 0)
					{
						// assign a random port for passive mode
						srand(conn_s);
						
						int rand1 = (rand() % 251) + 4;
						int rand2 = rand() % 256;
						
						sprintf(buffer, "227 Entering Passive Mode (%u,%u,%u,%u,%i,%i)\r\n",
							(snf.local_adr.s_addr & 0xFF000000) >> 24,
							(snf.local_adr.s_addr & 0xFF0000) >> 16,
							(snf.local_adr.s_addr & 0xFF00) >> 8,
							(snf.local_adr.s_addr & 0xFF),
							rand1, rand2);
						
						short int pasvport = (rand1 * 256) + rand2;
						
						struct sockaddr_in servaddr;
						memset(&servaddr, 0, sizeof(servaddr));
						servaddr.sin_family      = AF_INET;
						servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
						servaddr.sin_port        = htons(pasvport);
						
						list_s_data = netSocket(AF_INET, SOCK_STREAM, 0);
						netBind(list_s_data, (struct sockaddr *) &servaddr, sizeof(servaddr));
						netListen(list_s_data, 1);
						
						swritel(conn_s, buffer);
						
						if((conn_s_data = netAccept(list_s_data, NULL, NULL)) == -1)
						{
							swritel(conn_s, "550 PASV command failed\r\n");
						}
						else
						{
							datareq = 1;
						}
						break;
					}
		
					swritel(conn_s, "550 PASV command failed\r\n");
					break;
				case 4: // PORT
					if(parameter_count == 1)
					{
						rest = 0;
						
						char connectinfo[32];
						strcpy(connectinfo, client_cmd[1]);
						
						char data[7][4];
						int i = 0;
						
						char *result = strtok(connectinfo, ",");
	
						strcpy(data[0], result);
	
						while(i < 6 && (result = strtok(NULL, ",")) != NULL)
						{
							i++;
							strcpy(data[i], result);
						}
					
						char conn_ipaddr[16];
						sprintf(conn_ipaddr, "%s.%s.%s.%s", data[0], data[1], data[2], data[3]);
						
						struct sockaddr_in servaddr;
						memset(&servaddr, 0, sizeof(servaddr));
						servaddr.sin_family	= AF_INET;
						servaddr.sin_port	= htons((atoi(data[4]) * 256) + atoi(data[5]));
						inet_pton(AF_INET, conn_ipaddr, &servaddr.sin_addr);
						
						conn_s_data = netSocket(AF_INET, SOCK_STREAM, 0);
					
						if(connect(conn_s_data, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0)
						{
							swritel(conn_s, "200 PORT command successful\r\n");
							datareq = 1;
						}
						else
						{
							swritel(conn_s, "550 PORT command failed\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 5: // SITE
					if(strcasecmp(client_cmd[1], "CHMOD") == 0)
					{
						int i;
						for(i = 4; i <= parameter_count; i++)
						{
							strcat(client_cmd[3], " ");
							strcat(client_cmd[3], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[3], cwd);
					
						char perms[4];
						sprintf(perms, "0%s", client_cmd[2]);
						
						if(lv2FsChmod(filename, S_IFMT | strtol(perms, NULL, 8)) == 0)
						{
							swritel(conn_s, "250 File permissions successfully set\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to set file permissions\r\n");
						}
					}
					else
					{
						swritel(conn_s, "500 Unrecognized SITE command\r\n");
					}
					break;
				case 6: // FEAT
					swritel(conn_s, "211- Extensions supported:\r\n");
				
					int i;
					for(i = 0; i < feat_cmds_count; i++)
					{
						sprintf(buffer, " %s\r\n", feat_cmds[i]);
						swritel(conn_s, buffer);
					}
				
					swritel(conn_s, "211 End.\r\n");
					break;
				case 7: // TYPE
					swritel(conn_s, "200 TYPE command successful\r\n");
					break;
				case 8: // REST
					if(parameter_count == 1)
					{
						rest = atoi(client_cmd[1]);
						swritel(conn_s, "350 REST command successful\r\n");
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 9: // RETR
					if(parameter_count >= 1)
					{
						if(conn_s_data == -1)
						{
							swritel(conn_s, "425 No data connection\r\n");
							break;
						}
					
						swritel(conn_s, "150 Opening data connection\r\n");

						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
						
						u64 pos;
						u64 read = -1;
					
						Lv2FsFile fd;
					
						lv2FsOpen(filename, LV2_O_RDONLY, &fd, 0, NULL, 0);
						lv2FsLSeek64(fd, (s64)rest, SEEK_SET, &pos);
					
						if(fd >= 0)
						{
							while(lv2FsRead(fd, buf, BUFFER_SIZE - 1, &read) == 0 && read > 0)
							{
								netSend(conn_s_data, buf, read, 0);
							}
						
							if(read == 0)
							{
								swritel(conn_s, "226 Transfer complete\r\n");
							}
							else
							{
								swritel(conn_s, "426 Transfer failed\r\n");
							}
						}
						else
						{
							swritel(conn_s, "452 File access error\r\n");
						}
						
						lv2FsClose(fd);
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 10: // PWD
					sprintf(buffer, "257 \"%s\" is the current directory\r\n", cwd);
					swritel(conn_s, buffer);
					break;
				case 11: // CWD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						strcpy(filename, client_cmd[1]);
						
						if(strcmp(filename, "../") == 0)
						{
							for(int i = strlen(cwd) - 2; i > 0; i--)
							{
								if(cwd[i] != '/')
								{
									cwd[i] = '\0';
								}
								else
								{
									break;
								}
							}
							
							sprintf(buffer, "250 Directory change successful: %s\r\n", cwd);
							swritel(conn_s, buffer);
							break;
						}
					
						if(filename[0] == '/')
						{
							strcpy(cwd, (strlen(filename) == 1) ? "/" : filename);
						}
						else
						{
							strcat(cwd, filename);
						}
					
						if(cwd[strlen(cwd) - 1] != '/')
						{
							strcat(cwd, "/");
						}
					
						if(isDir(cwd))
						{
							sprintf(buffer, "250 Directory change successful: %s\r\n", cwd);
						}
						else
						{
							sprintf(buffer, "550 Could not change directory: %s\r\n", cwd);
						}
					
						swritel(conn_s, buffer);
					}
					else
					{
						sprintf(buffer, "257 \"%s\" is the current directory\r\n", cwd);
						swritel(conn_s, buffer);
					}
					break;
				case 12: // CDUP
					for(int i = strlen(cwd) - 2; i > 0; i--)
					{
						if(cwd[i] != '/')
						{
							cwd[i] = '\0';
						}
						else
						{
							break;
						}
					}
				
					sprintf(buffer, "250 Directory change successful: %s\r\n", cwd);
					swritel(conn_s, buffer);
					break;
				case 13: // NLST
					if(conn_s_data == -1)
					{
						swritel(conn_s, "425 No data connection\r\n");
						break;
					}
				
					swritel(conn_s, "150 Opening data connection\r\n");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
				
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
					
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(buffer, "%s\r\n", ent.d_name);
							swritel(conn_s_data, buffer);
						}
						
						swritel(conn_s, "226 Transfer complete\r\n");
					}
					else
					{
						swritel(conn_s, "451 Cannot access directory\r\n");
					}
				
					lv2FsCloseDir(tempfd);
					break;
				case 14: // LIST
					if(conn_s_data == -1)
					{
						swritel(conn_s, "425 No data connection\r\n");
						break;
					}
				
					swritel(conn_s, "150 Opening data connection\r\n");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
				
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
						
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(filename, "%s%s", cwd, ent.d_name);
							
							Lv2FsStat entry;
							lv2FsStat(filename, &entry);
						
							struct tm *tm;
							char timebuf[32];
							tm = localtime(&entry.st_mtime);
							strftime(timebuf, 31, "%b %d %Y", tm);
						
							sprintf(buffer, "%s%s%s%s%s%s%s%s%s%s 1 root root %lu %s %s\r\n", 
								((entry.st_mode & S_IFDIR) != 0)?"d":"-", 
								((entry.st_mode & S_IRUSR) != 0)?"r":"-",
								((entry.st_mode & S_IWUSR) != 0)?"w":"-",
								((entry.st_mode & S_IXUSR) != 0)?"x":"-",
								((entry.st_mode & S_IRGRP) != 0)?"r":"-",
								((entry.st_mode & S_IWGRP) != 0)?"w":"-",
								((entry.st_mode & S_IXGRP) != 0)?"x":"-",
								((entry.st_mode & S_IROTH) != 0)?"r":"-",
								((entry.st_mode & S_IWOTH) != 0)?"w":"-",
								((entry.st_mode & S_IXOTH) != 0)?"x":"-",
								(long unsigned int)entry.st_size, 
								timebuf, 
								ent.d_name);

							swritel(conn_s_data, buffer);
						}
						
						swritel(conn_s, "226 Transfer complete\r\n");
					}
					else
					{
						swritel(conn_s, "451 Cannot access directory\r\n");
					}
				
					lv2FsCloseDir(tempfd);
					break;
				case 15: // STOR
					if(parameter_count >= 1)
					{
						if(conn_s_data == -1)
						{
							swritel(conn_s, "425 No data connection\r\n");
							break;
						}
						
						swritel(conn_s, "150 Opening data connection\r\n");

						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
						
						u64 pos;
						u64 read = -1;
						u64 write = -1;
						
						Lv2FsFile fd;
					
						lv2FsOpen(filename, LV2_O_WRONLY | LV2_O_CREAT, &fd, 0, NULL, 0);
						lv2FsChmod(filename, S_IFMT | 0666);
					
						lv2FsLSeek64(fd, (s32)rest, SEEK_SET, &pos);
						
						if(fd >= 0)
						{
							while((read = (u64)netRecv(conn_s_data, buf, BUFFER_SIZE - 1, MSG_WAITALL)) > 0)
							{
								lv2FsWrite(fd, buf, read, &write);
							
								if(write != read)
								{
									break;
								}
							}
							
							if(read == 0)
							{
								swritel(conn_s, "226 Transfer complete\r\n");
							}
							else
							{
								swritel(conn_s, "426 Transfer failed\r\n");
							}
						}
						else
						{
							swritel(conn_s, "452 File access error\r\n");
						}
						
						lv2FsClose(fd);
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 16: // NOOP
					swritel(conn_s, "200 Zzzz...\r\n");
					break;
				case 17: // DELE
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
						
						if(lv2FsUnlink(filename) == 0)
						{
							swritel(conn_s, "250 File successfully deleted\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to delete file\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 18: // MKD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						if(lv2FsMkdir(filename, 0775) == 0)
						{
							swritel(conn_s, "250 Directory successfully created\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to create directory\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 19: // RMD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						if(lv2FsRmdir(filename) == 0)
						{
							swritel(conn_s, "250 Directory successfully deleted\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to remove directory\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 20: // RNFR
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(rnfr, client_cmd[1], cwd);
					
						if(exists(rnfr) == 0)
						{
							swritel(conn_s, "350 RNFR successful - ready for destination\r\n");
						}
						else
						{
							swritel(conn_s, "550 RNFR failed - file does not exist\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 21: // RNTO
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						if(lv2FsRename(rnfr, filename) == 0)
						{
							swritel(conn_s, "250 File successfully renamed\r\n");
						}
						else
						{
							swritel(conn_s, "550 Failed to rename file\r\n");
						}
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 22: // SIZE
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					
						Lv2FsStat entry;
						
						if(lv2FsStat(filename, &entry) == 0)
						{
							sprintf(buffer, "213 %lu\r\n", (long unsigned int)entry.st_size);
						}
						else
						{
							sprintf(buffer, "550 Requested file doesn't exist\r\n");
						}
					
						swritel(conn_s, buffer);
					}
					else
					{
						swritel(conn_s, "501 Syntax error\r\n");
					}
					break;
				case 23: // SYST
					swritel(conn_s, "215 UNIX Type: L8\r\n");
					break;
				case 24: // HELP
					swritel(conn_s, "214 No help for you.\r\n");
					break;
				case 25: // PASSWD
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						// hash the password given
						char output[33];
						md5(output, client_cmd[1]);
					
						Lv2FsFile fd;
						u64 written;
					
						lv2FsOpen(PASSWORD_FPATH, LV2_O_WRONLY | LV2_O_CREAT, &fd, 0, NULL, 0);
						lv2FsWrite(fd, output, 32, &written);
						lv2FsClose(fd);
					
						swritel(conn_s, "200 Password successfully changed\r\n");
					}
					else
					{
						swritel(conn_s, "501 Invalid password\r\n");
					}
					break;
				case 26: // MLSD
					if(conn_s_data == -1)
					{
						swritel(conn_s, "425 No data connection\r\n");
						break;
					}
				
					swritel(conn_s, "150 Opening data connection\r\n");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
				
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
					
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(filename, "%s%s", cwd, ent.d_name);
							
							Lv2FsStat entry;
							lv2FsStat(filename, &entry);
						
							struct tm *tm;
							char timebuf[32];
							tm = localtime(&entry.st_mtime);
							strftime(timebuf, 31, "%Y%m%d%H%M%S", tm);
						
							int permint = 0;

							permint +=	(((entry.st_mode & S_IRUSR) != 0)?400:0) +
									(((entry.st_mode & S_IWUSR) != 0)?200:0) +
									(((entry.st_mode & S_IXUSR) != 0)?100:0);
						
							permint +=	(((entry.st_mode & S_IRGRP) != 0)?40:0) +
									(((entry.st_mode & S_IWGRP) != 0)?20:0) +
									(((entry.st_mode & S_IXGRP) != 0)?10:0);
						
							permint +=	(((entry.st_mode & S_IROTH) != 0)?4:0) +
									(((entry.st_mode & S_IWOTH) != 0)?2:0) +
									(((entry.st_mode & S_IXOTH) != 0)?1:0);
						
							sprintf(buffer, "type=%s;size=%lu;modify=%s;UNIX.mode=0%i;UNIX.uid=root;UNIX.gid=root; %s\r\n", 
								((entry.st_mode & S_IFDIR) != 0)?"dir":"file", 
								(long unsigned int)entry.st_size, 
								timebuf, 
								permint,
								ent.d_name);
						
							swritel(conn_s_data, buffer);
						}
						
						swritel(conn_s, "226 Transfer complete\r\n");
					}
					else
					{
						swritel(conn_s, "501 Directory access error\r\n");
					}

					lv2FsCloseDir(tempfd);
					break;
				case 27: // MLST
					swritel(conn_s, "250- Listing directory");
				
					if(parameter_count >= 1)
					{
						int i;
						for(i = 2; i <= parameter_count; i++)
						{
							strcat(client_cmd[1], " ");
							strcat(client_cmd[1], client_cmd[i]);
						}
						
						absPath(filename, client_cmd[1], cwd);
					}
					else
					{
						strcpy(filename, cwd);
					}
					
					if(lv2FsOpenDir(filename, &tempfd) == 0)
					{
						u64 read;
						Lv2FsDirent ent;
					
						while(lv2FsReadDir(tempfd, &ent, &read) == 0 && read != 0)
						{
							sprintf(filename, "%s%s", cwd, ent.d_name);
							
							Lv2FsStat entry;
							lv2FsStat(filename, &entry);
						
							struct tm *tm;
							char timebuf[32];
							tm = localtime(&entry.st_mtime);
							strftime(timebuf, 31, "%Y%m%d%H%M%S", tm);
						
							int permint = 0;

							permint +=	(((entry.st_mode & S_IRUSR) != 0)?400:0) +
									(((entry.st_mode & S_IWUSR) != 0)?200:0) +
									(((entry.st_mode & S_IXUSR) != 0)?100:0);
						
							permint +=	(((entry.st_mode & S_IRGRP) != 0)?40:0) +
									(((entry.st_mode & S_IWGRP) != 0)?20:0) +
									(((entry.st_mode & S_IXGRP) != 0)?10:0);
						
							permint +=	(((entry.st_mode & S_IROTH) != 0)?4:0) +
									(((entry.st_mode & S_IWOTH) != 0)?2:0) +
									(((entry.st_mode & S_IXOTH) != 0)?1:0);
						
							sprintf(buffer, " type=%s;size=%lu;modify=%s;UNIX.mode=0%i;UNIX.uid=root;UNIX.gid=root; %s\r\n", 
								((entry.st_mode & S_IFDIR) != 0)?"dir":"file", 
								(long unsigned int)entry.st_size, 
								timebuf, 
								permint,
								ent.d_name);
						
							swritel(conn_s, buffer);
						}
					}
				
					swritel(conn_s, "250 End\r\n");
				
					lv2FsCloseDir(tempfd);
					break;
				case 28: // EXITAPP
					swritel(conn_s, "221 Exiting OpenPS3FTP, bye\r\n");
					exitapp = 1;
					break;
				case 29: // TEST
					swritel(conn_s, "211-Listing parameters\r\n");
					sprintf(buffer, "211-Count: %i\r\n", parameter_count);
					swritel(conn_s, buffer);
					
					int tx;
					for(tx = 0; tx <= parameter_count; tx++)
					{
						sprintf(buffer, " %i:%s\r\n", tx, client_cmd[tx]);
						swritel(conn_s, buffer);
					}
					
					swritel(conn_s, "211 End\r\n");
					break;
				default: swritel(conn_s, "500 Unrecognized command\r\n");
			}
			
			if(datareq == 1)
			{
				datareq = 0;
			}
			else
			{
				// close any active data connections
				if(conn_s_data > -1)
				{
					netShutdown(conn_s_data, 2);
					netClose(conn_s_data);
					conn_s_data = -1;
				}
				
				if(list_s_data > -1)
				{
					netShutdown(list_s_data, 2);
					netClose(list_s_data);
					list_s_data = -1;
				}
			}
		}
	}
Example #6
0
static void handleclient(u64 conn_s_p)
{
	int conn_s = (int)conn_s_p;
	int list_s_data = -1;
	int conn_s_data = -1;
	
	char	cwd[2048];
	char	login_user[32];
	char	login_pass[64];
	char	rename_from[2048];
	u32	rest = 0;
	int	authd = 0;
	
	char	message[4096];
	char	buffer[2048];
	
	sprintf(cwd, "/");
	
	sprintf(message, "220-OpenPS3FTP by @jjolano\r\n");
	Writeline(conn_s, message, strlen(message));
	
	sprintf(message, "220 Version %s\r\n", VERSION);
	Writeline(conn_s, message, strlen(message));
	
	while(program_running == 1)
	{
		sys_ppu_thread_yield();
		
		if(Readline(conn_s, buffer, 2047) == 0 || strncmp(buffer, "QUIT", 4) == 0 || strncmp(buffer, "BYE", 3) == 0)
		{
			break;
		}
		
		buffer[strcspn(buffer, "\n")] = '\0';
		buffer[strcspn(buffer, "\r")] = '\0';
		
		if(strncmp(buffer, "USER", 4) == 0)
		{
			if(strlen(buffer) > 7)
			{
				strcpy(login_user, buffer+5);
				
				sprintf(message, "331 Username %s OK. Password required\r\n", login_user);
				Writeline(conn_s, message, strlen(message));
			}
			else
			{
				sprintf(message, "430 No username specified\r\n");
				Writeline(conn_s, message, strlen(message));
			}
		}
		else if(strncmp(buffer, "PASS", 4) == 0)
		{
			if(strlen(buffer) > 7)
			{
				strcpy(login_pass, buffer+5);
				
				if(strcmp(LOGIN_USERNAME, login_user) == 0 && strcmp(LOGIN_PASSWORD, login_pass) == 0)
				{
					authd = 1;
					sprintf(message, "230 Successful authentication\r\n");
				}
				else
				{
					sprintf(message, "430 Invalid username or password\r\n");
					Writeline(conn_s, message, strlen(message));
				}
			}
			else
			{
				sprintf(message, "430 Invalid username or password\r\n");
			}
			
			Writeline(conn_s, message, strlen(message));
		}
		else if(authd == 0)
		{
			sprintf(message, "530 Not logged in\r\n");
			Writeline(conn_s, message, strlen(message));
		}
		else if(strncmp(buffer, "FEAT", 4) == 0)
		{
			sprintf(message, "211-Extensions supported:\r\n");
			Writeline(conn_s, message, strlen(message));
			
			sprintf(message, " SIZE\r\n");
			Writeline(conn_s, message, strlen(message));
			sprintf(message, " PASV\r\n");
			Writeline(conn_s, message, strlen(message));
			
			
			sprintf(message, "211 End\r\n");
			Writeline(conn_s, message, strlen(message));
		}
		else if(strncmp(buffer, "TYPE", 4) == 0)
		{
			sprintf(message, "200 TYPE is now %s\r\n", buffer+5);
			Writeline(conn_s, message, strlen(message));
		}
		else if(strncmp(buffer, "PORT", 4) == 0)
		{
			rest = 0;
			
			char connectinfo[24];
			strcpy(connectinfo, buffer+5);
			
			char data[7][4];
			int len = strlen(connectinfo);
			int i, x = 0, y = 0;
			
			for(i = 0;i < len;i++)
			{
				if(connectinfo[i] == ',')
				{
					data[x][y] = '\0';
					x++;
					y = 0;
				}
				else
				{
					data[x][y] =  connectinfo[i];
					y++;
				}
			}
			
			char conn_ipaddr[16];
			sprintf(conn_ipaddr, "%s.%s.%s.%s", data[0], data[1], data[2], data[3]);

			int p1 = atoi(data[4]);
			int p2 = atoi(data[5]);
			
			short int conn_port = (p1 * 256) + p2;
			
			netClose(conn_s_data);
			netClose(list_s_data);
			
			list_s_data = -1;
			conn_s_data = netSocket(AF_INET, SOCK_STREAM, 0);
			
			struct sockaddr_in servaddr;
			memset(&servaddr, 0, sizeof(servaddr));
			servaddr.sin_family	= AF_INET;
			servaddr.sin_port	= htons(conn_port);
			inet_pton(AF_INET, conn_ipaddr, &servaddr.sin_addr);
			
			if(connect(conn_s_data, (struct sockaddr *)&servaddr, sizeof(servaddr)) == 0)
			{
				sprintf(message, "200 PORT command successful\r\n");
				Writeline(conn_s, message, strlen(message));
				continue;
			}
			
			sprintf(message, "425 Internal Error\r\n");
			Writeline(conn_s, message, strlen(message));
		}
		else if(strncmp(buffer, "PASV", 4) == 0)
		{
			rest = 0;
			netSocketInfo snf;
			
			int ret = netGetSockInfo(conn_s, &snf, 1);
			
			if(ret >= 0 && snf.local_adr.s_addr != 0)
			{
				netClose(conn_s_data);
				netClose(list_s_data);
				
				conn_s_data = -1;
				list_s_data = -1;
				
				// create the socket
				list_s_data = netSocket(AF_INET, SOCK_STREAM, 0);

				// calculate the passive mode port
				//srand((unsigned)time(NULL));
				//srand((unsigned)time(NULL) + rand());
				
				int rand1 = 4 + rand() % 255;
				int rand2 = rand() % 256;
				
				short int port = (rand1 * 256) + rand2;
				
				struct sockaddr_in servaddr;
				memset(&servaddr, 0, sizeof(servaddr));
				servaddr.sin_family      = AF_INET;
				servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
				servaddr.sin_port        = htons(port);
				
				// bind address to listener, listen, and accept
				netBind(list_s_data, (struct sockaddr *) &servaddr, sizeof(servaddr));
				netListen(list_s_data, LISTENQ);
				sprintf(message, "227 Entering Passive Mode (%u,%u,%u,%u,%i,%i)\r\n",
					(snf.local_adr.s_addr & 0xFF000000) >> 24,
					(snf.local_adr.s_addr & 0xFF0000) >> 16,
					(snf.local_adr.s_addr & 0xFF00) >> 8,
					(snf.local_adr.s_addr & 0xFF),
					rand1, rand2);
				
				Writeline(conn_s, message, strlen(message));
						
				if((conn_s_data = netAccept(list_s_data, NULL, NULL)) < 0)
				{
					printf("warning: failed to accept a connection\n");
					netClose(conn_s_data);
					netClose(list_s_data);
					
					conn_s_data = -1;
					list_s_data = -1;
				}
				else
				{
					// PASV success
					continue;
				}
			}
		
		sprintf(message, "425 Internal Error\r\n");
		Writeline(conn_s, message, strlen(message));
		}