diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 609 |
1 files changed, 0 insertions, 609 deletions
@@ -1,609 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <sys/stat.h> -#include <errno.h> -#include <unistd.h> - -#define MAX_PATH 1024 -#define MAX_CONTENT 65536 -#define MAX_LOCALES 10 -#define MAX_LOCALE_ENTRIES 100 - -typedef struct { - char key[256]; - char value[1024]; -} LocaleEntry; - -typedef struct { - char code[8]; - LocaleEntry entries[MAX_LOCALE_ENTRIES]; - int count; -} Locale; - -typedef struct { - Locale locales[MAX_LOCALES]; - int count; - int has_locales; -} LocaleData; - -// Safe string copy -void safe_strcpy(char *dest, const char *src, size_t dest_size) { - if (!dest || !src || dest_size == 0) return; - strncpy(dest, src, dest_size - 1); - dest[dest_size - 1] = '\0'; -} - -// Utility functions -int create_directory(const char *path) { - if (!path) return -1; - - char tmp[MAX_PATH]; - char *p = NULL; - size_t len; - - safe_strcpy(tmp, path, sizeof(tmp)); - len = strlen(tmp); - if (len > 0 && tmp[len - 1] == '/') - tmp[len - 1] = 0; - - for (p = tmp + 1; *p; p++) { - if (*p == '/') { - *p = 0; - if (mkdir(tmp, 0755) != 0 && errno != EEXIST) { - return -1; - } - *p = '/'; - } - } - if (mkdir(tmp, 0755) != 0 && errno != EEXIST) { - return -1; - } - return 0; -} - -int copy_file(const char *src, const char *dest) { - if (!src || !dest) return -1; - - FILE *source = fopen(src, "rb"); - if (!source) { - printf("Warning: Could not open source file: %s\n", src); - return -1; - } - - // Create directory for destination file - char dest_dir[MAX_PATH]; - safe_strcpy(dest_dir, dest, sizeof(dest_dir)); - char *last_slash = strrchr(dest_dir, '/'); - if (last_slash) { - *last_slash = '\0'; - create_directory(dest_dir); - } - - FILE *target = fopen(dest, "wb"); - if (!target) { - printf("Warning: Could not create destination file: %s\n", dest); - fclose(source); - return -1; - } - - char buffer[4096]; - size_t bytes; - while ((bytes = fread(buffer, 1, sizeof(buffer), source)) > 0) { - fwrite(buffer, 1, bytes, target); - } - - fclose(source); - fclose(target); - return 0; -} - -int copy_directory_recursive(const char *src, const char *dest) { - if (!src || !dest) return -1; - - DIR *dir = opendir(src); - if (!dir) { - printf("Warning: Could not open directory: %s\n", src); - return -1; - } - - if (create_directory(dest) != 0) { - printf("Warning: Could not create directory: %s\n", dest); - closedir(dir); - return -1; - } - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - - char src_path[MAX_PATH]; - char dest_path[MAX_PATH]; - snprintf(src_path, sizeof(src_path), "%s/%s", src, entry->d_name); - snprintf(dest_path, sizeof(dest_path), "%s/%s", dest, entry->d_name); - - struct stat statbuf; - if (stat(src_path, &statbuf) == 0) { - if (S_ISDIR(statbuf.st_mode)) { - copy_directory_recursive(src_path, dest_path); - } else { - copy_file(src_path, dest_path); - } - } - } - - closedir(dir); - return 0; -} - -int load_locale_file(const char *filepath, Locale *locale) { - if (!filepath || !locale) return -1; - - FILE *file = fopen(filepath, "r"); - if (!file) { - printf("Warning: Could not open locale file: %s\n", filepath); - return -1; - } - - fseek(file, 0, SEEK_END); - long length = ftell(file); - fseek(file, 0, SEEK_SET); - - if (length <= 0 || length > 100000) { - printf("Warning: Invalid file size for locale: %s\n", filepath); - fclose(file); - return -1; - } - - char *content = malloc(length + 1); - if (!content) { - printf("Error: Memory allocation failed\n"); - fclose(file); - return -1; - } - - size_t read_bytes = fread(content, 1, length, file); - content[read_bytes] = '\0'; - fclose(file); - - // Simple JSON parsing - extract key-value pairs - locale->count = 0; - char *pos = content; - - while (*pos && locale->count < MAX_LOCALE_ENTRIES) { - // Find opening quote for key - char *quote1 = strchr(pos, '"'); - if (!quote1) break; - quote1++; - - // Find closing quote for key - char *quote2 = strchr(quote1, '"'); - if (!quote2) break; - - size_t key_len = quote2 - quote1; - if (key_len >= sizeof(locale->entries[0].key) || key_len == 0) { - pos = quote2 + 1; - continue; - } - - // Copy key - strncpy(locale->entries[locale->count].key, quote1, key_len); - locale->entries[locale->count].key[key_len] = '\0'; - - // Find colon - char *colon = strchr(quote2, ':'); - if (!colon) { - pos = quote2 + 1; - continue; - } - - // Find opening quote for value - char *quote3 = strchr(colon, '"'); - if (!quote3) { - pos = quote2 + 1; - continue; - } - quote3++; - - // Find closing quote for value - char *quote4 = strchr(quote3, '"'); - if (!quote4) { - pos = quote3; - continue; - } - - size_t value_len = quote4 - quote3; - if (value_len >= sizeof(locale->entries[0].value)) { - pos = quote4 + 1; - continue; - } - - // Copy value - strncpy(locale->entries[locale->count].value, quote3, value_len); - locale->entries[locale->count].value[value_len] = '\0'; - - locale->count++; - pos = quote4 + 1; - } - - free(content); - printf("Loaded locale with %d entries from %s\n", locale->count, filepath); - return 0; -} - -int load_locales(LocaleData *locale_data) { - if (!locale_data) return -1; - - locale_data->has_locales = 0; - locale_data->count = 0; - - DIR *dir = opendir("locale"); - if (!dir) { - printf("No locale directory found\n"); - return 0; - } - - locale_data->has_locales = 1; - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL && locale_data->count < MAX_LOCALES) { - if (strstr(entry->d_name, ".json")) { - char filepath[MAX_PATH]; - snprintf(filepath, sizeof(filepath), "locale/%s", entry->d_name); - - // Extract locale code from filename - char locale_code[256]; - safe_strcpy(locale_code, entry->d_name, sizeof(locale_code)); - char *dot = strrchr(locale_code, '.'); - if (dot) *dot = '\0'; - - if (strlen(locale_code) < sizeof(locale_data->locales[0].code)) { - safe_strcpy(locale_data->locales[locale_data->count].code, locale_code, - sizeof(locale_data->locales[locale_data->count].code)); - - if (load_locale_file(filepath, &locale_data->locales[locale_data->count]) == 0) { - locale_data->count++; - } - } - } - } - - closedir(dir); - return 0; -} - -char* get_locale_value(const Locale *locale, const char *key) { - if (!locale || !key) return NULL; - - for (int i = 0; i < locale->count; i++) { - if (strcmp(locale->entries[i].key, key) == 0) { - return locale->entries[i].value; - } - } - return NULL; -} - -char* load_file(const char *path) { - if (!path) return NULL; - - FILE *file = fopen(path, "r"); - if (!file) return NULL; - - fseek(file, 0, SEEK_END); - long length = ftell(file); - fseek(file, 0, SEEK_SET); - - if (length <= 0 || length > MAX_CONTENT) { - fclose(file); - return NULL; - } - - char *content = malloc(length + 1); - if (!content) { - fclose(file); - return NULL; - } - - size_t read_bytes = fread(content, 1, length, file); - content[read_bytes] = '\0'; - fclose(file); - - return content; -} - -char* load_partial(const char *name) { - if (!name) return NULL; - - char path[MAX_PATH]; - snprintf(path, sizeof(path), "src/partials/%s.html", name); - return load_file(path); -} - -char* process_template(const char *content, const Locale *locale) { - if (!content) return NULL; - - size_t content_len = strlen(content); - char *result = malloc(MAX_CONTENT); - if (!result) return NULL; - - char *output = result; - const char *input = content; - size_t remaining = MAX_CONTENT - 1; - - while (*input && remaining > 1) { - if (strncmp(input, "<!-- %include.", 14) == 0) { - // Handle includes - input += 14; - const char *end = strstr(input, "% -->"); - if (end) { - size_t name_len = end - input; - if (name_len < 255) { - char partial_name[256]; - strncpy(partial_name, input, name_len); - partial_name[name_len] = '\0'; - - char *partial_content = load_partial(partial_name); - if (partial_content) { - char *processed_partial = process_template(partial_content, locale); - if (processed_partial) { - size_t partial_len = strlen(processed_partial); - if (partial_len < remaining) { - strcpy(output, processed_partial); - output += partial_len; - remaining -= partial_len; - } - free(processed_partial); - } - free(partial_content); - } - } - input = end + 5; - } else { - *output++ = *input++; - remaining--; - } - } else if (strncmp(input, "%locale.", 8) == 0) { - // Handle locale variables - input += 8; - const char *end = strchr(input, '%'); - if (end && locale) { - size_t key_len = end - input; - if (key_len < 255) { - char key[256]; - strncpy(key, input, key_len); - key[key_len] = '\0'; - - char *value = get_locale_value(locale, key); - if (value) { - size_t value_len = strlen(value); - if (value_len < remaining) { - strcpy(output, value); - output += value_len; - remaining -= value_len; - } - } - } - input = end + 1; - } else { - *output++ = *input++; - remaining--; - } - } else { - *output++ = *input++; - remaining--; - } - } - - *output = '\0'; - return result; -} - -int process_pages_directory(const char *src_dir, const char *build_dir, - const char *relative_path, const LocaleData *locale_data) { - if (!src_dir || !build_dir || !relative_path || !locale_data) return -1; - - char full_src_path[MAX_PATH]; - if (strlen(relative_path) > 0) { - snprintf(full_src_path, sizeof(full_src_path), "%s/%s", src_dir, relative_path); - } else { - safe_strcpy(full_src_path, src_dir, sizeof(full_src_path)); - } - - DIR *dir = opendir(full_src_path); - if (!dir) { - printf("Warning: Could not open pages directory: %s\n", full_src_path); - return -1; - } - - struct dirent *entry; - while ((entry = readdir(dir)) != NULL) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - - char src_path[MAX_PATH]; - char rel_path[MAX_PATH]; - - snprintf(src_path, sizeof(src_path), "%s/%s", full_src_path, entry->d_name); - - if (strlen(relative_path) > 0) { - snprintf(rel_path, sizeof(rel_path), "%s/%s", relative_path, entry->d_name); - } else { - safe_strcpy(rel_path, entry->d_name, sizeof(rel_path)); - } - - struct stat statbuf; - if (stat(src_path, &statbuf) == 0) { - if (S_ISDIR(statbuf.st_mode)) { - process_pages_directory(src_dir, build_dir, rel_path, locale_data); - } else if (strstr(entry->d_name, ".html")) { - printf("Processing: %s\n", rel_path); - - char *content = load_file(src_path); - if (!content) { - printf("Warning: Could not load file: %s\n", src_path); - continue; - } - - if (locale_data->has_locales && locale_data->count > 0) { - for (int i = 0; i < locale_data->count; i++) { - char output_path[MAX_PATH]; - snprintf(output_path, sizeof(output_path), "%s/%s/%s", - build_dir, locale_data->locales[i].code, rel_path); - - // Create directory structure - char output_dir[MAX_PATH]; - safe_strcpy(output_dir, output_path, sizeof(output_dir)); - char *last_slash = strrchr(output_dir, '/'); - if (last_slash) { - *last_slash = '\0'; - create_directory(output_dir); - } - - char *processed = process_template(content, &locale_data->locales[i]); - if (processed) { - FILE *output_file = fopen(output_path, "w"); - if (output_file) { - fputs(processed, output_file); - fclose(output_file); - } else { - printf("Warning: Could not write file: %s\n", output_path); - } - free(processed); - } - } - } else { - char output_path[MAX_PATH]; - snprintf(output_path, sizeof(output_path), "%s/%s", build_dir, rel_path); - - // Create directory structure - char output_dir[MAX_PATH]; - safe_strcpy(output_dir, output_path, sizeof(output_dir)); - char *last_slash = strrchr(output_dir, '/'); - if (last_slash) { - *last_slash = '\0'; - create_directory(output_dir); - } - - char *processed = process_template(content, NULL); - if (processed) { - FILE *output_file = fopen(output_path, "w"); - if (output_file) { - fputs(processed, output_file); - fclose(output_file); - } else { - printf("Warning: Could not write file: %s\n", output_path); - } - free(processed); - } - } - - free(content); - } - } - } - - closedir(dir); - return 0; -} - -int main(int argc, char *argv[]) { - if (argc != 2 || strcmp(argv[1], "build") != 0) { - printf("Usage: %s build\nDocs: %s help\n", argv[0], argv[0]); - return 1; - } - - printf("Building Jelly CMS...\n"); - - // Create build directory - if (create_directory("build") != 0) { - printf("Error: Could not create build directory\n"); - return 1; - } - - // Copy vendor directory - if (access("vendor", F_OK) == 0) { - printf("Copying vendor directory...\n"); - copy_directory_recursive("vendor", "build/vendor"); - } else { - printf("No vendor directory found\n"); - } - - // Copy cgi directory - if (access("src/cgi", F_OK) == 0) { - printf("Copying cgi directory...\n"); - copy_directory_recursive("src/cgi", "build/cgi"); - } else { - printf("No cgi directory found\n"); - } - - // Copy public directory contents - if (access("public", F_OK) == 0) { - printf("Copying public directory...\n"); - DIR *public_dir = opendir("public"); - if (public_dir) { - struct dirent *entry; - while ((entry = readdir(public_dir)) != NULL) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - - char src_path[MAX_PATH]; - char dest_path[MAX_PATH]; - snprintf(src_path, sizeof(src_path), "public/%s", entry->d_name); - snprintf(dest_path, sizeof(dest_path), "build/%s", entry->d_name); - - struct stat statbuf; - if (stat(src_path, &statbuf) == 0) { - if (S_ISDIR(statbuf.st_mode)) { - copy_directory_recursive(src_path, dest_path); - } else { - copy_file(src_path, dest_path); - } - } - } - closedir(public_dir); - } - } else { - printf("No public directory found\n"); - } - - // Copy assets directory - if (access("assets", F_OK) == 0) { - printf("Copying assets directory...\n"); - copy_directory_recursive("assets", "build/assets"); - } else { - printf("No assets directory found\n"); - } - - // Load locales - LocaleData locale_data; - if (load_locales(&locale_data) != 0) { - printf("Error loading locales\n"); - return 1; - } - - if (locale_data.has_locales && locale_data.count > 0) { - printf("Found %d locales: ", locale_data.count); - for (int i = 0; i < locale_data.count; i++) { - printf("%s ", locale_data.locales[i].code); - } - printf("\n"); - } else { - printf("No locales found, building single language version\n"); - } - - // Process pages - if (access("src/pages", F_OK) == 0) { - printf("Processing pages...\n"); - if (process_pages_directory("src/pages", "build", "", &locale_data) != 0) { - printf("Error processing pages\n"); - return 1; - } - } else { - printf("No src/pages directory found\n"); - } - - printf("Build completed successfully!\n"); - return 0; -}
\ No newline at end of file |
