libreplace: Fix the build on Solaris
[sfrench/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 #undef strtoll
542 long long int rep_strtoll(const char *str, char **endptr, int base)
543 {
544         long long int nb = strtoll(str, endptr, base);
545         /* With glibc EINVAL is only returned if base is not ok */
546         if (errno == EINVAL) {
547                 if (base == 0 || (base >1 && base <37)) {
548                         /* Base was ok so it's because we were not
549                          * able to make the convertion.
550                          * Let's reset errno.
551                          */
552                         errno = 0;
553                 }
554         }
555         return nb;
556 }
557 #endif /* HAVE_BSD_STRTOLL */
558 #endif /* HAVE_STRTOLL */
559
560
561 #ifndef HAVE_STRTOULL
562 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
563 {
564 #ifdef HAVE_STRTOUQ
565         return strtouq(str, endptr, base);
566 #elif defined(HAVE___STRTOULL) 
567         return __strtoull(str, endptr, base);
568 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
569         return (unsigned long long int) strtoul(str, endptr, base);
570 #else
571 # error "You need a strtoull function"
572 #endif
573 }
574 #else
575 #ifdef HAVE_BSD_STRTOLL
576 #ifdef HAVE_STRTOUQ
577 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
578 {
579         unsigned long long int nb = strtouq(str, endptr, base);
580         /* In linux EINVAL is only returned if base is not ok */
581         if (errno == EINVAL) {
582                 if (base == 0 || (base >1 && base <37)) {
583                         /* Base was ok so it's because we were not
584                          * able to make the convertion.
585                          * Let's reset errno.
586                          */
587                         errno = 0;
588                 }
589         }
590         return nb;
591 }
592 #else
593 #error "You need the strtouq function"
594 #endif /* HAVE_STRTOUQ */
595 #endif /* HAVE_BSD_STRTOLL */
596 #endif /* HAVE_STRTOULL */
597
598 #ifndef HAVE_SETENV
599 int rep_setenv(const char *name, const char *value, int overwrite) 
600 {
601         char *p;
602         size_t l1, l2;
603         int ret;
604
605         if (!overwrite && getenv(name)) {
606                 return 0;
607         }
608
609         l1 = strlen(name);
610         l2 = strlen(value);
611
612         p = malloc(l1+l2+2);
613         if (p == NULL) {
614                 return -1;
615         }
616         memcpy(p, name, l1);
617         p[l1] = '=';
618         memcpy(p+l1+1, value, l2);
619         p[l1+l2+1] = 0;
620
621         ret = putenv(p);
622         if (ret != 0) {
623                 free(p);
624         }
625
626         return ret;
627 }
628 #endif
629
630 #ifndef HAVE_UNSETENV
631 int rep_unsetenv(const char *name)
632 {
633         extern char **environ;
634         size_t len = strlen(name);
635         size_t i, count;
636
637         if (environ == NULL || getenv(name) == NULL) {
638                 return 0;
639         }
640
641         for (i=0;environ[i];i++) /* noop */ ;
642
643         count=i;
644         
645         for (i=0;i<count;) {
646                 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
647                         /* note: we do _not_ free the old variable here. It is unsafe to 
648                            do so, as the pointer may not have come from malloc */
649                         memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
650                         count--;
651                 } else {
652                         i++;
653                 }
654         }
655
656         return 0;
657 }
658 #endif
659
660 #ifndef HAVE_UTIME
661 int rep_utime(const char *filename, const struct utimbuf *buf)
662 {
663         errno = ENOSYS;
664         return -1;
665 }
666 #endif
667
668 #ifndef HAVE_UTIMES
669 int rep_utimes(const char *filename, const struct timeval tv[2])
670 {
671         struct utimbuf u;
672
673         u.actime = tv[0].tv_sec;
674         if (tv[0].tv_usec > 500000) {
675                 u.actime += 1;
676         }
677
678         u.modtime = tv[1].tv_sec;
679         if (tv[1].tv_usec > 500000) {
680                 u.modtime += 1;
681         }
682
683         return utime(filename, &u);
684 }
685 #endif
686
687 #ifndef HAVE_DUP2
688 int rep_dup2(int oldfd, int newfd) 
689 {
690         errno = ENOSYS;
691         return -1;
692 }
693 #endif
694
695 #ifndef HAVE_CHOWN
696 /**
697 chown isn't used much but OS/2 doesn't have it
698 **/
699 int rep_chown(const char *fname, uid_t uid, gid_t gid)
700 {
701         errno = ENOSYS;
702         return -1;
703 }
704 #endif
705
706 #ifndef HAVE_LINK
707 int rep_link(const char *oldpath, const char *newpath)
708 {
709         errno = ENOSYS;
710         return -1;
711 }
712 #endif
713
714 #ifndef HAVE_READLINK
715 int rep_readlink(const char *path, char *buf, size_t bufsiz)
716 {
717         errno = ENOSYS;
718         return -1;
719 }
720 #endif
721
722 #ifndef HAVE_SYMLINK
723 int rep_symlink(const char *oldpath, const char *newpath)
724 {
725         errno = ENOSYS;
726         return -1;
727 }
728 #endif
729
730 #ifndef HAVE_LCHOWN
731 int rep_lchown(const char *fname,uid_t uid,gid_t gid)
732 {
733         errno = ENOSYS;
734         return -1;
735 }
736 #endif
737
738 #ifndef HAVE_REALPATH
739 char *rep_realpath(const char *path, char *resolved_path)
740 {
741         /* As realpath is not a system call we can't return ENOSYS. */
742         errno = EINVAL;
743         return NULL;
744 }
745 #endif
746
747
748 #ifndef HAVE_MEMMEM
749 void *rep_memmem(const void *haystack, size_t haystacklen,
750                  const void *needle, size_t needlelen)
751 {
752         if (needlelen == 0) {
753                 return discard_const(haystack);
754         }
755         while (haystacklen >= needlelen) {
756                 char *p = (char *)memchr(haystack, *(const char *)needle,
757                                          haystacklen-(needlelen-1));
758                 if (!p) return NULL;
759                 if (memcmp(p, needle, needlelen) == 0) {
760                         return p;
761                 }
762                 haystack = p+1;
763                 haystacklen -= (p - (const char *)haystack) + 1;
764         }
765         return NULL;
766 }
767 #endif
768
769 #if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF)
770 int rep_vdprintf(int fd, const char *format, va_list ap)
771 {
772         char *s = NULL;
773         int ret;
774
775         vasprintf(&s, format, ap);
776         if (s == NULL) {
777                 errno = ENOMEM;
778                 return -1;
779         }
780         ret = write(fd, s, strlen(s));
781         free(s);
782         return ret;
783 }
784 #endif
785
786 #if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF)
787 int rep_dprintf(int fd, const char *format, ...)
788 {
789         int ret;
790         va_list ap;
791
792         va_start(ap, format);
793         ret = vdprintf(fd, format, ap);
794         va_end(ap);
795
796         return ret;
797 }
798 #endif
799
800 #ifndef HAVE_GET_CURRENT_DIR_NAME
801 char *rep_get_current_dir_name(void)
802 {
803         char buf[PATH_MAX+1];
804         char *p;
805         p = getcwd(buf, sizeof(buf));
806         if (p == NULL) {
807                 return NULL;
808         }
809         return strdup(p);
810 }
811 #endif
812
813 #ifndef HAVE_STRERROR_R
814 int rep_strerror_r(int errnum, char *buf, size_t buflen)
815 {
816         char *s = strerror(errnum);
817         if (strlen(s)+1 > buflen) {
818                 errno = ERANGE;
819                 return -1;
820         }
821         strncpy(buf, s, buflen);
822         return 0;
823 }
824 #endif
825
826 #ifndef HAVE_CLOCK_GETTIME
827 int rep_clock_gettime(clockid_t clk_id, struct timespec *tp)
828 {
829         struct timeval tval;
830         switch (clk_id) {
831                 case 0: /* CLOCK_REALTIME :*/
832 #if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
833                         gettimeofday(&tval,NULL);
834 #else
835                         gettimeofday(&tval);
836 #endif
837                         tp->tv_sec = tval.tv_sec;
838                         tp->tv_nsec = tval.tv_usec * 1000;
839                         break;
840                 default:
841                         errno = EINVAL;
842                         return -1;
843         }
844         return 0;
845 }
846 #endif
847
848 #ifndef HAVE_MEMALIGN
849 void *rep_memalign( size_t align, size_t size )
850 {
851 #if defined(HAVE_POSIX_MEMALIGN)
852         void *p = NULL;
853         int ret = posix_memalign( &p, align, size );
854         if ( ret == 0 )
855                 return p;
856
857         return NULL;
858 #else
859         /* On *BSD systems memaligns doesn't exist, but memory will
860          * be aligned on allocations of > pagesize. */
861 #if defined(SYSCONF_SC_PAGESIZE)
862         size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
863 #elif defined(HAVE_GETPAGESIZE)
864         size_t pagesize = (size_t)getpagesize();
865 #else
866         size_t pagesize = (size_t)-1;
867 #endif
868         if (pagesize == (size_t)-1) {
869                 errno = ENOSYS;
870                 return NULL;
871         }
872         if (size < pagesize) {
873                 size = pagesize;
874         }
875         return malloc(size);
876 #endif
877 }
878 #endif
879
880 #ifndef HAVE_GETPEEREID
881 int rep_getpeereid(int s, uid_t *uid, gid_t *gid)
882 {
883 #if defined(HAVE_PEERCRED)
884         struct ucred cred;
885         socklen_t cred_len = sizeof(struct ucred);
886         int ret;
887
888 #undef getsockopt
889         ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
890         if (ret != 0) {
891                 return -1;
892         }
893
894         if (cred_len != sizeof(struct ucred)) {
895                 errno = EINVAL;
896                 return -1;
897         }
898
899         *uid = cred.uid;
900         *gid = cred.gid;
901         return 0;
902 #else
903         errno = ENOSYS;
904         return -1;
905 #endif
906 }
907 #endif
908
909 #ifndef HAVE_USLEEP
910 int rep_usleep(useconds_t sec)
911 {
912         struct timeval tval;
913         /*
914          * Fake it with select...
915          */
916         tval.tv_sec = 0;
917         tval.tv_usec = usecs/1000;
918         select(0,NULL,NULL,NULL,&tval);
919         return 0;
920 }
921 #endif /* HAVE_USLEEP */
922
923 #ifndef HAVE_SETPROCTITLE
924 void rep_setproctitle(const char *fmt, ...)
925 {
926 }
927 #endif