Parse commandline strings, move away from old env vars
All checks were successful
Build ISO image / build-and-deploy (push) Successful in 2m6s
Build documentation / build-and-deploy (push) Successful in 1m18s

This commit is contained in:
2026-04-28 22:45:31 +02:00
parent 9fbe23024c
commit fbf067d418
15 changed files with 265 additions and 185 deletions

44
ce/ce.c
View File

@@ -3,6 +3,7 @@
#include "interp.h"
#include "strbuf.h"
#include <arena.h>
#include <cmdline_parser.h>
#include <debugconsole.h>
#include <filereader.h>
#include <in_gb.h>
@@ -22,7 +23,16 @@
#define PROMPT "$ "
bool print_commands = false;
static bool cmdline_printcmds = false;
static char cmdline_script[CMDLINE_OPT_VALUE_MAX];
static char cmdline_posvars[CMDLINE_OPT_VALUE_MAX];
static struct cmdline_opt cmdline_opts[] = {
CMDLINE_OPT("p", "printcmds", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_printcmds),
CMDLINE_OPT("s", "script", CMDLINE_OPT_VALUE_STRING, false, (char*)cmdline_script),
CMDLINE_OPT("a", "args", CMDLINE_OPT_VALUE_STRING, false, (char*)cmdline_posvars),
CMDLINE_END(),
};
void* wmalloc(void* ctx, size_t size) {
(void)ctx;
@@ -59,7 +69,7 @@ struct edit_line {
static void exec_line(const char* line) {
struct list_node_link* tokens = NULL;
if (print_commands)
if (cmdline_printcmds)
mprintf("+%s\n", line);
tokenize(&tokens, line);
@@ -98,35 +108,23 @@ static bool split_args_cb(void* ctx, const char* start, size_t len) {
}
void app_main(void) {
char scriptpathbuf[PATH_MAX];
char posvarsbuf[2048];
char printcmdsbuf[4];
char line[1024];
const char* cmdline = get_cmdline();
debug_printf("cmdline=\"%s\"\n", cmdline);
if (env_get(process_get_pgid(), "printcmds", (void*)printcmdsbuf, sizeof(printcmdsbuf)) ==
ST_OK &&
strcmp(printcmdsbuf, "yes") == 0) {
print_commands = true;
if (cmdline_parse(get_cmdline(), cmdline_opts) < 0) {
mprintf("Failed to parse commandline arguments\n");
return;
}
memset(scriptpathbuf, 0, sizeof(scriptpathbuf));
int has_script = env_get(process_get_pgid(), "s", (void*)scriptpathbuf, sizeof(scriptpathbuf));
char line[1024];
if (has_script == ST_OK) {
if (env_get(process_get_pgid(), "args", (void*)posvarsbuf, sizeof(posvarsbuf)) == ST_OK) {
strtokenize(posvarsbuf, ' ', NULL, &split_args_cb);
}
if (strlen(cmdline_script) > 0) {
if (strlen(cmdline_posvars) > 0)
strtokenize(cmdline_posvars, ' ', NULL, &split_args_cb);
char volume[VOLUME_MAX];
const char* path;
int ret;
if (!path_parse(scriptpathbuf, volume, &path)) {
mprintf("ERROR bad path '%s'\n", scriptpathbuf);
if (!path_parse(cmdline_script, volume, &path)) {
mprintf("ERROR bad path '%s'\n", cmdline_script);
return;
}

View File

@@ -27,11 +27,11 @@
#include <tscreen.h>
#include <write_file.h>
static bool run = true;
struct posvar posvars[POSVAR_MAX];
int posvar_count = 0;
static bool run = true;
bool interp_is_running(void) { return run; }
void interp_shutdown(void) { run = false; }
@@ -532,7 +532,17 @@ static void execute_cmd(struct ast_cmd* cmd, struct context* context, bool run_b
return;
}
int pid = exec_partial(volume, path);
struct strbuf tmpstrbuf;
memset(&tmpstrbuf, 0, sizeof(tmpstrbuf));
for (int i = 0; i < cmd->arg_count; i++) {
strbuf_append_str(&tmpstrbuf, cmd->args[i]);
strbuf_append(&tmpstrbuf, ' ');
}
strbuf_append(&tmpstrbuf, '\0');
int pid = exec_partial(volume, path, tmpstrbuf.items);
if (pid < 0) {
cprintf(context, "ERROR could not run '%s': %s\n", cmd->name, str_status[-pid]);
@@ -541,26 +551,6 @@ static void execute_cmd(struct ast_cmd* cmd, struct context* context, bool run_b
int pgid = get_procgroup(pid);
int i = 0;
while (i < cmd->arg_count) {
char* arg = cmd->args[i];
char *key, *value;
if (arg[0] == '-') {
key = &arg[1];
if (i < cmd->arg_count - 1) {
value = cmd->args[++i];
} else {
value = "yes";
}
env_set(pgid, key, value, strlen(value) + 1);
}
i++;
}
if (run_bg) {
exec_partial_fini(pid);

View File

@@ -1,3 +1,4 @@
#include <cmdline_parser.h>
#include <device_info.h>
#include <devices.h>
#include <malloc.h>
@@ -7,6 +8,13 @@
#include <string.h>
#include <system.h>
static bool cmdline_list_all = false;
static struct cmdline_opt cmdline_opts[] = {
CMDLINE_OPT("la", "list-all", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_list_all),
CMDLINE_END(),
};
static const char* device_types_str[] = {
[DEVICE_TYPE_DEBUGCONSOLE] = "Debug console", [DEVICE_TYPE_TERMINAL] = "System terminal",
[DEVICE_TYPE_KEYBOARD] = "Keyboard", [DEVICE_TYPE_DRIVE] = "Drive",
@@ -28,21 +36,12 @@ static void list_all_devices(void) {
}
void app_main(void) {
char commandbuf[32];
memset(commandbuf, 0, sizeof(commandbuf));
if (env_get(process_get_pgid(), "help", (void*)commandbuf, sizeof(commandbuf)) == ST_OK) {
mprintf("devices -C command\n");
mprintf("commands: list_all\n");
if (cmdline_parse(get_cmdline(), cmdline_opts) < 0) {
mprintf("Failed to parse commandline arguments\n");
return;
}
if (env_get(process_get_pgid(), "C", (void*)commandbuf, sizeof(commandbuf)) != ST_OK) {
mprintf("ERROR C=???. No command provided\n");
return;
}
if (strcmp(commandbuf, "list_all") == 0) {
if (cmdline_list_all) {
list_all_devices();
}
}

View File

@@ -4,13 +4,13 @@ terminfo
echo "\n"
echo "Starting USB poller...\n"
sys:/usb -C poll &
sys:/usb -poll &
echo "\n"
stall 2000
echo "Available devices:\n"
sys:/devices -C list_all
sys:/devices -list-all
echo "\n"
echo "Running processes:\n"

View File

@@ -28,7 +28,7 @@ static void receiver(void* arg) {
}
static void run_ce_interactive(void) {
int ce_pid = exec("sys", "/ce", "-i");
int ce_pid = exec("sys", "/ce", NULL);
ce_pgid = get_procgroup(ce_pid);
process_spawn(&receiver, NULL);
@@ -44,12 +44,9 @@ static void run_ce_interactive(void) {
}
static void ce_run_init_script(void) {
int ce_pid = exec_partial("sys", "/ce");
int ce_pid = exec_partial("sys", "/ce", "-script sys:/init.cmd");
ce_pgid = get_procgroup(ce_pid);
const char* script_path = "sys:/init.cmd";
env_set(ce_pgid, "s", (void*)script_path, strlen(script_path) + 1);
struct process_data* recv_pdata = process_spawn(&receiver, NULL);
exec_partial_fini(ce_pgid);

View File

@@ -162,23 +162,6 @@ static void intr_exception(struct saved_regs* regs) {
regs->error, regs->rip, regs->cs, regs->rflags, regs->rsp, regs->ss, cr2, cr3,
regs->rbx);
debugprintf("call stack:\n");
uint64_t rbp = regs->rbp;
for (size_t depth = 0; depth < 20; depth++) {
if (rbp == 0)
break;
uint64_t rip = *(uint64_t*)(rbp + 8);
debugprintf(" #%d %016lx\n", depth, rip);
rbp = *(uint64_t*)rbp;
if (rbp == 0)
break;
}
if (regs->cs == (GDT_UCODE | 0x03)) {
biglock_lock();

View File

@@ -340,10 +340,11 @@ DEFINE_SYSCALL(sys_exec) {
return SYSRESULT(pid);
}
/* int exec_partial (char* volume, char* path) */
/* int exec_partial (char* volume, char* path, char* cmdline) */
DEFINE_SYSCALL(sys_exec_partial) {
uintptr_t uvaddr_volume = a1;
uintptr_t uvaddr_path = a2;
uintptr_t uvaddr_cmdline = a3;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -367,12 +368,21 @@ DEFINE_SYSCALL(sys_exec_partial) {
const char* volume = (const char*)((uintptr_t)hhdm->offset + out_paddr);
out_paddr = mm_v2p(&procgroup->pd, uvaddr_cmdline);
char* cmdline = (out_paddr != 0) ? (char*)((uintptr_t)hhdm->offset + out_paddr) : NULL;
struct proc* new = proc_from_file(proc, volume, path, rctx);
if (new == NULL) {
return SYSRESULT(-ST_EXEC_ERROR);
}
if (cmdline != NULL) {
void* cmdline_dest = (void*)((uintptr_t)hhdm->offset + new->procgroup->paddr_cmdline);
strncpy(cmdline_dest, cmdline, PAGE_SIZE);
}
int pid = new->pid;
new->exec_pid = pid1;
new->state = PROC_PARTIAL;

91
libu/cmdline_parser.c Normal file
View File

@@ -0,0 +1,91 @@
#include <cmdline_parser.h>
#include <debugconsole.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <strconv.h>
#include <string.h>
#define PARSE_MODE_NAME 0
#define PARSE_MODE_VALUE 1
static void cmdline_parse_opt(const char* cmdline, struct cmdline_opt* opt) {
const char* p = cmdline;
char optnamebuf[CMDLINE_OPT_NAME_MAX];
char optvaluebuf[CMDLINE_OPT_VALUE_MAX];
int mode = PARSE_MODE_NAME;
while (*p) {
if (isspace(*p)) {
p++;
continue;
}
if (mode == PARSE_MODE_NAME) {
if (*p == '-') {
p++;
memset(optnamebuf, 0, sizeof(optnamebuf));
size_t i = 0;
while (*p && !isspace(*p) && i < CMDLINE_OPT_NAME_MAX - 1) {
optnamebuf[i++] = *p++;
}
optnamebuf[i] = '\0';
if (strcmp(optnamebuf, opt->name) == 0 || strcmp(optnamebuf, opt->altname) == 0) {
if (opt->type == CMDLINE_OPT_VALUE_BOOL) {
*(bool*)opt->valueptr = true;
opt->set = true;
} else {
mode = PARSE_MODE_VALUE;
}
}
continue;
}
} else if (mode == PARSE_MODE_VALUE) {
memset(optvaluebuf, 0, sizeof(optvaluebuf));
size_t i = 0;
while (*p && !isspace(*p) && i < CMDLINE_OPT_VALUE_MAX - 1) {
optvaluebuf[i++] = *p++;
}
optvaluebuf[i] = '\0';
if (opt->type == CMDLINE_OPT_VALUE_STRING) {
strncpy(opt->valueptr, optvaluebuf, CMDLINE_OPT_VALUE_MAX);
opt->set = true;
} else if (opt->type == CMDLINE_OPT_VALUE_INT) {
*(uint64_t*)opt->valueptr = str_to_uint64(optvaluebuf);
opt->set = true;
}
mode = PARSE_MODE_NAME;
continue;
}
p++;
}
}
int cmdline_parse(const char* cmdline, struct cmdline_opt* opt_array) {
size_t curr_opt_idx = 0;
while (!opt_array[curr_opt_idx].end) {
struct cmdline_opt* curr_opt = &opt_array[curr_opt_idx++];
cmdline_parse_opt(cmdline, curr_opt);
}
curr_opt_idx = 0;
while (!opt_array[curr_opt_idx].end) {
struct cmdline_opt* curr_opt = &opt_array[curr_opt_idx++];
if (!curr_opt->set && curr_opt->required)
return -1;
}
return 0;
}

36
libu/cmdline_parser.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef _LIBU_CMDLINE_PARSER_H
#define _LIBU_CMDLINE_PARSER_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define CMDLINE_OPT_NAME_MAX 32
#define CMDLINE_OPT_VALUE_MAX 512
#define CMDLINE_OPT_VALUE_STRING 0
#define CMDLINE_OPT_VALUE_BOOL 1
#define CMDLINE_OPT_VALUE_INT 2
struct cmdline_opt {
const char* name;
const char* altname;
int type;
bool required;
void* valueptr;
bool end;
bool set;
};
#define CMDLINE_OPT(name1, altname1, type1, required1, valueptr1) \
((struct cmdline_opt){.name = (name1), \
.altname = (altname1), \
.type = (type1), \
.required = (required1), \
.valueptr = (valueptr1)})
#define CMDLINE_END() ((struct cmdline_opt){.end = true})
int cmdline_parse(const char* cmdline, struct cmdline_opt* opt_array);
#endif // _LIBU_CMDLINE_PARSER_H

View File

@@ -19,7 +19,8 @@ c += terminal.c \
_fat.c \
libfat.c \
in_gb.c \
in_input.c
in_input.c \
cmdline_parser.c
o += terminal.o \
__premain.o \
@@ -40,4 +41,5 @@ o += terminal.o \
_fat.o \
libfat.o \
in_gb.o \
in_input.o
in_input.o \
cmdline_parser.o

View File

@@ -97,8 +97,8 @@ int env_get(int pgid, const char* key, void* buffer, size_t len) {
return (int)do_syscall(SYS_ENV_GET, pgid, key, buffer, len);
}
int exec_partial(const char* volume, const char* path) {
return (int)do_syscall(SYS_EXEC_PARTIAL, volume, path);
int exec_partial(const char* volume, const char* path, const char* cmdline) {
return (int)do_syscall(SYS_EXEC_PARTIAL, volume, path, cmdline);
}
int exec_partial_fini(int pid) { return (int)do_syscall(SYS_EXEC_PARTIAL_FINI, pid); }

View File

@@ -104,7 +104,7 @@ int env_set(int pgid, const char* key, void* buffer, size_t len);
int env_get(int pgid, const char* key, void* buffer, size_t len);
/* Prepare process for execution */
int exec_partial(const char* volume, const char* path);
int exec_partial(const char* volume, const char* path, const char* cmdline);
/* Finish process for execution - run it! */
int exec_partial_fini(int pid);

View File

@@ -1,3 +1,4 @@
#include <cmdline_parser.h>
#include <debugconsole.h>
#include <process.h>
#include <status.h>
@@ -5,19 +6,25 @@
#include <string.h>
#include <system.h>
void app_main(void) {
char commandbuf[32];
memset(commandbuf, 0, sizeof(commandbuf));
char payloadbuf[32];
memset(payloadbuf, 0, sizeof(payloadbuf));
char procgroupbuf[32];
memset(procgroupbuf, 0, sizeof(procgroupbuf));
static bool cmdline_send = false;
static bool cmdline_recv = false;
static char cmdline_payload[CMDLINE_OPT_VALUE_MAX];
static uint64_t cmdline_pg;
if (env_get(process_get_pgid(), "C", (void*)commandbuf, sizeof(commandbuf)) != ST_OK) {
static struct cmdline_opt cmdline_opts[] = {
CMDLINE_OPT("s", "send", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_send),
CMDLINE_OPT("r", "recv", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_recv),
CMDLINE_OPT("p", "payload", CMDLINE_OPT_VALUE_STRING, false, (char*)cmdline_payload),
CMDLINE_OPT("pg", "procgroup", CMDLINE_OPT_VALUE_INT, false, &cmdline_pg),
CMDLINE_END(),
};
void app_main(void) {
if (cmdline_parse(get_cmdline(), cmdline_opts) < 0) {
return;
}
if (strcmp(commandbuf, "recv") == 0) {
if (cmdline_recv) {
char recv_buffer[1024];
for (;;) {
@@ -27,19 +34,9 @@ void app_main(void) {
debug_printf("Recv: %s\n", recv_buffer);
}
} else if (strcmp(commandbuf, "send") == 0) {
if (env_get(process_get_pgid(), "payload", (void*)payloadbuf, sizeof(payloadbuf)) != ST_OK) {
return;
}
} else if (cmdline_send) {
debug_printf("sending [%s] to PG %d\n", cmdline_payload, (int)cmdline_pg);
if (env_get(process_get_pgid(), "pg", (void*)procgroupbuf, sizeof(procgroupbuf)) != ST_OK) {
return;
}
int pgid = str_to_uint32(procgroupbuf);
debug_printf("sending %s to PG %s (%d)\n", payloadbuf, procgroupbuf, pgid);
mail_send(pgid, payloadbuf, sizeof(payloadbuf));
mail_send((int)cmdline_pg, cmdline_payload, strlen(cmdline_payload));
}
}

View File

@@ -1,4 +1,5 @@
#include "limine-bios-hdd.h"
#include <cmdline_parser.h>
#include <devices.h>
#include <endianess.h>
#include <fs_types.h>
@@ -14,6 +15,26 @@
#include <tcursor.h>
#include <tscreen.h>
static bool cmdline_part_dos = false;
static bool cmdline_list_part_dos = false;
static bool cmdline_format_fat32 = false;
static bool cmdline_format_fat16 = false;
static bool cmdline_install_limine_stage2 = false;
static bool cmdline_part_rescan = false;
static char cmdline_dev[CMDLINE_OPT_VALUE_MAX];
static struct cmdline_opt cmdline_opts[] = {
CMDLINE_OPT("pd", "part-dos", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_part_dos),
CMDLINE_OPT("lpd", "list-part-dos", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_list_part_dos),
CMDLINE_OPT("ff32", "format-fat32", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_format_fat32),
CMDLINE_OPT("ff16", "format-fat16", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_format_fat16),
CMDLINE_OPT("ils2", "install-limine-stage2", CMDLINE_OPT_VALUE_BOOL, false,
&cmdline_install_limine_stage2),
CMDLINE_OPT("pr", "part-rescan", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_part_rescan),
CMDLINE_OPT("d", "device", CMDLINE_OPT_VALUE_STRING, true, (char*)cmdline_dev),
CMDLINE_END(),
};
struct dos_pte {
uint8_t drive_attrs;
uint8_t chs_start_addr[3];
@@ -245,69 +266,25 @@ static void install_limine_stage2(const char* dev_name) {
}
void app_main(void) {
char commandbuf[32];
memset(commandbuf, 0, sizeof(commandbuf));
char devnamebuf[64];
memset(devnamebuf, 0, sizeof(devnamebuf));
if (env_get(process_get_pgid(), "help", (void*)commandbuf, sizeof(commandbuf)) == ST_OK) {
mprintf("sdutil -C command -dev device_key\n");
mprintf("commands: part_dos, list_part_dos, format_fat32, format_fat16\n");
mprintf(" install_limine_stage2, partition_rescan\n");
if (cmdline_parse(get_cmdline(), cmdline_opts) < 0) {
mprintf("Failed to parse commandline arguments\n");
return;
}
if (env_get(process_get_pgid(), "C", (void*)commandbuf, sizeof(commandbuf)) != ST_OK) {
mprintf("ERROR C=???. No command provided\n");
return;
}
if (strcmp(commandbuf, "part_dos") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR dev=???. No device name provided for part_dos\n");
return;
}
start_part_dos(devnamebuf);
} else if (strcmp(commandbuf, "list_part_dos") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR dev=???. No device name provided for list_part_dos\n");
return;
}
list_part_dos(devnamebuf);
} else if (strcmp(commandbuf, "format_fat32") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR dev=???. No device name provided for format_fat32\n");
return;
}
format_fat32(devnamebuf);
} else if (strcmp(commandbuf, "format_fat16") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR dev=???. No device name provided for format_fat16\n");
return;
}
format_fat16(devnamebuf);
} else if (strcmp(commandbuf, "install_limine_stage2") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR dev=???. No device name provided for install_limine_stage2\n");
return;
}
install_limine_stage2(devnamebuf);
} else if (strcmp(commandbuf, "partition_rescan") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR dev=???. No device name provided for partition_rescan\n");
return;
}
if (cmdline_part_dos) {
start_part_dos(cmdline_dev);
} else if (cmdline_list_part_dos) {
list_part_dos(cmdline_dev);
} else if (cmdline_format_fat32) {
format_fat32(cmdline_dev);
} else if (cmdline_format_fat16) {
format_fat16(cmdline_dev);
} else if (cmdline_install_limine_stage2) {
install_limine_stage2(cmdline_dev);
} else if (cmdline_part_rescan) {
mprintf("WARNING Make sure all filesystems were unmounted from this device.\n");
mprintf("Otherwise a rescan may result in broken filesystems and crashes!\n");
device_do(devnamebuf, XDRV_PARTITION_RESCAN, NULL, NULL, NULL, NULL);
} else {
mprintf("ERROR C=%s. Unknown command\n", commandbuf);
device_do(cmdline_dev, XDRV_PARTITION_RESCAN, NULL, NULL, NULL, NULL);
}
}

View File

@@ -1,3 +1,4 @@
#include <cmdline_parser.h>
#include <device_info.h>
#include <devices.h>
#include <malloc.h>
@@ -9,6 +10,17 @@
#include <system.h>
#include <volume_info.h>
static bool cmdline_poll = false;
static bool cmdline_eject = false;
static char cmdline_dev[CMDLINE_OPT_VALUE_MAX];
static struct cmdline_opt cmdline_opts[] = {
CMDLINE_OPT("p", "poll", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_poll),
CMDLINE_OPT("e", "eject", CMDLINE_OPT_VALUE_BOOL, false, &cmdline_eject),
CMDLINE_OPT("d", "device", CMDLINE_OPT_VALUE_STRING, false, (char*)cmdline_dev),
CMDLINE_END(),
};
static void usb_poll(void) {
struct device_info* infos = malloc(sizeof(struct device_info) * 1024);
memset(infos, 0, sizeof(struct device_info) * 1024);
@@ -64,26 +76,14 @@ static void usb_eject(const char* dev_key) {
}
void app_main(void) {
char commandbuf[32];
memset(commandbuf, 0, sizeof(commandbuf));
char devnamebuf[32];
memset(devnamebuf, 0, sizeof(devnamebuf));
if (env_get(process_get_pgid(), "C", (void*)commandbuf, sizeof(commandbuf)) != ST_OK) {
mprintf("ERROR C=???. No command provided\n");
if (cmdline_parse(get_cmdline(), cmdline_opts) < 0) {
mprintf("Failed to parse commandline arguments\n");
return;
}
if (strcmp(commandbuf, "poll") == 0) {
if (cmdline_poll) {
usb_poll();
} else if (strcmp(commandbuf, "eject") == 0) {
if (env_get(process_get_pgid(), "dev", (void*)devnamebuf, sizeof(devnamebuf)) != ST_OK) {
mprintf("ERROR No device provided\n");
return;
}
usb_eject(devnamebuf);
} else {
mprintf("ERROR unknown command %s\n", commandbuf);
} else if (cmdline_eject) {
usb_eject(cmdline_dev);
}
}