dwm

Kris's build of dwm
git clone git clone https://git.krisyotam.com/krisyotam/dwm.git
Log | Files | Refs | README | LICENSE

util.c (2635B)


      1 #include <errno.h>
      2 #include <sys/stat.h>
      3 
      4 int
      5 normalizepath(const char *path, char **normal)
      6 {
      7   size_t len = strlen(path);
      8   *normal = (char *)malloc((len + 1) * sizeof(char));
      9   const char *walk = path;
     10   const char *match;
     11   size_t newlen = 0;
     12 
     13   while ((match = strchr(walk, '/'))) {
     14     // Copy everything between match and walk
     15     strncpy(*normal + newlen, walk, match - walk);
     16     newlen += match - walk;
     17     walk += match - walk;
     18 
     19     // Skip all repeating slashes
     20     while (*walk == '/')
     21       walk++;
     22 
     23     // If not last character in path
     24     if (walk != path + len)
     25       (*normal)[newlen++] = '/';
     26   }
     27 
     28   (*normal)[newlen++] = '\0';
     29 
     30   // Copy remaining path
     31   strcat(*normal, walk);
     32   newlen += strlen(walk);
     33 
     34   *normal = (char *)realloc(*normal, newlen * sizeof(char));
     35 
     36   return 0;
     37 }
     38 
     39 int
     40 parentdir(const char *path, char **parent)
     41 {
     42   char *normal;
     43   char *walk;
     44 
     45   normalizepath(path, &normal);
     46 
     47   // Pointer to last '/'
     48   if (!(walk = strrchr(normal, '/'))) {
     49     free(normal);
     50     return -1;
     51   }
     52 
     53   // Get path up to last '/'
     54   size_t len = walk - normal;
     55   *parent = (char *)malloc((len + 1) * sizeof(char));
     56 
     57   // Copy path up to last '/'
     58   strncpy(*parent, normal, len);
     59   // Add null char
     60   (*parent)[len] = '\0';
     61 
     62   free(normal);
     63 
     64   return 0;
     65 }
     66 
     67 int
     68 mkdirp(const char *path)
     69 {
     70   char *normal;
     71   char *walk;
     72   size_t normallen;
     73 
     74   normalizepath(path, &normal);
     75   normallen = strlen(normal);
     76   walk = normal;
     77 
     78   while (walk < normal + normallen + 1) {
     79     // Get length from walk to next /
     80     size_t n = strcspn(walk, "/");
     81 
     82     // Skip path /
     83     if (n == 0) {
     84       walk++;
     85       continue;
     86     }
     87 
     88     // Length of current path segment
     89     size_t curpathlen = walk - normal + n;
     90     char curpath[curpathlen + 1];
     91     struct stat s;
     92 
     93     // Copy path segment to stat
     94     strncpy(curpath, normal, curpathlen);
     95     strcpy(curpath + curpathlen, "");
     96     int res = stat(curpath, &s);
     97 
     98     if (res < 0) {
     99       if (errno == ENOENT) {
    100         DEBUG("Making directory %s\n", curpath);
    101         if (mkdir(curpath, 0700) < 0) {
    102           fprintf(stderr, "Failed to make directory %s\n", curpath);
    103           perror("");
    104           free(normal);
    105           return -1;
    106         }
    107       } else {
    108         fprintf(stderr, "Error statting directory %s\n", curpath);
    109         perror("");
    110         free(normal);
    111         return -1;
    112       }
    113     }
    114 
    115     // Continue to next path segment
    116     walk += n;
    117   }
    118 
    119   free(normal);
    120 
    121   return 0;
    122 }
    123 
    124 int
    125 nullterminate(char **str, size_t *len)
    126 {
    127   if ((*str)[*len - 1] == '\0')
    128     return 0;
    129 
    130   (*len)++;
    131   *str = (char*)realloc(*str, *len * sizeof(char));
    132   (*str)[*len - 1] = '\0';
    133 
    134   return 0;
    135 }
    136