From 11e470ab4254304192997834e26166cfddc78f80 Mon Sep 17 00:00:00 2001 From: Nikita Langer Date: Thu, 6 Aug 2026 12:12:00 +0200 Subject: ipc --- util.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'util.c') diff --git a/util.c b/util.c index 8e26a51..5e6794c 100644 --- a/util.c +++ b/util.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "util.h" @@ -35,3 +37,136 @@ ecalloc(size_t nmemb, size_t size) die("calloc:"); return p; } + +int +normalizepath(const char *path, char **normal) +{ + size_t len = strlen(path); + *normal = (char *)malloc((len + 1) * sizeof(char)); + const char *walk = path; + const char *match; + size_t newlen = 0; + + while ((match = strchr(walk, '/'))) { + // Copy everything between match and walk + strncpy(*normal + newlen, walk, match - walk); + newlen += match - walk; + walk += match - walk; + + // Skip all repeating slashes + while (*walk == '/') + walk++; + + // If not last character in path + if (walk != path + len) + (*normal)[newlen++] = '/'; + } + + (*normal)[newlen++] = '\0'; + + // Copy remaining path + strcat(*normal, walk); + newlen += strlen(walk); + + *normal = (char *)realloc(*normal, newlen * sizeof(char)); + + return 0; +} + +int +parentdir(const char *path, char **parent) +{ + char *normal; + char *walk; + + normalizepath(path, &normal); + + // Pointer to last '/' + if (!(walk = strrchr(normal, '/'))) { + free(normal); + return -1; + } + + // Get path up to last '/' + size_t len = walk - normal; + *parent = (char *)malloc((len + 1) * sizeof(char)); + + // Copy path up to last '/' + strncpy(*parent, normal, len); + // Add null char + (*parent)[len] = '\0'; + + free(normal); + + return 0; +} + +int +mkdirp(const char *path) +{ + char *normal; + char *walk; + size_t normallen; + + normalizepath(path, &normal); + normallen = strlen(normal); + walk = normal; + + while (walk < normal + normallen + 1) { + // Get length from walk to next / + size_t n = strcspn(walk, "/"); + + // Skip path / + if (n == 0) { + walk++; + continue; + } + + // Length of current path segment + size_t curpathlen = walk - normal + n; + char curpath[curpathlen + 1]; + struct stat s; + + // Copy path segment to stat + strncpy(curpath, normal, curpathlen); + strcpy(curpath + curpathlen, ""); + int res = stat(curpath, &s); + + if (res < 0) { + if (errno == ENOENT) { + DEBUG("Making directory %s\n", curpath); + if (mkdir(curpath, 0700) < 0) { + fprintf(stderr, "Failed to make directory %s\n", curpath); + perror(""); + free(normal); + return -1; + } + } else { + fprintf(stderr, "Error statting directory %s\n", curpath); + perror(""); + free(normal); + return -1; + } + } + + // Continue to next path segment + walk += n; + } + + free(normal); + + return 0; +} + +int +nullterminate(char **str, size_t *len) +{ + if ((*str)[*len - 1] == '\0') + return 0; + + (*len)++; + *str = (char*)realloc(*str, *len * sizeof(char)); + (*str)[*len - 1] = '\0'; + + return 0; +} -- cgit