1 #include "links.h"
2 
3 #ifndef HAVE_SNPRINTF
4 
5 #define B_SZ	65536
6 
7 static char snprtintf_buffer[B_SZ];
8 
my_snprintf(char * str,int n,char * f,...)9 int my_snprintf(char *str, int n, char *f, ...)
10 {
11 	int i;
12 	va_list l;
13 	if (!n) return -1;
14 	va_start(l, f);
15 #ifdef HAVE_VPRINTF
16 	vsprintf(snprtintf_buffer, f, l);
17 #elif defined(HAVE_DOPRNT)
18 	{
19 		struct _iobuf strbuf;
20 		strbuf._flag = _IOWRT+_IOSTRG;
21 		strbuf._ptr = snprtintf_buffer;
22 		strbuf._cnt = 32767;
23 		_doprnt(f, l, &strbuf);
24 		putc('\0', &strbuf);
25 	}
26 #else
27 	fatal_exit("No vsprintf!");
28 #endif
29 	va_end(l);
30 	i = strlen(snprtintf_buffer);
31 	if (i >= B_SZ) {
32 		fatal_exit("String size too large!");
33 	}
34 	if (i >= n) {
35 		memcpy(str, snprtintf_buffer, n);
36 		str[n - 1] = 0;
37 		return -1;
38 	}
39 	strcpy(str, snprtintf_buffer);
40 	return i;
41 }
42 
43 #endif
44 
45 #ifndef HAVE_RAISE
raise(int s)46 int raise(int s)
47 {
48 #ifdef HAVE_GETPID
49 	pid_t p;
50 	EINTRLOOP(p, getpid());
51 	if (p == -1) return -1;
52 	return kill(p, s);
53 #else
54 	return 0;
55 #endif
56 };
57 #endif
58 #ifndef HAVE_GETTIMEOFDAY
gettimeofday(struct timeval * tv,struct timezone * tz)59 int gettimeofday(struct timeval *tv, struct timezone *tz)
60 {
61 	time_t t;
62 	errno = 0;
63 	EINTRLOOPX(t, time(NULL), (time_t)-1);
64 	if (tv) tv->tv_sec = t, tv->tv_usec = 0;
65 	if (tz) tz->tz_minuteswest = tz->tz_dsttime = 0;
66 	return 0;
67 }
68 #endif
69 #ifndef HAVE_GETCWD
getcwd(char * buf,size_t size)70 char *getcwd(char *buf, size_t size)
71 {
72 #ifndef MAXPATHLEN
73 #define	MAXPATHLEN	1024
74 #endif
75 	static char cwd[MAXPATHLEN];
76 	if (!getwd(cwd))
77 		return NULL;
78 	if (strlen(cwd) >= size) {
79 		errno = ERANGE;
80 		return NULL;
81 	}
82 	strcpy(buf, cwd);
83 	return 0;
84 }
85 #endif
86 #ifndef HAVE_TEMPNAM
tempnam(const char * dir,const char * pfx)87 char *tempnam(const char *dir, const char *pfx)
88 {
89 	static int counter = 0;
90 	unsigned char *d, *s, *a;
91 	int l;
92 	if (!(d = cast_uchar getenv("TMPDIR"))) {
93 		if (dir) d = cast_uchar dir;
94 		else if (!(d = cast_uchar getenv("TMP")) && !(d = cast_uchar getenv("TEMP"))) {
95 #ifdef P_tmpdir
96 			d = cast_uchar(P_tmpdir);
97 #else
98 			d = cast_uchar "/tmp";
99 #endif
100 		}
101 	}
102 	l = 0;
103 	s = init_str();
104 	add_to_str(&s, &l, d);
105 	if (s[0] && s[strlen(cast_const_char s) - 1] != '/') add_chr_to_str(&s, &l, '/');
106 	add_to_str(&s, &l, cast_uchar pfx);
107 	add_num_to_str(&s, &l, counter++);
108 	a = cast_uchar strdup(cast_const_char s);
109 	mem_free(s);
110 	return cast_char a;
111 }
112 #endif
113 #ifndef HAVE_STRDUP
strdup(const char * s)114 char *strdup(const char *s)
115 {
116 	char *a = malloc(strlen(s) + 1);
117 	if (!a) return NULL;
118 	return strcpy(a, s);
119 }
120 #endif
121 #ifndef HAVE_STRTOL
strtol(const char * nptr,char ** endptr,int base)122 long strtol(const char *nptr, char **endptr, int base)
123 {
124 	unsigned long result;
125 	char negative = 0;
126 	if (*nptr == '-') {
127 		negative = 1;
128 		nptr++;
129 	}
130 	result = 0;
131 	while (1) {
132 		char c = *nptr;
133 		char val;
134 		unsigned long nr;
135 		if (c >= '0' && c <= '9') val = c - '0';
136 		else if (c >= 'A' && c <= 'Z') val = c - 'A' + 10;
137 		else if (c >= 'a' && c <= 'z') val = c - 'a' + 10;
138 		else break;
139 		if (val >= base) break;
140 		nr = result * base + val;
141 		if ((long)nr < val || (nr - val) / base != result) break;
142 		result = nr;
143 		nptr++;
144 	}
145 	if (endptr) *endptr = (char *)nptr;
146 	if (negative) return -result;
147 	return result;
148 }
149 #endif
150 #ifndef HAVE_STRTOUL
strtoul(const char * nptr,char ** endptr,int base)151 unsigned long strtoul(const char *nptr, char **endptr, int base)
152 {
153 	if (*nptr == '-') {
154 		if (endptr) *endptr = nptr;
155 		return 0;
156 	}
157 	return (unsigned long)strtol(nptr,endptr,base);
158 };
159 #endif
160 #ifndef HAVE_STRTOD
strtod(const char * nptr,char ** endptr)161 double strtod(const char *nptr, char **endptr)
162 {
163 	double d = 0;
164 	char dummy;
165 	if (endptr) *endptr = (char *)nptr;
166 	if (sscanf(nptr, "%lf%c", &d, &dummy) == 1) {
167 		if (endptr) *endptr = strchr(nptr, 0);
168 	}
169 	return d;
170 }
171 #endif
172 #ifndef HAVE_STRLEN
strlen(const char * s)173 size_t strlen(const char *s)
174 {
175 	size_t len = 0;
176 	while (s[len]) len++;
177 	return len;
178 }
179 #endif
180 #ifndef HAVE_STRNLEN
strnlen(const char * s,size_t max)181 size_t strnlen(const char *s, size_t max)
182 {
183 	size_t len = 0;
184 	while (len < max && s[len]) len++;
185 	return len;
186 }
187 #endif
188 #ifndef HAVE_STRCPY
strcpy(char * dst,const char * src)189 char *strcpy(char *dst, const char *src)
190 {
191 	return memcpy(dst, src, strlen(src) + 1);
192 }
193 #endif
194 #ifndef HAVE_STRNCPY
strncpy(char * dst,const char * src,size_t len)195 char *strncpy(char *dst, const char *src, size_t len)
196 {
197 	size_t sl = strlen(src);
198 	if (sl >= len) {
199 		memcpy(dst, src, len);
200 	} else {
201 		memcpy(dst, src, sl);
202 		memset(dst + sl, 0, len - sl);
203 	}
204 	return dst;
205 }
206 #endif
207 #ifndef HAVE_STRCHR
strchr(const char * s,int c)208 char *strchr(const char *s, int c)
209 {
210 	do {
211 		if (*s == (char)c)
212 			return (char *)s;
213 	} while (*s++);
214 	return NULL;
215 }
216 #endif
217 #ifndef HAVE_STRRCHR
strrchr(const char * s,int c)218 char *strrchr(const char *s, int c)
219 {
220 	char *ret = NULL;
221 	do {
222 		if (*s == (char)c)
223 			ret = (char *)s;
224 	} while (*s++);
225 	return ret;
226 }
227 #endif
228 #ifndef HAVE_STRCMP
strcmp(const char * s1,const char * s2)229 int strcmp(const char *s1, const char *s2)
230 {
231 	while (1) {
232 		unsigned char c1 = (unsigned char)*s1;
233 		unsigned char c2 = (unsigned char)*s2;
234 		if (c1 != c2) {
235 			return (int)c1 - (int)c2;
236 		}
237 		if (!c1) break;
238 		s1++, s2++;
239 	}
240 	return 0;
241 }
242 #endif
243 #ifndef HAVE_STRNCMP
strncmp(const char * s1,const char * s2,size_t n)244 int strncmp(const char *s1, const char *s2, size_t n)
245 {
246 	while (n--) {
247 		unsigned char c1 = (unsigned char)*s1;
248 		unsigned char c2 = (unsigned char)*s2;
249 		if (c1 != c2) {
250 			return (int)c1 - (int)c2;
251 		}
252 		if (!c1) break;
253 		s1++, s2++;
254 	}
255 	return 0;
256 }
257 #endif
258 #ifndef HAVE_STRCSPN
strcspn(const char * s,const char * reject)259 size_t strcspn(const char *s, const char *reject)
260 {
261 	size_t r;
262 	for (r = 0; *s; r++, s++) {
263 		const char *rj;
264 		for (rj = reject; *rj; rj++) if (*s == *rj) goto brk;
265 	}
266 	brk:
267 	return r;
268 }
269 #endif
270 #ifndef HAVE_STRSPN
strspn(const char * s,const char * accept)271 size_t strspn(const char *s, const char *accept)
272 {
273 	size_t r;
274 	for (r = 0; *s; r++, s++) {
275 		const char *rj;
276 		for (rj = accept; *rj; rj++) if (*s == *rj) goto ac;
277 		break;
278 		ac:;
279 	}
280 	return r;
281 }
282 #endif
283 #ifndef HAVE_STRSTR
strstr(const char * haystack,const char * needle)284 char *strstr(const char *haystack, const char *needle)
285 {
286 	size_t hs = strlen(haystack);
287 	size_t ns = strlen(needle);
288 	if (!ns) return (char *)haystack;
289 	while (hs >= ns) {
290 		if (*haystack == *needle && !memcmp(haystack, needle, ns)) return (char *)haystack;
291 		haystack++, hs--;
292 	}
293 	return NULL;
294 }
295 #endif
296 #ifndef HAVE_MEMCHR
memchr(const void * s,int c,size_t length)297 void *memchr(const void *s, int c, size_t length)
298 {
299 	const char *sp = s;
300 	while (length--) {
301 		if (*sp == (char)c)
302 			return (char *)s;
303 		sp++;
304 	}
305 	return NULL;
306 }
307 #endif
308 #ifndef HAVE_MEMRCHR
memrchr(const void * s,int c,size_t length)309 void *memrchr(const void *s, int c, size_t length)
310 {
311 	const char *sp = s;
312 	char *ret = NULL;
313 	while (length--) {
314 		if (*sp == (char)c)
315 			ret = (char *)s;
316 		sp++;
317 	}
318 	return ret;
319 }
320 #endif
321 #ifndef HAVE_MEMCMP
memcmp(const void * src0,const void * src1,size_t length)322 int memcmp(const void *src0, const void *src1, size_t length)
323 {
324 	const unsigned char *s0, *s1;
325 #ifdef HAVE_BCMP
326 	if (!bcmp(src0, src1, length))
327 		return 0;
328 #endif
329 	s0 = src0;
330 	s1 = src1;
331 	while (length--) {
332 		int c = *s0 - *s1;
333 		if (c) return c;
334 		s0++, s1++;
335 	}
336 	return 0;
337 }
338 #endif
339 #ifndef HAVE_MEMCPY
memcpy(void * dst0,const void * src0,size_t length)340 void *memcpy(void *dst0, const void *src0, size_t length)
341 {
342 	return memmove(dst0, src0, length);
343 }
344 #endif
345 #ifndef HAVE_MEMMOVE
memmove(void * dst0,const void * src0,size_t length)346 void *memmove(void *dst0, const void *src0, size_t length)
347 {
348 #ifdef HAVE_BCOPY
349 	bcopy(src0, dst0, length);
350 	return dst0;
351 #else
352 	unsigned char *dst = dst0;
353 	const unsigned char *src = src0;
354 
355 	if ((const unsigned char *)dst == src || !length)
356 		return dst0;
357 
358 	if ((const unsigned char *)dst <= src) {
359 		while (length--) *dst++ = *src++;
360 	} else {
361 		dst += length - 1;
362 		src += length - 1;
363 		while (length--) *dst-- = *src--;
364 	}
365 	return dst0;
366 #endif
367 }
368 #endif
369 #ifndef HAVE_MEMSET
memset(void * s,int c,size_t n)370 void *memset(void *s, int c, size_t n)
371 {
372 	char *sc = s;
373 #ifdef HAVE_BZERO
374 	if (!c) bzero(s, n);
375 	else
376 #endif
377 	while (n--) *sc++ = c;
378 	return s;
379 }
380 #endif
381 #ifndef HAVE_MEMMEM
memmem(const void * haystack,size_t hs,const void * needle,size_t ns)382 void *memmem(const void *haystack, size_t hs, const void *needle, size_t ns)
383 {
384 	if (!ns) return (void *)haystack;
385 	while (hs >= ns) {
386 		if (*(const char *)haystack == *(const char *)needle && !memcmp(haystack, needle, ns)) return (void *)haystack;
387 		haystack = (const void *)((const char *)haystack + 1), hs--;
388 	}
389 	return NULL;
390 }
391 #endif
392 #ifndef HAVE_STRERROR
393 extern char *sys_errlist[];
394 extern int sys_nerr;
strerror(int errnum)395 char *strerror(int errnum)
396 {
397 	if (errnum < 0 || errnum >= sys_nerr) return "Unknown error";
398 	return sys_errlist[errnum];
399 };
400 #endif
401