source: bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 4.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <console.h>
4#include <string.h>
5
6#include <sys/module.h>
7#include <sys/exec.h>
8
9#define INFO_PRINT(fmt, args...)        printf("[COM32] " fmt, ##args)
10
11#define MAX_COMMAND_SIZE        80      // Maximum size of the cmd line
12#define COMMAND_DELIM           " \t\n" // Whitespace delimiters
13#define MAX_COMMAND_ARGS        (MAX_COMMAND_SIZE/2)    // Maximum argument count for
14                                                                                                 // program execution
15
16/**
17 * print_help - Display usage instructions on the screen.
18 */
19static void print_help(void)
20{
21    printf("List of available commands:\n");
22    printf("exit - exits the program\n");
23    printf("help - shows this message\n");
24    printf("load <library>... - loads the libraries into the environment\n");
25    printf("spawn <executable> <args> - launches an executable module\n");
26    printf
27        ("unload <library>... - unloads the libraries from the environment\n");
28    printf("list - prints the currently loaded modules\n");
29}
30
31/**
32 * print_prompt - Display the command prompt.
33 */
34static void print_prompt(void)
35{
36    printf("\nelflink> ");
37}
38
39/**
40 * read_command - Read a new command from the standard input.
41 * @cmd: the buffer to store the command
42 * @size: the maximum size of the string that can be stored in the buffer
43 *
44 * If the command is larger than the specified size, it is truncated.
45 */
46static void read_command(char *cmd, int size)
47{
48    char *nl = NULL;
49    fgets(cmd, size, stdin);
50
51    // Strip the newline
52    nl = strchr(cmd, '\n');
53
54    if (nl != NULL)
55        *nl = '\0';
56}
57
58/**
59 * process_spawn - Handles the execution of a 'spawn' command.
60 *
61 * The command line is in the internal buffer of strtok.
62 */
63static void process_spawn(void)
64{
65    // Compose the command line
66    char **cmd_line = malloc((MAX_COMMAND_ARGS + 1) * sizeof(char *));
67    int argc = 0, result;
68    char *crt_arg;
69
70    do {
71        crt_arg = strtok(NULL, COMMAND_DELIM);
72        if (crt_arg != NULL && strlen(crt_arg) > 0) {
73            cmd_line[argc] = crt_arg;
74            argc++;
75        } else {
76            break;
77        }
78    } while (argc < MAX_COMMAND_ARGS);
79
80    cmd_line[argc] = NULL;
81
82    if (cmd_line[0] == NULL) {
83        printf("You must specify an executable module.\n");
84    } else {
85        result = spawnv(cmd_line[0], cmd_line);
86
87        printf("Spawn returned %d\n", result);
88    }
89
90    free(cmd_line);
91}
92
93/**
94 * process_library - Handles the execution of the 'load' and 'unload' commands.
95 * @load: contains 1 if the libraries are to be loaded, 0 for unloading.
96 *
97 * The command line is in the internal buffer of strtok.
98 */
99static void process_library(int load)
100{
101    char *crt_lib;
102    int result;
103
104    while ((crt_lib = strtok(NULL, COMMAND_DELIM)) != NULL) {
105        if (strlen(crt_lib) > 0) {
106            if (load)
107                result = load_library(crt_lib);
108            else
109                result = unload_library(crt_lib);
110
111            if (result == 0) {
112                printf("Library '%s' %sloaded successfully.\n", crt_lib,
113                       load ? "" : "un");
114            } else {
115                printf("Could not %sload library '%s': error %d\n",
116                       load ? "" : "un", crt_lib, result);
117            }
118        }
119    }
120}
121
122/**
123 * process_list - Handles the execution of the 'list' command.
124 *
125 */
126static void process_list(void)
127{
128    struct elf_module *module;
129    struct module_dep *crt_dep;
130
131    for_each_module(module) {
132        printf("%s (%dK, %s, %s) : ", module->name, module->module_size >> 10,
133               module->shallow ? "shallow" : "regular",
134               module->main_func == NULL ? "library" : "program");
135
136        list_for_each_entry(crt_dep, &module->required, list) {
137            printf("%s ", crt_dep->module->name);
138        }
139
140        printf("\n");
141    }
142}
143
144/**
145 * process_command - Recognizes the requested command and executes it.
146 * @cmd: the command to be executed.
147 *
148 * Returns 1 if the command was 'exit', 0 otherwise.
149 */
150static int process_command(char *cmd)
151{
152    char *cmd_name;
153
154    cmd_name = strtok(cmd, COMMAND_DELIM);
155
156    if (strcmp(cmd_name, "exit") == 0) {
157        printf("Goodbye!\n");
158        return 1;
159    } else if (strcmp(cmd_name, "help") == 0) {
160        print_help();
161    } else if (strcmp(cmd_name, "load") == 0) {
162        process_library(1);
163    } else if (strcmp(cmd_name, "spawn") == 0) {
164        process_spawn();
165    } else if (strcmp(cmd_name, "unload") == 0) {
166        process_library(0);
167    } else if (strcmp(cmd_name, "list") == 0) {
168        process_list();
169    } else {
170        printf("Unknown command. Type 'help' for a list of valid commands.\n");
171    }
172
173    return 0;
174}
175
176/**
177 * The entry point of 'test_com32' COM module.
178 */
179int main(int argc, char **argv)
180{
181    int done = 0;
182    int res;
183    char command[MAX_COMMAND_SIZE] = { 0 };
184
185    // Open a standard r/w console
186    openconsole(&dev_stdcon_r, &dev_stdcon_w);
187
188    res = exec_init();
189    if (res != 0) {
190        printf("Failed to initialize the execution environment.\n");
191        return res;
192    } else {
193        printf("Execution environment initialized successfully.\n");
194    }
195
196    printf("\nFor a list of available commands, type 'help'.\n");
197
198    do {
199        print_prompt();
200        read_command(command, MAX_COMMAND_SIZE);
201        done = process_command(command);
202
203    } while (!done);
204
205    exec_term();
206
207    return 0;
208}
Note: See TracBrowser for help on using the repository browser.