PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/timidity/utils/support.c

http://github.com/xbmc/xbmc
C | 823 lines | 704 code | 41 blank | 78 comment | 53 complexity | 0ffacde74b0bc9f1998389e888519056 MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, LGPL-2.0, 0BSD, Unlicense, GPL-2.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0
  1. /*
  2. TiMidity++ -- MIDI to WAVE converter and player
  3. Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
  4. Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. support.c - Define missing function
  17. Written by Masanao Izumo <mo@goice.co.jp>
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif /* HAVE_CONFIG_H */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #ifdef HAVE_UNISTD_H
  25. #include <unistd.h>
  26. #endif /* HAVE_UNISTD_H */
  27. #include <stdarg.h>
  28. #ifdef HAVE_SYS_TIME_H
  29. #include <sys/time.h>
  30. #endif /* HAVE_SYS_TIME_H */
  31. #ifdef HAVE_SYS_TYPES_H
  32. #include <sys/types.h>
  33. #endif /* HAVE_SYS_TYPES_H */
  34. #ifndef NO_STRING_H
  35. #include <string.h>
  36. #else
  37. #include <strings.h>
  38. #endif
  39. #ifdef __W32__
  40. #include <windows.h>
  41. #endif /* __W32__ */
  42. #ifdef HAVE_SYS_PARAM_H
  43. #include <sys/param.h>
  44. #endif /* HAVE_SYS_PARAM_H */
  45. #include <ctype.h>
  46. #include "timidity.h"
  47. #include "common.h"
  48. #include "mblock.h"
  49. #ifdef __MACOS__
  50. #include <Threads.h>
  51. #endif
  52. #ifndef HAVE_VSNPRINTF
  53. /* From glib-1.1.13:gstrfuncs.c
  54. * Modified by Masanao Izumo <mo@goice.co.jp>
  55. */
  56. static int printf_string_upper_bound (const char* format,
  57. va_list args)
  58. {
  59. int len = 1;
  60. while (*format)
  61. {
  62. int long_int = 0;
  63. int extra_long = 0;
  64. char c;
  65. c = *format++;
  66. if (c == '%')
  67. {
  68. int done = 0;
  69. while (*format && !done)
  70. {
  71. switch (*format++)
  72. {
  73. char *string_arg;
  74. case '*':
  75. len += va_arg (args, int);
  76. break;
  77. case '1':
  78. case '2':
  79. case '3':
  80. case '4':
  81. case '5':
  82. case '6':
  83. case '7':
  84. case '8':
  85. case '9':
  86. /* add specified format length, since it might exceed the
  87. * size we assume it to have.
  88. */
  89. format -= 1;
  90. len += strtol (format, (char**) &format, 10);
  91. break;
  92. case 'h':
  93. /* ignore short int flag, since all args have at least the
  94. * same size as an int
  95. */
  96. break;
  97. case 'l':
  98. if (long_int)
  99. extra_long = 1; /* linux specific */
  100. else
  101. long_int = 1;
  102. break;
  103. case 'q':
  104. case 'L':
  105. long_int = 1;
  106. extra_long = 1;
  107. break;
  108. case 's':
  109. string_arg = va_arg (args, char *);
  110. if (string_arg)
  111. len += strlen (string_arg);
  112. else
  113. {
  114. /* add enough padding to hold "(null)" identifier */
  115. len += 16;
  116. }
  117. done = 1;
  118. break;
  119. case 'd':
  120. case 'i':
  121. case 'o':
  122. case 'u':
  123. case 'x':
  124. case 'X':
  125. #ifdef G_HAVE_GINT64
  126. if (extra_long)
  127. (void) va_arg (args, gint64);
  128. else
  129. #endif /* G_HAVE_GINT64 */
  130. {
  131. if (long_int)
  132. (void) va_arg (args, long);
  133. else
  134. (void) va_arg (args, int);
  135. }
  136. len += extra_long ? 64 : 32;
  137. done = 1;
  138. break;
  139. case 'D':
  140. case 'O':
  141. case 'U':
  142. (void) va_arg (args, long);
  143. len += 32;
  144. done = 1;
  145. break;
  146. case 'e':
  147. case 'E':
  148. case 'f':
  149. case 'g':
  150. #ifdef HAVE_LONG_DOUBLE
  151. if (extra_long)
  152. (void) va_arg (args, long double);
  153. else
  154. #endif /* HAVE_LONG_DOUBLE */
  155. (void) va_arg (args, double);
  156. len += extra_long ? 64 : 32;
  157. done = 1;
  158. break;
  159. case 'c':
  160. (void) va_arg (args, int);
  161. len += 1;
  162. done = 1;
  163. break;
  164. case 'p':
  165. case 'n':
  166. (void) va_arg (args, void*);
  167. len += 32;
  168. done = 1;
  169. break;
  170. case '%':
  171. len += 1;
  172. done = 1;
  173. break;
  174. default:
  175. /* ignore unknow/invalid flags */
  176. break;
  177. }
  178. }
  179. }
  180. else
  181. len += 1;
  182. }
  183. return len;
  184. }
  185. void vsnprintf(char *buff, size_t bufsiz, const char *fmt, va_list ap)
  186. {
  187. MBlockList pool;
  188. char *tmpbuf = buff;
  189. init_mblock(&pool);
  190. tmpbuf = new_segment(&pool, printf_string_upper_bound(fmt, ap));
  191. vsprintf(tmpbuf, fmt, ap);
  192. strncpy(buff, tmpbuf, bufsiz-1);
  193. buff[bufsiz-1] = '\0';
  194. reuse_mblock(&pool);
  195. }
  196. #endif /* HAVE_VSNPRINTF */
  197. #ifndef HAVE_SNPRINTF
  198. void snprintf(char *buff, size_t bufsiz, const char *fmt, ...)
  199. {
  200. va_list ap;
  201. va_start(ap, fmt);
  202. vsnprintf(buff, bufsiz, fmt, ap);
  203. va_end(ap);
  204. }
  205. #endif /* HAVE_VSNPRINTF */
  206. #ifndef HAVE_STRERROR
  207. #ifndef HAVE_ERRNO_H
  208. char *strerror(int errnum) {
  209. static char s[32];
  210. sprintf(s, "ERROR %d", errnum);
  211. return s;
  212. }
  213. #else
  214. char *strerror(int errnum)
  215. {
  216. int i;
  217. static char s[32];
  218. struct {
  219. int id;
  220. char *str;
  221. } error_list[] = {
  222. #ifdef EPERM
  223. {EPERM, "Not super-user"},
  224. #endif /* EPERM */
  225. #ifdef ENOENT
  226. {ENOENT, "No such file or directory"},
  227. #endif /* ENOENT */
  228. #ifdef ESRCH
  229. {ESRCH, "No such process"},
  230. #endif /* ESRCH */
  231. #ifdef EINTR
  232. {EINTR, "interrupted system call"},
  233. #endif /* EINTR */
  234. #ifdef EIO
  235. {EIO, "I/O error"},
  236. #endif /* EIO */
  237. #ifdef ENXIO
  238. {ENXIO, "No such device or address"},
  239. #endif /* ENXIO */
  240. #ifdef E2BIG
  241. {E2BIG, "Arg list too long"},
  242. #endif /* E2BIG */
  243. #ifdef ENOEXEC
  244. {ENOEXEC, "Exec format error"},
  245. #endif /* ENOEXEC */
  246. #ifdef EBADF
  247. {EBADF, "Bad file number"},
  248. #endif /* EBADF */
  249. #ifdef ECHILD
  250. {ECHILD, "No children"},
  251. #endif /* ECHILD */
  252. #ifdef EAGAIN
  253. {EAGAIN, "Resource temporarily unavailable"},
  254. #endif /* EAGAIN */
  255. #ifdef EWOULDBLOCK
  256. {EWOULDBLOCK, "Resource temporarily unavailable"},
  257. #endif /* EWOULDBLOCK */
  258. #ifdef ENOMEM
  259. {ENOMEM, "Not enough core"},
  260. #endif /* ENOMEM */
  261. #ifdef EACCES
  262. {EACCES, "Permission denied"},
  263. #endif /* EACCES */
  264. #ifdef EFAULT
  265. {EFAULT, "Bad address"},
  266. #endif /* EFAULT */
  267. #ifdef ENOTBLK
  268. {ENOTBLK, "Block device required"},
  269. #endif /* ENOTBLK */
  270. #ifdef EBUSY
  271. {EBUSY, "Mount device busy"},
  272. #endif /* EBUSY */
  273. #ifdef EEXIST
  274. {EEXIST, "File exists"},
  275. #endif /* EEXIST */
  276. #ifdef EXDEV
  277. {EXDEV, "Cross-device link"},
  278. #endif /* EXDEV */
  279. #ifdef ENODEV
  280. {ENODEV, "No such device"},
  281. #endif /* ENODEV */
  282. #ifdef ENOTDIR
  283. {ENOTDIR, "Not a directory"},
  284. #endif /* ENOTDIR */
  285. #ifdef EISDIR
  286. {EISDIR, "Is a directory"},
  287. #endif /* EISDIR */
  288. #ifdef EINVAL
  289. {EINVAL, "Invalid argument"},
  290. #endif /* EINVAL */
  291. #ifdef ENFILE
  292. {ENFILE, "File table overflow"},
  293. #endif /* ENFILE */
  294. #ifdef EMFILE
  295. {EMFILE, "Too many open files"},
  296. #endif /* EMFILE */
  297. #ifdef ENOTTY
  298. {ENOTTY, "Inappropriate ioctl for device"},
  299. #endif /* ENOTTY */
  300. #ifdef ETXTBSY
  301. {ETXTBSY, "Text file busy"},
  302. #endif /* ETXTBSY */
  303. #ifdef EFBIG
  304. {EFBIG, "File too large"},
  305. #endif /* EFBIG */
  306. #ifdef ENOSPC
  307. {ENOSPC, "No space left on device"},
  308. #endif /* ENOSPC */
  309. #ifdef ESPIPE
  310. {ESPIPE, "Illegal seek"},
  311. #endif /* ESPIPE */
  312. #ifdef EROFS
  313. {EROFS, "Read only file system"},
  314. #endif /* EROFS */
  315. #ifdef EMLINK
  316. {EMLINK, "Too many links"},
  317. #endif /* EMLINK */
  318. #ifdef EPIPE
  319. {EPIPE, "Broken pipe"},
  320. #endif /* EPIPE */
  321. #ifdef EDOM
  322. {EDOM, "Math arg out of domain of func"},
  323. #endif /* EDOM */
  324. #ifdef ERANGE
  325. {ERANGE, "Math result not representable"},
  326. #endif /* ERANGE */
  327. #ifdef ENOMSG
  328. {ENOMSG, "No message of desired type"},
  329. #endif /* ENOMSG */
  330. #ifdef EIDRM
  331. {EIDRM, "Identifier removed"},
  332. #endif /* EIDRM */
  333. #ifdef ECHRNG
  334. {ECHRNG, "Channel number out of range"},
  335. #endif /* ECHRNG */
  336. #ifdef EL2NSYNC
  337. {EL2NSYNC, "Level 2 not synchronized"},
  338. #endif /* EL2NSYNC */
  339. #ifdef EL3HLT
  340. {EL3HLT, "Level 3 halted"},
  341. #endif /* EL3HLT */
  342. #ifdef EL3RST
  343. {EL3RST, "Level 3 reset"},
  344. #endif /* EL3RST */
  345. #ifdef ELNRNG
  346. {ELNRNG, "Link number out of range"},
  347. #endif /* ELNRNG */
  348. #ifdef EUNATCH
  349. {EUNATCH, "Protocol driver not attached"},
  350. #endif /* EUNATCH */
  351. #ifdef ENOCSI
  352. {ENOCSI, "No CSI structure available"},
  353. #endif /* ENOCSI */
  354. #ifdef EL2HLT
  355. {EL2HLT, "Level 2 halted"},
  356. #endif /* EL2HLT */
  357. #ifdef EDEADLK
  358. {EDEADLK, "Deadlock condition."},
  359. #endif /* EDEADLK */
  360. #ifdef ENOLCK
  361. {ENOLCK, "No record locks available."},
  362. #endif /* ENOLCK */
  363. #ifdef ECANCELED
  364. {ECANCELED, "Operation canceled"},
  365. #endif /* ECANCELED */
  366. #ifdef ENOTSUP
  367. {ENOTSUP, "Operation not supported"},
  368. #endif /* ENOTSUP */
  369. #ifdef EDQUOT
  370. {EDQUOT, "Disc quota exceeded"},
  371. #endif /* EDQUOT */
  372. #ifdef EBADE
  373. {EBADE, "invalid exchange"},
  374. #endif /* EBADE */
  375. #ifdef EBADR
  376. {EBADR, "invalid request descriptor"},
  377. #endif /* EBADR */
  378. #ifdef EXFULL
  379. {EXFULL, "exchange full"},
  380. #endif /* EXFULL */
  381. #ifdef ENOANO
  382. {ENOANO, "no anode"},
  383. #endif /* ENOANO */
  384. #ifdef EBADRQC
  385. {EBADRQC, "invalid request code"},
  386. #endif /* EBADRQC */
  387. #ifdef EBADSLT
  388. {EBADSLT, "invalid slot"},
  389. #endif /* EBADSLT */
  390. #ifdef EDEADLOCK
  391. {EDEADLOCK, "file locking deadlock error"},
  392. #endif /* EDEADLOCK */
  393. #ifdef EBFONT
  394. {EBFONT, "bad font file fmt"},
  395. #endif /* EBFONT */
  396. #ifdef ENOSTR
  397. {ENOSTR, "Device not a stream"},
  398. #endif /* ENOSTR */
  399. #ifdef ENODATA
  400. {ENODATA, "no data (for no delay io)"},
  401. #endif /* ENODATA */
  402. #ifdef ETIME
  403. {ETIME, "timer expired"},
  404. #endif /* ETIME */
  405. #ifdef ENOSR
  406. {ENOSR, "out of streams resources"},
  407. #endif /* ENOSR */
  408. #ifdef ENONET
  409. {ENONET, "Machine is not on the network"},
  410. #endif /* ENONET */
  411. #ifdef ENOPKG
  412. {ENOPKG, "Package not installed"},
  413. #endif /* ENOPKG */
  414. #ifdef EREMOTE
  415. {EREMOTE, "The object is remote"},
  416. #endif /* EREMOTE */
  417. #ifdef ENOLINK
  418. {ENOLINK, "the link has been severed"},
  419. #endif /* ENOLINK */
  420. #ifdef EADV
  421. {EADV, "advertise error"},
  422. #endif /* EADV */
  423. #ifdef ESRMNT
  424. {ESRMNT, "srmount error"},
  425. #endif /* ESRMNT */
  426. #ifdef ECOMM
  427. {ECOMM, "Communication error on send"},
  428. #endif /* ECOMM */
  429. #ifdef EPROTO
  430. {EPROTO, "Protocol error"},
  431. #endif /* EPROTO */
  432. #ifdef EMULTIHOP
  433. {EMULTIHOP, "multihop attempted"},
  434. #endif /* EMULTIHOP */
  435. #ifdef EBADMSG
  436. {EBADMSG, "trying to read unreadable message"},
  437. #endif /* EBADMSG */
  438. #ifdef ENAMETOOLONG
  439. {ENAMETOOLONG, "path name is too long"},
  440. #endif /* ENAMETOOLONG */
  441. #ifdef EOVERFLOW
  442. {EOVERFLOW, "value too large to be stored in data type"},
  443. #endif /* EOVERFLOW */
  444. #ifdef ENOTUNIQ
  445. {ENOTUNIQ, "given log. name not unique"},
  446. #endif /* ENOTUNIQ */
  447. #ifdef EBADFD
  448. {EBADFD, "f.d. invalid for this operation"},
  449. #endif /* EBADFD */
  450. #ifdef EREMCHG
  451. {EREMCHG, "Remote address changed"},
  452. #endif /* EREMCHG */
  453. #ifdef ELIBACC
  454. {ELIBACC, "Can't access a needed shared lib."},
  455. #endif /* ELIBACC */
  456. #ifdef ELIBBAD
  457. {ELIBBAD, "Accessing a corrupted shared lib."},
  458. #endif /* ELIBBAD */
  459. #ifdef ELIBSCN
  460. {ELIBSCN, ".lib section in a.out corrupted."},
  461. #endif /* ELIBSCN */
  462. #ifdef ELIBMAX
  463. {ELIBMAX, "Attempting to link in too many libs."},
  464. #endif /* ELIBMAX */
  465. #ifdef ELIBEXEC
  466. {ELIBEXEC, "Attempting to exec a shared library."},
  467. #endif /* ELIBEXEC */
  468. #ifdef EILSEQ
  469. {EILSEQ, "Illegal byte sequence."},
  470. #endif /* EILSEQ */
  471. #ifdef ENOSYS
  472. {ENOSYS, "Unsupported file system operation"},
  473. #endif /* ENOSYS */
  474. #ifdef ELOOP
  475. {ELOOP, "Symbolic link loop"},
  476. #endif /* ELOOP */
  477. #ifdef ERESTART
  478. {ERESTART, "Restartable system call"},
  479. #endif /* ERESTART */
  480. #ifdef ESTRPIPE
  481. {ESTRPIPE, "if pipe/FIFO, don't sleep in stream head"},
  482. #endif /* ESTRPIPE */
  483. #ifdef ENOTEMPTY
  484. {ENOTEMPTY, "directory not empty"},
  485. #endif /* ENOTEMPTY */
  486. #ifdef EUSERS
  487. {EUSERS, "Too many users (for UFS)"},
  488. #endif /* EUSERS */
  489. #ifdef ENOTSOCK
  490. {ENOTSOCK, "Socket operation on non-socket"},
  491. #endif /* ENOTSOCK */
  492. #ifdef EDESTADDRREQ
  493. {EDESTADDRREQ, "Destination address required"},
  494. #endif /* EDESTADDRREQ */
  495. #ifdef EMSGSIZE
  496. {EMSGSIZE, "Message too long"},
  497. #endif /* EMSGSIZE */
  498. #ifdef EPROTOTYPE
  499. {EPROTOTYPE, "Protocol wrong type for socket"},
  500. #endif /* EPROTOTYPE */
  501. #ifdef ENOPROTOOPT
  502. {ENOPROTOOPT, "Protocol not available"},
  503. #endif /* ENOPROTOOPT */
  504. #ifdef EPROTONOSUPPORT
  505. {EPROTONOSUPPORT, "Protocol not supported"},
  506. #endif /* EPROTONOSUPPORT */
  507. #ifdef ESOCKTNOSUPPORT
  508. {ESOCKTNOSUPPORT, "Socket type not supported"},
  509. #endif /* ESOCKTNOSUPPORT */
  510. #ifdef EOPNOTSUPP
  511. {EOPNOTSUPP, "Operation not supported on socket"},
  512. #endif /* EOPNOTSUPP */
  513. #ifdef EPFNOSUPPORT
  514. {EPFNOSUPPORT, "Protocol family not supported"},
  515. #endif /* EPFNOSUPPORT */
  516. #ifdef EAFNOSUPPORT
  517. {EAFNOSUPPORT, "Address family not supported by"},
  518. #endif /* EAFNOSUPPORT */
  519. #ifdef EADDRINUSE
  520. {EADDRINUSE, "Address already in use"},
  521. #endif /* EADDRINUSE */
  522. #ifdef EADDRNOTAVAIL
  523. {EADDRNOTAVAIL, "Can't assign requested address"},
  524. #endif /* EADDRNOTAVAIL */
  525. #ifdef ENETDOWN
  526. {ENETDOWN, "Network is down"},
  527. #endif /* ENETDOWN */
  528. #ifdef ENETUNREACH
  529. {ENETUNREACH, "Network is unreachable"},
  530. #endif /* ENETUNREACH */
  531. #ifdef ENETRESET
  532. {ENETRESET, "Network dropped connection because"},
  533. #endif /* ENETRESET */
  534. #ifdef ECONNABORTED
  535. {ECONNABORTED, "Software caused connection abort"},
  536. #endif /* ECONNABORTED */
  537. #ifdef ECONNRESET
  538. {ECONNRESET, "Connection reset by peer"},
  539. #endif /* ECONNRESET */
  540. #ifdef ENOBUFS
  541. {ENOBUFS, "No buffer space available"},
  542. #endif /* ENOBUFS */
  543. #ifdef EISCONN
  544. {EISCONN, "Socket is already connected"},
  545. #endif /* EISCONN */
  546. #ifdef ENOTCONN
  547. {ENOTCONN, "Socket is not connected"},
  548. #endif /* ENOTCONN */
  549. #ifdef ESHUTDOWN
  550. {ESHUTDOWN, "Can't send after socket shutdown"},
  551. #endif /* ESHUTDOWN */
  552. #ifdef ETOOMANYREFS
  553. {ETOOMANYREFS, "Too many references: can't splice"},
  554. #endif /* ETOOMANYREFS */
  555. #ifdef ETIMEDOUT
  556. {ETIMEDOUT, "Connection timed out"},
  557. #endif /* ETIMEDOUT */
  558. #ifdef ECONNREFUSED
  559. {ECONNREFUSED, "Connection refused"},
  560. #endif /* ECONNREFUSED */
  561. #ifdef EHOSTDOWN
  562. {EHOSTDOWN, "Host is down"},
  563. #endif /* EHOSTDOWN */
  564. #ifdef EHOSTUNREACH
  565. {EHOSTUNREACH, "No route to host"},
  566. #endif /* EHOSTUNREACH */
  567. #ifdef EALREADY
  568. {EALREADY, "operation already in progress"},
  569. #endif /* EALREADY */
  570. #ifdef EINPROGRESS
  571. {EINPROGRESS, "operation now in progress"},
  572. #endif /* EINPROGRESS */
  573. #ifdef ESTALE
  574. {ESTALE, "Stale NFS file handle"},
  575. #endif /* ESTALE */
  576. {0, NULL}};
  577. for(i = 0; error_list[i].str != NULL; i++)
  578. if(error_list[i].id == errnum)
  579. return error_list[i].str;
  580. sprintf(s, "ERROR %d", errnum);
  581. return s;
  582. }
  583. #endif /* HAVE_ERRNO_H */
  584. #endif /* HAVE_STRERROR */
  585. #ifndef HAVE_USLEEP
  586. #ifdef __W32__
  587. int usleep(unsigned int usec)
  588. {
  589. Sleep(usec / 1000);
  590. return 0;
  591. }
  592. #elif __MACOS__
  593. int usleep(unsigned int /*usec*/)
  594. {
  595. YieldToAnyThread();
  596. return 0;
  597. }
  598. #else
  599. int usleep(unsigned int usec)
  600. {
  601. struct timeval tv;
  602. tv.tv_sec = usec / 1000000;
  603. tv.tv_usec = usec % 1000000;
  604. select(0, NULL, NULL, NULL, &tv);
  605. return 0;
  606. }
  607. #endif /* __W32__ */
  608. #endif /* HAVE_USLEEP */
  609. #ifndef HAVE_STRDUP
  610. char *strdup(const char *s)
  611. {
  612. size_t len;
  613. char *p;
  614. len = strlen(s);
  615. if((p = (char *)safe_malloc(len + 1)) == NULL)
  616. return NULL;
  617. return strcpy(p, s);
  618. }
  619. #endif /* HAVE_STRDUP */
  620. #ifndef HAVE_GETCWD
  621. #ifndef MAXPATHLEN
  622. #define MAXPATHLEN 1024 /* It must be defined in <sys/param.h> */
  623. #endif /* MAXPATHLEN */
  624. char *getcwd(char *buf, size_t size)
  625. {
  626. char path[MAXPATHLEN+1];
  627. if(getwd(path) == NULL)
  628. strcpy(path, ".");
  629. if(buf != NULL)
  630. return strncpy(buf, path, size);
  631. return safe_strdup(path);
  632. }
  633. #endif /* HAVE_GETCWD */
  634. #ifndef HAVE_STRNCASECMP
  635. int strncasecmp(char *s1, char *s2, unsigned int len) {
  636. int dif;
  637. while (len-- > 0) {
  638. if ((dif =
  639. (unsigned char)tolower(*s1) - (unsigned char)tolower(*s2++)) != 0)
  640. return(dif);
  641. if (*s1++ == '\0')
  642. break;
  643. }
  644. return (0);
  645. }
  646. #endif /* HAVE_STRNCASECMP */
  647. #ifndef HAVE_SYS_STAT_H
  648. #ifdef __MACOS__
  649. int stat(const char *filename, struct stat *st)
  650. {
  651. Str255 pfilename;
  652. CInfoPBRec pb;
  653. FSSpec fss;
  654. c2pstrcpy(pfilename, filename);
  655. if (FSMakeFSSpec(0, 0, pfilename, &fss) == noErr)
  656. {
  657. pb.hFileInfo.ioNamePtr = fss.name;
  658. pb.hFileInfo.ioVRefNum = fss.vRefNum;
  659. pb.hFileInfo.ioFDirIndex = 0;
  660. pb.hFileInfo.ioDirID = fss.parID;
  661. if (PBGetCatInfoSync(&pb) == noErr)
  662. {
  663. st->st_mode = (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) ? S_IFDIR : 0;
  664. st->st_dev = pb.hFileInfo.ioVRefNum;
  665. st->st_ino = pb.hFileInfo.ioDirID;
  666. st->st_size = pb.hFileInfo.ioFlLgLen;
  667. st->st_mtime = pb.hFileInfo.ioFlMdDat;
  668. st->st_ctime = pb.hFileInfo.ioFlCrDat;
  669. st->st_btime = pb.hFileInfo.ioFlBkDat;
  670. return 0;
  671. }
  672. }
  673. st->st_mode = 0;
  674. st->st_dev = 0;
  675. st->st_ino = 0;
  676. st->st_size = 0;
  677. st->st_mtime = st->st_ctime = st->st_btime = 0;
  678. errno = EIO;
  679. return -1;
  680. }
  681. #endif /* __MACOS__ */
  682. #endif /* HAVE_SYS_STAT_H */
  683. #ifndef HAVE_STRLCPY
  684. /*
  685. * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  686. *
  687. * Permission to use, copy, modify, and distribute this software for any
  688. * purpose with or without fee is hereby granted, provided that the above
  689. * copyright notice and this permission notice appear in all copies.
  690. *
  691. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  692. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  693. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  694. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  695. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  696. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  697. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  698. */
  699. #include <sys/types.h>
  700. #include <string.h>
  701. /*
  702. * Copy src to string dst of size siz. At most siz-1 characters
  703. * will be copied. Always NUL terminates (unless siz == 0).
  704. * Returns strlen(src); if retval >= siz, truncation occurred.
  705. */
  706. size_t
  707. strlcpy(char *dst, const char *src, size_t siz)
  708. {
  709. register char *d = dst;
  710. register const char *s = src;
  711. register size_t n = siz;
  712. /* Copy as many bytes as will fit */
  713. if (n != 0 && --n != 0) {
  714. do {
  715. if ((*d++ = *s++) == 0)
  716. break;
  717. } while (--n != 0);
  718. }
  719. /* Not enough room in dst, add NUL and traverse rest of src */
  720. if (n == 0) {
  721. if (siz != 0)
  722. *d = '\0'; /* NUL-terminate dst */
  723. while (*s++)
  724. ;
  725. }
  726. return(s - src - 1); /* count does not include NUL */
  727. }
  728. #endif /* strlcpy() */
  729. #ifndef HAVE_STRLCAT
  730. /*
  731. * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
  732. *
  733. * Permission to use, copy, modify, and distribute this software for any
  734. * purpose with or without fee is hereby granted, provided that the above
  735. * copyright notice and this permission notice appear in all copies.
  736. *
  737. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  738. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  739. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  740. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  741. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  742. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  743. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  744. */
  745. #include <sys/types.h>
  746. #include <string.h>
  747. /*
  748. * Appends src to string dst of size siz (unlike strncat, siz is the
  749. * full size of dst, not space left). At most siz-1 characters
  750. * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
  751. * Returns strlen(src) + MIN(siz, strlen(initial dst)).
  752. * If retval >= siz, truncation occurred.
  753. */
  754. size_t
  755. strlcat(char *dst, const char *src, size_t siz)
  756. {
  757. register char *d = dst;
  758. register const char *s = src;
  759. register size_t n = siz;
  760. size_t dlen;
  761. /* Find the end of dst and adjust bytes left but don't go past end */
  762. while (n-- != 0 && *d != '\0')
  763. d++;
  764. dlen = d - dst;
  765. n = siz - dlen;
  766. if (n == 0)
  767. return(dlen + strlen(s));
  768. while (*s != '\0') {
  769. if (n != 1) {
  770. *d++ = *s;
  771. n--;
  772. }
  773. s++;
  774. }
  775. *d = '\0';
  776. return(dlen + (s - src)); /* count does not include NUL */
  777. }
  778. #endif /* strlcat() */