/* ckutil.c - utility functions for ck ---------------------------------*- C -*- * * This file is part of ck, the config keeper * * ----------------------------------------------------------------------------- * * Copyright (C) 2018 Anastasis Grammenos * GPLv3 (see LICENCE for the full notice) * * -------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #include "ckutil.h" #include "ckerrlog.h" ERRLOG(utility); int util_is_dir(const char *path) { if (!path) { return 0; } DIR *dir; dir = opendir(path); if (!dir) { return 0; } closedir(dir); return 1; } int util_file_exists(const char* path, char *absPath) { if (!path || !absPath) { return 0; } struct stat st = {0}; if (stat(path, &st) == -1) { return 0; } if (absPath) { realpath(path, absPath); } return 1; } int util_is_file_rw(const char *path) { if (!path) { return 0; } if (access(path, R_OK | W_OK) == 0) { return 1; } return 0; } int util_is_file_link(const char *path) { if (!path) { return 0; } struct stat buf; lstat(path, &buf); if (S_ISLNK(buf.st_mode)) { return 0; } return 1; } void util_mkdir(const char *name) { if (!name) { return; } mkdir(name, 0755); } int util_move_file(const char *path, const char* dest) { if (!path || !dest) { return 0; } int srcFile = open(path, O_RDONLY); int destFile = open(dest, O_WRONLY | O_CREAT); struct stat st, newSt; fstat(srcFile, &st); sendfile(destFile, srcFile, NULL, (size_t)st.st_size); close(srcFile); fchmod(destFile, st.st_mode); fstat(destFile, &newSt); if (st.st_size == newSt.st_size) { unlink(path); close(destFile); return 0; } close(destFile); return -1; } int util_symlink_file(const char *path, const char* dest) { if (!path || !dest) { return -1; } return symlink(path, dest); } void str_make_ck_config_name(char *ret, const char *path, const char *progName) { if (!path || !ret || !progName) { return; } char *basec = strdup(path); char *bname = basename(basec); str_join_dirname_with_basename(ret, progName, bname); free(basec); } void str_join_dirname_with_basename(char *ret, const char *dirname, const char *basename) { if (!dirname || !ret || !basename) { return; } strcpy(ret, dirname); strcat(ret, "/"); strcat(ret, basename); } int str_is_empty(const char *s) { if (!s) { return 1; } while (*s != '\0') { if (!isspace((unsigned char)*s)) { return 0; } s++; } return 1; } int util_own_grp_copy(const char *dest, const char *original) { if (!dest || !original) { return -1; } struct stat destbuf, origbuf; if (lstat(dest, &destbuf)) { sERR("error stating %s", dest) return -1; } if (stat(original, &origbuf)) { sERR("error stating %s", original) return -1; } if (destbuf.st_uid != origbuf.st_uid || destbuf.st_gid != origbuf.st_gid) { hLOG("Copying uid & gid: %s -> %s", original, dest); if (lchown(dest, origbuf.st_uid, origbuf.st_gid)) { sERR("Cannot change owner and group of %s", dest); return -1; } } return 0; } int util_is_link_owned_by_root(const char *link) { if (!link) { return 0; } struct stat buf; if (!lstat(link, &buf)) { if (buf.st_uid == (uid_t)0) { return 1; } } return 0; }