Skip to content

Commit

Permalink
Implemented arg parsing for NRO env. When args aren't available, set …
Browse files Browse the repository at this point in the history
…__system_argv to {ptr to NULL} instead of NULL.
  • Loading branch information
yellows8 committed Feb 18, 2018
1 parent a1462c8 commit 20cd940
Showing 1 changed file with 73 additions and 56 deletions.
129 changes: 73 additions & 56 deletions nx/source/runtime/argv.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ extern char* fake_heap_end;

extern u32 __argdata__;

static char* g_argv_empty = NULL;

void argvSetup(void)
{
Result rc=0;
Expand All @@ -21,22 +23,20 @@ void argvSetup(void)

u8 *argdata = (u8*)&__argdata__;
u32 *arg32 = (u32*)argdata;
u64 argdata_allocsize;
u64 argdata_strsize;
u32 argvptr_pos;
u64 argdata_allocsize=0;
u64 argdata_strsize=0;
u32 argvptr_pos=0;
u32 max_argv;
u32 argi;
u32 arglen=0;
bool quote_flag=0;
bool end_flag=0;
char *args;
char *args = NULL;
char *argstart;
char *argstorage;

__system_argc = 0;
__system_argv = NULL;

// TODO: Use envHasArgv()/envGetArgv() here for the NRO case.
__system_argv = &g_argv_empty;

if (envIsNso()) {
memset(&meminfo, 0, sizeof(meminfo));
Expand All @@ -57,67 +57,84 @@ void argvSetup(void)

argvptr_pos = 0x20 + argdata_strsize+1;
if (argvptr_pos >= argdata_allocsize) return;
argstorage = (char*)&argdata[argvptr_pos];
}
else if (envHasArgv()) {
args = envGetArgv();
argdata_allocsize = 0x9000;//Use the same size as NSO.
argdata_strsize = strlen(args);
argdata = (u8*)fake_heap_start;

argvptr_pos += (argdata_strsize+1 + 0x9) & ~0x7;
if (argvptr_pos >= argdata_allocsize) return;
if (argdata_strsize==0) return;

if (fake_heap_end - fake_heap_start < argdata_allocsize) return;

fake_heap_start += argdata_allocsize;

argvptr_pos = 0;

memset(argdata, 0, argdata_allocsize);
}

max_argv = (argdata_allocsize - argvptr_pos) >> 3;
if (max_argv < 2) return;
argstorage = (char*)&argdata[argvptr_pos];

__system_argv = (char**)&argdata[argvptr_pos];
argvptr_pos += (argdata_strsize+1 + 0x9) & ~0x7;
if (argvptr_pos >= argdata_allocsize) return;

argstart = NULL;
max_argv = (argdata_allocsize - argvptr_pos) >> 3;
if (max_argv < 2) return;

for(argi=0; argi<argdata_strsize; argi++) {
if (argstart == NULL && isspace(args[argi])) continue;
__system_argv = (char**)&argdata[argvptr_pos];

if (argstart == NULL) {
if (args[argi] == '"') {
argstart = &args[argi+1];
quote_flag = 1;
}
else if(args[argi]!=0) {
argstart = &args[argi];
arglen++;
}
argstart = NULL;

for(argi=0; argi<argdata_strsize; argi++) {
if (argstart == NULL && isspace(args[argi])) continue;

if (argstart == NULL) {
if (args[argi] == '"') {
argstart = &args[argi+1];
quote_flag = 1;
}
else {
end_flag = 0;

if (quote_flag && args[argi] == '"') {
end_flag = 1;
}
else if (isspace(args[argi])) {
end_flag = 1;
}
else if(args[argi]!=0) {
arglen++;
}

if ((args[argi]==0 || end_flag) && arglen) {
strncpy(argstorage, argstart, arglen);
argstorage[arglen] = 0;
__system_argv[__system_argc] = argstorage;
__system_argc++;
argstart = NULL;
quote_flag = 0;
argstorage+= arglen+1;
arglen = 0;

if (__system_argc >= max_argv) break;
}
else if(args[argi]!=0) {
argstart = &args[argi];
arglen++;
}
}
else {
end_flag = 0;

if (arglen && __system_argc < max_argv) {
strncpy(argstorage, argstart, arglen);
argstorage[arglen] = 0;
__system_argv[__system_argc] = argstorage;
__system_argc++;
if (quote_flag && args[argi] == '"') {
end_flag = 1;
}
else if (isspace(args[argi])) {
end_flag = 1;
}
else if(args[argi]!=0) {
arglen++;
}

if ((args[argi]==0 || end_flag) && arglen) {
strncpy(argstorage, argstart, arglen);
argstorage[arglen] = 0;
__system_argv[__system_argc] = argstorage;
__system_argc++;
argstart = NULL;
quote_flag = 0;
argstorage+= arglen+1;
arglen = 0;

if (__system_argc >= max_argv) break;
}
}
}

__system_argv[__system_argc] = NULL;
if (arglen && __system_argc < max_argv) {
strncpy(argstorage, argstart, arglen);
argstorage[arglen] = 0;
__system_argv[__system_argc] = argstorage;
__system_argc++;
}

__system_argv[__system_argc] = NULL;
}

0 comments on commit 20cd940

Please sign in to comment.