From d38c13b2fe1293b499312bb4cfd66a56108c4b5e Mon Sep 17 00:00:00 2001 From: bigfoot547 Date: Mon, 8 Jan 2024 12:17:20 -0600 Subject: WIP: JRE stuff --- src/launcherutil.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) (limited to 'src/launcherutil.c') diff --git a/src/launcherutil.c b/src/launcherutil.c index e1e8c40..b292df9 100644 --- a/src/launcherutil.c +++ b/src/launcherutil.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include /* handcoded string functions * @@ -138,6 +140,44 @@ int l2_launcher_open_config(const char *path, int flags, mode_t mode) return instfd; } +int l2_launcher__rmtree_ftw_delete_with_reckless_abandon(const char *fpath, const struct stat *st, int typeflag, struct FTW *ftwbuf) +{ + L2_UNUSED(ftwbuf); + L2_UNUSED(st); + + switch (typeflag) { + case FTW_F: + case FTW_SL: + if (unlink(fpath) < 0) { + CMD_WARN("l2_rm_tree: Failed to delete file or symlink %s: %s", fpath, strerror(errno)); + return 1; + } + break; + case FTW_DP: + if (rmdir(fpath) < 0) { + CMD_WARN("l2_rm_tree: Failed to delete directory %s: %s", fpath, strerror(errno)); + return 1; + } + break; + case FTW_DNR: + CMD_WARN("l2_rm_tree: Not traversing into directory I cannot read: %s", fpath); + break; + case FTW_NS: + CMD_WARN("l2_rm_tree: Not deleting/traversing file I cannot stat: %s", fpath); + break; + } + return 0; +} + +int l2_launcher_rm_tree(const char *path, int nfds) +{ + if (nfds <= 0) nfds = 64; + + int res = nftw(path, &l2_launcher__rmtree_ftw_delete_with_reckless_abandon, nfds, FTW_DEPTH | FTW_PHYS); + if (res != 0) return -1; + return 0; +} + int l2_launcher_mkdir_parents(const char *path) { return l2_launcher_mkdir_parents_ex(path, 0); @@ -465,3 +505,131 @@ cleanup: if (pc) curl_easy_cleanup(pc); return res; } + +struct l2_ftw__data_int { + struct l2_ftw_data user; + + size_t pathcap; + size_t pathlen; + int abort; +}; + +int l2_launcher__ftw_update_path(char **path, struct l2_ftw__data_int *ftw, const char *entname) +{ + size_t entlen = strlen(entname); + if (ftw->pathlen + entlen + 2 > ftw->pathcap) { + char *newpathbuf = realloc(*path, ftw->pathlen + entlen + 2); + if (!newpathbuf) return -1; + *path = newpathbuf; + ftw->pathcap = ftw->pathlen + entlen + 2; + } + + (*path)[ftw->pathlen] = '/'; + ++ftw->pathlen; + memcpy(*path + ftw->pathlen, entname, entlen + 1); + ftw->pathlen += entlen; + return 0; +} + +int l2_launcher__ftw_internal(char **path, int depth, l2_ftw_proc_t *proc, struct l2_ftw__data_int *ftw) +{ + if (depth <= 0) { + CMD_DEBUG0("myftw: interation depth exceeded"); + return -1; + } + + DIR *thisdir = opendir(*path); + int res; + if (!thisdir) { + if (errno != ENOENT || ftw->user.depth == 0) { + CMD_DEBUG("myftw: could not open %s: %s", *path, strerror(errno)); + return -1; + } + CMD_DEBUG("myftw: directory %s does not exist. (maybe it was deleted?)", *path); + return 0; + } + + ++ftw->user.depth; + + struct dirent *ent; + struct stat st; + size_t pathlen = ftw->pathlen; + + errno = 0; + while ((ent = readdir(thisdir))) { + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; + + int flags = 0; + if (fstatat(dirfd(thisdir), ent->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { + CMD_DEBUG("myftw: stat failed %s: %s", *path, strerror(errno)); + res = -1; + goto cleanup; + } + + ftw->pathlen = pathlen; + (*path)[pathlen] = '\0'; + l2_launcher__ftw_update_path(path, ftw, ent->d_name); + + if (S_ISREG(st.st_mode)) { + flags |= L2_FTW_FILE; + } + + if (S_ISDIR(st.st_mode)) { + flags |= L2_FTW_DIR; + } + + if (S_ISLNK(st.st_mode)) { + flags |= L2_FTW_SYMLINK; + } + + if ((res = (*proc)(*path, &st, flags, (struct l2_ftw_data *)ftw))) { + CMD_DEBUG("myftw: user aborted %s: %d", *path, res); + ftw->abort = 1; + goto cleanup; + } + + if (S_ISDIR(st.st_mode)) { + if ((res = l2_launcher__ftw_internal(path, depth - 1, proc, ftw)) < 0 || ftw->abort) { + goto cleanup; + } + } + + errno = 0; + } + + if (errno) { + CMD_DEBUG("myftw: readdir failed on %s: %s", *path, strerror(errno)); + res = -1; + goto cleanup; + } + + --ftw->user.depth; + res = 0; + +cleanup: + closedir(thisdir); + return res; +} + +int l2_launcher_ftw(const char *path, int depth, l2_ftw_proc_t *proc, void *user) +{ + struct l2_ftw__data_int data; + size_t pathlen = strlen(path); + + data.user.depth = 0; + data.user.reloffset = pathlen + 1; + data.user.user = user; + data.abort = 0; + + char *pathdup = strdup(path); + data.pathcap = pathlen + 1; + data.pathlen = pathlen; + + if (!pathdup) return -1; + + int res = l2_launcher__ftw_internal(&pathdup, depth, proc, &data); + + free(pathdup); + + return res; +} -- cgit v1.2.3-70-g09d2