/* This contains the code for ending speedwm, along with memory allocation and IPC support. * * See LICENSE file for copyright and license details. */ #include #include #include #include #include "toggle.h" #ifdef USEIPC #include #include #endif #include "main.h" void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if (fmt[0] && fmt[strlen(fmt)-1] == ':') { fputc(' ', stderr); perror(NULL); } else { fputc('\n', stderr); } exit(1); } void * ecalloc(size_t nmemb, size_t size) { void *p; if (!(p = calloc(nmemb, size))) die("calloc:"); return p; } #if USEIPC 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; } #endif