214 lines
4.1 KiB
C
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;
|
|
}
|