PageRenderTime 63ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/uClinux-dist/user/samba/source/lib/replace/replace.c

https://github.com/labx-technologies-llc/mb-linux-labx
C | 612 lines | 460 code | 77 blank | 75 comment | 96 complexity | fd66cc876c36f4e3acf8932e2e8ad883 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, MPL-2.0-no-copyleft-exception, ISC, AGPL-1.0, LGPL-2.0, GPL-3.0, LGPL-3.0, 0BSD
  1. /*
  2. Unix SMB/CIFS implementation.
  3. replacement routines for broken systems
  4. Copyright (C) Andrew Tridgell 1992-1998
  5. ** NOTE! The following LGPL license applies to the replace
  6. ** library. This does NOT imply that all of Samba is released
  7. ** under the LGPL
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public
  10. License as published by the Free Software Foundation; either
  11. version 2 of the License, or (at your option) any later version.
  12. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with this library; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include "replace.h"
  21. #include "system/filesys.h"
  22. #include "system/time.h"
  23. #include "system/passwd.h"
  24. #include "system/syslog.h"
  25. #include "system/network.h"
  26. #include "system/locale.h"
  27. #include "system/wait.h"
  28. void replace_dummy(void);
  29. void replace_dummy(void) {}
  30. #ifndef HAVE_FTRUNCATE
  31. /*******************************************************************
  32. ftruncate for operating systems that don't have it
  33. ********************************************************************/
  34. int rep_ftruncate(int f, off_t l)
  35. {
  36. #ifdef HAVE_CHSIZE
  37. return chsize(f,l);
  38. #elif defined(F_FREESP)
  39. struct flock fl;
  40. fl.l_whence = 0;
  41. fl.l_len = 0;
  42. fl.l_start = l;
  43. fl.l_type = F_WRLCK;
  44. return fcntl(f, F_FREESP, &fl);
  45. #else
  46. #error "you must have a ftruncate function"
  47. #endif
  48. }
  49. #endif /* HAVE_FTRUNCATE */
  50. #ifndef HAVE_STRLCPY
  51. /* like strncpy but does not 0 fill the buffer and always null
  52. terminates. bufsize is the size of the destination buffer */
  53. size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
  54. {
  55. size_t len = strlen(s);
  56. size_t ret = len;
  57. if (bufsize <= 0) return 0;
  58. if (len >= bufsize) len = bufsize-1;
  59. memcpy(d, s, len);
  60. d[len] = 0;
  61. return ret;
  62. }
  63. #endif
  64. #ifndef HAVE_STRLCAT
  65. /* like strncat but does not 0 fill the buffer and always null
  66. terminates. bufsize is the length of the buffer, which should
  67. be one more than the maximum resulting string length */
  68. size_t rep_strlcat(char *d, const char *s, size_t bufsize)
  69. {
  70. size_t len1 = strlen(d);
  71. size_t len2 = strlen(s);
  72. size_t ret = len1 + len2;
  73. if (len1+len2 >= bufsize) {
  74. len2 = bufsize - (len1+1);
  75. }
  76. if (len2 > 0) {
  77. memcpy(d+len1, s, len2);
  78. d[len1+len2] = 0;
  79. }
  80. return ret;
  81. }
  82. #endif
  83. #ifndef HAVE_MKTIME
  84. /*******************************************************************
  85. a mktime() replacement for those who don't have it - contributed by
  86. C.A. Lademann <cal@zls.com>
  87. Corrections by richard.kettlewell@kewill.com
  88. ********************************************************************/
  89. #define MINUTE 60
  90. #define HOUR 60*MINUTE
  91. #define DAY 24*HOUR
  92. #define YEAR 365*DAY
  93. time_t rep_mktime(struct tm *t)
  94. {
  95. struct tm *u;
  96. time_t epoch = 0;
  97. int n;
  98. int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
  99. y, m, i;
  100. if(t->tm_year < 70)
  101. return((time_t)-1);
  102. n = t->tm_year + 1900 - 1;
  103. epoch = (t->tm_year - 70) * YEAR +
  104. ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
  105. y = t->tm_year + 1900;
  106. m = 0;
  107. for(i = 0; i < t->tm_mon; i++) {
  108. epoch += mon [m] * DAY;
  109. if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
  110. epoch += DAY;
  111. if(++m > 11) {
  112. m = 0;
  113. y++;
  114. }
  115. }
  116. epoch += (t->tm_mday - 1) * DAY;
  117. epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
  118. if((u = localtime(&epoch)) != NULL) {
  119. t->tm_sec = u->tm_sec;
  120. t->tm_min = u->tm_min;
  121. t->tm_hour = u->tm_hour;
  122. t->tm_mday = u->tm_mday;
  123. t->tm_mon = u->tm_mon;
  124. t->tm_year = u->tm_year;
  125. t->tm_wday = u->tm_wday;
  126. t->tm_yday = u->tm_yday;
  127. t->tm_isdst = u->tm_isdst;
  128. }
  129. return(epoch);
  130. }
  131. #endif /* !HAVE_MKTIME */
  132. #ifndef HAVE_INITGROUPS
  133. /****************************************************************************
  134. some systems don't have an initgroups call
  135. ****************************************************************************/
  136. int rep_initgroups(char *name, gid_t id)
  137. {
  138. #ifndef HAVE_SETGROUPS
  139. /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
  140. errno = ENOSYS;
  141. return -1;
  142. #else /* HAVE_SETGROUPS */
  143. #include <grp.h>
  144. gid_t *grouplst = NULL;
  145. int max_gr = 32;
  146. int ret;
  147. int i,j;
  148. struct group *g;
  149. char *gr;
  150. if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
  151. errno = ENOMEM;
  152. return -1;
  153. }
  154. grouplst[0] = id;
  155. i = 1;
  156. while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
  157. if (g->gr_gid == id)
  158. continue;
  159. j = 0;
  160. gr = g->gr_mem[0];
  161. while (gr && (*gr != (char)NULL)) {
  162. if (strcmp(name,gr) == 0) {
  163. grouplst[i] = g->gr_gid;
  164. i++;
  165. gr = (char *)NULL;
  166. break;
  167. }
  168. gr = g->gr_mem[++j];
  169. }
  170. }
  171. endgrent();
  172. ret = setgroups(i, grouplst);
  173. free(grouplst);
  174. return ret;
  175. #endif /* HAVE_SETGROUPS */
  176. }
  177. #endif /* HAVE_INITGROUPS */
  178. #if (defined(SecureWare) && defined(SCO))
  179. /* This is needed due to needing the nap() function but we don't want
  180. to include the Xenix libraries since that will break other things...
  181. BTW: system call # 0x0c28 is the same as calling nap() */
  182. long nap(long milliseconds) {
  183. return syscall(0x0c28, milliseconds);
  184. }
  185. #endif
  186. #ifndef HAVE_MEMMOVE
  187. /*******************************************************************
  188. safely copies memory, ensuring no overlap problems.
  189. this is only used if the machine does not have it's own memmove().
  190. this is not the fastest algorithm in town, but it will do for our
  191. needs.
  192. ********************************************************************/
  193. void *rep_memmove(void *dest,const void *src,int size)
  194. {
  195. unsigned long d,s;
  196. int i;
  197. if (dest==src || !size) return(dest);
  198. d = (unsigned long)dest;
  199. s = (unsigned long)src;
  200. if ((d >= (s+size)) || (s >= (d+size))) {
  201. /* no overlap */
  202. memcpy(dest,src,size);
  203. return(dest);
  204. }
  205. if (d < s) {
  206. /* we can forward copy */
  207. if (s-d >= sizeof(int) &&
  208. !(s%sizeof(int)) &&
  209. !(d%sizeof(int)) &&
  210. !(size%sizeof(int))) {
  211. /* do it all as words */
  212. int *idest = (int *)dest;
  213. int *isrc = (int *)src;
  214. size /= sizeof(int);
  215. for (i=0;i<size;i++) idest[i] = isrc[i];
  216. } else {
  217. /* simplest */
  218. char *cdest = (char *)dest;
  219. char *csrc = (char *)src;
  220. for (i=0;i<size;i++) cdest[i] = csrc[i];
  221. }
  222. } else {
  223. /* must backward copy */
  224. if (d-s >= sizeof(int) &&
  225. !(s%sizeof(int)) &&
  226. !(d%sizeof(int)) &&
  227. !(size%sizeof(int))) {
  228. /* do it all as words */
  229. int *idest = (int *)dest;
  230. int *isrc = (int *)src;
  231. size /= sizeof(int);
  232. for (i=size-1;i>=0;i--) idest[i] = isrc[i];
  233. } else {
  234. /* simplest */
  235. char *cdest = (char *)dest;
  236. char *csrc = (char *)src;
  237. for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
  238. }
  239. }
  240. return(dest);
  241. }
  242. #endif /* HAVE_MEMMOVE */
  243. #ifndef HAVE_STRDUP
  244. /****************************************************************************
  245. duplicate a string
  246. ****************************************************************************/
  247. char *rep_strdup(const char *s)
  248. {
  249. size_t len;
  250. char *ret;
  251. if (!s) return(NULL);
  252. len = strlen(s)+1;
  253. ret = (char *)malloc(len);
  254. if (!ret) return(NULL);
  255. memcpy(ret,s,len);
  256. return(ret);
  257. }
  258. #endif /* HAVE_STRDUP */
  259. #ifndef WITH_PTHREADS
  260. /* REWRITE: not thread safe */
  261. #ifdef REPLACE_INET_NTOA
  262. char *rep_inet_ntoa(struct in_addr ip)
  263. {
  264. uint8_t *p = (uint8_t *)&ip.s_addr;
  265. static char buf[18];
  266. slprintf(buf, 17, "%d.%d.%d.%d",
  267. (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
  268. return buf;
  269. }
  270. #endif /* REPLACE_INET_NTOA */
  271. #endif
  272. #ifndef HAVE_SETLINEBUF
  273. void rep_setlinebuf(FILE *stream)
  274. {
  275. setvbuf(stream, (char *)NULL, _IOLBF, 0);
  276. }
  277. #endif /* HAVE_SETLINEBUF */
  278. #ifndef HAVE_VSYSLOG
  279. #ifdef HAVE_SYSLOG
  280. void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
  281. {
  282. char *msg = NULL;
  283. vasprintf(&msg, format, arglist);
  284. if (!msg)
  285. return;
  286. syslog(facility_priority, "%s", msg);
  287. free(msg);
  288. }
  289. #endif /* HAVE_SYSLOG */
  290. #endif /* HAVE_VSYSLOG */
  291. #ifndef HAVE_STRNLEN
  292. /**
  293. Some platforms don't have strnlen
  294. **/
  295. size_t rep_strnlen(const char *s, size_t max)
  296. {
  297. size_t len;
  298. for (len = 0; len < max; len++) {
  299. if (s[len] == '\0') {
  300. break;
  301. }
  302. }
  303. return len;
  304. }
  305. #endif
  306. #ifndef HAVE_STRNDUP
  307. /**
  308. Some platforms don't have strndup.
  309. **/
  310. char *rep_strndup(const char *s, size_t n)
  311. {
  312. char *ret;
  313. n = strnlen(s, n);
  314. ret = malloc(n+1);
  315. if (!ret)
  316. return NULL;
  317. memcpy(ret, s, n);
  318. ret[n] = 0;
  319. return ret;
  320. }
  321. #endif
  322. #ifndef HAVE_WAITPID
  323. int rep_waitpid(pid_t pid,int *status,int options)
  324. {
  325. return wait4(pid, status, options, NULL);
  326. }
  327. #endif
  328. #ifndef HAVE_SETEUID
  329. int rep_seteuid(uid_t euid)
  330. {
  331. #ifdef HAVE_SETRESUID
  332. return setresuid(-1, euid, -1);
  333. #else
  334. # error "You need a seteuid function"
  335. #endif
  336. }
  337. #endif
  338. #ifndef HAVE_SETEGID
  339. int rep_setegid(gid_t egid)
  340. {
  341. #ifdef HAVE_SETRESGID
  342. return setresgid(-1, egid, -1);
  343. #else
  344. # error "You need a setegid function"
  345. #endif
  346. }
  347. #endif
  348. /*******************************************************************
  349. os/2 also doesn't have chroot
  350. ********************************************************************/
  351. #ifndef HAVE_CHROOT
  352. int rep_chroot(const char *dname)
  353. {
  354. errno = ENOSYS;
  355. return -1;
  356. }
  357. #endif
  358. /*****************************************************************
  359. Possibly replace mkstemp if it is broken.
  360. *****************************************************************/
  361. #ifndef HAVE_SECURE_MKSTEMP
  362. int rep_mkstemp(char *template)
  363. {
  364. /* have a reasonable go at emulating it. Hope that
  365. the system mktemp() isn't completly hopeless */
  366. char *p = mktemp(template);
  367. if (!p)
  368. return -1;
  369. return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
  370. }
  371. #endif
  372. #ifndef HAVE_MKDTEMP
  373. char *rep_mkdtemp(char *template)
  374. {
  375. char *dname;
  376. if ((dname = mktemp(template))) {
  377. if (mkdir(dname, 0700) >= 0) {
  378. return dname;
  379. }
  380. }
  381. return NULL;
  382. }
  383. #endif
  384. #ifndef HAVE_PREAD
  385. ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
  386. {
  387. if (lseek(__fd, __offset, SEEK_SET) != __offset) {
  388. return -1;
  389. }
  390. return read(__fd, __buf, __nbytes);
  391. }
  392. #endif
  393. #ifndef HAVE_PWRITE
  394. ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
  395. {
  396. if (lseek(__fd, __offset, SEEK_SET) != __offset) {
  397. return -1;
  398. }
  399. return write(__fd, __buf, __nbytes);
  400. }
  401. #endif
  402. #ifndef HAVE_STRCASESTR
  403. char *rep_strcasestr(const char *haystack, const char *needle)
  404. {
  405. const char *s;
  406. size_t nlen = strlen(needle);
  407. for (s=haystack;*s;s++) {
  408. if (toupper(*needle) == toupper(*s) &&
  409. strncasecmp(s, needle, nlen) == 0) {
  410. return (char *)((intptr_t)s);
  411. }
  412. }
  413. return NULL;
  414. }
  415. #endif
  416. #ifndef HAVE_STRTOK_R
  417. /* based on GLIBC version, copyright Free Software Foundation */
  418. char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
  419. {
  420. char *token;
  421. if (s == NULL) s = *save_ptr;
  422. s += strspn(s, delim);
  423. if (*s == '\0') {
  424. *save_ptr = s;
  425. return NULL;
  426. }
  427. token = s;
  428. s = strpbrk(token, delim);
  429. if (s == NULL) {
  430. *save_ptr = token + strlen(token);
  431. } else {
  432. *s = '\0';
  433. *save_ptr = s + 1;
  434. }
  435. return token;
  436. }
  437. #endif
  438. #ifndef HAVE_STRTOLL
  439. long long int rep_strtoll(const char *str, char **endptr, int base)
  440. {
  441. #ifdef HAVE_STRTOQ
  442. return strtoq(str, endptr, base);
  443. #elif defined(HAVE___STRTOLL)
  444. return __strtoll(str, endptr, base);
  445. #elif SIZEOF_LONG == SIZEOF_LONG_LONG
  446. return (long long int) strtol(str, endptr, base);
  447. #else
  448. # error "You need a strtoll function"
  449. #endif
  450. }
  451. #endif
  452. #ifndef HAVE_STRTOULL
  453. unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
  454. {
  455. #ifdef HAVE_STRTOUQ
  456. return strtouq(str, endptr, base);
  457. #elif defined(HAVE___STRTOULL)
  458. return __strtoull(str, endptr, base);
  459. #elif SIZEOF_LONG == SIZEOF_LONG_LONG
  460. return (unsigned long long int) strtoul(str, endptr, base);
  461. #else
  462. # error "You need a strtoull function"
  463. #endif
  464. }
  465. #endif
  466. #ifndef HAVE_SETENV
  467. int rep_setenv(const char *name, const char *value, int overwrite)
  468. {
  469. char *p;
  470. size_t l1, l2;
  471. int ret;
  472. if (!overwrite && getenv(name)) {
  473. return 0;
  474. }
  475. l1 = strlen(name);
  476. l2 = strlen(value);
  477. p = malloc(l1+l2+2);
  478. if (p == NULL) {
  479. return -1;
  480. }
  481. memcpy(p, name, l1);
  482. p[l1] = '=';
  483. memcpy(p+l1+1, value, l2);
  484. p[l1+l2+1] = 0;
  485. ret = putenv(p);
  486. if (ret != 0) {
  487. free(p);
  488. }
  489. return ret;
  490. }
  491. #endif
  492. #ifndef HAVE_UNSETENV
  493. int rep_unsetenv(const char *name)
  494. {
  495. extern char **environ;
  496. size_t len = strlen(name);
  497. size_t i;
  498. int found = 0;
  499. for (i=0; (environ && environ[i]); i++) {
  500. if (found) {
  501. environ[i-1] = environ[i];
  502. continue;
  503. }
  504. if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
  505. free(environ[i]);
  506. environ[i] = NULL;
  507. found = 1;
  508. continue;
  509. }
  510. }
  511. return 0;
  512. }
  513. #endif
  514. #ifndef HAVE_SOCKETPAIR
  515. int rep_socketpair(int d, int type, int protocol, int sv[2])
  516. {
  517. if (d != AF_UNIX) {
  518. errno = EAFNOSUPPORT;
  519. return -1;
  520. }
  521. if (protocol != 0) {
  522. errno = EPROTONOSUPPORT;
  523. return -1;
  524. }
  525. if (type != SOCK_STREAM) {
  526. errno = EOPNOTSUPP;
  527. return -1;
  528. }
  529. return pipe(sv);
  530. }
  531. #endif