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