diff options
Diffstat (limited to 'src/driver')
-rw-r--r-- | src/driver/ntux_amain.c | 5 | ||||
-rw-r--r-- | src/driver/ntux_driver_ctx.c | 160 |
2 files changed, 154 insertions, 11 deletions
diff --git a/src/driver/ntux_amain.c b/src/driver/ntux_amain.c index d103046..a18d67e 100644 --- a/src/driver/ntux_amain.c +++ b/src/driver/ntux_amain.c @@ -105,6 +105,11 @@ int ntux_main(char ** argv, char ** envp, const struct ntux_fd_ctx * fdctx) __xfi_exit(dctx->cctx->status); } + if (dctx->cctx->cmd == NTUX_CMD_BRIDGE) { + ntux_cmd_bridge(dctx); + __xfi_exit(dctx->cctx->status); + } + for (unit=dctx->units; *unit; unit++) ntux_perform_unit_actions(dctx,*unit); diff --git a/src/driver/ntux_driver_ctx.c b/src/driver/ntux_driver_ctx.c index 129992c..09d2142 100644 --- a/src/driver/ntux_driver_ctx.c +++ b/src/driver/ntux_driver_ctx.c @@ -6,10 +6,14 @@ #include <psxabi/sys_abitypes.h> #include <psxabi/sys_fcntl.h> +#include <psxabi/sys_process.h> +#include <psxabi/sys_sysapi.h> +#include <psxxfi/xfi_framework.h> #include <psxscl/psxscl.h> #include <ntapi/nt_tty.h> #include <stdint.h> +#include <stdbool.h> #include <ntux/ntux.h> #include "ntux_nolibc_impl.h" @@ -36,6 +40,18 @@ static const char * const ntux_cmd_name[NTUX_CMD_CAP] = { [NTUX_CMD_CHMOD] = "chmod", [NTUX_CMD_ACEIT] = "aceit", [NTUX_CMD_FSPATH] = "fspath", + [NTUX_CMD_BRIDGE] = "bridge", +}; + +/* ntux exec commands */ +static const bool const ntux_cmd_exec[NTUX_CMD_CAP] = { + [NTUX_CMD_STAT] = false, + [NTUX_CMD_SPAWN] = true, + [NTUX_CMD_STRACE] = true, + [NTUX_CMD_CHMOD] = false, + [NTUX_CMD_ACEIT] = false, + [NTUX_CMD_FSPATH] = false, + [NTUX_CMD_BRIDGE] = true, }; /* ntux command options */ @@ -47,6 +63,7 @@ static const struct argv_option * ntux_cmd_options[NTUX_CMD_CAP] = { [NTUX_CMD_CHMOD] = ntux_chmod_options, [NTUX_CMD_ACEIT] = ntux_aceit_options, [NTUX_CMD_FSPATH] = ntux_fspath_options, + [NTUX_CMD_BRIDGE] = ntux_bridge_options, }; /* package info */ @@ -216,6 +233,9 @@ static int ntux_cctx_update( else if (!strcmp(entry->arg,"fspath")) cctx->cmd = NTUX_CMD_FSPATH; + else if (!strcmp(entry->arg,"bridge")) + cctx->cmd = NTUX_CMD_BRIDGE; + break; case TAG_LOADER: @@ -264,6 +284,14 @@ static int ntux_cctx_update( cctx->drvflags |= NTUX_DRIVER_DUMP; break; + case TAG_INTERP: + cctx->interp = entry->arg; + break; + + case TAG_OPTARG: + cctx->optarg = entry->arg; + break; + case TAG_SYNTAX: case TAG_RPATH: case TAG_APATH: @@ -316,6 +344,29 @@ static int ntux_get_driver_ctx_fail(struct argv_meta * meta) return -1; } +static int ntux_cmd_program_is_bridge(const char * program) +{ + const char * slash; + const char * mark; + + mark = (slash = strrchr(program,'/')) + ? ++slash : program; + + if (!strcmp(mark,"ntux.bridge.exe")) + return true; + + else if (!strcmp(mark,"ntux.bridge.exe.interp")) + return true; + + else if (!strcmp(mark,"ntux.bridge.exe.interp.abspath")) + return true; + + else if (!strcmp(mark,"ntux.bridge.exe.interp.cwdpath")) + return true; + + return false; +} + static int ntux_cmd_from_program(const char * program) { const char * dot; @@ -332,20 +383,33 @@ static int ntux_cmd_from_program(const char * program) else mark = program; - if (!strcmp(mark,"stat")) + if (!strcmp(mark,"stat")) { return NTUX_CMD_STAT; - else if (!strcmp(mark,"spawn")) + + } else if (!strcmp(mark,"spawn")) { return NTUX_CMD_SPAWN; - else if (!strcmp(mark,"strace")) + + } else if (!strcmp(mark,"strace")) { return NTUX_CMD_STRACE; - else if (!strcmp(mark,"chmod")) + + } else if (!strcmp(mark,"chmod")) { return NTUX_CMD_CHMOD; - else if (!strcmp(mark,"aceit")) + + } else if (!strcmp(mark,"aceit")) { return NTUX_CMD_ACEIT; - else if (!strcmp(mark,"fspath")) + + } else if (!strcmp(mark,"fspath")) { return NTUX_CMD_FSPATH; - return NTUX_CMD_DEFAULT; + } else if (!strcmp(mark,"bridge")) { + return NTUX_CMD_BRIDGE; + + } else if (ntux_cmd_program_is_bridge(program)) { + return NTUX_CMD_BRIDGE; + + } else { + return NTUX_CMD_DEFAULT; + } } int ntux_get_driver_ctx( @@ -355,6 +419,8 @@ int ntux_get_driver_ctx( const struct ntux_fd_ctx * fdctx, struct ntux_driver_ctx ** pctx) { + int ret; + int val; struct ntux_driver_ctx_impl * ictx; struct ntux_common_ctx cctx; const struct argv_option * optv[NTUX_OPTV_ELEMENTS]; @@ -367,6 +433,9 @@ int ntux_get_driver_ctx( char * cmdmark; char ** execargv; char * execarg; + char * interp; + char * pathbuf; + size_t pathlen; struct argv_ctx ctx = {ARGV_VERBOSITY_NONE, ARGV_MODE_SCAN, 0,0,0,0,0,0,0}; @@ -392,6 +461,58 @@ int ntux_get_driver_ctx( cctx.cmd = ntux_cmd_from_program(program); cctx.drvflags = flags; + switch (cctx.cmd) { + case NTUX_CMD_BRIDGE: + break; + + default: + /* potential .exe bridge setup? */ + pathlen = ntux_strlen(argv[0]); + + if (pathlen + NTUX_EXE_SUFFIX_LEN >= NTUX_MAX_PATH) + break; + + + /* intermediate buffers */ + if (!(pathbuf = ntux_calloc(1,NTUX_MAX_PATH))) + return NTUX_ERROR; + + if (!(interp = ntux_calloc(1,NTUX_MAX_PATH))) { + ntux_free(pathbuf); + return NTUX_ERROR; + } + + /* is argv[0] a symlink to ntux's bridge symlink? */ + ret = __sys_readlinkat( + fdctx->fdcwd, + (const unsigned char *)argv[0], + pathbuf,NTUX_MAX_PATH); + + if ((ret > 0) && (ret < NTUX_MAX_PATH)) { + if (ntux_cmd_program_is_bridge(pathbuf)) { + ntux_strcpy(pathbuf,argv[0]); + ntux_strcpy(&pathbuf[pathlen],NTUX_EXE_SUFFIX); + + ret = __sys_readlinkat( + fdctx->fdcwd, + (const unsigned char *)pathbuf, + interp,NTUX_MAX_PATH); + + ntux_free(pathbuf); + + if ((ret < 0) || (ret >= NTUX_MAX_PATH)) { + ntux_free(interp); + return NTUX_ERROR; + } + + cctx.cmd = NTUX_CMD_BRIDGE; + cctx.interp = interp; + } + } + + break; + } + /* missing arguments? */ argv_optv_init(ntux_cmd_options[cctx.cmd],optv); @@ -488,8 +609,11 @@ int ntux_get_driver_ctx( else if (cctx.cmd == NTUX_CMD_FSPATH) argv_optv_init(ntux_fspath_options,optv); - /* spawn, strace */ - if ((cctx.cmd == NTUX_CMD_SPAWN) || (cctx.cmd == NTUX_CMD_STRACE)) { + else if (cctx.cmd == NTUX_CMD_BRIDGE) + argv_optv_init(ntux_bridge_options,optv); + + /* spawn, strace, bridge */ + if (ntux_cmd_exec[cctx.cmd]) { argv_scan(argv,optv,&ctx,0); if (ctx.erridx && !ctx.unitidx) { @@ -529,12 +653,22 @@ int ntux_get_driver_ctx( return -1; } - /* spawn, strace: exec argv */ - if (execargv) { + /* spawn, strace, bridge: exec argv */ + if (ntux_cmd_exec[cctx.cmd]) { *execargv = execarg; cctx.sargv = execargv; cctx.senvp = envp; nunits = 0; + + ret = __xfi_framework_get_int32_slot_value( + PSX_RTDATA_UDAT32_ARGV0_IS_INTERP, + &val); + + if (ret < 0) + return NTUX_ERROR; + + if (val) + cctx.sargv--; } /* finalize */ @@ -548,6 +682,7 @@ int ntux_get_driver_ctx( if (!(ictx = ntux_driver_ctx_alloc(meta,fdctx,&cctx,nunits))) return ntux_get_driver_ctx_fail(meta); + ictx->interp = interp; ictx->ctx.program = program; ictx->ctx.cctx = &ictx->cctx; *pctx = &ictx->ctx; @@ -557,6 +692,9 @@ int ntux_get_driver_ctx( static void ntux_free_driver_ctx_impl(struct ntux_driver_ctx_alloc * ictx) { + if (ictx->ctx.interp) + ntux_free(ictx->ctx.interp); + argv_free(ictx->meta); free(ictx); } |