Files
confer/src/util.c
2024-08-01 04:48:11 +03:00

214 lines
4.1 KiB
C

#include <dirent.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "error.h"
#include "intl.h"
#include "util.h"
bool eq(char *s1, char *s2) {
if (strlen(s1) != strlen(s2))
return false;
return strcmp(s1, s2) == 0;
}
bool exists(char *path) {
return access(path, F_OK) == 0;
}
bool endswith(const char *str, const char *suf) {
int strl = strlen(str);
int sufl = strlen(suf);
if (sufl > strl)
return false;
return strncmp(str + strl - sufl, suf, sufl) == 0;
}
bool startswith(char *str, char *sub) {
if (strlen(sub) > strlen(str))
return false;
return strncmp(str, sub, strlen(sub)) == 0;
}
char *check_path(char *bin) {
char *path = getenv("PATH");
char *res = NULL;
if (NULL == path)
return NULL;
path = strdup(path);
char *p = strtok(path, ":");
while (NULL != p) {
char *fp = malloc(PATH_MAX);
snprintf(fp, PATH_MAX, "%s/%s", p, bin);
if (exists(fp)) {
res = fp;
break;
}
p = strtok(NULL, ":");
}
free(path);
return res;
}
int join(char *res, const char *base, const char *pth) {
int blen = strlen(base);
if ((base[blen - 1] == '/' && pth[0] != '/') || (base[blen - 1] != '/' && pth[0] == '/')) {
return sprintf(res, "%s%s", base, pth);
} else if (base[blen - 1] != '/' && pth[0] != '/') {
return sprintf(res, "%s/%s", base, pth);
} else if (base[blen - 1] == '/' && pth[0] == '/') {
char *basedup = strdup(base);
basedup[blen - 1] = '\0';
return sprintf(res, "%s%s", basedup, pth);
}
return -1;
}
int randint(int min, int max) {
srand(time(NULL));
return rand() % max + min;
}
bool is_dir(char *path) {
DIR *dir = opendir(path);
if (dir) {
closedir(dir);
return true;
}
return false;
}
bool mksubdirsp(char *path, int perms) {
char cur[PATH_MAX];
bzero(cur, PATH_MAX);
int indx = 0;
for (char *c = path; *c != '\0'; c++) {
if (*c == '/' && indx != 0) {
cur[indx] = '\0';
if (!exists(cur) && mkdir(cur, perms) < 0) {
error_set(_("Failed to create directory: %s"), cur);
errno = MkdirFail;
return false;
}
}
cur[indx] = *c;
indx++;
}
if (!exists(cur) && mkdir(cur, perms) < 0) {
error_set(_("Failed to create directory: %s"), cur);
errno = MkdirFail;
return false;
}
return true;
}
bool rmrf(char *path) {
if (!exists(path))
return true;
if (!is_dir(path))
return unlink(path) == 0;
DIR *dir = opendir(path);
struct dirent *ent = NULL;
char fp[PATH_MAX] = {};
while ((ent = readdir(dir)) != NULL) {
if (eq(ent->d_name, ".") || eq(ent->d_name, ".."))
continue;
join(fp, path, ent->d_name);
if (!rmrf(fp))
return false;
}
closedir(dir);
rmdir(path);
return true;
}
void clist_init(clist_t *l) {
l->c = NULL;
l->s = 0;
}
void clist_from_str(clist_t *l, char *str) {
char *save = NULL, *el = NULL;
char *strdp = strdup(str);
el = strtok_r(strdp, ",", &save);
while (NULL != el) {
clist_add(l, strdup(el));
el = strtok_r(NULL, ",", &save);
}
free(strdp);
}
void clist_free(clist_t *l) {
if (NULL == l->c || 0 == l->s)
return;
for (int i = 0; i < l->s; i++)
free(l->c[i]);
free(l->c);
l->s = 0;
}
void clist_add(clist_t *l, char *en) {
if (NULL == l->c || 0 == l->s) {
l->c = malloc(sizeof(char *));
l->c[l->s] = en;
l->s++;
return;
}
l->c = realloc(l->c, sizeof(char *) * (l->s + 1));
l->c[l->s] = en;
l->s++;
}
bool copyfile(char *src, char *dst) {
FILE *srcf = fopen(src, "r");
FILE *dstf = fopen(dst, "w");
if (NULL == srcf || NULL == dstf) {
if (NULL == srcf)
error_set(_("Failed to open \"%s\" for reading"), srcf);
else
error_set(_("Failed to open \"%s\" for writing"), dstf);
errno = OpenFail;
return false;
}
char buffer[32];
int read = -1;
bzero(buffer, 32);
while ((read = fread(buffer, 1, 32, srcf)) > 0)
fwrite(buffer, 1, read, dstf);
fclose(srcf);
fclose(dstf);
return true;
}