Skip to content

Commit 89fac16

Browse files
Add webserver
New basic keywords: - FILESIZE - MEMALLOC - MEMRELEASE - SOCKBINWRITE - SOCKBINREAD - BINREAD - BINWRITE Note: MEMALLOC and MEMRELEASE allocate in the current process's pool.
1 parent 3a322ec commit 89fac16

File tree

12 files changed

+209
-19
lines changed

12 files changed

+209
-19
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ foreach (timezone ${timezone_list})
9696
string(REPLACE "/" "_" TZ_NAME ${timezone})
9797
list(APPEND TIMEZONE_TARGETS "timezone_${TZ_NAME}")
9898
endforeach()
99+
set(WEB_TARGETS "")
100+
file(GLOB_RECURSE web_list RELATIVE ${CMAKE_SOURCE_DIR}/os/system/webserver ${CMAKE_SOURCE_DIR}/os/system/webserver/*)
101+
foreach(web ${web_list})
102+
copy_system_web(${web})
103+
string(REPLACE "/" "_" WEB_NAME ${web})
104+
list(APPEND WEB_TARGETS "web_${WEB_NAME}")
105+
endforeach()
99106
set(CONFIG_TARGETS "")
100107
file(GLOB_RECURSE config_list RELATIVE ${CMAKE_SOURCE_DIR}/os/system/config ${CMAKE_SOURCE_DIR}/os/system/config/*)
101108
foreach (config ${config_list})

cmake/custom_targets.cmake

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,22 @@ function(copy_system_timezone SOURCEFILE)
6464
add_dependencies(ISO timezone_${TZ_TARGET})
6565
endfunction()
6666

67+
function(copy_system_web SOURCEFILE)
68+
set(FILENAME "${CMAKE_SOURCE_DIR}/os/system/webserver/${SOURCEFILE}")
69+
set(OUTNAME "${CMAKE_BINARY_DIR}/iso/system/webserver/${SOURCEFILE}")
70+
71+
add_custom_command(OUTPUT ${OUTNAME}
72+
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/iso/system/webserver"
73+
COMMAND ${CMAKE_COMMAND} -E copy "${FILENAME}" "${OUTNAME}"
74+
DEPENDS ${FILENAME})
75+
76+
string(REPLACE "/" "_" WEB_TARGET ${SOURCEFILE})
77+
78+
add_custom_target(web_${WEB_TARGET} ALL DEPENDS ${OUTNAME})
79+
add_dependencies("kernel.bin" web_${WEB_TARGET})
80+
add_dependencies(ISO web_${WEB_TARGET})
81+
endfunction()
82+
6783
function(copy_system_config SOURCEFILE)
6884
set(FILENAME "${CMAKE_SOURCE_DIR}/os/system/config/${SOURCEFILE}")
6985
set(OUTNAME "${CMAKE_BINARY_DIR}/iso/system/config/${SOURCEFILE}")
@@ -134,7 +150,7 @@ function(run TARGETFILE)
134150
-boot d \
135151
-vnc 0.0.0.0:2 \
136152
-debugcon file:debug.log \
137-
-netdev user,id=netuser,hostfwd=tcp:127.0.0.1:2000-10.0.2.15:2000 \
153+
-netdev user,id=netuser,hostfwd=tcp::2000-:2000,hostfwd=tcp::2080-:80 \
138154
-object filter-dump,id=dump,netdev=netuser,file=dump.dat \
139155
${NET_DEVICE} ${PROFILE}" >${OUTNAME} && chmod ugo+x ${OUTNAME}
140156
DEPENDS ${FILENAME})
@@ -166,6 +182,6 @@ function(iso TARGETFILE SOURCEFILE)
166182
set(OUTNAME "${CMAKE_BINARY_DIR}/${TARGETFILE}")
167183
add_custom_command(OUTPUT ${OUTNAME}
168184
COMMAND php ../build-boot-image.php && xorriso -as mkisofs --quiet -b limine-bios-cd.bin -joliet -no-emul-boot -boot-load-size 4 -boot-info-table -V "RETROROCKET" --protective-msdos-label "${CMAKE_BINARY_DIR}/iso" -o "${CMAKE_BINARY_DIR}/rr.iso"
169-
DEPENDS SYMBOLS "kernel.bin" "RUN_run.sh" "DEBUG_debug.sh" ${basic_program_list} ${basic_library_list} ${basic_driver_list} ${KEYMAP_TARGETS} ${TIMEZONE_TARGETS} ${CONFIG_TARGETS} ${IMAGE_TARGETS} ${MODULE_TARGETS})
185+
DEPENDS SYMBOLS "kernel.bin" "RUN_run.sh" "DEBUG_debug.sh" ${basic_program_list} ${basic_library_list} ${basic_driver_list} ${KEYMAP_TARGETS} ${TIMEZONE_TARGETS} ${WEB_TARGETS} ${CONFIG_TARGETS} ${IMAGE_TARGETS} ${MODULE_TARGETS})
170186
add_dependencies(ISO SYMBOLS "kernel.bin" "RUN_run.sh" "DEBUG_debug.sh" "config_limine.conf")
171187
endfunction()

include/basic/builtin_file_io_functions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ int64_t basic_getnamecount(struct basic_ctx* ctx);
227227
*/
228228
int64_t basic_getsize(struct basic_ctx* ctx);
229229

230+
int64_t basic_filesize(struct basic_ctx* ctx);
231+
230232
/**
231233
* @brief Returns the name of a file or directory at a specified index.
232234
*
@@ -257,4 +259,6 @@ char* basic_ramdisk_from_device(struct basic_ctx* ctx);
257259
*/
258260
char* basic_ramdisk_from_size(struct basic_ctx* ctx);
259261

262+
void readbinary_statement(struct basic_ctx* ctx);
260263

264+
void writebinary_statement(struct basic_ctx* ctx);

include/basic/lowlevel.h

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -122,23 +122,6 @@ int64_t basic_cpuid(struct basic_ctx* ctx);
122122
*/
123123
void outport_statement(struct basic_ctx* ctx);
124124

125-
/**
126-
* @brief Implements the BASIC statement OUTPORTW.
127-
*
128-
* BASIC syntax:
129-
* @code
130-
* OUTPORTW port, value
131-
* @endcode
132-
*
133-
* Writes a 16-bit value to the specified I/O port.
134-
*
135-
* @param ctx Interpreter context.
136-
*
137-
* @note The value is truncated to 16 bits before being written.
138-
* @warning Raises a runtime error if the number or type of arguments is invalid.
139-
*/
140-
void outportw_statement(struct basic_ctx* ctx);
141-
142125
/**
143126
* @brief Implements the BASIC statement OUTPORTD.
144127
*
@@ -410,3 +393,7 @@ int64_t basic_bitrol(struct basic_ctx* ctx);
410393
* @note Width is usually 1–64; the result is masked to @p width bits.
411394
*/
412395
int64_t basic_bitror(struct basic_ctx* ctx);
396+
397+
void memrelease_statement(struct basic_ctx* ctx);
398+
399+
int64_t basic_memalloc(struct basic_ctx* ctx);

include/basic/sockets.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ struct basic_ctx;
1717
*/
1818
void sockwrite_statement(struct basic_ctx* ctx);
1919

20+
void sockbinwrite_statement(struct basic_ctx* ctx);
21+
22+
void sockbinread_statement(struct basic_ctx* ctx);
23+
24+
25+
2026
/**
2127
* @brief Perform a DNS lookup and return the corresponding IP address.
2228
*

include/basic/tokenizer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ typedef void (*keyword_handler_t)(struct basic_ctx*);
183183
T(MODLOAD, STMT, modload_statement) /* 111 */ \
184184
T(MODUNLOAD, STMT, modunload_statement) /* 112 */ \
185185
T(SOCKFLUSH, STMT, sockflush_statement) /* 113 */ \
186+
T(MEMRELEASE, STMT, memrelease_statement) /* 114 */ \
187+
T(SOCKBINWRITE, STMT, sockbinwrite_statement) /* 115 */ \
188+
T(SOCKBINREAD, STMT, sockbinread_statement) /* 116 */ \
189+
T(BINREAD, STMT, readbinary_statement) /* 117 */ \
190+
T(BINWRITE, STMT, writebinary_statement) /* 118 */ \
186191

187192
GENERATE_ENUM_LIST(TOKEN, token_t)
188193

os/programs/webserver.rrbasic

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
IF EXISTSVARI("client_socket") THEN
2+
PROCprocessRequest
3+
END
4+
ENDIF
5+
6+
server = SOCKLISTEN(NETINFO$("ip"), 80, 5)
7+
PRINT "Web server running. Press any key to terminate."
8+
REPEAT
9+
client = SOCKACCEPT(server)
10+
IF client >= 0 THEN PROCspawnChild(client)
11+
UNTIL INKEY$ <> ""
12+
SOCKCLOSE server
13+
END
14+
15+
DEF PROCspawnChild(client)
16+
GLOBAL client_socket = client
17+
CHAIN PROGRAM$, TRUE ' Spawn an async background instance
18+
ENDPROC
19+
20+
DEF PROCprocessRequest
21+
SOCKREAD client_socket, REQUEST$
22+
VERB$ = TOKENIZE$(REQUEST$, " ") ' Get the request details
23+
FILEPATH$ = TOKENIZE$(REQUEST$, " ")
24+
IF FILEPATH$ = "/" THEN FILEPATH$ = "/index.html"
25+
PRINT FILEPATH$
26+
VERSION$ = REQUEST$
27+
FILEPATH$ = "/system/webserver" + FILEPATH$
28+
FH = OPENIN(FILEPATH$)
29+
IF FH > -1 THEN
30+
SOCKWRITE client_socket, "HTTP/1.0 200 OK"; CHR$(13); CHR$(10);
31+
size = FILESIZE(FILEPATH$)
32+
buffer = MEMALLOC(size)
33+
SOCKWRITE client_socket, "Content-Length: "; size; CHR$(13); CHR$(10);
34+
SOCKWRITE client_socket, "Connection: close"; CHR$(13); CHR$(10); CHR$(13); CHR$(10);
35+
BINREAD FH, buffer, size
36+
SOCKBINWRITE client_socket, buffer, size
37+
SOCKFLUSH client_socket
38+
MEMRELEASE buffer
39+
SOCKCLOSE client_socket
40+
CLOSE FH
41+
ELSE
42+
SOCKWRITE client_socket, "HTTP/1.0 404 Not Found"; CHR$(13); CHR$(10);
43+
SOCKWRITE client_socket, "Content-Length: 0"; CHR$(13); CHR$(10);
44+
SOCKWRITE client_socket, "Connection: close"; CHR$(13); CHR$(10); CHR$(13); CHR$(10);
45+
SOCKFLUSH client_socket
46+
SOCKCLOSE client_socket
47+
ENDIF
48+
ENDPROC

os/system/webserver/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<h1>HELLORLD!</h1>
2+
<br><br>
3+
This is the Retro Rocket Web Server default page.
4+
<br><br>
5+
It is hosted at /system/webserver.

src/basic/file_io.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,19 @@ char* basic_filetype(struct basic_ctx* ctx)
199199
return fs_is_directory(dir) ? "directory" : "file";
200200
}
201201

