PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/replace/replace.c

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