1 /* Copyright 1991 Free Software Foundation, Inc.
2 * Copyright 1997,1999-2002,2007-2009 Alain Knaff.
3 * This file is part of mtools.
4 *
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "sysincludes.h"
19 #include "mtools.h"
20
21 #ifndef HAVE_STRDUP
22
23
strdup(const char * str)24 char *strdup(const char *str)
25 {
26 char *nstr;
27
28 if (str == (char*)0)
29 return 0;
30
31 nstr = (char*)malloc((strlen(str) + 1));
32
33 if (nstr == (char*)0)
34 {
35 (void)fprintf(stderr, "strdup(): not enough memory to duplicate `%s'\n",
36 str);
37 exit(1);
38 }
39
40 (void)strcpy(nstr, str);
41
42 return nstr;
43 }
44 #endif /* HAVE_STRDUP */
45
46 #ifndef HAVE_STRNDUP
strndup(const char * s,size_t n)47 char *strndup( const char *s, size_t n )
48 {
49 size_t nAvail;
50 char *p;
51
52 if ( !s )
53 return 0;
54
55 nAvail = min( strlen(s) + 1, n + 1 );
56 p = malloc( nAvail );
57 if ( !p )
58 return 0;
59 memcpy( p, s, nAvail );
60 p[nAvail - 1] = '\0';
61
62 return p;
63 }
64 #endif /* HAVE_STRNDUP */
65
66
67 #ifdef HAVE_WCHAR_H
68 #ifndef HAVE_WCSDUP
wcsdup(const wchar_t * wcs)69 wchar_t *wcsdup(const wchar_t *wcs)
70 {
71 wchar_t *nwcs;
72
73 if (wcs == (wchar_t*)0)
74 return 0;
75
76 nwcs = (wchar_t*)calloc(wcslen(wcs) + 1, sizeof(wchar_t));
77
78 if (nwcs == (wchar_t*)0)
79 {
80 (void)fprintf(stderr, "wcsdup(): not enough memory to duplicate `%ls'\n",
81 wcs);
82 exit(1);
83 }
84
85 (void)wcscpy(nwcs, wcs);
86
87 return nwcs;
88 }
89 #endif /* HAVE_WCSDUP */
90 #endif
91
92 #ifndef HAVE_MEMCPY
93 /*
94 * Copy contents of memory (with possible overlapping).
95 */
memcpy(char * s1,const char * s2,size_t n)96 char *memcpy(char *s1, const char *s2, size_t n)
97 {
98 bcopy(s2, s1, n);
99 return(s1);
100 }
101 #endif
102
103 #ifndef HAVE_MEMSET
104 /*
105 * Copies the character c, n times to string s
106 */
memset(char * s,char c,size_t n)107 char *memset(char *s, char c, size_t n)
108 {
109 char *s1 = s;
110
111 while (n > 0) {
112 --n;
113 *s++ = c;
114 }
115 return(s1);
116 }
117 #endif /* HAVE_MEMSET */
118
119
120 #ifndef HAVE_STRCHR
121
strchr(const char * s,int c)122 char * strchr (const char* s, int c)
123 {
124 if (!s) return NULL;
125 while (*s && *s != c) s++;
126 if (*s)
127 return (char*) s;
128 else
129 return NULL;
130 }
131
132 #endif
133
134 #ifndef HAVE_STRRCHR
135
strrchr(const char * s1,int c)136 char * strrchr (const char* s1, int c)
137 {
138 char* s = (char*) s1;
139 char* start = (char*) s;
140 if (!s) return NULL;
141 s += strlen(s)-1;
142 while (*s != c && (unsigned long) s != (unsigned long) start) s--;
143 if ((unsigned long) s == (unsigned long) start && *s != c)
144 return NULL;
145 else
146 return s;
147 }
148
149 #endif
150
151 #ifndef HAVE_STRPBRK
152 /*
153 * Return ptr to first occurrence of any character from `brkset'
154 * in the character string `string'; NULL if none exists.
155 */
strpbrk(const char * string,const char * brkset)156 char *strpbrk(const char *string, const char *brkset)
157 {
158 register char *p;
159
160 if (!string || !brkset)
161 return(0);
162 do {
163 for (p = brkset; *p != '\0' && *p != *string; ++p)
164 ;
165 if (*p != '\0')
166 return(string);
167 }
168 while (*string++);
169 return(0);
170 }
171 #endif /* HAVE_STRPBRK */
172
173
174 #ifndef HAVE_STRTOUL
getdigit(char a,int max)175 static int getdigit(char a, int max)
176 {
177 int dig;
178
179 if(a < '0')
180 return -1;
181 if(a <= '9') {
182 dig = a - '0';
183 } else if(a >= 'a')
184 dig = a - 'a' + 10;
185 else if(a >= 'A')
186 dig = a - 'A' + 10;
187 if(dig >= max)
188 return -1;
189 else
190 return dig;
191 }
192
strtoul(const char * string,char ** eptr,int base)193 unsigned long strtoul(const char *string, char **eptr, int base)
194 {
195 int accu, dig;
196
197 if(base < 1 || base > 36) {
198 if(string[0] == '0') {
199 switch(string[1]) {
200 case 'x':
201 case 'X':
202 return strtoul(string+2, eptr, 16);
203 case 'b':
204 case 'B':
205 return strtoul(string+2, eptr, 2);
206 default:
207 return strtoul(string, eptr, 8);
208 }
209 }
210 return strtoul(string, eptr, 10);
211 }
212 if(base == 16 && string[0] == '0' &&
213 (string[1] == 'x' || string[1] == 'X'))
214 string += 2;
215
216 if(base == 2 && string[0] == '0' &&
217 (string[1] == 'b' || string[1] == 'B'))
218 string += 2;
219 accu = 0;
220 while( (dig = getdigit(*string, base)) != -1 ) {
221 accu = accu * base + dig;
222 string++;
223 }
224 if(eptr)
225 *eptr = (char *) string;
226 return accu;
227 }
228 #endif /* HAVE_STRTOUL */
229
230 #ifndef HAVE_STRTOL
strtol(const char * string,char ** eptr,int base)231 long strtol(const char *string, char **eptr, int base)
232 {
233 long l;
234
235 if(*string == '-') {
236 return -(long) strtoul(string+1, eptr, base);
237 } else {
238 if (*string == '+')
239 string ++;
240 return (long) strtoul(string, eptr, base);
241 }
242 }
243 #endif
244
245
246
247 #ifndef HAVE_STRSPN
248 /* Return the length of the maximum initial segment
249 of S which contains only characters in ACCEPT. */
strspn(const char * s,const char * accept)250 size_t strspn(const char *s, const char *accept)
251 {
252 register char *p;
253 register char *a;
254 register size_t count = 0;
255
256 for (p = s; *p != '\0'; ++p)
257 {
258 for (a = accept; *a != '\0'; ++a)
259 if (*p == *a)
260 break;
261 if (*a == '\0')
262 return count;
263 else
264 ++count;
265 }
266
267 return count;
268 }
269 #endif /* HAVE_STRSPN */
270
271 #ifndef HAVE_STRCSPN
272 /* Return the length of the maximum initial segment of S
273 which contains no characters from REJECT. */
strcspn(const char * s,const char * reject)274 size_t strcspn (const char *s, const char *reject)
275 {
276 register size_t count = 0;
277
278 while (*s != '\0')
279 if (strchr (reject, *s++) == NULL)
280 ++count;
281 else
282 return count;
283
284 return count;
285 }
286
287 #endif /* HAVE_STRCSPN */
288
289 #ifndef HAVE_STRERROR
290
291 #ifndef DECL_SYS_ERRLIST
292 extern char *sys_errlist[];
293 #endif
294
strerror(int errno)295 char *strerror(int errno)
296 {
297 return sys_errlist[errno];
298 }
299 #endif
300
301 #ifndef HAVE_STRCASECMP
302 /* Compare S1 and S2, ignoring case, returning less than, equal to or
303 greater than zero if S1 is lexiographically less than,
304 equal to or greater than S2. */
strcasecmp(const char * s1,const char * s2)305 int strcasecmp(const char *s1, const char *s2)
306 {
307 register const unsigned char *p1 = (const unsigned char *) s1;
308 register const unsigned char *p2 = (const unsigned char *) s2;
309 unsigned char c1, c2;
310
311 if (p1 == p2)
312 return 0;
313
314 do
315 {
316 c1 = tolower (*p1++);
317 c2 = tolower (*p2++);
318 if (c1 == '\0')
319 break;
320 }
321 while (c1 == c2);
322
323 return c1 - c2;
324 }
325 #endif
326
327 #ifdef HAVE_WCHAR_H
328 #ifndef HAVE_WCSCASECMP
329 /* Compare S1 and S2, ignoring case, returning less than, equal to or
330 greater than zero if S1 is lexiographically less than,
331 equal to or greater than S2. */
wcscasecmp(const wchar_t * s1,const wchar_t * s2)332 int wcscasecmp(const wchar_t *s1, const wchar_t *s2)
333 {
334 register const wchar_t *p1 = s1;
335 register const wchar_t *p2 = s2;
336 wchar_t c1, c2;
337
338 if (p1 == p2)
339 return 0;
340
341 do
342 {
343 c1 = towlower (*p1++);
344 c2 = towlower (*p2++);
345 if (c1 == '\0')
346 break;
347 }
348 while (c1 == c2);
349
350 return c1 - c2;
351 }
352 #endif
353 #endif
354
355
356 #ifndef HAVE_STRCASECMP
357 /* Compare S1 and S2, ignoring case, returning less than, equal to or
358 greater than zero if S1 is lexiographically less than,
359 equal to or greater than S2. */
strncasecmp(const char * s1,const char * s2,size_t n)360 int strncasecmp(const char *s1, const char *s2, size_t n)
361 {
362 register const unsigned char *p1 = (const unsigned char *) s1;
363 register const unsigned char *p2 = (const unsigned char *) s2;
364 unsigned char c1, c2;
365
366 if (p1 == p2)
367 return 0;
368
369 c1 = c2 = 1;
370 while (c1 && c1 == c2 && n-- > 0)
371 {
372 c1 = tolower (*p1++);
373 c2 = tolower (*p2++);
374 }
375
376 return c1 - c2;
377 }
378 #endif
379
380 #ifndef HAVE_GETPASS
getpass(const char * prompt)381 char *getpass(const char *prompt)
382 {
383 static char password[129];
384 int l;
385
386 fprintf(stderr,"%s",prompt);
387 fgets(password, 128, stdin);
388 l = strlen(password);
389 if(l && password[l-1] == '\n')
390 password[l-1] = '\0';
391 return password;
392
393 }
394 #endif
395
396 #ifndef HAVE_ATEXIT
397
398 #ifdef HAVE_ON_EXIT
atexit(void (* function)(void))399 int atexit(void (*function)(void))
400 {
401 return on_exit( (void(*)(int,void*)) function, 0);
402 }
403 #else
404
405 typedef struct exitCallback {
406 void (*function) (void);
407 struct exitCallback *next;
408 } exitCallback_t;
409
410 static exitCallback_t *callback = 0;
411
atexit(void (* function)(void))412 int atexit(void (*function) (void))
413 {
414 exitCallback_t *newCallback;
415
416 newCallback = New(exitCallback_t);
417 if(!newCallback) {
418 printOom();
419 exit(1);
420 }
421 newCallback->function = function;
422 newCallback->next = callback;
423 callback = newCallback;
424 return 0;
425 }
426 #undef exit
427
myexit(int code)428 void myexit(int code)
429 {
430 void (*function)(void);
431
432 while(callback) {
433 function = callback->function;
434 callback = callback->next;
435 function();
436 }
437 exit(code);
438 }
439
440 #endif
441
442 #endif
443
444 static const char PATH_SEP = '/';
445
446 /*#ifndef HAVE_BASENAME*/
_basename(const char * filename)447 const char *_basename(const char *filename)
448 {
449 char *ptr;
450
451 ptr = strrchr(filename, PATH_SEP);
452 if(ptr)
453 filename = ptr + 1;
454
455 #ifdef OS_mingw32msvc
456 ptr = strrchr(filename, '\\');
457 if(ptr)
458 filename = ptr + 1;
459 #endif
460
461 return filename;
462 }
463 /*#endif*/
464
465 /* Strip the suffix ".exe" from the argument, if present. */
_stripexe(char * filename)466 void _stripexe(char *filename)
467 {
468 char *ptr;
469 ptr = strrchr(filename, '.');
470 if(ptr && !strcasecmp(ptr, ".exe"))
471 *ptr = '\0';
472 }
473
474 #ifndef HAVE_STRNLEN
strnlen(const char * str,size_t l)475 size_t strnlen(const char *str, size_t l)
476 {
477 size_t i;
478 for(i=0; i<l; i++) {
479 if(str[i] == 0)
480 break;
481 }
482 return i;
483 }
484 #endif /* HAVE_STRNLEN */
485
486 #ifdef HAVE_WCHAR_H
487 #ifndef HAVE_WCSNLEN
wcsnlen(const wchar_t * wcs,size_t l)488 size_t wcsnlen(const wchar_t *wcs, size_t l)
489 {
490 size_t i;
491 for(i=0; i<l; i++) {
492 if(wcs[i] == 0)
493 break;
494 }
495 return i;
496 }
497 #endif /* HAVE_WCSNLEN */
498 #endif
499