#include "cms_err.h" | |||||
#include <stdio.h> | |||||
#include <unistd.h> | |||||
static char* get_message(cms_err err) | |||||
{ | |||||
switch (err) | |||||
{ | |||||
case CMS_ERR_NONE: | |||||
return ""; | |||||
case CMS_ERR_UNKNOWN: | |||||
return "Unknown error."; | |||||
case CMS_ERR_MEMORY: | |||||
return "Memory allocation failed."; | |||||
case CMS_ERR_PARSE: | |||||
return "Parse error."; | |||||
case CMS_ERR_FILENOENT: | |||||
return "File doesn't exist."; | |||||
case CMS_ERR_DIRNOENT: | |||||
return "Directory doesn't exist."; | |||||
case CMS_ERR_NOTFILE: | |||||
return "Not a file."; | |||||
case CMS_ERR_NOTDIR: | |||||
return "Not a directory."; | |||||
case CMS_ERR_PERM: | |||||
return "Permission denied."; | |||||
} | |||||
} | |||||
void cms_err_panic(cms_err err, char* msg) | |||||
{ | |||||
if (err == CMS_ERR_NONE) | |||||
return; | |||||
if (msg == NULL) | |||||
printf("Error: %s\n", get_message(err)); | |||||
else | |||||
printf("Error: %s (%s)\n", get_message(err), msg); | |||||
exit(1); | |||||
} |
#include "cms_err.h" | |||||
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include <errno.h> | |||||
static char* get_message(cms_err err) | |||||
{ | |||||
switch (err) | |||||
{ | |||||
case CMS_ERR_NONE: | |||||
return ""; | |||||
case CMS_ERR_UNKNOWN: | |||||
return "Unknown error."; | |||||
case CMS_ERR_ALLOC: | |||||
return "Memory allocation failed."; | |||||
case CMS_ERR_PARSE: | |||||
return "Parse error."; | |||||
case CMS_ERR_FILENOENT: | |||||
return "File doesn't exist."; | |||||
case CMS_ERR_DIRNOENT: | |||||
return "Directory doesn't exist."; | |||||
case CMS_ERR_NOTFILE: | |||||
return "Not a file."; | |||||
case CMS_ERR_NOTDIR: | |||||
return "Not a directory."; | |||||
case CMS_ERR_PERM: | |||||
return "Permission denied."; | |||||
case CMS_ERR_INITED: | |||||
return "Already initiated."; | |||||
case CMS_ERR_NOTINITED: | |||||
return "Not initiated."; | |||||
} | |||||
} | |||||
void cms_err_panic(cms_err err, char* msg) | |||||
{ | |||||
if (err == CMS_ERR_NONE) | |||||
return; | |||||
if (msg == NULL) | |||||
fprintf(stderr, "Error: %s\n", get_message(err)); | |||||
else | |||||
fprintf(stderr, "Error: %s (%s)\n", get_message(err), msg); | |||||
exit(1); | |||||
} | |||||
cms_err cms_err_from_std_err(int err) | |||||
{ | |||||
switch (err) | |||||
{ | |||||
case EACCES: | |||||
return CMS_ERR_PERM; | |||||
case EEXIST: | |||||
return CMS_ERR_FILEEXISTS; | |||||
case EFAULT: | |||||
return CMS_ERR_PERM; | |||||
case EISDIR: | |||||
return CMS_ERR_NOTFILE; | |||||
case ENOENT: | |||||
return CMS_ERR_FILENOENT; | |||||
case ENOMEM: | |||||
return CMS_ERR_ALLOC; | |||||
case ENOTDIR: | |||||
return CMS_ERR_NOTDIR; | |||||
case EROFS: | |||||
return CMS_ERR_PERM; | |||||
default: | |||||
return CMS_ERR_UNKNOWN; | |||||
} | |||||
} |
#ifndef CMS_ERR_H | |||||
#define CMS_ERR_H | |||||
typedef enum cms_err | |||||
{ | |||||
CMS_ERR_NONE, | |||||
CMS_ERR_UNKNOWN, | |||||
CMS_ERR_ALLOC, | |||||
CMS_ERR_PARSE, | |||||
CMS_ERR_FILENOENT, | |||||
CMS_ERR_DIRNOENT, | |||||
CMS_ERR_NOTFILE, | |||||
CMS_ERR_NOTDIR, | |||||
CMS_ERR_FILEEXISTS, | |||||
CMS_ERR_DIREXISTS, | |||||
CMS_ERR_PERM, | |||||
CMS_ERR_INITED, | |||||
CMS_ERR_NOTINITED | |||||
} cms_err; | |||||
void cms_err_panic(cms_err err, char* msg); | |||||
cms_err cms_err_from_std_err(int err); | |||||
#endif |
#include <stdio.h> | |||||
#include <stdlib.h> | |||||
#include "cms_log.h" | |||||
void cms_log_panic(char* msg) | |||||
{ | |||||
fprintf(stderr, "Fatal error: %s\n", msg); | |||||
exit(1); | |||||
} | |||||
void cms_log_error(char* msg) | |||||
{ | |||||
fprintf(stderr, "Error: %s\n", msg); | |||||
exit(1); | |||||
} |
#ifndef CMS_LOG_H | |||||
#define CMS_LOG_H | |||||
//Panic and halt execution. | |||||
void cms_log_panic(char* msg); | |||||
//Halt execution. | |||||
void cms_log_error(char* msg); | |||||
#endif |
#include "cms_page.h" | #include "cms_page.h" | ||||
#include "cms_err.h" | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <string.h> | #include <string.h> | ||||
cms_page* cms_page_create() | cms_page* cms_page_create() | ||||
{ | { | ||||
cms_page* page = malloc(sizeof(cms_page)); | cms_page* page = malloc(sizeof(cms_page)); | ||||
if (page == NULL) | |||||
cms_err_panic(CMS_ERR_ALLOC, NULL); | |||||
return page; | return page; | ||||
} | } | ||||
int cms_page_parse(cms_page* page, char* str) | |||||
cms_err cms_page_parse(cms_page* page, char* str) | |||||
{ | { | ||||
size_t len = strlen(str) + 1; | size_t len = strlen(str) + 1; | ||||
page->_str = malloc(len * sizeof(char)); | page->_str = malloc(len * sizeof(char)); | ||||
if (page->_str == 0) | if (page->_str == 0) | ||||
return 1; //alloc error | |||||
return CMS_ERR_ALLOC; | |||||
memcpy(page->_str, str, len * sizeof(char)); | memcpy(page->_str, str, len * sizeof(char)); | ||||
} | } | ||||
if (line == 2) | if (line == 2) | ||||
return 0; | |||||
return CMS_ERR_NONE; | |||||
else | else | ||||
return 1; //parse error | |||||
return CMS_ERR_PARSE; | |||||
} | } | ||||
int 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->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 == 0) | |||||
return 1; //alloc error | |||||
if (page->posts == NULL) | |||||
return CMS_ERR_ALLOC; | |||||
page->posts[page->numposts - 1] = *post; | page->posts[page->numposts - 1] = *post; | ||||
return CMS_ERR_NONE; | |||||
} | } | ||||
int cms_page_create_tree(cms_page* root, const char* path) | |||||
cms_err cms_page_create_tree(cms_page* root, const char* path) | |||||
{ | { | ||||
DIR* dp = opendir(path); | DIR* dp = opendir(path); | ||||
if (dp == NULL) | if (dp == NULL) | ||||
{ | |||||
switch (errno) | |||||
{ | |||||
case ENOMEM: | |||||
return 1; | |||||
case EACCES: | |||||
return 2; | |||||
case ENOENT: | |||||
return 3; | |||||
case ENOTDIR: | |||||
return 4; | |||||
default: | |||||
return 5; | |||||
} | |||||
} | |||||
return cms_err_from_std_err(errno); | |||||
closedir(dp); | |||||
return CMS_ERR_NONE; | |||||
} | } |
#define CMS_PAGE_H | #define CMS_PAGE_H | ||||
#include "cms_post.h" | #include "cms_post.h" | ||||
#include "cms_err.h" | |||||
#include <stddef.h> | #include <stddef.h> | ||||
typedef struct cms_page | typedef struct cms_page | ||||
// 1: allloc error | // 1: allloc error | ||||
// 2: parse error | // 2: parse error | ||||
// 3: unknown | // 3: unknown | ||||
int cms_page_parse(cms_page* page, char* str); | |||||
cms_err cms_page_parse(cms_page* page, char* str); | |||||
//1: alloc error | //1: alloc error | ||||
//2: unknown | //2: unknown | ||||
int 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 | //1: alloc error | ||||
//2: permission denied | //2: permission denied | ||||
//3: dir doesn't exist | //3: dir doesn't exist | ||||
//4: not a directory | //4: not a directory | ||||
//5: unknown | //5: unknown | ||||
int cms_page_create_tree(cms_page* root, const char* path); | |||||
cms_err cms_page_create_tree(cms_page* root, const char* path); | |||||
#endif | #endif |
{ | { | ||||
int f = open(fname, O_RDONLY); | int f = open(fname, O_RDONLY); | ||||
close(f); | |||||
if (errno == ENOENT) | if (errno == ENOENT) | ||||
return 0; | return 0; | ||||
else | else | ||||
return 1; | return 1; | ||||
close(f); | |||||
} | } | ||||
void cms_util_file_create(char* fname) | |||||
cms_err cms_util_file_create(char* fname) | |||||
{ | { | ||||
int f = open(fname, O_CREAT); | int f = open(fname, O_CREAT); | ||||
close(f); | close(f); | ||||
if (f == -1) | |||||
return cms_err_from_std_err(errno); | |||||
else | |||||
return CMS_ERR_NONE; | |||||
} | } | ||||
int cms_util_file_copy(char* fname1, char* fname2) | |||||
cms_err cms_util_file_copy(char* fname1, char* fname2) | |||||
{ | { | ||||
int f1 = open(fname1, O_RDONLY); | int f1 = open(fname1, O_RDONLY); | ||||
int f2 = open(fname2, O_WRONLY); | int f2 = open(fname2, O_WRONLY); | ||||
struct stat* s = malloc(sizeof(struct stat)); | struct stat* s = malloc(sizeof(struct stat)); | ||||
if (s == NULL) | if (s == NULL) | ||||
return 1; | |||||
return CMS_ERR_ALLOC; | |||||
fstat(f1, s); | fstat(f1, s); | ||||
void* buf = malloc(s->st_size); | void* buf = malloc(s->st_size); | ||||
if (buf == NULL) | if (buf == NULL) | ||||
return 1; | |||||
return CMS_ERR_ALLOC; | |||||
read(f1, buf, s->st_size); | read(f1, buf, s->st_size); | ||||
write(f2, buf, s->st_size); | write(f2, buf, s->st_size); | ||||
free(s); | free(s); | ||||
free(buf); | free(buf); | ||||
return 0; | |||||
return CMS_ERR_NONE; | |||||
} | } | ||||
int cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||||
cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2) | |||||
{ | { | ||||
mkdir(dir2, 0777); | |||||
if (mkdir(dir2, 0777) == -1) | |||||
return cms_err_from_std_err(errno); | |||||
DIR* dp = opendir(dir1); | DIR* dp = opendir(dir1); | ||||
if (dp == NULL) | |||||
return cms_err_from_std_err(errno); | |||||
struct dirent* ep; | struct dirent* ep; | ||||
if (dp == NULL) | |||||
return 1; | |||||
struct stat* st = malloc(sizeof(struct stat)); | |||||
if (st == NULL) | |||||
return CMS_ERR_ALLOC; | |||||
while (ep = readdir(dp)) | while (ep = readdir(dp)) | ||||
{ | { | ||||
char* path1 = cms_util_path_join(dir1, ep->d_name); | char* path1 = cms_util_path_join(dir1, ep->d_name); | ||||
char* path2 = cms_util_path_join(dir2, ep->d_name); | char* path2 = cms_util_path_join(dir2, ep->d_name); | ||||
struct stat* s = malloc(sizeof(struct stat)); | |||||
stat(path1, s); | |||||
stat(path1, st); | |||||
if (S_ISDIR(s->st_mode)) | |||||
if (S_ISDIR(st->st_mode)) | |||||
{ | { | ||||
cms_util_dir_copy_recursive(path1, path2); | |||||
cms_err err = cms_util_dir_copy_recursive(path1, path2); | |||||
if (err != CMS_ERR_NONE) | |||||
return err; | |||||
} | } | ||||
else | else | ||||
{ | { | ||||
cms_util_file_copy(path1, path2); | |||||
cms_err err = cms_util_file_copy(path1, path2); | |||||
if (err != CMS_ERR_NONE) | |||||
return err; | |||||
} | } | ||||
free(s); | |||||
} | } | ||||
free(st); | |||||
return 0; | return 0; | ||||
} | } | ||||
} | } | ||||
char* path = malloc((len1 + len2 + 1) * sizeof(char)); | char* path = malloc((len1 + len2 + 1) * sizeof(char)); | ||||
if (path == NULL) | |||||
cms_err_panic(CMS_ERR_ALLOC, ""); | |||||
if (path == NULL) | if (path == NULL) | ||||
return NULL; | return NULL; |
#ifndef CMS_UTIL_H | #ifndef CMS_UTIL_H | ||||
#define CMS_UTIL_H | #define CMS_UTIL_H | ||||
#include "cms_err.h" | |||||
//Return 1 if a file exists, 0 if it doesn't | //Return 1 if a file exists, 0 if it doesn't | ||||
int cms_util_file_exists(char* fname); | int cms_util_file_exists(char* fname); | ||||
//Create a file | //Create a file | ||||
void cms_util_file_create(char* fname); | |||||
cms_err cms_util_file_create(char* fname); | |||||
//Copy a file | //Copy a file | ||||
int cms_util_file_copy(char* fname1, char* fname2); | |||||
cms_err cms_util_file_copy(char* fname1, char* fname2); | |||||
//Recursively copy a directory | //Recursively copy a directory | ||||
int cms_util_dir_copy_recursive(char* dir1, char* dir2); | |||||
cms_err cms_util_dir_copy_recursive(char* dir1, char* dir2); | |||||
//Join together two paths | //Join together two paths | ||||
char* cms_util_path_join(char* str1, char* str2); | char* cms_util_path_join(char* str1, char* str2); |
#include <stdio.h> | #include <stdio.h> | ||||
#include "cms_util.h" | #include "cms_util.h" | ||||
#include "cms_log.h" | |||||
#include "cms_err.h" | |||||
#include "cms_files.h" | #include "cms_files.h" | ||||
int main(int argc, char** argv) | int main(int argc, char** argv) | ||||
//Get the path of .cmsinited, which tells us | //Get the path of .cmsinited, which tells us | ||||
//whether or not the directory is already inited | //whether or not the directory is already inited | ||||
char* initedPath = cms_util_path_join(dirname, CMS_FILE_INITED); | char* initedPath = cms_util_path_join(dirname, CMS_FILE_INITED); | ||||
if (initedPath == NULL) | |||||
cms_log_panic("Memory allocation failed."); | |||||
//Check if the .cmsinited file exists | |||||
//Panic if the directory is already initiated | |||||
if (cms_util_file_exists(initedPath)) | if (cms_util_file_exists(initedPath)) | ||||
cms_log_error("Directory already initiated."); | |||||
cms_err_panic(CMS_ERR_INITED, NULL); | |||||
//Create .cmsinited file | //Create .cmsinited file | ||||
cms_util_file_create(initedPath); | cms_util_file_create(initedPath); | ||||
else if (strcmp(argv[1], "build") == 0) //Build | else if (strcmp(argv[1], "build") == 0) //Build | ||||
{ | { | ||||
char* dirname = argv[2]; | |||||
//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); | |||||
//Panic if the directory isn't initiated | |||||
if (!cms_util_file_exists(initedPath)) | |||||
cms_err_panic(CMS_ERR_NOTINITED, NULL); | |||||
} | } | ||||
} | } |