utils.c (2218B)
1 #include "utils.h" 2 3 #include <err.h> 4 #include <errno.h> 5 #include <limits.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <sys/stat.h> 9 #include <sys/types.h> 10 11 #include "third_party/openbsd/strlcat.h" 12 #include "third_party/openbsd/strlcpy.h" 13 14 char* path_concat(char* out, size_t out_len, const char* p1, const char* p2) { 15 size_t p1_len = strlen(p1); 16 size_t p2_len = strlen(p2); 17 if (p1_len == 0) { 18 estrlcpy(out, p2, out_len); 19 return out; 20 } 21 if (p2_len == 0) { 22 estrlcpy(out, p1, out_len); 23 return out; 24 } 25 if (p1_len + p2_len + 2 > out_len) { 26 errx(1, "path truncated. p1: '%s' p2: '%s'", p1, p2); 27 } 28 if (snprintf(out, out_len, "%s/%s", p1, p2) < 0) { 29 err(1, "snprintf"); 30 } 31 return out; 32 } 33 34 int mkdirp(const char* path) { 35 char mut_path[PATH_MAX]; 36 estrlcpy(mut_path, path, sizeof(mut_path)); 37 38 for (char* p = mut_path + (mut_path[0] == '/'); *p; p++) { 39 if (*p != '/') { 40 continue; 41 } 42 *p = '\0'; 43 if (mkdir(mut_path, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) { 44 return -1; 45 } 46 *p = '/'; 47 } 48 if (mkdir(mut_path, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST) { 49 return -1; 50 } 51 return 0; 52 } 53 54 void* ecalloc(size_t count, size_t size) { 55 void* ptr = calloc(count, size); 56 if (!ptr) { 57 err(1, "calloc"); 58 } 59 return ptr; 60 } 61 62 char* estrdup(const char* s) { 63 char* out_str = strdup(s); 64 if (!out_str) { 65 err(1, "strcpy"); 66 } 67 return out_str; 68 } 69 70 size_t estrlcpy(char* dst, const char* src, size_t dsize) { 71 size_t len = strlcpy(dst, src, dsize); 72 if (len >= dsize) { 73 errx(1, "string truncated: '%s'", src); 74 } 75 return len; 76 } 77 78 size_t estrlcat(char* dst, const char* src, size_t dsize) { 79 size_t len = strlcat(dst, src, dsize); 80 if (len >= dsize) { 81 errx(1, "string truncated: '%s'", src); 82 } 83 return len; 84 } 85 86 FILE* efopen(const char* filename, const char* flags) { 87 FILE* fp = fopen(filename, flags); 88 if (!fp) { 89 err(1, "fopen: '%s'", filename); 90 } 91 return fp; 92 } 93 94 void checkfileerror(FILE* fp, const char* name, char mode) { 95 if (mode == 'r' && ferror(fp)) { 96 errx(1, "read error: %s", name); 97 } else if (mode == 'w' && (fflush(fp) || ferror(fp))) { 98 errx(1, "write error: %s", name); 99 } 100 }