osbind.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Copyright (c) 1983-2013 Martin Atkins, Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /*
  22. * emulation of Misc Atari OS routines
  23. */
  24. /*
  25. * Revision 1.2 1995/02/01 10:54:37 martin
  26. * Added CDP_MEMORY_BBSIZE to control Malloc(-1) result
  27. *
  28. * Revision 1.1 1994/10/31 15:46:36 martin
  29. * Initial revision
  30. *
  31. */
  32. /*RWD 16/1/96 changed hz200 to GetSystemTime() from GetLocalTime() */
  33. /*RWD 7/9/96 fixed bug in getdrivefreespace() */
  34. #ifdef _WIN32
  35. #include <windows.h>
  36. #include <time.h>
  37. #endif
  38. #include <stdlib.h>
  39. #include <osbind.h>
  40. #if defined __GNUWIN32__ || defined unix
  41. #include <ctype.h>
  42. #include <sys/types.h>
  43. #include <limits.h>
  44. #include <sys/time.h>
  45. #include <unistd.h>
  46. #endif
  47. #ifdef __GNUWIN32__
  48. #include <io.h>
  49. #endif
  50. #ifdef unix
  51. #include <string.h>
  52. #include <sys/param.h>
  53. #include <sys/mount.h>
  54. #endif
  55. #ifdef linux
  56. #include <stdint.h>
  57. #include <sys/vfs.h>
  58. #endif
  59. /*RWD May 2005: has to be a signed value sadly!*/
  60. /* RWD Jan 2014 not any longer... */
  61. #define BIGFILESIZE (0xFFFFFFFFLU)
  62. void *
  63. Malloc(long size)
  64. {
  65. char *bbs;
  66. unsigned long res;
  67. if(size != -1)
  68. return malloc(size);
  69. /* this is a request for the maximum block size */
  70. if((bbs = getenv("CDP_MEMORY_BBSIZE")) == NULL)
  71. return (void *)(1024*1024);
  72. res = atol(bbs);
  73. if(res < 10)
  74. res = 100;
  75. else if(res > 20*1024)
  76. res = 20 * 1024;
  77. res *= 1024;
  78. return (void *)res;
  79. }
  80. void
  81. Mfree(void *ptr)
  82. {
  83. free(ptr);
  84. }
  85. /************** WINDOWS ************************/
  86. #ifdef _WIN32
  87. unsigned int
  88. hz200(void)
  89. {
  90. unsigned long secs, ticks;
  91. SYSTEMTIME st;
  92. GetLocalTime(&st);
  93. ticks = st.wMilliseconds/(1000/200);
  94. secs = (st.wHour*60 + st.wMinute) * 60 + st.wSecond;
  95. return (unsigned int)(secs*200 + ticks);
  96. }
  97. /*TW*/
  98. unsigned int
  99. hz1000(void)
  100. {
  101. unsigned long secs, ticks;
  102. SYSTEMTIME st;
  103. GetLocalTime(&st);
  104. ticks = st.wMilliseconds;
  105. secs = (st.wHour*60 + st.wMinute) * 60 + st.wSecond;
  106. return (unsigned int)( secs*1000 + ticks);
  107. }
  108. unsigned int
  109. getdrivefreespace(const char *path)
  110. {
  111. DWORD sectorspercluster;
  112. DWORD bytespersector;
  113. DWORD freeclusters;
  114. DWORD totclusters;
  115. __int64 freesectors; /*RWD Jan 2014 */
  116. char pbuf[4];
  117. if(path[0] != '\0' && path[1] == ':') {
  118. pbuf[0] = path[0];
  119. pbuf[1] = ':';
  120. pbuf[2] = '\\';
  121. pbuf[3] = '\0'; /*RWD*/
  122. path = pbuf;
  123. } else
  124. path = 0;
  125. if(!GetDiskFreeSpace(path, &sectorspercluster, &bytespersector, &freeclusters, &totclusters))
  126. return 0;
  127. freesectors = (__int64)freeclusters * sectorspercluster;
  128. if(freesectors > BIGFILESIZE/bytespersector)
  129. return BIGFILESIZE; /* next line would overflow!! */
  130. return (unsigned int)(freesectors * bytespersector);
  131. }
  132. char *
  133. legalfilename(char *filename)
  134. {
  135. char *lastdot = strrchr(filename, '.');
  136. char *lastfs = strrchr(filename, '\\');
  137. DWORD maxcl;
  138. char path[4];
  139. char fstname[10];
  140. if(lastdot == 0 || lastfs == 0 || lastdot <= lastfs || filename[1] != ':')
  141. return "Illegal filename: internal error";
  142. path[0] = filename[0];
  143. path[1] = ':';
  144. path[2] = '\\';
  145. path[3] = '\0';
  146. if(!GetVolumeInformation(path,
  147. (LPTSTR)0, 0, /* volume name */
  148. (LPDWORD)0, /* volume serial number */
  149. &maxcl, /* maximum component length */
  150. (LPDWORD)0, /* filesystem flags */
  151. fstname, 10 /* file system type name */
  152. ))
  153. return "Illegal filename: can't get volume information";
  154. if(strcmp(fstname, "FAT") == 0 && maxcl == 12) {/* don't know what vfat under windows4 will look like! */
  155. if(strchr(lastfs+1, '.') != lastdot)
  156. return "Illegal filename: FAT filenames cannot have more than 1 dot";
  157. if(strlen(lastdot+1) > 3)
  158. return "Illegal filename: FAT filenames cannot have more than 3 letters after dot";
  159. if(lastdot - (lastfs+1) > 8)
  160. return "Illegal filename: FAT filenames cannot have more than 8 letters before dot";
  161. return 0;
  162. }
  163. if(strlen(lastfs+1) > maxcl)
  164. return "Illegal filename: filename component is too long";
  165. return 0;
  166. }
  167. #endif
  168. /***************************** OS X (at least)******************/
  169. #ifdef unix
  170. unsigned int
  171. hz200(void)
  172. {
  173. struct timeval tv;
  174. if(gettimeofday(&tv, (struct timezone *)0) < 0)
  175. abort();
  176. return (unsigned int)(tv.tv_sec*200 + tv.tv_usec/(1000000/200));
  177. }
  178. unsigned int
  179. hz1000(void)
  180. {
  181. struct timeval tv;
  182. if(gettimeofday(&tv, (struct timezone *)0) < 0)
  183. abort();
  184. return (unsigned int)(tv.tv_sec*1000 + tv.tv_usec/(1000000/1000));
  185. }
  186. unsigned int
  187. getdrivefreespace(const char *path)
  188. {
  189. int ret;
  190. uint64_t avail = 0; /*RWD Jan 2014 */
  191. struct statfs diskstat = {0};
  192. /* RWD we ignore path, and use current dir; cannot use non-existent file path anyway */
  193. ret = statfs(".",&diskstat);
  194. if(ret==0){
  195. if(diskstat.f_bfree > (uint64_t) BIGFILESIZE / diskstat.f_bsize)
  196. avail = BIGFILESIZE;
  197. else
  198. avail = diskstat.f_bsize * diskstat.f_bfree;
  199. }
  200. return (unsigned int) avail;
  201. }
  202. int
  203. _stricmp(const char *a, const char *b)
  204. {
  205. while(*a != '\0' && *b != '\0') {
  206. int ca = islower(*a) ? toupper(*a) : *a;
  207. int cb = islower(*b) ? toupper(*b) : *b;
  208. if(ca < cb)
  209. return -1;
  210. if(ca > cb)
  211. return 1;
  212. a++;
  213. b++;
  214. }
  215. if(*a == '\0' && *b == '\0')
  216. return 0;
  217. if(*a != '\0')
  218. return 1;
  219. return -1;
  220. }
  221. int
  222. _strnicmp(const char *a, const char *b, size_t length)
  223. {
  224. size_t len = length;
  225. while(*a != '\0' && *b != '\0') {
  226. int ca = islower(*a) ? toupper(*a) : *a;
  227. int cb = islower(*b) ? toupper(*b) : *b;
  228. if(len-- < 1)
  229. return 0;
  230. if(ca < cb)
  231. return -1;
  232. if(ca > cb)
  233. return 1;
  234. a++;
  235. b++;
  236. }
  237. if(*a == '\0' && *b == '\0')
  238. return 0;
  239. if(*a != '\0')
  240. return 1;
  241. return -1;
  242. }
  243. char *
  244. _fullpath(char *buf, const char *filename, size_t maxlen)
  245. {
  246. int mybuf = 0;
  247. if(filename[0] == '/') {
  248. if((buf = malloc(strlen(filename) + 1)) == 0)
  249. return (char *)filename;
  250. strcpy(buf, filename);
  251. return buf;
  252. }
  253. if(buf == 0) {
  254. mybuf++;
  255. maxlen = 2 * /*PATH_MAX*/ MAXPATHLEN;
  256. if((buf = malloc(maxlen)) == 0)
  257. return NULL;
  258. }
  259. if(getcwd(buf, maxlen) == NULL)
  260. return (char *)filename;
  261. if(strlen(buf) + strlen(filename) + 2 >= maxlen)
  262. return (char *)filename;
  263. strcat(buf, "/");
  264. strcat(buf, filename);
  265. if(mybuf)
  266. buf = realloc(buf, strlen(buf)+1);
  267. return buf;
  268. }
  269. char *
  270. legalfilename(char *filename)
  271. {
  272. return 0;
  273. }
  274. #endif
  275. /* for both WIN32 and unix! */
  276. void
  277. initrand48(void)
  278. {
  279. srand(time((time_t *)0));
  280. }
  281. double
  282. drand48(void)
  283. {
  284. return (double)rand()/(double)RAND_MAX;
  285. }