• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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