static inline int client_send_recv_raw(ClientInfo *client, void *buf, unsigned int len) { if (client->data_con_type == FTP_DATA_CONNECTION_ACTIVE) { return sceNetRecv(client->data_sockfd, buf, len, 0); } else { return sceNetRecv(client->pasv_sockfd, buf, len, 0); } }
void _start(void) { // Pass address of a syscall gadget in rcx register f rcx asm("rcx"); directSyscall = rcx; // Load modules int libNet = 14; // Resolve functions int (*sceNetSocket)(const char *, int, int, int); int (*sceNetSocketClose)(int); int (*sceNetBind)(int, struct sockaddr_in *, int); int (*sceNetListen)(int, int); int (*sceNetAccept)(int, struct sockaddr_in *, int *); int (*sceNetRecv)(int, void *, size_t, int); STACK_RESOLVE(libNet, sceNetSocket); STACK_RESOLVE(libNet, sceNetSocketClose); STACK_RESOLVE(libNet, sceNetBind); STACK_RESOLVE(libNet, sceNetListen); STACK_RESOLVE(libNet, sceNetAccept); STACK_RESOLVE(libNet, sceNetRecv); // Fetch code char socketName[] = "loader"; struct sockaddr_in serverAddress; serverAddress.sin_family = htons(AF_INET); serverAddress.sin_addr.s_addr = IN_ADDR_ANY; serverAddress.sin_port = htons(9023); serverAddress.sin_zero[0] = 0; serverAddress.sin_zero[1] = 0; serverAddress.sin_zero[2] = 0; serverAddress.sin_zero[3] = 0; serverAddress.sin_zero[4] = 0; serverAddress.sin_zero[5] = 0; serverAddress.sin_zero[6] = 0; serverAddress.sin_zero[7] = 0; int server = sceNetSocket(socketName, AF_INET, SOCK_STREAM, 0); sceNetBind(server, &serverAddress, sizeof(serverAddress)); sceNetListen(server, 10); int client = sceNetAccept(server, NULL, NULL); void *write = DATA; int length; while((length = sceNetRecv(client, write, 4096, 0)) > 0) { write += length; } sceNetSocketClose(server); sceNetSocketClose(client); }
int ps4link_recv_bytes(int sock, char *buf, int bytes) { size_t left; int len; left =(size_t) bytes; while (left > 0) { len = sceNetRecv(sock, &buf[bytes - left], left, MSG_WAITALL); //len = read(sock, &buf[bytes - left], left); if (len < 0) { debugNetPrintf(DEBUG,"[PS4LINK] ps4link_recv_bytes error!! 0x%08X\n",len); return -1; } left -= len; } return bytes; }
static int client_thread(SceSize args, void *argp) { char cmd[16]; cmd_dispatch_func dispatch_func; ClientInfo *client = (ClientInfo *)argp; DEBUG("Client thread %i started!\n", client->num); client_send_ctrl_msg(client, "220 FTPVita Server ready.\n"); while (1) { memset(client->recv_buffer, 0, sizeof(client->recv_buffer)); client->n_recv = sceNetRecv(client->ctrl_sockfd, client->recv_buffer, sizeof(client->recv_buffer), 0); if (client->n_recv > 0) { DEBUG("Received %i bytes from client number %i:\n", client->n_recv, client->num); INFO("\t%i> %s", client->num, client->recv_buffer); /* The command are the first chars until the first space */ sscanf(client->recv_buffer, "%s", cmd); /* Wait 1 ms before sending any data */ sceKernelDelayThread(1*1000); if ((dispatch_func = get_dispatch_func(cmd))) { dispatch_func(client); } else { client_send_ctrl_msg(client, "502 Sorry, command not implemented. :(\n"); } } else if (client->n_recv == 0) { /* Value 0 means connection closed by the remote peer */ INFO("Connection closed by the client %i.\n", client->num); /* Delete itself from the client list */ client_list_delete(client); break; } else if (client->n_recv == PSP2_NET_ERROR_ECANCELED) { /* PSP2_NET_ERROR_ECANCELED means socket shutdown */ DEBUG("Client %i socket shutdown\n", client->num); break; } else { /* Other errors */ INFO("Socket error client %i.\n", client->num); client_list_delete(client); break; } } /* Close the client's socket */ sceNetSocketClose(client->ctrl_sockfd); /* If there's an open data connection, close it */ if (client->data_con_type != FTP_DATA_CONNECTION_NONE) { sceNetSocketClose(client->data_sockfd); if (client->data_con_type == FTP_DATA_CONNECTION_PASSIVE) { sceNetSocketClose(client->pasv_sockfd); } } DEBUG("Client thread %i exiting!\n", client->num); /* Temporary newlib thread malloc bug fix */ // free(client); sceKernelExitDeleteThread(0); return 0; }