| @@ -1,10 +1,10 @@ | |||
| appname = cms | |||
| build: | |||
| gcc -o $(appname) src/*.c -std=c99 | |||
| gcc -o3 -o $(appname) src/*.c -std=c99 | |||
| debug: | |||
| gcc -o $(appname) src/*.c -std=c99 -DDEBUG=1 | |||
| gcc -o3 -o $(appname) src/*.c -std=c99 -DDEBUG=1 | |||
| install: | |||
| mv $(appname) /usr/bin/$(appname) | |||
| @@ -0,0 +1,3 @@ | |||
| Example Post | |||
| <p>This post is an example.</p> | |||
| @@ -0,0 +1 @@ | |||
| Example Page | |||
| @@ -1,7 +0,0 @@ | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| @@ -1,8 +0,0 @@ | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| This is placeholder text. | |||
| @@ -0,0 +1,4 @@ | |||
| <article> | |||
| <header> | |||
| <h1>{title}</h1> | |||
| </article> | |||
| @@ -0,0 +1,15 @@ | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <meta charset="utf-8"> | |||
| <link rel="stylesheet" href="/_style.css"> | |||
| <title>{title}</title> | |||
| </head> | |||
| <body> | |||
| {menu} | |||
| <div id="articles"> | |||
| {articles} | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @@ -0,0 +1,8 @@ | |||
| <div class="page"> | |||
| <span class="name"> | |||
| {name} | |||
| </span> | |||
| <div class="sub"> | |||
| {sub} | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,5 @@ | |||
| <header class="menu"> | |||
| <nav class="menu-nav"> | |||
| {pages} | |||
| </nav> | |||
| </header> | |||
| @@ -0,0 +1,92 @@ | |||
| #include "cms_build.h" | |||
| #include "cms_err.h" | |||
| #include "cms_files.h" | |||
| #include "cms_util.h" | |||
| #include "cms_page.h" | |||
| #include "cms_post.h" | |||
| #include <sys/stat.h> | |||
| #include <sys/types.h> | |||
| #include <dirent.h> | |||
| #include <errno.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| cms_err* cms_build_make_tree(cms_page* root, char* path, char* dirname) | |||
| { | |||
| DIR* dp = opendir(path); | |||
| if (dp == NULL) | |||
| return cms_err_from_std_err(errno); | |||
| struct dirent* ep; | |||
| struct stat* st = malloc(sizeof(struct stat)); | |||
| if (st == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| while (ep = readdir(dp)) | |||
| { | |||
| if (ep->d_name[0] == '.') | |||
| continue; | |||
| char* entpath = cms_util_path_join(path, ep->d_name); | |||
| stat(entpath, st); | |||
| //Entry is directory, recurse | |||
| if (S_ISDIR(st->st_mode)) | |||
| { | |||
| cms_page* sub = cms_page_create(); | |||
| if (sub == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| cms_err* err; | |||
| err = cms_build_make_tree(sub, entpath, ep->d_name); | |||
| if (err) | |||
| return err; | |||
| err = cms_page_add_sub(root, sub); | |||
| if (err) | |||
| return err; | |||
| } | |||
| //Entry is the file which contains metadata | |||
| //about a page, parse | |||
| else if (strcmp(ep->d_name, CMS_FILE_PAGE) == 0) | |||
| { | |||
| char* content = cms_util_file_read(entpath); | |||
| if (content == NULL) | |||
| return cms_err_create(CMS_ERR_FILEREAD, entpath); | |||
| cms_err* err = cms_page_parse(root, content, dirname); | |||
| free(content); | |||
| if (err) | |||
| return err; | |||
| } | |||
| //Entry is a post, read it and add to page | |||
| else | |||
| { | |||
| cms_post* post = cms_post_create(); | |||
| char* content = cms_util_file_read(entpath); | |||
| if (content == NULL) | |||
| return cms_err_create(CMS_ERR_FILEREAD, entpath); | |||
| cms_err* err; | |||
| err = cms_post_parse(post, content, ep->d_name); | |||
| free(content); | |||
| if (err) | |||
| return err; | |||
| err = cms_page_add_post(root, post); | |||
| if (err) | |||
| return err; | |||
| } | |||
| free(entpath); | |||
| } | |||
| closedir(dp); | |||
| free(st); | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| @@ -0,0 +1,9 @@ | |||
| #ifndef CMS_BUILD_H | |||
| #define CMS_BUILD_H | |||
| #include "cms_err.h" | |||
| #include "cms_page.h" | |||
| cms_err* cms_build_make_tree(cms_page* root, char* path, char* dirname); | |||
| #endif | |||
| @@ -1,5 +1,6 @@ | |||
| #include "cms_err.h" | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <stdlib.h> | |||
| #include <errno.h> | |||
| @@ -7,9 +8,9 @@ | |||
| #include <error.h> | |||
| #endif | |||
| static char* get_error_message(cms_err err) | |||
| static char* get_error_message(cms_err* err) | |||
| { | |||
| switch (err) | |||
| switch (err->code) | |||
| { | |||
| case CMS_ERR_NONE: | |||
| return ""; | |||
| @@ -27,6 +28,8 @@ static char* get_error_message(cms_err err) | |||
| return "Not a directory."; | |||
| case CMS_ERR_FILEEXISTS: | |||
| return "File exists."; | |||
| case CMS_ERR_FILEREAD: | |||
| return "Failed to read file."; | |||
| case CMS_ERR_DIREXISTS: | |||
| return "Directory exists."; | |||
| case CMS_ERR_PERM: | |||
| @@ -38,24 +41,72 @@ static char* get_error_message(cms_err err) | |||
| } | |||
| } | |||
| void _cms_err_panic(cms_err err, char* msg, const char* file, int line) | |||
| cms_err* _cms_err_create(cms_err_code code, char* msg, const char* file, int line) | |||
| { | |||
| //We want to just return NULL if there is no error | |||
| if (code == CMS_ERR_NONE) | |||
| return NULL; | |||
| cms_err* err = malloc(sizeof(cms_err)); | |||
| if (err == NULL) | |||
| { | |||
| fprintf(stderr, "Failed to allocate memory.\n"); | |||
| exit(1); | |||
| } | |||
| err->code = code; | |||
| if (msg == NULL) | |||
| { | |||
| err->msg = NULL; | |||
| } | |||
| else | |||
| { | |||
| size_t msglen = strlen(msg) + 1; | |||
| err->msg = malloc(msglen * sizeof(char)); | |||
| if (err->msg == NULL) | |||
| { | |||
| fprintf(stderr, "Failed to allocate memory.\n"); | |||
| exit(1); | |||
| } | |||
| memcpy(err->msg, msg, msglen * sizeof(char)); | |||
| } | |||
| err->file = file; | |||
| err->line = line; | |||
| return err; | |||
| } | |||
| void cms_err_free(cms_err* err) | |||
| { | |||
| //The error can be null, in which case, we don't want to do anything | |||
| if (err == NULL) | |||
| return; | |||
| free(err->msg); | |||
| free(err); | |||
| } | |||
| void cms_err_panic(cms_err* err) | |||
| { | |||
| if (!err) | |||
| return; | |||
| #ifdef DEBUG | |||
| fprintf(stderr, "File %s, line %i:\n\t", file, line); | |||
| fprintf(stderr, "File %s, line %i:\n\t", err->file, err->line); | |||
| #endif | |||
| if (msg == NULL) | |||
| if (err->msg == NULL) | |||
| fprintf(stderr, "Error: %s\n", get_error_message(err)); | |||
| else | |||
| fprintf(stderr, "Error: %s: %s\n", msg, get_error_message(err)); | |||
| fprintf(stderr, "Error: %s: %s\n", err->msg, get_error_message(err)); | |||
| exit(1); | |||
| } | |||
| cms_err cms_err_from_std_err(int err) | |||
| cms_err* cms_err_from_std_err(int err) | |||
| { | |||
| #ifdef DEBUG | |||
| error(0, err, "converting to cms_err"); | |||
| @@ -64,22 +115,22 @@ cms_err cms_err_from_std_err(int err) | |||
| switch (err) | |||
| { | |||
| case EACCES: | |||
| return CMS_ERR_PERM; | |||
| return cms_err_create(CMS_ERR_PERM, NULL); | |||
| case EEXIST: | |||
| return CMS_ERR_FILEEXISTS; | |||
| return cms_err_create(CMS_ERR_FILEEXISTS, NULL); | |||
| case EFAULT: | |||
| return CMS_ERR_PERM; | |||
| return cms_err_create(CMS_ERR_PERM, NULL); | |||
| case EISDIR: | |||
| return CMS_ERR_NOTFILE; | |||
| return cms_err_create(CMS_ERR_NOTFILE, NULL); | |||
| case ENOENT: | |||
| return CMS_ERR_NOENT; | |||
| return cms_err_create(CMS_ERR_NOENT, NULL); | |||
| case ENOMEM: | |||
| return CMS_ERR_ALLOC; | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| case ENOTDIR: | |||
| return CMS_ERR_NOTDIR; | |||
| return cms_err_create(CMS_ERR_NOTDIR, NULL); | |||
| case EROFS: | |||
| return CMS_ERR_PERM; | |||
| return cms_err_create(CMS_ERR_PERM, NULL); | |||
| default: | |||
| return CMS_ERR_UNKNOWN; | |||
| return cms_err_create(CMS_ERR_UNKNOWN, NULL); | |||
| } | |||
| } | |||
| @@ -1,9 +1,9 @@ | |||
| #ifndef CMS_ERR_H | |||
| #define CMS_ERR_H | |||
| typedef enum cms_err | |||
| typedef enum cms_err_code | |||
| { | |||
| CMS_ERR_NONE, | |||
| CMS_ERR_NONE = 0, | |||
| CMS_ERR_UNKNOWN, | |||
| CMS_ERR_ALLOC, | |||
| CMS_ERR_PARSE, | |||
| @@ -11,16 +11,30 @@ typedef enum cms_err | |||
| CMS_ERR_NOTFILE, | |||
| CMS_ERR_NOTDIR, | |||
| CMS_ERR_FILEEXISTS, | |||
| CMS_ERR_FILEREAD, | |||
| CMS_ERR_DIREXISTS, | |||
| CMS_ERR_PERM, | |||
| CMS_ERR_INITED, | |||
| CMS_ERR_NOTINITED | |||
| } cms_err_code; | |||
| typedef struct cms_err | |||
| { | |||
| cms_err_code code; | |||
| char* msg; | |||
| const char* file; | |||
| int line; | |||
| } cms_err; | |||
| void _cms_err_panic(cms_err err, char* msg, const char* file, int line); | |||
| #define cms_err_panic(err, msg) _cms_err_panic(err, msg, __FILE__, __LINE__) | |||
| //Create an error. Returns NULL if the error code is CMS_ERR_NONE. | |||
| cms_err* _cms_err_create(cms_err_code code, char* msg, const char* file, int line); | |||
| #define cms_err_create(code, msg) _cms_err_create(code, msg, __FILE__, __LINE__) | |||
| void cms_err_free(cms_err* err); | |||
| void cms_err_panic(cms_err* err); | |||
| cms_err cms_err_from_std_err(int err); | |||
| cms_err* cms_err_from_std_err(int err); | |||
| #endif | |||
| @@ -7,4 +7,11 @@ | |||
| //File which tells us if a directory is already initiated. | |||
| #define CMS_FILE_INITED ".cmsinited" | |||
| //The name of the dir which specifies the title and | |||
| //other metadata of a page | |||
| #define CMS_FILE_PAGE "page" | |||
| //Directory containing the user's resources. | |||
| #define CMS_FILE_ROOT "pages" | |||
| #endif | |||
| @@ -7,28 +7,33 @@ | |||
| #include <sys/types.h> | |||
| #include <errno.h> | |||
| #define PREFIX_LENGTH 5 | |||
| cms_page* cms_page_create() | |||
| { | |||
| cms_page* page = malloc(sizeof(cms_page)); | |||
| if (page == NULL) | |||
| cms_err_panic(CMS_ERR_ALLOC, NULL); | |||
| page->numposts = 0; | |||
| page->numsubs = 0; | |||
| page->posts = NULL; | |||
| page->subs = NULL; | |||
| return page; | |||
| } | |||
| cms_err cms_page_parse(cms_page* page, char* str) | |||
| cms_err* cms_page_parse(cms_page* page, char* str, char* slugstr) | |||
| { | |||
| //Adding 1 because strlen() returns the length without \0 | |||
| size_t len = strlen(str) + 1; | |||
| page->_str = malloc(len * sizeof(char)); | |||
| if (page->_str == 0) | |||
| return CMS_ERR_ALLOC; | |||
| if (page->_str == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| memcpy(page->_str, str, len * sizeof(char)); | |||
| //The page's title will be the first line. | |||
| page->title = page->_str; | |||
| size_t line = 0; | |||
| //Replace newlines with \0 | |||
| for (size_t i = 0; i < len; ++i) | |||
| { | |||
| char c = str[i]; | |||
| @@ -36,45 +41,49 @@ cms_err cms_page_parse(cms_page* page, char* str) | |||
| switch (c) | |||
| { | |||
| case '\n': | |||
| line += 1; | |||
| if (line == 1) | |||
| page->slug = (page->_str + i + 1); | |||
| case '\r': | |||
| page->_str[i] = '\0'; | |||
| break; | |||
| } | |||
| if (line == 2) | |||
| break; | |||
| } | |||
| if (line == 2) | |||
| return CMS_ERR_NONE; | |||
| else | |||
| return CMS_ERR_PARSE; | |||
| //Strip out the leading "xxxx-" from slugstr (the filename) | |||
| //to get the real slug | |||
| size_t slugstrlen = strlen(slugstr); | |||
| page->slug = malloc((slugstrlen + 1 - PREFIX_LENGTH) * sizeof(char)); | |||
| if (page->slug == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| memcpy(page->slug, slugstr + PREFIX_LENGTH, (slugstrlen - PREFIX_LENGTH)); | |||
| //Add \0 to the end of the string | |||
| page->slug[slugstrlen - PREFIX_LENGTH] = '\0'; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| cms_err cms_page_add_post(cms_page* page, cms_post* post) | |||
| cms_err* cms_page_add_post(cms_page* page, cms_post* post) | |||
| { | |||
| page->numposts += 1; | |||
| page->posts = realloc(page->posts, page->numposts * sizeof(cms_post)); | |||
| page->posts = realloc(page->posts, page->numposts * sizeof(cms_post)); | |||
| if (page->posts == NULL) | |||
| return CMS_ERR_ALLOC; | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| page->posts[page->numposts - 1] = *post; | |||
| return CMS_ERR_NONE; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| cms_err cms_page_create_tree(cms_page* root, const char* path) | |||
| cms_err* cms_page_add_sub(cms_page* page, cms_page* sub) | |||
| { | |||
| DIR* dp = opendir(path); | |||
| if (dp == NULL) | |||
| return cms_err_from_std_err(errno); | |||
| page->numsubs += 1; | |||
| page->subs = realloc(page->subs, page->numsubs * sizeof(cms_page)); | |||
| if (page->subs == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| closedir(dp); | |||
| page->subs[page->numsubs - 1] = *sub; | |||
| return CMS_ERR_NONE; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| @@ -1,8 +1,8 @@ | |||
| #ifndef CMS_PAGE_H | |||
| #define CMS_PAGE_H | |||
| #include "cms_post.h" | |||
| #include "cms_err.h" | |||
| #include "cms_post.h" | |||
| #include <stddef.h> | |||
| typedef struct cms_page | |||
| @@ -12,24 +12,16 @@ typedef struct cms_page | |||
| char* slug; | |||
| cms_post* posts; | |||
| size_t numposts; | |||
| struct cms_page* subs; | |||
| size_t numsubs; | |||
| } cms_page; | |||
| cms_page* cms_page_create(); | |||
| // 1: allloc error | |||
| // 2: parse error | |||
| // 3: unknown | |||
| cms_err cms_page_parse(cms_page* page, char* str); | |||
| cms_err* cms_page_parse(cms_page* page, char* str, char* slugstr); | |||
| //1: alloc error | |||
| //2: unknown | |||
| cms_err cms_page_add_post(cms_page* page, cms_post* post); | |||
| cms_err* cms_page_add_post(cms_page* page, cms_post* post); | |||
| //1: alloc error | |||
| //2: permission denied | |||
| //3: dir doesn't exist | |||
| //4: not a directory | |||
| //5: unknown | |||
| cms_err cms_page_create_tree(cms_page* root, const char* path); | |||
| cms_err* cms_page_add_sub(cms_page* page, cms_page* sub); | |||
| #endif | |||
| @@ -1,22 +1,29 @@ | |||
| #include "cms_post.h" | |||
| #include "cms_err.h" | |||
| #include <stdlib.h> | |||
| #include <stddef.h> | |||
| #include <string.h> | |||
| #define PREFIX_LENGTH 5 | |||
| cms_post* cms_post_create() | |||
| { | |||
| cms_post* post = malloc(sizeof(cms_post)); | |||
| return post; | |||
| } | |||
| int cms_post_parse(cms_post* post, char* str) | |||
| cms_err* cms_post_parse(cms_post* post, char* str, char* slugstr) | |||
| { | |||
| //Adding 1 because strlen() returns the length without \0 | |||
| size_t len = strlen(str) + 1; | |||
| post->_str = malloc(len * sizeof(char)); | |||
| if (post->_str == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| memcpy(post->_str, str, len * sizeof(char)); | |||
| //The post's title will be the first line. | |||
| post->title = post->_str; | |||
| size_t line = 0; | |||
| @@ -28,22 +35,36 @@ int cms_post_parse(cms_post* post, char* str) | |||
| { | |||
| case '\n': | |||
| line += 1; | |||
| if (line == 1) | |||
| post->slug = (post->_str + i + 1); | |||
| else if (line == 2) | |||
| post->markdown = (post->_str + i + 1); | |||
| if (line == 2) | |||
| { | |||
| post->html = (post->_str + i + 1); | |||
| } | |||
| //falls through | |||
| case '\r': | |||
| post->_str[i] = '\0'; | |||
| break; | |||
| } | |||
| if (line == 3) | |||
| if (line == 2) | |||
| break; | |||
| } | |||
| if (line == 3) | |||
| return 0; | |||
| //Strip out the leading "xxxx-" from slugstr (the filename) | |||
| //to get the real slug | |||
| size_t slugstrlen = strlen(slugstr); | |||
| post->slug = malloc((slugstrlen + 1 - PREFIX_LENGTH) * sizeof(char)); | |||
| if (post->slug == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| memcpy(post->slug, slugstr + PREFIX_LENGTH, (slugstrlen - PREFIX_LENGTH)); | |||
| //Add \0 to the end of the string | |||
| post->slug[slugstrlen - PREFIX_LENGTH] = '\0'; | |||
| if (line >= 2) | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| else | |||
| return 1; | |||
| return cms_err_create(CMS_ERR_PARSE, slugstr); | |||
| } | |||
| @@ -1,16 +1,18 @@ | |||
| #ifndef CMS_POST_H | |||
| #define CMS_POST_H | |||
| #include "cms_err.h" | |||
| typedef struct cms_post | |||
| { | |||
| char* _str; | |||
| char* title; | |||
| char* slug; | |||
| char* markdown; | |||
| char* html; | |||
| } cms_post; | |||
| cms_post* cms_post_create(); | |||
| int cms_post_parse(cms_post* post, char* str); | |||
| cms_err* cms_post_parse(cms_post* post, char* str, char* slugstr); | |||
| #endif | |||
| @@ -1,3 +1,5 @@ | |||
| #include "cms_util.h" | |||
| #include "cms_err.h" | |||
| #include <fcntl.h> | |||
| #include <unistd.h> | |||
| #include <stdio.h> | |||
| @@ -9,8 +11,6 @@ | |||
| #include <sys/types.h> | |||
| #include <errno.h> | |||
| #include "cms_util.h" | |||
| int cms_util_file_exists(char* fname) | |||
| { | |||
| int f = open(fname, O_RDONLY); | |||
| @@ -26,7 +26,7 @@ int cms_util_file_exists(char* fname) | |||
| return 1; | |||
| } | |||
| cms_err cms_util_file_create(char* fname) | |||
| cms_err* cms_util_file_create(char* fname) | |||
| { | |||
| int f = open(fname, O_CREAT, 0777); | |||
| close(f); | |||
| @@ -34,10 +34,10 @@ cms_err cms_util_file_create(char* fname) | |||
| if (f == -1) | |||
| return cms_err_from_std_err(errno); | |||
| else | |||
| return CMS_ERR_NONE; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| cms_err cms_util_file_copy(char* fname1, char* fname2) | |||
| cms_err* cms_util_file_copy(char* fname1, char* fname2) | |||
| { | |||
| int f1 = open(fname1, O_RDONLY); | |||
| if (f1 == -1) | |||
| @@ -47,29 +47,54 @@ cms_err cms_util_file_copy(char* fname1, char* fname2) | |||
| if (f1 == -1) | |||
| return cms_err_from_std_err(errno); | |||
| struct stat* s = malloc(sizeof(struct stat)); | |||
| if (s == NULL) | |||
| return CMS_ERR_ALLOC; | |||
| struct stat* st = malloc(sizeof(struct stat)); | |||
| if (st == NULL) | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| fstat(f1, s); | |||
| fstat(f1, st); | |||
| void* buf = malloc(s->st_size); | |||
| void* buf = malloc(st->st_size); | |||
| if (buf == NULL) | |||
| return CMS_ERR_ALLOC; | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| read(f1, buf, s->st_size); | |||
| write(f2, buf, s->st_size); | |||
| read(f1, buf, st->st_size); | |||
| write(f2, buf, st->st_size); | |||
| close(f1); | |||
| close(f2); | |||
| free(s); | |||
| free(st); | |||
| free(buf); | |||
| return CMS_ERR_NONE; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| char* cms_util_file_read(char* fname) | |||
| { | |||
| int file = open(fname, O_RDONLY); | |||
| if (file == -1) | |||
| return NULL; | |||
| struct stat* st = malloc(sizeof(struct stat)); | |||
| if (st == NULL) | |||
| return NULL; | |||
| fstat(file, st); | |||
| char* buf = malloc(st->st_size + 1); | |||
| if (buf == NULL) | |||
| return NULL; | |||
| read(file, buf, st->st_size + 1); | |||
| buf[st->st_size] = '\0'; | |||
| close(file); | |||
| free(st); | |||
| return buf; | |||
| } | |||
| cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| cms_err* cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| { | |||
| if (mkdir(dir2, 0777) == -1 && errno != EEXIST) | |||
| return cms_err_from_std_err(errno); | |||
| @@ -82,7 +107,7 @@ cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| struct stat* st = malloc(sizeof(struct stat)); | |||
| if (st == NULL) | |||
| return CMS_ERR_ALLOC; | |||
| return cms_err_create(CMS_ERR_ALLOC, NULL); | |||
| while (ep = readdir(dp)) | |||
| { | |||
| @@ -97,13 +122,17 @@ cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| if (S_ISDIR(st->st_mode)) | |||
| { | |||
| cms_err err = cms_util_dir_copy_recursive(path1, path2); | |||
| cms_err* err = cms_util_dir_copy_recursive(path1, path2); | |||
| free(path1); | |||
| free(path2); | |||
| if (err) | |||
| return err; | |||
| } | |||
| else | |||
| { | |||
| cms_err err = cms_util_file_copy(path1, path2); | |||
| cms_err* err = cms_util_file_copy(path1, path2); | |||
| free(path1); | |||
| free(path2); | |||
| if (err) | |||
| return err; | |||
| } | |||
| @@ -112,7 +141,7 @@ cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||
| closedir(dp); | |||
| free(st); | |||
| return CMS_ERR_NONE; | |||
| return cms_err_create(CMS_ERR_NONE, NULL); | |||
| } | |||
| char* cms_util_path_join(char* str1, char* str2) | |||
| @@ -125,9 +154,9 @@ char* cms_util_path_join(char* str1, char* str2) | |||
| len1 -= 1; | |||
| } | |||
| char* path = malloc((len1 + len2 + 1) * sizeof(char)); | |||
| char* path = malloc((len1 + len2 + 2) * sizeof(char)); | |||
| if (path == NULL) | |||
| cms_err_panic(CMS_ERR_ALLOC, ""); | |||
| cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); | |||
| if (path == NULL) | |||
| return NULL; | |||
| @@ -7,13 +7,16 @@ | |||
| int cms_util_file_exists(char* fname); | |||
| //Create a file | |||
| cms_err cms_util_file_create(char* fname); | |||
| cms_err* cms_util_file_create(char* fname); | |||
| //Copy a file | |||
| cms_err cms_util_file_copy(char* fname1, char* fname2); | |||
| cms_err* cms_util_file_copy(char* fname1, char* fname2); | |||
| //Read a file into a string | |||
| char* cms_util_file_read(char* fname); | |||
| //Recursively copy a directory | |||
| cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2); | |||
| cms_err* cms_util_dir_copy_recursive(char* dir1, char* dir2); | |||
| //Join together two paths | |||
| char* cms_util_path_join(char* str1, char* str2); | |||
| @@ -1,15 +1,18 @@ | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <stdlib.h> | |||
| #include "cms_util.h" | |||
| #include "cms_err.h" | |||
| #include "cms_files.h" | |||
| #include "cms_page.h" | |||
| #include "cms_build.h" | |||
| int main(int argc, char** argv) | |||
| { | |||
| if (argc < 2) | |||
| { | |||
| fprintf(stderr, "Usage: %s <init|deinit|build>\n", argv[0]); | |||
| fprintf(stderr, "Usage: %s <init|build>\n", argv[0]); | |||
| return 1; | |||
| } | |||
| @@ -27,21 +30,23 @@ int main(int argc, char** argv) | |||
| //Get the path of .cmsinited, which tells us | |||
| //whether or not the directory is already inited | |||
| char* initedPath = cms_util_path_join(dirname, CMS_FILE_INITED); | |||
| if (initedPath == NULL) | |||
| cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); | |||
| //Panic if the directory is already initiated | |||
| if (cms_util_file_exists(initedPath)) | |||
| cms_err_panic(CMS_ERR_INITED, NULL); | |||
| cms_err_panic(cms_err_create(CMS_ERR_INITED, NULL)); | |||
| //Copy files from resources | |||
| cms_err err; | |||
| cms_err* err; | |||
| err = cms_util_dir_copy_recursive(CMS_FILE_RESOURCES, dirname); | |||
| if (err) | |||
| cms_err_panic(err, dirname); | |||
| cms_err_panic(err); | |||
| //Create .cmsinited file | |||
| err = cms_util_file_create(initedPath); | |||
| if (err) | |||
| cms_err_panic(err, initedPath); | |||
| cms_err_panic(err); | |||
| } | |||
| //Build | |||
| @@ -61,6 +66,28 @@ int main(int argc, char** argv) | |||
| //Panic if the directory isn't initiated | |||
| if (!cms_util_file_exists(initedPath)) | |||
| cms_err_panic(CMS_ERR_NOTINITED, NULL); | |||
| cms_err_panic(cms_err_create(CMS_ERR_NOTINITED, NULL)); | |||
| cms_page* root = cms_page_create(); | |||
| if (root == NULL) | |||
| cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); | |||
| char* path = cms_util_path_join(dirname, CMS_FILE_ROOT); | |||
| if (path == NULL) | |||
| cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); | |||
| //Build tree of pages and posts | |||
| cms_err* err; | |||
| err = cms_build_make_tree(root, path, NULL); | |||
| free(path); | |||
| if (err) | |||
| cms_err_panic(err); | |||
| } | |||
| //Nothing, print usage | |||
| else | |||
| { | |||
| fprintf(stderr, "Usage: %s <init|build>\n", argv[0]); | |||
| return 1; | |||
| } | |||
| } | |||