202+
int64_t basic_filesize(struct basic_ctx* ctx)
203+
{
204+
PARAMS_START;
205+
PARAMS_GET_ITEM(BIP_STRING);
206+
PARAMS_END("FILESIZE", 0);
207+
fs_directory_entry_t* file = fs_get_file_info(strval);
208+
if (file) {
209+
return file->size;
210+
}
211+
tokenizer_error_printf(ctx, "Error retrieving size: %s", fs_strerror(fs_get_error()));
212+
return 0;
213+
}
214+
202215
int64_t basic_getsize(struct basic_ctx* ctx)
203216
{
204217
PARAMS_START;
@@ -262,6 +275,34 @@ void rmdir_statement(struct basic_ctx* ctx)
262275
}
263276
}
264277

278+
void readbinary_statement(struct basic_ctx* ctx)
279+
{
280+
accept_or_return(BINREAD, ctx);
281+
int64_t fd = expr(ctx);
282+
accept_or_return(COMMA, ctx);
283+
int64_t buffer = expr(ctx);
284+
accept_or_return(COMMA, ctx);
285+
int64_t size = expr(ctx);
286+
if (_read(fd, buffer, size) == -1) {
287+
tokenizer_error_printf(ctx, "Error reading from file: %s", fs_strerror(fs_get_error()));
288+
}
289+
accept_or_return(NEWLINE, ctx);
290+
}
291+
292+
void writebinary_statement(struct basic_ctx* ctx)
293+
{
294+
accept_or_return(BINWRITE, ctx);
295+
int64_t fd = expr(ctx);
296+
accept_or_return(COMMA, ctx);
297+
int64_t buffer = expr(ctx);
298+
accept_or_return(COMMA, ctx);
299+
int64_t size = expr(ctx);
300+
if (_write(fd, buffer, size) == -1) {
301+
tokenizer_error_printf(ctx, "Error writing to file: %s", fs_strerror(fs_get_error()));
302+
}
303+
accept_or_return(NEWLINE, ctx);
304+
}
305+
265306

266307
void delete_statement(struct basic_ctx* ctx)
267308
{

src/basic/function.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ struct basic_int_fn builtin_int[] =
8686
{ basic_peekd, "PEEKD" },
8787
{ basic_peekw, "PEEKW" },
8888
{ basic_peek, "PEEK" },
89+
{ basic_memalloc, "MEMALLOC" },
90+
{ basic_filesize, "FILESIZE" },
8991
{ NULL, NULL },
9092
};
9193

0 commit comments

Comments
 (0)