global cell shops
This commit is contained in:
185
source/cell.c
185
source/cell.c
@@ -11,103 +11,100 @@
|
||||
#include "cell.h"
|
||||
#include "cell_internal.h"
|
||||
|
||||
#define QOP_IMPLEMENTATION
|
||||
#include "qop.h"
|
||||
|
||||
#define ENGINE "engine.cm"
|
||||
#define ENGINE "scripts/engine.cm"
|
||||
#define CELL_SHOP_DIR ".cell"
|
||||
#define CELL_CORE_DIR "core"
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static qop_desc qop_core;
|
||||
static qop_file *qop_hashmap = NULL;
|
||||
cell_rt *root_cell = NULL;
|
||||
static char *core_path = NULL;
|
||||
|
||||
int get_executable_path(char *buffer, unsigned int buffer_size) {
|
||||
#if defined(__linux__)
|
||||
ssize_t len = readlink("/proc/self/exe", buffer, buffer_size - 1);
|
||||
if (len == -1) {
|
||||
return 0;
|
||||
// Get the home directory
|
||||
static const char* get_home_dir(void) {
|
||||
const char *home = getenv("HOME");
|
||||
if (!home) {
|
||||
home = getenv("USERPROFILE"); // Windows fallback
|
||||
}
|
||||
buffer[len] = '\0';
|
||||
return len;
|
||||
#elif defined(__APPLE__)
|
||||
if (_NSGetExecutablePath(buffer, &buffer_size) == 0) {
|
||||
return buffer_size;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
return GetModuleFileName(NULL, buffer, buffer_size);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
return home;
|
||||
}
|
||||
|
||||
int prosperon_mount_core(void)
|
||||
// Find and verify the cell shop at ~/.cell
|
||||
int find_cell_shop(void)
|
||||
{
|
||||
char exe_path[PATH_MAX];
|
||||
int exe_path_len = get_executable_path(exe_path, sizeof(exe_path));
|
||||
if (exe_path_len == 0) {
|
||||
printf("ERROR: Could not get executable path\n");
|
||||
const char *home = get_home_dir();
|
||||
if (!home) {
|
||||
printf("ERROR: Could not determine home directory. Set HOME environment variable.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load the entire executable into memory
|
||||
FILE *fh = fopen(exe_path, "rb");
|
||||
if (!fh) {
|
||||
printf("ERROR: Could not open executable\n");
|
||||
// Build path to ~/.cell/core
|
||||
size_t path_len = strlen(home) + strlen("/" CELL_SHOP_DIR "/" CELL_CORE_DIR) + 1;
|
||||
core_path = malloc(path_len);
|
||||
if (!core_path) {
|
||||
printf("ERROR: Could not allocate memory for core path\n");
|
||||
return 0;
|
||||
}
|
||||
snprintf(core_path, path_len, "%s/" CELL_SHOP_DIR "/" CELL_CORE_DIR, home);
|
||||
|
||||
fseek(fh, 0, SEEK_END);
|
||||
long file_size = ftell(fh);
|
||||
fseek(fh, 0, SEEK_SET);
|
||||
|
||||
unsigned char *buf = malloc(file_size);
|
||||
if (!buf) {
|
||||
printf("ERROR: Could not allocate memory for executable\n");
|
||||
fclose(fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fread(buf, 1, file_size, fh) != (size_t)file_size) {
|
||||
printf("ERROR: Could not read executable\n");
|
||||
free(buf);
|
||||
fclose(fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
|
||||
// Open the QOP archive from the in-memory data
|
||||
int archive_size = qop_open_data(buf, file_size, &qop_core);
|
||||
if (archive_size == 0) {
|
||||
printf("ERROR: Could not open QOP archive\n");
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read the archive index
|
||||
qop_hashmap = malloc(qop_core.hashmap_size);
|
||||
if (!qop_hashmap) {
|
||||
printf("ERROR: Could not allocate memory for QOP hashmap\n");
|
||||
qop_close(&qop_core);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int index_len = qop_read_index(&qop_core, qop_hashmap);
|
||||
if (index_len == 0) {
|
||||
printf("ERROR: Could not read QOP index\n");
|
||||
free(qop_hashmap);
|
||||
qop_hashmap = NULL;
|
||||
qop_close(&qop_core);
|
||||
free(buf);
|
||||
// Check if the core directory exists
|
||||
struct stat st;
|
||||
if (stat(core_path, &st) != 0 || !S_ISDIR(st.st_mode)) {
|
||||
printf("ERROR: Cell shop not found at %s/" CELL_SHOP_DIR "\n", home);
|
||||
printf("Run 'cell install' to set up the cell environment.\n");
|
||||
free(core_path);
|
||||
core_path = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Load a file from the core directory
|
||||
static char* load_core_file(const char *filename, size_t *out_size) {
|
||||
if (!core_path) return NULL;
|
||||
|
||||
size_t path_len = strlen(core_path) + 1 + strlen(filename) + 1;
|
||||
char *full_path = malloc(path_len);
|
||||
if (!full_path) return NULL;
|
||||
|
||||
snprintf(full_path, path_len, "%s/%s", core_path, filename);
|
||||
|
||||
FILE *fh = fopen(full_path, "rb");
|
||||
free(full_path);
|
||||
|
||||
if (!fh) return NULL;
|
||||
|
||||
fseek(fh, 0, SEEK_END);
|
||||
long file_size = ftell(fh);
|
||||
fseek(fh, 0, SEEK_SET);
|
||||
|
||||
char *data = malloc(file_size + 1);
|
||||
if (!data) {
|
||||
fclose(fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(data, 1, file_size, fh) != (size_t)file_size) {
|
||||
free(data);
|
||||
fclose(fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
data[file_size] = 0;
|
||||
|
||||
if (out_size) *out_size = file_size;
|
||||
return data;
|
||||
}
|
||||
|
||||
// Get the core path for use by scripts
|
||||
const char* cell_get_core_path(void) {
|
||||
return core_path;
|
||||
}
|
||||
|
||||
void actor_disrupt(cell_rt *crt)
|
||||
{
|
||||
crt->disrupt = 1;
|
||||
@@ -163,39 +160,28 @@ void script_startup(cell_rt *prt)
|
||||
crt->init_wota = NULL;
|
||||
}
|
||||
|
||||
// Store the core path for scripts to use
|
||||
JSValue js_cell = JS_GetPropertyStr(js, globalThis, "cell");
|
||||
JSValue hidden = JS_GetPropertyStr(js, js_cell, "hidden");
|
||||
size_t archive_size = qop_core.data_size - qop_core.files_offset;
|
||||
JSValue blob = js_new_blob_stoned_copy(js, qop_core.data + qop_core.files_offset, archive_size);
|
||||
JS_SetPropertyStr(js, hidden, "core_qop_blob", blob);
|
||||
if (core_path) {
|
||||
JS_SetPropertyStr(js, hidden, "core_path", JS_NewString(js, core_path));
|
||||
}
|
||||
JS_FreeValue(js, hidden);
|
||||
JS_FreeValue(js, js_cell);
|
||||
|
||||
JS_FreeValue(js, globalThis);
|
||||
|
||||
// Find and load engine.cm from QOP archive
|
||||
qop_file *engine_file = qop_find(&qop_core, ENGINE);
|
||||
if (!engine_file) {
|
||||
printf("ERROR: Could not find file %s in QOP archive!\n", ENGINE);
|
||||
return;
|
||||
}
|
||||
|
||||
char *data = malloc(engine_file->size + 1);
|
||||
// Load engine.cm from the core directory
|
||||
size_t engine_size;
|
||||
char *data = load_core_file(ENGINE, &engine_size);
|
||||
if (!data) {
|
||||
printf("ERROR: Could not allocate memory for %s!\n", ENGINE);
|
||||
printf("ERROR: Could not load %s from %s!\n", ENGINE, core_path);
|
||||
return;
|
||||
}
|
||||
|
||||
int bytes_read = qop_read(&qop_core, engine_file, (unsigned char *)data);
|
||||
if (bytes_read != (int)engine_file->size) {
|
||||
printf("ERROR: Could not read file %s from QOP archive!\n", ENGINE);
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
data[engine_file->size] = 0;
|
||||
|
||||
crt->state = ACTOR_RUNNING;
|
||||
JSValue v = JS_Eval(js, data, (size_t)engine_file->size, ENGINE, 0);
|
||||
JSValue v = JS_Eval(js, data, engine_size, ENGINE, 0);
|
||||
free(data);
|
||||
uncaught_exception(js, v);
|
||||
crt->state = ACTOR_IDLE;
|
||||
set_actor_state(crt);
|
||||
@@ -223,10 +209,9 @@ int cell_init(int argc, char **argv)
|
||||
{
|
||||
int script_start = 1;
|
||||
|
||||
/* Load QOP package attached to executable - this is now mandatory! */
|
||||
int mounted = prosperon_mount_core();
|
||||
if (!mounted) {
|
||||
printf("ERROR: Could not load core QOP package.\n");
|
||||
/* Find the cell shop at ~/.cell */
|
||||
int found = find_cell_shop();
|
||||
if (!found) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user