lib: replace: Add strsep function (missing on Solaris).
[Samba.git] / lib / replace / replace.c
blob488da0a5ec376e17461bbc37db8d8b3337b65215
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
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
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.
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.
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/>.
26 #include "replace.h"
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"
36 #ifdef _WIN32
37 #define mkdir(d,m) _mkdir(d)
38 #endif
40 void replace_dummy(void);
41 void replace_dummy(void) {}
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)
49 #ifdef HAVE_CHSIZE
50 return chsize(f,l);
51 #elif defined(F_FREESP)
52 struct flock fl;
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
63 #endif /* HAVE_FTRUNCATE */
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)
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;
79 #endif
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)
87 size_t len1 = strlen(d);
88 size_t len2 = strlen(s);
89 size_t ret = len1 + len2;
91 if (len1+len2 >= bufsize) {
92 if (bufsize < (len1+1)) {
93 return ret;
95 len2 = bufsize - (len1+1);
97 if (len2 > 0) {
98 memcpy(d+len1, s, len2);
99 d[len1+len2] = 0;
101 return ret;
103 #endif
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 ********************************************************************/
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)
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;
124 if(t->tm_year < 70)
125 return((time_t)-1);
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;
131 y = t->tm_year + 1900;
132 m = 0;
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;
139 if(++m > 11) {
140 m = 0;
141 y++;
145 epoch += (t->tm_mday - 1) * DAY;
146 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
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;
160 return(epoch);
162 #endif /* !HAVE_MKTIME */
165 #ifndef HAVE_INITGROUPS
166 /****************************************************************************
167 some systems don't have an initgroups call
168 ****************************************************************************/
169 int rep_initgroups(char *name, gid_t id)
171 #ifndef HAVE_SETGROUPS
172 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
173 errno = ENOSYS;
174 return -1;
175 #else /* HAVE_SETGROUPS */
177 #include <grp.h>
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;
186 if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
187 errno = ENOMEM;
188 return -1;
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;
205 gr = g->gr_mem[++j];
208 endgrent();
209 ret = setgroups(i, grouplst);
210 free(grouplst);
211 return ret;
212 #endif /* HAVE_SETGROUPS */
214 #endif /* HAVE_INITGROUPS */
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)
226 unsigned long d,s;
227 int i;
228 if (dest==src || !size) return(dest);
230 d = (unsigned long)dest;
231 s = (unsigned long)src;
233 if ((d >= (s+size)) || (s >= (d+size))) {
234 /* no overlap */
235 memcpy(dest,src,size);
236 return(dest);
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];
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];
274 return(dest);
276 #endif /* HAVE_MEMMOVE */
278 #ifndef HAVE_STRDUP
279 /****************************************************************************
280 duplicate a string
281 ****************************************************************************/
282 char *rep_strdup(const char *s)
284 size_t len;
285 char *ret;
287 if (!s) return(NULL);
289 len = strlen(s)+1;
290 ret = (char *)malloc(len);
291 if (!ret) return(NULL);
292 memcpy(ret,s,len);
293 return(ret);
295 #endif /* HAVE_STRDUP */
297 #ifndef HAVE_SETLINEBUF
298 void rep_setlinebuf(FILE *stream)
300 setvbuf(stream, (char *)NULL, _IOLBF, 0);
302 #endif /* HAVE_SETLINEBUF */
304 #ifndef HAVE_VSYSLOG
305 #ifdef HAVE_SYSLOG
306 void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
308 char *msg = NULL;
309 vasprintf(&msg, format, arglist);
310 if (!msg)
311 return;
312 syslog(facility_priority, "%s", msg);
313 free(msg);
315 #endif /* HAVE_SYSLOG */
316 #endif /* HAVE_VSYSLOG */
318 #ifndef HAVE_STRNLEN
320 Some platforms don't have strnlen
322 size_t rep_strnlen(const char *s, size_t max)
324 size_t len;
326 for (len = 0; len < max; len++) {
327 if (s[len] == '\0') {
328 break;
331 return len;
333 #endif
335 #ifndef HAVE_STRNDUP
337 Some platforms don't have strndup.
339 char *rep_strndup(const char *s, size_t n)
341 char *ret;
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;
350 return ret;
352 #endif
354 #if !defined(HAVE_WAITPID) && defined(HAVE_WAIT4)
355 int rep_waitpid(pid_t pid,int *status,int options)
357 return wait4(pid, status, options, NULL);
359 #endif
361 #ifndef HAVE_SETEUID
362 int rep_seteuid(uid_t euid)
364 #ifdef HAVE_SETRESUID
365 return setresuid(-1, euid, -1);
366 #else
367 errno = ENOSYS;
368 return -1;
369 #endif
371 #endif
373 #ifndef HAVE_SETEGID
374 int rep_setegid(gid_t egid)
376 #ifdef HAVE_SETRESGID
377 return setresgid(-1, egid, -1);
378 #else
379 errno = ENOSYS;
380 return -1;
381 #endif
383 #endif
385 /*******************************************************************
386 os/2 also doesn't have chroot
387 ********************************************************************/
388 #ifndef HAVE_CHROOT
389 int rep_chroot(const char *dname)
391 errno = ENOSYS;
392 return -1;
394 #endif
396 /*****************************************************************
397 Possibly replace mkstemp if it is broken.
398 *****************************************************************/
400 #ifndef HAVE_SECURE_MKSTEMP
401 int rep_mkstemp(char *template)
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);
410 #endif
412 #ifndef HAVE_MKDTEMP
413 char *rep_mkdtemp(char *template)
415 char *dname;
417 if ((dname = mktemp(template))) {
418 if (mkdir(dname, 0700) >= 0) {
419 return dname;
423 return NULL;
425 #endif
427 /*****************************************************************
428 Watch out: this is not thread safe.
429 *****************************************************************/
431 #ifndef HAVE_PREAD
432 ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
434 if (lseek(__fd, __offset, SEEK_SET) != __offset) {
435 return -1;
437 return read(__fd, __buf, __nbytes);
439 #endif
441 /*****************************************************************
442 Watch out: this is not thread safe.
443 *****************************************************************/
445 #ifndef HAVE_PWRITE
446 ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
448 if (lseek(__fd, __offset, SEEK_SET) != __offset) {
449 return -1;
451 return write(__fd, __buf, __nbytes);
453 #endif
455 #ifndef HAVE_STRCASESTR
456 char *rep_strcasestr(const char *haystack, const char *needle)
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);
466 return NULL;
468 #endif
470 #ifndef HAVE_STRSEP
471 char *rep_strsep(char **pps, const char *delim)
473 char *ret = *pps;
474 char *p = *pps;
476 if (p == NULL) {
477 return NULL;
479 p += strcspn(p, delim);
480 if (*p == '\0') {
481 *pps = NULL;
482 } else {
483 *p = '\0';
484 *pps = p + 1;
486 return ret;
488 #endif
490 #ifndef HAVE_STRTOK_R
491 /* based on GLIBC version, copyright Free Software Foundation */
492 char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
494 char *token;
496 if (s == NULL) s = *save_ptr;
498 s += strspn(s, delim);
499 if (*s == '\0') {
500 *save_ptr = s;
501 return NULL;
504 token = s;
505 s = strpbrk(token, delim);
506 if (s == NULL) {
507 *save_ptr = token + strlen(token);
508 } else {
509 *s = '\0';
510 *save_ptr = s + 1;
513 return token;
515 #endif
518 #ifndef HAVE_STRTOLL
519 long long int rep_strtoll(const char *str, char **endptr, int base)
521 #ifdef HAVE_STRTOQ
522 return strtoq(str, endptr, base);
523 #elif defined(HAVE___STRTOLL)
524 return __strtoll(str, endptr, base);
525 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
526 return (long long int) strtol(str, endptr, base);
527 #else
528 # error "You need a strtoll function"
529 #endif
531 #else
532 #ifdef HAVE_BSD_STRTOLL
533 #ifdef HAVE_STRTOQ
534 long long int rep_strtoll(const char *str, char **endptr, int base)
536 long long int nb = strtoq(str, endptr, base);
537 /* In linux EINVAL is only returned if base is not ok */
538 if (errno == EINVAL) {
539 if (base == 0 || (base >1 && base <37)) {
540 /* Base was ok so it's because we were not
541 * able to make the convertion.
542 * Let's reset errno.
544 errno = 0;
547 return nb;
549 #else
550 #error "You need the strtoq function"
551 #endif /* HAVE_STRTOQ */
552 #endif /* HAVE_BSD_STRTOLL */
553 #endif /* HAVE_STRTOLL */
556 #ifndef HAVE_STRTOULL
557 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
559 #ifdef HAVE_STRTOUQ
560 return strtouq(str, endptr, base);
561 #elif defined(HAVE___STRTOULL)
562 return __strtoull(str, endptr, base);
563 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
564 return (unsigned long long int) strtoul(str, endptr, base);
565 #else
566 # error "You need a strtoull function"
567 #endif
569 #else
570 #ifdef HAVE_BSD_STRTOLL
571 #ifdef HAVE_STRTOUQ
572 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
574 unsigned long long int nb = strtouq(str, endptr, base);
575 /* In linux EINVAL is only returned if base is not ok */
576 if (errno == EINVAL) {
577 if (base == 0 || (base >1 && base <37)) {
578 /* Base was ok so it's because we were not
579 * able to make the convertion.
580 * Let's reset errno.
582 errno = 0;
585 return nb;
587 #else
588 #error "You need the strtouq function"
589 #endif /* HAVE_STRTOUQ */
590 #endif /* HAVE_BSD_STRTOLL */
591 #endif /* HAVE_STRTOULL */
593 #ifndef HAVE_SETENV
594 int rep_setenv(const char *name, const char *value, int overwrite)
596 char *p;
597 size_t l1, l2;
598 int ret;
600 if (!overwrite && getenv(name)) {
601 return 0;
604 l1 = strlen(name);
605 l2 = strlen(value);
607 p = malloc(l1+l2+2);
608 if (p == NULL) {
609 return -1;
611 memcpy(p, name, l1);
612 p[l1] = '=';
613 memcpy(p+l1+1, value, l2);
614 p[l1+l2+1] = 0;
616 ret = putenv(p);
617 if (ret != 0) {
618 free(p);
621 return ret;
623 #endif
625 #ifndef HAVE_UNSETENV
626 int rep_unsetenv(const char *name)
628 extern char **environ;
629 size_t len = strlen(name);
630 size_t i, count;
632 if (environ == NULL || getenv(name) == NULL) {
633 return 0;
636 for (i=0;environ[i];i++) /* noop */ ;
638 count=i;
640 for (i=0;i<count;) {
641 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
642 /* note: we do _not_ free the old variable here. It is unsafe to
643 do so, as the pointer may not have come from malloc */
644 memmove(&environ[i], &environ[i+1], (count-i)*sizeof(char *));
645 count--;
646 } else {
647 i++;
651 return 0;
653 #endif
655 #ifndef HAVE_UTIME
656 int rep_utime(const char *filename, const struct utimbuf *buf)
658 errno = ENOSYS;
659 return -1;
661 #endif
663 #ifndef HAVE_UTIMES
664 int rep_utimes(const char *filename, const struct timeval tv[2])
666 struct utimbuf u;
668 u.actime = tv[0].tv_sec;
669 if (tv[0].tv_usec > 500000) {
670 u.actime += 1;
673 u.modtime = tv[1].tv_sec;
674 if (tv[1].tv_usec > 500000) {
675 u.modtime += 1;
678 return utime(filename, &u);
680 #endif
682 #ifndef HAVE_DUP2
683 int rep_dup2(int oldfd, int newfd)
685 errno = ENOSYS;
686 return -1;
688 #endif
690 #ifndef HAVE_CHOWN
692 chown isn't used much but OS/2 doesn't have it
694 int rep_chown(const char *fname, uid_t uid, gid_t gid)
696 errno = ENOSYS;
697 return -1;
699 #endif
701 #ifndef HAVE_LINK
702 int rep_link(const char *oldpath, const char *newpath)
704 errno = ENOSYS;
705 return -1;
707 #endif
709 #ifndef HAVE_READLINK
710 int rep_readlink(const char *path, char *buf, size_t bufsiz)
712 errno = ENOSYS;
713 return -1;
715 #endif
717 #ifndef HAVE_SYMLINK
718 int rep_symlink(const char *oldpath, const char *newpath)
720 errno = ENOSYS;
721 return -1;
723 #endif
725 #ifndef HAVE_LCHOWN
726 int rep_lchown(const char *fname,uid_t uid,gid_t gid)
728 errno = ENOSYS;
729 return -1;
731 #endif
733 #ifndef HAVE_REALPATH
734 char *rep_realpath(const char *path, char *resolved_path)
736 /* As realpath is not a system call we can't return ENOSYS. */
737 errno = EINVAL;
738 return NULL;
740 #endif
743 #ifndef HAVE_MEMMEM
744 void *rep_memmem(const void *haystack, size_t haystacklen,
745 const void *needle, size_t needlelen)
747 if (needlelen == 0) {
748 return discard_const(haystack);
750 while (haystacklen >= needlelen) {
751 char *p = (char *)memchr(haystack, *(const char *)needle,
752 haystacklen-(needlelen-1));
753 if (!p) return NULL;
754 if (memcmp(p, needle, needlelen) == 0) {
755 return p;
757 haystack = p+1;
758 haystacklen -= (p - (const char *)haystack) + 1;
760 return NULL;
762 #endif
764 #if !defined(HAVE_VDPRINTF) || !defined(HAVE_C99_VSNPRINTF)
765 int rep_vdprintf(int fd, const char *format, va_list ap)
767 char *s = NULL;
768 int ret;
770 vasprintf(&s, format, ap);
771 if (s == NULL) {
772 errno = ENOMEM;
773 return -1;
775 ret = write(fd, s, strlen(s));
776 free(s);
777 return ret;
779 #endif
781 #if !defined(HAVE_DPRINTF) || !defined(HAVE_C99_VSNPRINTF)
782 int rep_dprintf(int fd, const char *format, ...)
784 int ret;
785 va_list ap;
787 va_start(ap, format);
788 ret = vdprintf(fd, format, ap);
789 va_end(ap);
791 return ret;
793 #endif
795 #ifndef HAVE_GET_CURRENT_DIR_NAME
796 char *rep_get_current_dir_name(void)
798 char buf[PATH_MAX+1];
799 char *p;
800 p = getcwd(buf, sizeof(buf));
801 if (p == NULL) {
802 return NULL;
804 return strdup(p);
806 #endif
808 #ifndef HAVE_STRERROR_R
809 int rep_strerror_r(int errnum, char *buf, size_t buflen)
811 char *s = strerror(errnum);
812 if (strlen(s)+1 > buflen) {
813 errno = ERANGE;
814 return -1;
816 strncpy(buf, s, buflen);
817 return 0;
819 #endif
821 #ifndef HAVE_CLOCK_GETTIME
822 int rep_clock_gettime(clockid_t clk_id, struct timespec *tp)
824 struct timeval tval;
825 switch (clk_id) {
826 case 0: /* CLOCK_REALTIME :*/
827 #ifdef HAVE_GETTIMEOFDAY_TZ
828 gettimeofday(&tval,NULL);
829 #else
830 gettimeofday(&tval);
831 #endif
832 tp->tv_sec = tval.tv_sec;
833 tp->tv_nsec = tval.tv_usec * 1000;
834 break;
835 default:
836 errno = EINVAL;
837 return -1;
839 return 0;
841 #endif
843 #ifndef HAVE_MEMALIGN
844 void *rep_memalign( size_t align, size_t size )
846 #if defined(HAVE_POSIX_MEMALIGN)
847 void *p = NULL;
848 int ret = posix_memalign( &p, align, size );
849 if ( ret == 0 )
850 return p;
852 return NULL;
853 #else
854 /* On *BSD systems memaligns doesn't exist, but memory will
855 * be aligned on allocations of > pagesize. */
856 #if defined(SYSCONF_SC_PAGESIZE)
857 size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
858 #elif defined(HAVE_GETPAGESIZE)
859 size_t pagesize = (size_t)getpagesize();
860 #else
861 size_t pagesize = (size_t)-1;
862 #endif
863 if (pagesize == (size_t)-1) {
864 errno = ENOSYS;
865 return NULL;
867 if (size < pagesize) {
868 size = pagesize;
870 return malloc(size);
871 #endif
873 #endif
875 #ifndef HAVE_GETPEEREID
876 int rep_getpeereid(int s, uid_t *uid, gid_t *gid)
878 #if defined(HAVE_PEERCRED)
879 struct ucred cred;
880 socklen_t cred_len = sizeof(struct ucred);
881 int ret;
883 #undef getsockopt
884 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
885 if (ret != 0) {
886 return -1;
889 if (cred_len != sizeof(struct ucred)) {
890 errno = EINVAL;
891 return -1;
894 *uid = cred.uid;
895 *gid = cred.gid;
896 return 0;
897 #else
898 errno = ENOSYS;
899 return -1;
900 #endif
902 #endif
904 #ifndef HAVE_USLEEP
905 int rep_usleep(useconds_t sec)
907 struct timeval tval;
909 * Fake it with select...
911 tval.tv_sec = 0;
912 tval.tv_usec = usecs/1000;
913 select(0,NULL,NULL,NULL,&tval);
914 return 0;
916 #endif /* HAVE_USLEEP */
918 #ifndef HAVE_SETPROCTITLE
919 void rep_setproctitle(const char *fmt, ...)
922 #endif