#include #include #include #include #include #include #include #include #include #include #include "cms_util.h" #include "cms_err.h" #include int cms_util_file_exists(char* fname) { int f = open(fname, O_RDONLY); //The file doesn't exist if the open command returned the ENOENT error. if (f == -1 && errno == ENOENT) return 0; //If the open command succeeded, we want to close the file descriptor. else if (f != -1) close(f); return 1; } cms_err* cms_util_file_create(char* fname) { int f = open(fname, O_CREAT, 0777); close(f); if (f == -1) return cms_err_from_std_err(errno); else return cms_err_create(CMS_ERR_NONE, NULL); } cms_err* cms_util_file_copy(char* fname1, char* fname2) { int f1 = open(fname1, O_RDONLY); if (f1 == -1) return cms_err_from_std_err(errno); int f2 = open(fname2, O_WRONLY | O_CREAT, 0777); if (f1 == -1) return cms_err_from_std_err(errno); struct stat* st = malloc(sizeof(struct stat)); if (st == NULL) return cms_err_create(CMS_ERR_ALLOC, NULL); fstat(f1, st); void* buf = malloc(st->st_size); if (buf == NULL) return cms_err_create(CMS_ERR_ALLOC, NULL); read(f1, buf, st->st_size); write(f2, buf, st->st_size); close(f1); close(f2); free(st); free(buf); 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) { if (mkdir(dir2, 0777) == -1 && errno != EEXIST) return cms_err_from_std_err(errno); DIR* dp = opendir(dir1); 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)) != NULL) { if (ep->d_name[0] == '.') continue; char* path1 = cms_util_path_join(dir1, ep->d_name); char* path2 = cms_util_path_join(dir2, ep->d_name); if (stat(path1, st) == -1) return cms_err_from_std_err(errno); if (S_ISDIR(st->st_mode)) { 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); free(path1); free(path2); if (err) return err; } } closedir(dp); free(st); return cms_err_create(CMS_ERR_NONE, NULL); } char* cms_util_path_join(char* str1, char* str2) { if (str1 == NULL || str2 == NULL) return NULL; size_t len1 = strlen(str1); size_t len2 = strlen(str2); if (str1[len1 - 1] == '/') { len1 -= 1; } char* path = malloc((len1 + len2 + 2) * sizeof(char)); if (path == NULL) cms_err_panic(cms_err_create(CMS_ERR_ALLOC, NULL)); if (path == NULL) return NULL; memcpy(path, str1, len1); //First part path[len1] = '/'; //Separator memcpy(path + len1 + 1, str2, len2); //Second part path[len1 + len2 + 1] = '\0'; //Null terminator return path; }