Move receiving URLs over the network to the top, add warning when opening NAND.

This commit is contained in:
Steveice10 2016-12-23 23:18:34 -08:00
parent 13a88f7adb
commit 45704ad4f9
3 changed files with 184 additions and 174 deletions

View File

@ -1,9 +1,7 @@
import atexit
import os import os
import socket import socket
import struct import struct
import sys import sys
import tempfile
import threading import threading
import time import time
import urllib import urllib

View File

@ -424,16 +424,28 @@ void files_open(FS_ArchiveID archiveId, FS_Path archivePath) {
list_display("Files", "A: Select, B: Back, X: Refresh, Select: Options", data, files_update, files_draw_top); list_display("Files", "A: Select, B: Back, X: Refresh, Select: Options", data, files_update, files_draw_top);
} }
static void files_open_nand_warning_onresponse(ui_view* view, void* data, bool response) {
FS_ArchiveID archive = (FS_ArchiveID) data;
if(response) {
files_open(archive, fsMakePath(PATH_EMPTY, ""));
}
}
void files_open_nand_warning(FS_ArchiveID archive) {
prompt_display("Confirmation", "Modifying the NAND is dangerous and can render\n the system inoperable.\nMake sure you know what you are doing.\n\nProceed?", COLOR_TEXT, true, (void*) archive, NULL, files_open_nand_warning_onresponse);
}
void files_open_sd() { void files_open_sd() {
files_open(ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, "")); files_open(ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
} }
void files_open_ctr_nand() { void files_open_ctr_nand() {
files_open(ARCHIVE_NAND_CTR_FS, fsMakePath(PATH_EMPTY, "")); files_open_nand_warning(ARCHIVE_NAND_CTR_FS);
} }
void files_open_twl_nand() { void files_open_twl_nand() {
files_open(ARCHIVE_NAND_TWL_FS, fsMakePath(PATH_EMPTY, "")); files_open_nand_warning(ARCHIVE_NAND_TWL_FS);
} }
void files_open_twl_photo() { void files_open_twl_photo() {

View File

@ -70,6 +70,174 @@ static Result remoteinstall_set_last_urls(const char* urls) {
return res; return res;
} }
typedef struct {
int serverSocket;
int clientSocket;
} remoteinstall_network_data;
static int remoteinstall_network_recvwait(int sockfd, void* buf, size_t len, int flags) {
errno = 0;
int ret = 0;
size_t read = 0;
while(((ret = recv(sockfd, buf + read, len - read, flags)) >= 0 && (read += ret) < len) || errno == EAGAIN) {
errno = 0;
}
return ret < 0 ? ret : (int) read;
}
static int remoteinstall_network_sendwait(int sockfd, void* buf, size_t len, int flags) {
errno = 0;
int ret = 0;
size_t written = 0;
while(((ret = send(sockfd, buf + written, len - written, flags)) >= 0 && (written += ret) < len) || errno == EAGAIN) {
errno = 0;
}
return ret < 0 ? ret : (int) written;
}
static void remoteinstall_network_close_client(void* data) {
remoteinstall_network_data* networkData = (remoteinstall_network_data*) data;
if(networkData->clientSocket != 0) {
u8 ack = 0;
remoteinstall_network_sendwait(networkData->clientSocket, &ack, sizeof(ack), 0);
close(networkData->clientSocket);
networkData->clientSocket = 0;
}
}
static void remoteinstall_network_free_data(remoteinstall_network_data* data) {
remoteinstall_network_close_client(data);
if(data->serverSocket != 0) {
close(data->serverSocket);
data->serverSocket = 0;
}
free(data);
}
static void remoteinstall_network_update(ui_view* view, void* data, float* progress, char* text) {
remoteinstall_network_data* networkData = (remoteinstall_network_data*) data;
if(hidKeysDown() & KEY_B) {
ui_pop();
info_destroy(view);
remoteinstall_network_free_data(networkData);
return;
}
struct sockaddr_in client;
socklen_t clientLen = sizeof(client);
int sock = accept(networkData->serverSocket, (struct sockaddr*) &client, &clientLen);
if(sock >= 0) {
networkData->clientSocket = sock;
u32 size = 0;
if(remoteinstall_network_recvwait(networkData->clientSocket, &size, sizeof(size), 0) != sizeof(size)) {
error_display_errno(NULL, NULL, errno, "Failed to read payload length.");
remoteinstall_network_close_client(data);
return;
}
size = ntohl(size);
if(size >= 128 * 1024) {
error_display(NULL, NULL, "Payload too large.");
remoteinstall_network_close_client(data);
return;
}
char* urls = (char*) calloc(size, sizeof(char));
if(urls == NULL) {
error_display(NULL, NULL, "Failed to allocate URL buffer.");
remoteinstall_network_close_client(data);
return;
}
if(remoteinstall_network_recvwait(networkData->clientSocket, urls, size, 0) != size) {
error_display_errno(NULL, NULL, errno, "Failed to read URL(s).");
free(urls);
remoteinstall_network_close_client(data);
return;
}
remoteinstall_set_last_urls(urls);
action_url_install("Install from the received URL(s)?", urls, data, remoteinstall_network_close_client);
free(urls);
} else if(errno != EAGAIN) {
if(errno == 22 || errno == 115) {
ui_pop();
info_destroy(view);
}
error_display_errno(NULL, NULL, errno, "Failed to open socket.");
if(errno == 22 || errno == 115) {
remoteinstall_network_free_data(networkData);
return;
}
}
struct in_addr addr = {(in_addr_t) gethostid()};
snprintf(text, PROGRESS_TEXT_MAX, "Waiting for connection...\nIP: %s\nPort: 5000", inet_ntoa(addr));
}
void remoteinstall_receive_urls_network() {
remoteinstall_network_data* data = (remoteinstall_network_data*) calloc(1, sizeof(remoteinstall_network_data));
if(data == NULL) {
error_display(NULL, NULL, "Failed to allocate network install data.");
return;
}
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(sock < 0) {
error_display_errno(NULL, NULL, errno, "Failed to open server socket.");
remoteinstall_network_free_data(data);
return;
}
data->serverSocket = sock;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(5000);
server.sin_addr.s_addr = (in_addr_t) gethostid();
if(bind(data->serverSocket, (struct sockaddr*) &server, sizeof(server)) < 0) {
error_display_errno(NULL, NULL, errno, "Failed to bind server socket.");
remoteinstall_network_free_data(data);
return;
}
fcntl(data->serverSocket, F_SETFL, fcntl(data->serverSocket, F_GETFL, 0) | O_NONBLOCK);
if(listen(data->serverSocket, 5) < 0) {
error_display_errno(NULL, NULL, errno, "Failed to listen on server socket.");
remoteinstall_network_free_data(data);
return;
}
info_display("Receive URL(s)", "B: Return", false, data, remoteinstall_network_update, NULL);
}
#define QR_IMAGE_WIDTH 400 #define QR_IMAGE_WIDTH 400
#define QR_IMAGE_HEIGHT 240 #define QR_IMAGE_HEIGHT 240
@ -253,174 +421,6 @@ void remoteinstall_scan_qr_code() {
info_display("QR Code Install", "B: Return", false, data, remoteinstall_qr_update, remoteinstall_qr_draw_top); info_display("QR Code Install", "B: Return", false, data, remoteinstall_qr_update, remoteinstall_qr_draw_top);
} }
typedef struct {
int serverSocket;
int clientSocket;
} remoteinstall_network_data;
static int remoteinstall_network_recvwait(int sockfd, void* buf, size_t len, int flags) {
errno = 0;
int ret = 0;
size_t read = 0;
while(((ret = recv(sockfd, buf + read, len - read, flags)) >= 0 && (read += ret) < len) || errno == EAGAIN) {
errno = 0;
}
return ret < 0 ? ret : (int) read;
}
static int remoteinstall_network_sendwait(int sockfd, void* buf, size_t len, int flags) {
errno = 0;
int ret = 0;
size_t written = 0;
while(((ret = send(sockfd, buf + written, len - written, flags)) >= 0 && (written += ret) < len) || errno == EAGAIN) {
errno = 0;
}
return ret < 0 ? ret : (int) written;
}
static void remoteinstall_network_close_client(void* data) {
remoteinstall_network_data* networkData = (remoteinstall_network_data*) data;
if(networkData->clientSocket != 0) {
u8 ack = 0;
remoteinstall_network_sendwait(networkData->clientSocket, &ack, sizeof(ack), 0);
close(networkData->clientSocket);
networkData->clientSocket = 0;
}
}
static void remoteinstall_network_free_data(remoteinstall_network_data* data) {
remoteinstall_network_close_client(data);
if(data->serverSocket != 0) {
close(data->serverSocket);
data->serverSocket = 0;
}
free(data);
}
static void remoteinstall_network_update(ui_view* view, void* data, float* progress, char* text) {
remoteinstall_network_data* networkData = (remoteinstall_network_data*) data;
if(hidKeysDown() & KEY_B) {
ui_pop();
info_destroy(view);
remoteinstall_network_free_data(networkData);
return;
}
struct sockaddr_in client;
socklen_t clientLen = sizeof(client);
int sock = accept(networkData->serverSocket, (struct sockaddr*) &client, &clientLen);
if(sock >= 0) {
networkData->clientSocket = sock;
u32 size = 0;
if(remoteinstall_network_recvwait(networkData->clientSocket, &size, sizeof(size), 0) != sizeof(size)) {
error_display_errno(NULL, NULL, errno, "Failed to read payload length.");
remoteinstall_network_close_client(data);
return;
}
size = ntohl(size);
if(size >= 128 * 1024) {
error_display(NULL, NULL, "Payload too large.");
remoteinstall_network_close_client(data);
return;
}
char* urls = (char*) calloc(size, sizeof(char));
if(urls == NULL) {
error_display(NULL, NULL, "Failed to allocate URL buffer.");
remoteinstall_network_close_client(data);
return;
}
if(remoteinstall_network_recvwait(networkData->clientSocket, urls, size, 0) != size) {
error_display_errno(NULL, NULL, errno, "Failed to read URL(s).");
free(urls);
remoteinstall_network_close_client(data);
return;
}
remoteinstall_set_last_urls(urls);
action_url_install("Install from the received URL(s)?", urls, data, remoteinstall_network_close_client);
free(urls);
} else if(errno != EAGAIN) {
if(errno == 22 || errno == 115) {
ui_pop();
info_destroy(view);
}
error_display_errno(NULL, NULL, errno, "Failed to open socket.");
if(errno == 22 || errno == 115) {
remoteinstall_network_free_data(networkData);
return;
}
}
struct in_addr addr = {(in_addr_t) gethostid()};
snprintf(text, PROGRESS_TEXT_MAX, "Waiting for connection...\nIP: %s\nPort: 5000", inet_ntoa(addr));
}
void remoteinstall_receive_urls_network() {
remoteinstall_network_data* data = (remoteinstall_network_data*) calloc(1, sizeof(remoteinstall_network_data));
if(data == NULL) {
error_display(NULL, NULL, "Failed to allocate network install data.");
return;
}
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(sock < 0) {
error_display_errno(NULL, NULL, errno, "Failed to open server socket.");
remoteinstall_network_free_data(data);
return;
}
data->serverSocket = sock;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(5000);
server.sin_addr.s_addr = (in_addr_t) gethostid();
if(bind(data->serverSocket, (struct sockaddr*) &server, sizeof(server)) < 0) {
error_display_errno(NULL, NULL, errno, "Failed to bind server socket.");
remoteinstall_network_free_data(data);
return;
}
fcntl(data->serverSocket, F_SETFL, fcntl(data->serverSocket, F_GETFL, 0) | O_NONBLOCK);
if(listen(data->serverSocket, 5) < 0) {
error_display_errno(NULL, NULL, errno, "Failed to listen on server socket.");
remoteinstall_network_free_data(data);
return;
}
info_display("Receive URL(s)", "B: Return", false, data, remoteinstall_network_update, NULL);
}
void remoteinstall_manually_enter_urls() { void remoteinstall_manually_enter_urls() {
SwkbdState swkbd; SwkbdState swkbd;
swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 2, -1); swkbdInit(&swkbd, SWKBD_TYPE_NORMAL, 2, -1);
@ -455,8 +455,8 @@ void remoteinstall_forget_last_request() {
} }
} }
static list_item scan_qr_code = {"Scan QR Code", COLOR_TEXT, remoteinstall_scan_qr_code};
static list_item receive_urls_network = {"Receive URLs over the network", COLOR_TEXT, remoteinstall_receive_urls_network}; static list_item receive_urls_network = {"Receive URLs over the network", COLOR_TEXT, remoteinstall_receive_urls_network};
static list_item scan_qr_code = {"Scan QR Code", COLOR_TEXT, remoteinstall_scan_qr_code};
static list_item manually_enter_urls = {"Manually enter URLs", COLOR_TEXT, remoteinstall_manually_enter_urls}; static list_item manually_enter_urls = {"Manually enter URLs", COLOR_TEXT, remoteinstall_manually_enter_urls};
static list_item repeat_last_request = {"Repeat last request", COLOR_TEXT, remoteinstall_repeat_last_request}; static list_item repeat_last_request = {"Repeat last request", COLOR_TEXT, remoteinstall_repeat_last_request};
static list_item forget_last_request = {"Forget last request", COLOR_TEXT, remoteinstall_forget_last_request}; static list_item forget_last_request = {"Forget last request", COLOR_TEXT, remoteinstall_forget_last_request};
@ -475,8 +475,8 @@ static void remoteinstall_update(ui_view* view, void* data, linked_list* items,
} }
if(linked_list_size(items) == 0) { if(linked_list_size(items) == 0) {
linked_list_add(items, &scan_qr_code);
linked_list_add(items, &receive_urls_network); linked_list_add(items, &receive_urls_network);
linked_list_add(items, &scan_qr_code);
linked_list_add(items, &manually_enter_urls); linked_list_add(items, &manually_enter_urls);
linked_list_add(items, &repeat_last_request); linked_list_add(items, &repeat_last_request);
linked_list_add(items, &forget_last_request); linked_list_add(items, &forget_last_request);