summaryrefslogtreecommitdiff
path: root/src/shared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared.c')
-rw-r--r--src/shared.c115
1 files changed, 108 insertions, 7 deletions
diff --git a/src/shared.c b/src/shared.c
index 40240d5..c46b001 100644
--- a/src/shared.c
+++ b/src/shared.c
@@ -13,7 +13,11 @@ void* xcalloc(size_t nmemb, size_t size) {
13 13
14 if(!mem) { 14 if(!mem) {
15 #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 15 #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0
16 error(1, errno, "<xcalloc> Could not allocate memory"); 16 #if defined ___VXGG___VERBOSE_ERRORS___ && ___VXGG___VERBOSE_ERRORS___ > 0
17 error(1, errno, "<xcalloc> Could not allocate memory");
18 #else
19 exit(EXIT_FAILURE);
20 #endif
17 #endif 21 #endif
18 22
19 abort(); 23 abort();
@@ -27,8 +31,11 @@ void* xreallocarray(void *ptr, size_t nmemb, size_t size) {
27 void *mem = reallocarray(ptr, nmemb, size); 31 void *mem = reallocarray(ptr, nmemb, size);
28 if(mem == NULL) { 32 if(mem == NULL) {
29 #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0 33 #if defined ___VXGG___XALLOC_EXIT_ON_ERROR___ && ___VXGG___XALLOC_EXIT_ON_ERROR___ > 0
30 error(1, errno, "<xreallocarray> Could not allocate memory"); 34 #if defined ___VXGG___VERBOSE_ERRORS___ && ___VXGG___VERBOSE_ERRORS___ > 0
31 35 error(1, errno, "<xreallocarray> Could not allocate memory");
36 #else
37 exit(EXIT_FAILURE);
38 #endif
32 #endif 39 #endif
33 40
34 abort(); 41 abort();
@@ -56,7 +63,9 @@ int readwholebuffer(char **str, unsigned long int initsize, int fd) {
56 63
57 tmp = realloc(lstr, csize * sizeof(char)); 64 tmp = realloc(lstr, csize * sizeof(char));
58 if(!tmp) { 65 if(!tmp) {
59 error(0, errno, "Could not reallocate enough space for lstr"); 66 #if defined ___VXGG___VERBOSE_ERRORS___ && ___VXGG___VERBOSE_ERRORS___ > 0
67 error(0, errno, "Could not reallocate enough space for lstr");
68 #endif
60 free(lstr); 69 free(lstr);
61 lstr = NULL; // Need to set this because of the break 70 lstr = NULL; // Need to set this because of the break
62 bytesread = -100; 71 bytesread = -100;
@@ -66,7 +75,9 @@ int readwholebuffer(char **str, unsigned long int initsize, int fd) {
66 } 75 }
67 } 76 }
68 if(bytesread < 0 && bytesread != -100) { 77 if(bytesread < 0 && bytesread != -100) {
69 error(0, errno, "Ran into a read() error"); 78 #if defined ___VXGG___VERBOSE_ERRORS___ && ___VXGG___VERBOSE_ERRORS___ > 0
79 error(0, errno, "Ran into a read() error");
80 #endif
70 free(lstr); 81 free(lstr);
71 lstr = NULL; 82 lstr = NULL;
72 } 83 }
@@ -74,7 +85,9 @@ int readwholebuffer(char **str, unsigned long int initsize, int fd) {
74 if(lstr) { 85 if(lstr) {
75 tmp = realloc(lstr, csize - ccap + 1); 86 tmp = realloc(lstr, csize - ccap + 1);
76 if(!tmp) { 87 if(!tmp) {
77 error(0, errno, "Could not shrink lstr after reading buffer"); 88 #if defined ___VXGG___VERBOSE_ERRORS___ && ___VXGG___VERBOSE_ERRORS___ > 0
89 error(0, errno, "Could not shrink lstr after reading buffer");
90 #endif
78 free(lstr); 91 free(lstr);
79 bytesread = -100; 92 bytesread = -100;
80 } 93 }
@@ -107,4 +120,92 @@ int writewholebuffer(int fd, const unsigned char *buf, int len) {
107} 120}
108// Adapted from Beej's `sendall()` function 121// Adapted from Beej's `sendall()` function
109// https://beej.us/guide/bgnet/html/split/slightly-advanced-techniques.html#sendall 122// https://beej.us/guide/bgnet/html/split/slightly-advanced-techniques.html#sendall
110 // Thanks Beej! \ No newline at end of file 123 // Thanks Beej!
124
125// dirname but less retarded hopefully
126char *xdirname(const char * const path) {
127 char *tmp = NULL;
128 if(!path) { // Path being null is a special case which should return super early, before anything else
129 tmp = strdup(".");
130 if(!tmp)
131 abort();
132
133 return tmp;
134 }
135
136 unsigned char flag = 0;
137 if(strcmp(path, ".") == 0) {tmp = strdup("."); flag++;}
138 if(strcmp(path, "/") == 0 && !flag) {tmp = strdup("/"); flag++;}
139 if(strcmp(path, "..") == 0 && !flag) {tmp = strdup("."); flag++;}
140
141 if(flag) {
142 if(!tmp)
143 abort();
144
145 return tmp;
146 }
147
148
149 /* From the manpages: (man 3 dirname)
150 // +=======================================+
151 // | path dirname basename |
152 // +=======================================+
153 // | /usr/lib /usr lib |
154 // | /usr/ / usr |
155 // | usr . usr |
156 // +=======================================+
157 */
158
159 // Get a temp copy of the path for manipulation purposes
160 tmp = strdup(path);
161 if(!tmp)
162 abort();
163
164 // If there's a trailing '/', delete it
165 size_t pathlen = strlen(path);
166 if(tmp[pathlen - 1] == '/') {
167 tmp[pathlen - 1] = '\0';
168 pathlen--;
169 }
170
171 // Ok, I think the easiest way to do this (if maybe a bit slow) is to count the number of '/'s in the string
172 // If there's only one, return '/'
173 // If there are 2 or more, find the last one in the list and set it to '\0'
174
175 size_t count = 0;
176 for(size_t i = 0; i < pathlen; i++) {
177 if(tmp[i] == '/')
178 count++;
179 }
180
181 if(count == 0) {
182 free(tmp);
183 tmp = strdup(".");
184 if(!tmp)
185 abort();
186
187 return tmp;
188 }
189 if(count == 1) {
190 free(tmp);
191 tmp = strdup("/");
192 if(!tmp)
193 abort();
194
195 return tmp;
196 }
197
198 for(size_t i = 0, c2 = 0; i < pathlen; i++) {
199 if(tmp[i] == '/')
200 c2++;
201 if(c2 == count)
202 tmp[i] = '\0';
203 }
204
205 char * const actual = strdup(tmp);
206 if(!actual)
207 abort();
208 free(tmp);
209
210 return actual;
211} \ No newline at end of file