#include #include #include #include #include #include #include #include #include #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; }