lib: replace: Add strsep function (missing on Solaris).
[kai/samba-autobuild/.git] / lib / replace / replace.c
1 /* 
2    Unix SMB/CIFS implementation.
3    replacement routines for broken systems
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jelmer Vernooij 2005-2008
6    Copyright (C) Matthieu Patou  2010
7
8      ** NOTE! The following LGPL license applies to the replace
9      ** library. This does NOT imply that all of Samba is released
10      ** under the LGPL
11    
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU Lesser General Public
14    License as published by the Free Software Foundation; either
15    version 3 of the License, or (at your option) any later version.
16
17    This library is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    Lesser General Public License for more details.
21
22    You should have received a copy of the GNU Lesser General Public
23    License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "replace.h"
27
28 #include "system/filesys.h"
29 #include "system/time.h"
30 #include "system/network.h"
31 #include "system/passwd.h"
32 #include "system/syslog.h"
33 #include "system/locale.h"
34 #include "system/wait.h"
35
36 #ifdef _WIN32
37 #define mkdir(d,m) _mkdir(d)
38 #endif
39
40 void replace_dummy(void);
41 void replace_dummy(void) {}
42
43 #ifndef HAVE_FTRUNCATE
44  /*******************************************************************
45 ftruncate for operating systems that don't have it
46 ********************************************************************/
47 int rep_ftruncate(int f, off_t l)
48 {
49 #ifdef HAVE_CHSIZE
50       return chsize(f,l);
51 #elif defined(F_FREESP)
52       struct  flock   fl;
53
54       fl.l_whence = 0;
55       fl.l_len = 0;
56       fl.l_start = l;
57       fl.l_type = F_WRLCK;
58       return fcntl(f, F_FREESP, &fl);
59 #else
60 #error "you must have a ftruncate function"
61 #endif
62 }
63 #endif /* HAVE_FTRUNCATE */
64
65
66 #ifndef HAVE_STRLCPY
67 /*
68  * Like strncpy but does not 0 fill the buffer and always null
69  * terminates. bufsize is the size of the destination buffer.
70  * Returns the length of s.
71  */
72 size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
73 {
74         size_t len = strlen(s);
75         size_t ret = len;
76
77         if (bufsize <= 0) {
78                 return 0;
79         }
80         if (len >= bufsize) {
81                 len = bufsize - 1;
82         }
83         memcpy(d, s, len);
84         d[len] = 0;
85         return ret;
86 }
87 #endif
88
89 #ifndef HAVE_STRLCAT
90 /* like strncat but does not 0 fill the buffer and always null 
91    terminates. bufsize is the length of the buffer, which should
92    be one more than the maximum resulting string length */
93 size_t rep_strlcat(char *d, const char *s, size_t bufsize)
94 {
95         size_t len1 = strnlen(d, bufsize);
96         size_t len2 = strlen(s);
97         size_t ret = len1 + len2;
98
99         if (len1+len2 >= bufsize) {
100                 if (bufsize < (len1+1)) {
101                         return ret;
102                 }
103                 len2 = bufsize - (len1+1);
104         }
105         if (len2 > 0) {
106                 memcpy(d+len1, s, len2);
107                 d[len1+len2] = 0;
108         }
109         return ret;
110 }
111 #endif
112
113 #ifndef HAVE_MKTIME
114 /*******************************************************************
115 a mktime() replacement for those who don't have it - contributed by 
116 C.A. Lademann <cal@zls.com>
117 Corrections by richard.kettlewell@kewill.com
118 ********************************************************************/
119
120 #define  MINUTE  60
121 #define  HOUR    60*MINUTE
122 #define  DAY             24*HOUR
123 #define  YEAR    365*DAY
124 time_t rep_mktime(struct tm *t)
125 {
126   struct tm       *u;
127   time_t  epoch = 0;
128   int n;
129   int             mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
130   y, m, i;
131
132   if(t->tm_year < 70)
133     return((time_t)-1);
134
135   n = t->tm_year + 1900 - 1;
136   epoch = (t->tm_year - 70) * YEAR + 
137     ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
138
139   y = t->tm_year + 1900;
140   m = 0;
141
142   for(i = 0; i < t->tm_mon; i++) {
143     epoch += mon [m] * DAY;
144     if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
145       epoch += DAY;
146     
147     if(++m > 11) {
148       m = 0;
149       y++;
150     }
151   }
152
153   epoch += (t->tm_mday - 1) * DAY;
154   epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
155   
156   if((u = localtime(&epoch)) != NULL) {
157     t->tm_sec = u->tm_sec;
158     t->tm_min = u->tm_min;
159     t->tm_hour = u->tm_hour;
160     t->tm_mday = u->tm_mday;
161     t->tm_mon = u->tm_mon;
162     t->tm_year = u->tm_year;
163     t->tm_wday = u->tm_wday;
164     t->tm_yday = u->tm_yday;
165     t->tm_isdst = u->tm_isdst;
166   }
167
168   return(epoch);
169 }
170 #endif /* !HAVE_MKTIME */
171
172
173 #ifndef HAVE_INITGROUPS
174 /****************************************************************************
175  some systems don't have an initgroups call 
176 ****************************************************************************/
177 int rep_initgroups(char *name, gid_t id)
178 {
179 #ifndef HAVE_SETGROUPS
180         /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
181         errno = ENOSYS;
182         return -1;
183 #else /* HAVE_SETGROUPS */
184
185 #include <grp.h>
186
187         gid_t *grouplst = NULL;
188         int max_gr = NGROUPS_MAX;
189         int ret;
190         int    i,j;
191         struct group *g;
192         char   *gr;
193         
194         if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
195                 errno = ENOMEM;
196                 return -1;
197         }
198
199         grouplst[0] = id;
200         i = 1;
201         while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
202                 if (g->gr_gid == id)
203                         continue;
204                 j = 0;
205                 gr = g->gr_mem[0];
206                 while (gr && (*gr != (char)NULL)) {
207                         if (strcmp(name,gr) == 0) {
208                                 grouplst[i] = g->gr_gid;
209                                 i++;
210                                 gr = (char *)NULL;
211                                 break;
212                         }
213                         gr = g->gr_mem[++j];
214                 }
215         }
216         endgrent();
217         ret = setgroups(i, grouplst);
218         free(grouplst);
219         return ret;
220 #endif /* HAVE_SETGROUPS */
221 }
222 #endif /* HAVE_INITGROUPS */
223
224
225 #ifndef HAVE_MEMMOVE
226 /*******************************************************************
227 safely copies memory, ensuring no overlap problems.
228 this is only used if the machine does not have its own memmove().
229 this is not the fastest algorithm in town, but it will do for our
230 needs.
231 ********************************************************************/
232 void *rep_memmove(void *dest,const void *src,int size)
233 {
234         unsigned long d,s;
235         int i;
236         if (dest==src || !size) return(dest);
237
238         d = (unsigned long)dest;
239         s = (unsigned long)src;
240
241         if ((d >= (s+size)) || (s >= (d+size))) {
242                 /* no overlap */
243                 memcpy(dest,src,size);
244                 return(dest);
245         }
246
247         if (d < s) {
248                 /* we can forward copy */
249                 if (s-d >= sizeof(int) && 
250                     !(s%sizeof(int)) && 
251                     !(d%sizeof(int)) && 
252                     !(size%sizeof(int))) {
253                         /* do it all as words */
254                         int *idest = (int *)dest;
255                         int *isrc = (int *)src;
256                         size /= sizeof(int);
257                         for (i=0;i<size;i++) idest[i] = isrc[i];
258                 } else {
259                         /* simplest */
260                         char *cdest = (char *)dest;
261                         char *csrc = (char *)src;
262                         for (i=0;i<size;i++) cdest[i] = csrc[i];
263                 }
264         } else {
265                 /* must backward copy */
266                 if (d-s >= sizeof(int) && 
267                     !(s%sizeof(int)) && 
268                     !(d%sizeof(int)) && 
269                     !(size%sizeof(int))) {
270                         /* do it all as words */
271                         int *idest = (int *)dest;
272                         int *isrc = (int *)src;
273                         size /= sizeof(int);
274                         for (i=size-1;i>=0;i--) idest[i] = isrc[i];
275                 } else {
276                         /* simplest */
277                         char *cdest = (char *)dest;
278                         char *csrc = (char *)src;
279                         for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
280                 }      
281         }
282         return(dest);
283 }
284 #endif /* HAVE_MEMMOVE */
285
286 #ifndef HAVE_STRDUP
287 /****************************************************************************
288 duplicate a string
289 ****************************************************************************/
290 char *rep_strdup(const char *s)
291 {
292         size_t len;
293         char *ret;
294
295         if (!s) return(NULL);
296
297         len = strlen(s)+1;
298         ret = (char *)malloc(len);
299         if (!ret) return(NULL);
300         memcpy(ret,s,len);
301         return(ret);
302 }
303 #endif /* HAVE_STRDUP */
304
305 #ifndef HAVE_SETLINEBUF
306 void rep_setlinebuf(FILE *stream)
307 {
308         setvbuf(stream, (char *)NULL, _IOLBF, 0);
309 }
310 #endif /* HAVE_SETLINEBUF */
311
312 #ifndef HAVE_VSYSLOG
313 #ifdef HAVE_SYSLOG
314 void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
315 {
316         char *msg = NULL;
317         vasprintf(&msg, format, arglist);
318         if (!msg)
319                 return;
320         syslog(facility_priority, "%s", msg);
321         free(msg);
322 }
323 #endif /* HAVE_SYSLOG */
324 #endif /* HAVE_VSYSLOG */
325
326 #ifndef HAVE_STRNLEN
327 /**
328  Some platforms don't have strnlen
329 **/
330  size_t rep_strnlen(const char *s, size_t max)
331 {
332         size_t len;
333   
334         for (len = 0; len < max; len++) {
335                 if (s[len] == '\0') {
336                         break;
337                 }
338         }
339         return len;  
340 }
341 #endif
342   
343 #ifndef HAVE_STRNDUP
344 /**
345  Some platforms don't have strndup.
346 **/
347 char *rep_strndup(const char *s, size_t n)
348 {
349         char *ret;
350         
351         n = strnlen(s, n);
352         ret = malloc(n+1);
353         if (!ret)
354                 return NULL;
355         memcpy(ret, s, n);
356         ret[n] = 0;
357
358         return ret;
359 }
360 #endif
361
362 #if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4)
363 int rep_waitpid(pid_t pid,int *status,int options)
364 {
365   return wait4(pid, status, options, NULL);
366 }
367 #endif
368
369 #ifndef HAVE_SETEUID
370 int rep_seteuid(uid_t euid)
371 {
372 #ifdef HAVE_SETRESUID
373         return setresuid(-1, euid, -1);
374 #else
375         errno = ENOSYS;
376         return -1;
377 #endif
378 }
379 #endif
380
381 #ifndef HAVE_SETEGID
382 int rep_setegid(gid_t egid)
383 {
384 #ifdef HAVE_SETRESGID
385         return setresgid(-1, egid, -1);
386 #else
387         errno = ENOSYS;
388         return -1;
389 #endif
390 }
391 #endif
392
393 /*******************************************************************
394 os/2 also doesn't have chroot
395 ********************************************************************/
396 #ifndef HAVE_CHROOT
397 int rep_chroot(const char *dname)
398 {
399         errno = ENOSYS;
400         return -1;
401 }
402 #endif
403
404 /*****************************************************************
405  Possibly replace mkstemp if it is broken.
406 *****************************************************************/  
407
408 #ifndef HAVE_SECURE_MKSTEMP
409 int rep_mkstemp(char *template)
410 {
411         /* have a reasonable go at emulating it. Hope that
412            the system mktemp() isn't completely hopeless */
413         mktemp(template);
414         if (template[0] == 0)
415                 return -1;
416         return open(template, O_CREAT|O_EXCL|O_RDWR, 0600);
417 }
418 #endif
419
420 #ifndef HAVE_MKDTEMP
421 char *rep_mkdtemp(char *template)
422 {
423         char *dname;
424         
425         if ((dname = mktemp(template))) {
426                 if (mkdir(dname, 0700) >= 0) {
427                         return dname;
428                 }
429         }
430
431         return NULL;
432 }
433 #endif
434
435 /*****************************************************************
436  Watch out: this is not thread safe.
437 *****************************************************************/
438
439 #ifndef HAVE_PREAD
440 ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
441 {
442         if (lseek(__fd, __offset, SEEK_SET) != __offset) {
443                 return -1;
444         }
445         return read(__fd, __buf, __nbytes);
446 }
447 #endif
448
449 /*****************************************************************
450  Watch out: this is not thread safe.
451 *****************************************************************/
452
453 #ifndef HAVE_PWRITE
454 ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
455 {
456         if (lseek(__fd, __offset, SEEK_SET) != __offset) {
457                 return -1;
458         }
459         return write(__fd, __buf, __nbytes);
460 }
461 #endif
462
463 #ifndef HAVE_STRCASESTR
464 char *rep_strcasestr(const char *haystack, const char *needle)
465 {
466         const char *s;
467         size_t nlen = strlen(needle);
468         for (s=haystack;*s;s++) {
469                 if (toupper(*needle) == toupper(*s) &&
470                     strncasecmp(s, needle, nlen) == 0) {
471                         return (char *)((uintptr_t)s);
472                 }
473         }
474         return NULL;
475 }
476 #endif
477
478 #ifndef HAVE_STRSEP
479 char *rep_strsep(char **pps, const char *delim)
480 {
481         char *ret = *pps;
482         char *p = *pps;
483
484         if (p == NULL) {
485                 return NULL;
486         }
487         p += strcspn(p, delim);
488         if (*p == '\0') {
489                 *pps = NULL;
490         } else {
491                 *p = '\0';
492                 *pps = p + 1;
493         }
494         return ret;
495 }
496 #endif
497
498 #ifndef HAVE_STRTOK_R
499 /* based on GLIBC version, copyright Free Software Foundation */
500 char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
501 {
502         char *token;
503
504         if (s == NULL) s = *save_ptr;
505
506         s += strspn(s, delim);
507         if (*s == '\0') {
508                 *save_ptr = s;
509                 return NULL;
510         }
511
512         token = s;
513         s = strpbrk(token, delim);
514         if (s == NULL) {
515                 *save_ptr = token + strlen(token);
516         } else {
517                 *s = '\0';
518                 *save_ptr = s + 1;
519         }
520
521         return token;
522 }
523 #endif
524
525
526 #ifndef HAVE_STRTOLL
527 long long int rep_strtoll(const char *str, char **endptr, int base)
528 {
529 #ifdef HAVE_STRTOQ
530         return strtoq(str, endptr, base);
531 #elif defined(HAVE___STRTOLL) 
532         return __strtoll(str, endptr, base);
533 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
534         return (long long int) strtol(str, endptr, base);
535 #else
536 # error "You need a strtoll function"
537 #endif
538 }
539 #else
540 #ifdef HAVE_BSD_STRTOLL
541 long long int rep_strtoll(const char *str, char **endptr, int base)
542 {
543         long long int nb = strtoll(str, endptr, base);
544         /* With glibc EINVAL is only returned if base is not ok */
545         if (errno == EINVAL) {
546                 if (base == 0 || (base >1 && base <37)) {
547                         /* Base was ok so it's because we were not
548                          * able to make the convertion.
549                          * Let's reset errno.
550                          */
551                         errno = 0;
552                 }
553         }
554         return nb;
555 }
556 #endif /* HAVE_BSD_STRTOLL */
557 #endif /* HAVE_STRTOLL */
558
559
560 #ifndef HAVE_STRTOULL
561 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
562 {
563 #ifdef HAVE_STRTOUQ
564         return strtouq(str, endptr, base);
565 #elif defined(HAVE___STRTOULL) 
566         return __strtoull(str, endptr, base);
567 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
568         return (unsigned long long int) strtoul(str, endptr, base);
569 #else
570 # error "You need a strtoull function"
571 #endif
572 }
573 #else
574 #ifdef HAVE_BSD_STRTOLL
575 #ifdef HAVE_STRTOUQ
576 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
577 {
578         unsigned long long int nb = strtouq(str, endptr, base);
579         /* In linux EINVAL is only returned if base is not ok */
580         if (errno == EINVAL) {
581                 if (base == 0 || (base >1 && base <37)) {
582                         /* Base was ok so it's because we were not
583                          * able to make the convertion.
584                          * Let's reset errno.
585                          */
586                         errno = 0;
587                 }
588         }
589         return nb;
590 }
591 #else
592 #error "You need the strtouq function"
593 #endif /* HAVE_STRTOUQ */
594 #endif /* HAVE_BSD_STRTOLL */
595 #endif /* HAVE_STRTOULL */
596
597 #ifndef HAVE_SETENV
598 int rep_setenv(const char *name, const char *value, int overwrite) 
599 {
600         char *p;
601         size_t l1, l2;
602         int ret;
603
604         if (!overwrite && getenv(name)) {
605                 return 0;
606         }
607
608         l1 = strlen(name);
609         l2 = strlen(value);
610
611         p = malloc(l1+l2+2);
612         if (p == NULL) {
613                 return -1;
614         }
615         memcpy(p, name, l1);
616         p[l1] = '=';
617         memcpy(p+l1+1, value, l2);
618         p[l1+l2+1] = 0;
619
620         ret = putenv(p);
621         if (ret != 0) {
622                 free(p);
623         }
624
625         return ret;
626 }
627 #endif
628
629 #ifndef HAVE_UNSETENV
630 int rep_unsetenv(const char *name)
631 {
632         extern char **environ;
633         size_t len = strlen(name);
634         size_t i, count;
635
636         if (environ == NULL || getenv(name) == NULL) {
637                 return 0;
638         }
639
640         for (i=0;environ[i];i++) /* noop */ ;
641
642         count=i;
643         
644         for (i=0;i<count;) {
645                 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
646                         /* note: we do _not_ free the old variable here. It is unsafe to 
647                            do so, as the pointer may not have come from malloc */
648                         memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
649                         count--;
650                 } else {
651                         i++;
652                 }
653         }
654
655         return 0;
656 }
657 #endif
658
659 #ifndef HAVE_UTIME
660 int rep_utime(const char *filename, const struct utimbuf *buf)
661 {
662         errno = ENOSYS;
663         return -1;
664 }
665 #endif
666
667 #ifndef HAVE_UTIMES
668 int rep_utimes(const char *filename, const struct timeval tv[2])
669 {
670         struct utimbuf u;
671
672         u.actime = tv[0].tv_sec;
673         if (tv[0].tv_usec > 500000) {
674                 u.actime += 1;
675         }
676
677         u.modtime = tv[1].tv_sec;
678         if (tv[1].tv_usec > 500000) {
679                 u.modtime += 1;
680         }
681
682         return utime(filename, &u);
683 }
684 #endif
685
686 #ifndef HAVE_DUP2
687 int rep_dup2(int oldfd, int newfd) 
688 {
689         errno = ENOSYS;
690         return -1;
691 }
692 #endif
693
694 #ifndef HAVE_CHOWN
695 /**
696 chown isn't used much but OS/2 doesn't have it
697 **/
698 int rep_chown(const char *fname, uid_t uid, gid_t gid)
699 {
700         errno = ENOSYS;
701         return -1;
702 }
703 #endif
704
705 #ifndef HAVE_LINK
706 int rep_link(const char *oldpath, const char *newpath)
707 {
708         errno = ENOSYS;
709         return -1;
710 }
711 #endif
712
713 #ifndef HAVE_READLINK
714 int rep_readlink(const char *path, char *buf, size_t bufsiz)
715 {
716         errno = ENOSYS;
717         return -1;
718 }
719 #endif
720
721 #ifndef HAVE_SYMLINK
722 int rep_symlink(const char *oldpath, const char *newpath)
723 {
724         errno = ENOSYS;
725         return -1;
726 }
727 #endif
728
729 #ifndef HAVE_LCHOWN
730 int rep_lchown(const char *fname,uid_t uid,gid_t gid)
731 {
732         errno = ENOSYS;
733         return -1;
734 }
735 #endif
736
737 #ifndef HAVE_REALPATH
738 char *rep_realpath(const char *path, char *resolved_path)
739 {
740         /* As realpath is not a system call we can't return ENOSYS. */
741         errno = EINVAL;
742         return NULL;
743 }
744 #endif
745
746
747 #ifndef HAVE_MEMMEM
748 void *rep_memmem(const void *haystack, size_t haystacklen,
749                  const void *needle, size_t needlelen)
750 {
751         if (needlelen == 0) {
752                 return discard_const(haystack);
753         }
754         while (haystacklen >= needlelen) {
755                 char *p = (char *)memchr(haystack, *(const char *)needle,
756                                          haystacklen-(needlelen-1));
757                 if (!p) return NULL;
758                 if (memcmp(p, needle, needlelen) == 0) {
759                         return p;
760                 }
761                 haystack = p+1;
762                 haystacklen -= (p - (const char *)haystack) + 1;
763         }
764         return NULL;
765 }
766 #endif
767
768 #if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF)
769 int rep_vdprintf(int fd, const char *format, va_list ap)
770 {
771         char *s = NULL;
772         int ret;
773
774         vasprintf(&s, format, ap);
775         if (s == NULL) {
776                 errno = ENOMEM;
777                 return -1;
778         }
779         ret = write(fd, s, strlen(s));
780         free(s);
781         return ret;
782 }
783 #endif
784
785 #if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF)
786 int rep_dprintf(int fd, const char *format, ...)
787 {
788         int ret;
789         va_list ap;
790
791         va_start(ap, format);
792         ret = vdprintf(fd, format, ap);
793         va_end(ap);
794
795         return ret;
796 }
797 #endif
798
799 #ifndef HAVE_GET_CURRENT_DIR_NAME
800 char *rep_get_current_dir_name(void)
801 {
802         char buf[PATH_MAX+1];
803         char *p;
804         p = getcwd(buf, sizeof(buf));
805         if (p == NULL) {
806                 return NULL;
807         }
808         return strdup(p);
809 }
810 #endif
811
812 #ifndef HAVE_STRERROR_R
813 int rep_strerror_r(int errnum, char *buf, size_t buflen)
814 {
815         char *s = strerror(errnum);
816         if (strlen(s)+1 > buflen) {
817                 errno = ERANGE;
818                 return -1;
819         }
820         strncpy(buf, s, buflen);
821         return 0;
822 }
823 #endif
824
825 #ifndef HAVE_CLOCK_GETTIME
826 int rep_clock_gettime(clockid_t clk_id, struct timespec *tp)
827 {
828         struct timeval tval;
829         switch (clk_id) {
830                 case 0: /* CLOCK_REALTIME :*/
831 #ifdef HAVE_GETTIMEOFDAY_TZ
832                         gettimeofday(&tval,NULL);
833 #else
834                         gettimeofday(&tval);
835 #endif
836                         tp->tv_sec = tval.tv_sec;
837                         tp->tv_nsec = tval.tv_usec * 1000;
838                         break;
839                 default:
840                         errno = EINVAL;
841                         return -1;
842         }
843         return 0;
844 }
845 #endif
846
847 #ifndef HAVE_MEMALIGN
848 void *rep_memalign( size_t align, size_t size )
849 {
850 #if defined(HAVE_POSIX_MEMALIGN)
851         void *p = NULL;
852         int ret = posix_memalign( &p, align, size );
853         if ( ret == 0 )
854                 return p;
855
856         return NULL;
857 #else
858         /* On *BSD systems memaligns doesn't exist, but memory will
859          * be aligned on allocations of > pagesize. */
860 #if defined(SYSCONF_SC_PAGESIZE)
861         size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
862 #elif defined(HAVE_GETPAGESIZE)
863         size_t pagesize = (size_t)getpagesize();
864 #else
865         size_t pagesize = (size_t)-1;
866 #endif
867         if (pagesize == (size_t)-1) {
868                 errno = ENOSYS;
869                 return NULL;
870         }
871         if (size < pagesize) {
872                 size = pagesize;
873         }
874         return malloc(size);
875 #endif
876 }
877 #endif
878
879 #ifndef HAVE_GETPEEREID
880 int rep_getpeereid(int s, uid_t *uid, gid_t *gid)
881 {
882 #if defined(HAVE_PEERCRED)
883         struct ucred cred;
884         socklen_t cred_len = sizeof(struct ucred);
885         int ret;
886
887 #undef getsockopt
888         ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
889         if (ret != 0) {
890                 return -1;
891         }
892
893         if (cred_len != sizeof(struct ucred)) {
894                 errno = EINVAL;
895                 return -1;
896         }
897
898         *uid = cred.uid;
899         *gid = cred.gid;
900         return 0;
901 #else
902         errno = ENOSYS;
903         return -1;
904 #endif
905 }
906 #endif
907
908 #ifndef HAVE_USLEEP
909 int rep_usleep(useconds_t sec)
910 {
911         struct timeval tval;
912         /*
913          * Fake it with select...
914          */
915         tval.tv_sec = 0;
916         tval.tv_usec = usecs/1000;
917         select(0,NULL,NULL,NULL,&tval);
918         return 0;
919 }
920 #endif /* HAVE_USLEEP */
921
922 #ifndef HAVE_SETPROCTITLE
923 void rep_setproctitle(const char *fmt, ...)
924 {
925 }
926 #endif