test_physfs.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406
  1. /**
  2. * Test program for PhysicsFS. May only work on Unix.
  3. *
  4. * Please see the file LICENSE.txt in the source's root directory.
  5. *
  6. * This file written by Ryan C. Gordon.
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <errno.h>
  11. #include <string.h>
  12. #if (defined __MWERKS__)
  13. #include <SIOUX.h>
  14. #endif
  15. #if (defined PHYSFS_HAVE_READLINE)
  16. #include <unistd.h>
  17. #include <readline/readline.h>
  18. #include <readline/history.h>
  19. #endif
  20. #include <time.h>
  21. #include "physfs.h"
  22. #define TEST_VERSION_MAJOR 2
  23. #define TEST_VERSION_MINOR 1
  24. #define TEST_VERSION_PATCH 0
  25. static FILE *history_file = NULL;
  26. static PHYSFS_uint32 do_buffer_size = 0;
  27. static void output_versions(void)
  28. {
  29. PHYSFS_Version compiled;
  30. PHYSFS_Version linked;
  31. PHYSFS_VERSION(&compiled);
  32. PHYSFS_getLinkedVersion(&linked);
  33. printf("test_physfs version %d.%d.%d.\n"
  34. " Compiled against PhysicsFS version %d.%d.%d,\n"
  35. " and linked against %d.%d.%d.\n\n",
  36. TEST_VERSION_MAJOR, TEST_VERSION_MINOR, TEST_VERSION_PATCH,
  37. (int) compiled.major, (int) compiled.minor, (int) compiled.patch,
  38. (int) linked.major, (int) linked.minor, (int) linked.patch);
  39. } /* output_versions */
  40. static void output_archivers(void)
  41. {
  42. const PHYSFS_ArchiveInfo **rc = PHYSFS_supportedArchiveTypes();
  43. const PHYSFS_ArchiveInfo **i;
  44. printf("Supported archive types:\n");
  45. if (*rc == NULL)
  46. printf(" * Apparently, NONE!\n");
  47. else
  48. {
  49. for (i = rc; *i != NULL; i++)
  50. {
  51. printf(" * %s: %s\n Written by %s.\n %s\n",
  52. (*i)->extension, (*i)->description,
  53. (*i)->author, (*i)->url);
  54. } /* for */
  55. } /* else */
  56. printf("\n");
  57. } /* output_archivers */
  58. static int cmd_quit(char *args)
  59. {
  60. return 0;
  61. } /* cmd_quit */
  62. static int cmd_init(char *args)
  63. {
  64. if (*args == '\"')
  65. {
  66. args++;
  67. args[strlen(args) - 1] = '\0';
  68. } /* if */
  69. if (PHYSFS_init(args))
  70. printf("Successful.\n");
  71. else
  72. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  73. return 1;
  74. } /* cmd_init */
  75. static int cmd_deinit(char *args)
  76. {
  77. if (PHYSFS_deinit())
  78. printf("Successful.\n");
  79. else
  80. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  81. return 1;
  82. } /* cmd_deinit */
  83. static int cmd_addarchive(char *args)
  84. {
  85. char *ptr = strrchr(args, ' ');
  86. int appending = atoi(ptr + 1);
  87. *ptr = '\0';
  88. if (*args == '\"')
  89. {
  90. args++;
  91. *(ptr - 1) = '\0';
  92. } /* if */
  93. /*printf("[%s], [%d]\n", args, appending);*/
  94. if (PHYSFS_mount(args, NULL, appending))
  95. printf("Successful.\n");
  96. else
  97. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  98. return 1;
  99. } /* cmd_addarchive */
  100. /* wrap free() to avoid calling convention wankery. */
  101. static void freeBuf(void *buf)
  102. {
  103. free(buf);
  104. } /* freeBuf */
  105. typedef enum
  106. {
  107. MNTTYPE_PATH,
  108. MNTTYPE_MEMORY,
  109. MNTTYPE_HANDLE
  110. } MountType;
  111. static int cmd_mount_internal(char *args, const MountType mnttype)
  112. {
  113. char *ptr;
  114. char *mntpoint = NULL;
  115. int appending = 0;
  116. int rc = 0;
  117. if (*args == '\"')
  118. {
  119. args++;
  120. ptr = strchr(args, '\"');
  121. if (ptr == NULL)
  122. {
  123. printf("missing string terminator in argument.\n");
  124. return 1;
  125. } /* if */
  126. *(ptr) = '\0';
  127. } /* if */
  128. else
  129. {
  130. ptr = strchr(args, ' ');
  131. *ptr = '\0';
  132. } /* else */
  133. mntpoint = ptr + 1;
  134. if (*mntpoint == '\"')
  135. {
  136. mntpoint++;
  137. ptr = strchr(mntpoint, '\"');
  138. if (ptr == NULL)
  139. {
  140. printf("missing string terminator in argument.\n");
  141. return 1;
  142. } /* if */
  143. *(ptr) = '\0';
  144. } /* if */
  145. else
  146. {
  147. ptr = strchr(mntpoint, ' ');
  148. *(ptr) = '\0';
  149. } /* else */
  150. appending = atoi(ptr + 1);
  151. /*printf("[%s], [%s], [%d]\n", args, mntpoint, appending);*/
  152. if (mnttype == MNTTYPE_PATH)
  153. rc = PHYSFS_mount(args, mntpoint, appending);
  154. else if (mnttype == MNTTYPE_HANDLE)
  155. {
  156. PHYSFS_File *f = PHYSFS_openRead(args);
  157. if (f == NULL)
  158. {
  159. printf("PHYSFS_openRead('%s') failed. reason: %s.\n", args, PHYSFS_getLastError());
  160. return 1;
  161. } /* if */
  162. rc = PHYSFS_mountHandle(f, args, mntpoint, appending);
  163. if (!rc)
  164. PHYSFS_close(f);
  165. } /* else if */
  166. else if (mnttype == MNTTYPE_MEMORY)
  167. {
  168. FILE *in = fopen(args, "rb");
  169. void *buf = NULL;
  170. long len = 0;
  171. if (in == NULL)
  172. {
  173. printf("Failed to open %s to read into memory: %s.\n", args, strerror(errno));
  174. return 1;
  175. } /* if */
  176. if ( (fseek(in, 0, SEEK_END) != 0) || ((len = ftell(in)) < 0) )
  177. {
  178. printf("Failed to find size of %s to read into memory: %s.\n", args, strerror(errno));
  179. fclose(in);
  180. return 1;
  181. } /* if */
  182. buf = malloc(len);
  183. if (buf == NULL)
  184. {
  185. printf("Failed to allocate space to read %s into memory: %s.\n", args, strerror(errno));
  186. fclose(in);
  187. return 1;
  188. } /* if */
  189. if ((fseek(in, 0, SEEK_SET) != 0) || (fread(buf, len, 1, in) != 1))
  190. {
  191. printf("Failed to read %s into memory: %s.\n", args, strerror(errno));
  192. fclose(in);
  193. free(buf);
  194. return 1;
  195. } /* if */
  196. fclose(in);
  197. rc = PHYSFS_mountMemory(buf, len, freeBuf, args, mntpoint, appending);
  198. } /* else */
  199. if (rc)
  200. printf("Successful.\n");
  201. else
  202. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  203. return 1;
  204. } /* cmd_mount_internal */
  205. static int cmd_mount(char *args)
  206. {
  207. return cmd_mount_internal(args, MNTTYPE_PATH);
  208. } /* cmd_mount */
  209. static int cmd_mount_mem(char *args)
  210. {
  211. return cmd_mount_internal(args, MNTTYPE_MEMORY);
  212. } /* cmd_mount_mem */
  213. static int cmd_mount_handle(char *args)
  214. {
  215. return cmd_mount_internal(args, MNTTYPE_HANDLE);
  216. } /* cmd_mount_handle */
  217. static int cmd_removearchive(char *args)
  218. {
  219. if (*args == '\"')
  220. {
  221. args++;
  222. args[strlen(args) - 1] = '\0';
  223. } /* if */
  224. if (PHYSFS_unmount(args))
  225. printf("Successful.\n");
  226. else
  227. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  228. return 1;
  229. } /* cmd_removearchive */
  230. static int cmd_enumerate(char *args)
  231. {
  232. char **rc;
  233. if (*args == '\"')
  234. {
  235. args++;
  236. args[strlen(args) - 1] = '\0';
  237. } /* if */
  238. rc = PHYSFS_enumerateFiles(args);
  239. if (rc == NULL)
  240. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  241. else
  242. {
  243. int file_count;
  244. char **i;
  245. for (i = rc, file_count = 0; *i != NULL; i++, file_count++)
  246. printf("%s\n", *i);
  247. printf("\n total (%d) files.\n", file_count);
  248. PHYSFS_freeList(rc);
  249. } /* else */
  250. return 1;
  251. } /* cmd_enumerate */
  252. static int cmd_getdirsep(char *args)
  253. {
  254. printf("Directory separator is [%s].\n", PHYSFS_getDirSeparator());
  255. return 1;
  256. } /* cmd_getdirsep */
  257. static int cmd_getlasterror(char *args)
  258. {
  259. printf("last error is [%s].\n", PHYSFS_getLastError());
  260. return 1;
  261. } /* cmd_getlasterror */
  262. static int cmd_getcdromdirs(char *args)
  263. {
  264. char **rc = PHYSFS_getCdRomDirs();
  265. if (rc == NULL)
  266. printf("Failure. Reason: [%s].\n", PHYSFS_getLastError());
  267. else
  268. {
  269. int dir_count;
  270. char **i;
  271. for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
  272. printf("%s\n", *i);
  273. printf("\n total (%d) drives.\n", dir_count);
  274. PHYSFS_freeList(rc);
  275. } /* else */
  276. return 1;
  277. } /* cmd_getcdromdirs */
  278. static int cmd_getsearchpath(char *args)
  279. {
  280. char **rc = PHYSFS_getSearchPath();
  281. if (rc == NULL)
  282. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  283. else
  284. {
  285. int dir_count;
  286. char **i;
  287. for (i = rc, dir_count = 0; *i != NULL; i++, dir_count++)
  288. printf("%s\n", *i);
  289. printf("\n total (%d) directories.\n", dir_count);
  290. PHYSFS_freeList(rc);
  291. } /* else */
  292. return 1;
  293. } /* cmd_getcdromdirs */
  294. static int cmd_getbasedir(char *args)
  295. {
  296. printf("Base dir is [%s].\n", PHYSFS_getBaseDir());
  297. return 1;
  298. } /* cmd_getbasedir */
  299. static int cmd_getuserdir(char *args)
  300. {
  301. printf("User dir is [%s].\n", PHYSFS_getUserDir());
  302. return 1;
  303. } /* cmd_getuserdir */
  304. static int cmd_getwritedir(char *args)
  305. {
  306. printf("Write dir is [%s].\n", PHYSFS_getWriteDir());
  307. return 1;
  308. } /* cmd_getwritedir */
  309. static int cmd_setwritedir(char *args)
  310. {
  311. if (*args == '\"')
  312. {
  313. args++;
  314. args[strlen(args) - 1] = '\0';
  315. } /* if */
  316. if (PHYSFS_setWriteDir(args))
  317. printf("Successful.\n");
  318. else
  319. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  320. return 1;
  321. } /* cmd_setwritedir */
  322. static int cmd_permitsyms(char *args)
  323. {
  324. int num;
  325. if (*args == '\"')
  326. {
  327. args++;
  328. args[strlen(args) - 1] = '\0';
  329. } /* if */
  330. num = atoi(args);
  331. PHYSFS_permitSymbolicLinks(num);
  332. printf("Symlinks are now %s.\n", num ? "permitted" : "forbidden");
  333. return 1;
  334. } /* cmd_permitsyms */
  335. static int cmd_setbuffer(char *args)
  336. {
  337. if (*args == '\"')
  338. {
  339. args++;
  340. args[strlen(args) - 1] = '\0';
  341. } /* if */
  342. do_buffer_size = (unsigned int) atoi(args);
  343. if (do_buffer_size)
  344. {
  345. printf("Further tests will set a (%lu) size buffer.\n",
  346. (unsigned long) do_buffer_size);
  347. } /* if */
  348. else
  349. {
  350. printf("Further tests will NOT use a buffer.\n");
  351. } /* else */
  352. return 1;
  353. } /* cmd_setbuffer */
  354. static int cmd_stressbuffer(char *args)
  355. {
  356. int num;
  357. if (*args == '\"')
  358. {
  359. args++;
  360. args[strlen(args) - 1] = '\0';
  361. } /* if */
  362. num = atoi(args);
  363. if (num < 0)
  364. printf("buffer must be greater than or equal to zero.\n");
  365. else
  366. {
  367. PHYSFS_File *f;
  368. int rndnum;
  369. printf("Stress testing with (%d) byte buffer...\n", num);
  370. f = PHYSFS_openWrite("test.txt");
  371. if (f == NULL)
  372. printf("Couldn't open test.txt for writing: %s.\n", PHYSFS_getLastError());
  373. else
  374. {
  375. int i, j;
  376. char buf[37];
  377. char buf2[37];
  378. if (!PHYSFS_setBuffer(f, num))
  379. {
  380. printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
  381. PHYSFS_close(f);
  382. PHYSFS_delete("test.txt");
  383. return 1;
  384. } /* if */
  385. strcpy(buf, "abcdefghijklmnopqrstuvwxyz0123456789");
  386. srand((unsigned int) time(NULL));
  387. for (i = 0; i < 10; i++)
  388. {
  389. for (j = 0; j < 10000; j++)
  390. {
  391. PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
  392. PHYSFS_uint32 left = 36 - right;
  393. if (PHYSFS_writeBytes(f, buf, left) != left)
  394. {
  395. printf("PHYSFS_writeBytes() failed: %s.\n", PHYSFS_getLastError());
  396. PHYSFS_close(f);
  397. return 1;
  398. } /* if */
  399. rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
  400. if (rndnum == 42)
  401. {
  402. if (!PHYSFS_flush(f))
  403. {
  404. printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
  405. PHYSFS_close(f);
  406. return 1;
  407. } /* if */
  408. } /* if */
  409. if (PHYSFS_writeBytes(f, buf + left, right) != right)
  410. {
  411. printf("PHYSFS_writeBytes() failed: %s.\n", PHYSFS_getLastError());
  412. PHYSFS_close(f);
  413. return 1;
  414. } /* if */
  415. rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
  416. if (rndnum == 42)
  417. {
  418. if (!PHYSFS_flush(f))
  419. {
  420. printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
  421. PHYSFS_close(f);
  422. return 1;
  423. } /* if */
  424. } /* if */
  425. } /* for */
  426. if (!PHYSFS_flush(f))
  427. {
  428. printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
  429. PHYSFS_close(f);
  430. return 1;
  431. } /* if */
  432. } /* for */
  433. if (!PHYSFS_close(f))
  434. {
  435. printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
  436. return 1; /* oh well. */
  437. } /* if */
  438. printf(" ... test file written ...\n");
  439. f = PHYSFS_openRead("test.txt");
  440. if (f == NULL)
  441. {
  442. printf("Failed to reopen stress file for reading: %s.\n", PHYSFS_getLastError());
  443. return 1;
  444. } /* if */
  445. if (!PHYSFS_setBuffer(f, num))
  446. {
  447. printf("PHYSFS_setBuffer() failed: %s.\n", PHYSFS_getLastError());
  448. PHYSFS_close(f);
  449. return 1;
  450. } /* if */
  451. for (i = 0; i < 10; i++)
  452. {
  453. for (j = 0; j < 10000; j++)
  454. {
  455. PHYSFS_uint32 right = 1 + (PHYSFS_uint32) (35.0 * rand() / (RAND_MAX + 1.0));
  456. PHYSFS_uint32 left = 36 - right;
  457. if (PHYSFS_readBytes(f, buf2, left) != left)
  458. {
  459. printf("PHYSFS_readBytes() failed: %s.\n", PHYSFS_getLastError());
  460. PHYSFS_close(f);
  461. return 1;
  462. } /* if */
  463. rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
  464. if (rndnum == 42)
  465. {
  466. if (!PHYSFS_flush(f))
  467. {
  468. printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
  469. PHYSFS_close(f);
  470. return 1;
  471. } /* if */
  472. } /* if */
  473. if (PHYSFS_readBytes(f, buf2 + left, right) != right)
  474. {
  475. printf("PHYSFS_readBytes() failed: %s.\n", PHYSFS_getLastError());
  476. PHYSFS_close(f);
  477. return 1;
  478. } /* if */
  479. rndnum = 1 + (int) (1000.0 * rand() / (RAND_MAX + 1.0));
  480. if (rndnum == 42)
  481. {
  482. if (!PHYSFS_flush(f))
  483. {
  484. printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
  485. PHYSFS_close(f);
  486. return 1;
  487. } /* if */
  488. } /* if */
  489. if (memcmp(buf, buf2, 36) != 0)
  490. {
  491. printf("readback is mismatched on iterations (%d, %d).\n", i, j);
  492. printf("wanted: [");
  493. for (i = 0; i < 36; i++)
  494. printf("%c", buf[i]);
  495. printf("]\n");
  496. printf(" got: [");
  497. for (i = 0; i < 36; i++)
  498. printf("%c", buf2[i]);
  499. printf("]\n");
  500. PHYSFS_close(f);
  501. return 1;
  502. } /* if */
  503. } /* for */
  504. if (!PHYSFS_flush(f))
  505. {
  506. printf("PHYSFS_flush() failed: %s.\n", PHYSFS_getLastError());
  507. PHYSFS_close(f);
  508. return 1;
  509. } /* if */
  510. } /* for */
  511. printf(" ... test file read ...\n");
  512. if (!PHYSFS_eof(f))
  513. printf("PHYSFS_eof() returned true! That's wrong.\n");
  514. if (!PHYSFS_close(f))
  515. {
  516. printf("PHYSFS_close() failed: %s.\n", PHYSFS_getLastError());
  517. return 1; /* oh well. */
  518. } /* if */
  519. PHYSFS_delete("test.txt");
  520. printf("stress test completed successfully.\n");
  521. } /* else */
  522. } /* else */
  523. return 1;
  524. } /* cmd_stressbuffer */
  525. static int cmd_setsaneconfig(char *args)
  526. {
  527. char *org;
  528. char *appName;
  529. char *arcExt;
  530. int inclCD;
  531. int arcsFirst;
  532. char *ptr = args;
  533. /* ugly. */
  534. org = ptr;
  535. ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; appName = ptr;
  536. ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; arcExt = ptr;
  537. ptr = strchr(ptr, ' '); *ptr = '\0'; ptr++; inclCD = atoi(arcExt);
  538. arcsFirst = atoi(ptr);
  539. if (strcmp(arcExt, "!") == 0)
  540. arcExt = NULL;
  541. if (PHYSFS_setSaneConfig(org, appName, arcExt, inclCD, arcsFirst))
  542. printf("Successful.\n");
  543. else
  544. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  545. return 1;
  546. } /* cmd_setsaneconfig */
  547. static int cmd_mkdir(char *args)
  548. {
  549. if (*args == '\"')
  550. {
  551. args++;
  552. args[strlen(args) - 1] = '\0';
  553. } /* if */
  554. if (PHYSFS_mkdir(args))
  555. printf("Successful.\n");
  556. else
  557. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  558. return 1;
  559. } /* cmd_mkdir */
  560. static int cmd_delete(char *args)
  561. {
  562. if (*args == '\"')
  563. {
  564. args++;
  565. args[strlen(args) - 1] = '\0';
  566. } /* if */
  567. if (PHYSFS_delete(args))
  568. printf("Successful.\n");
  569. else
  570. printf("Failure. reason: %s.\n", PHYSFS_getLastError());
  571. return 1;
  572. } /* cmd_delete */
  573. static int cmd_getrealdir(char *args)
  574. {
  575. const char *rc;
  576. if (*args == '\"')
  577. {
  578. args++;
  579. args[strlen(args) - 1] = '\0';
  580. } /* if */
  581. rc = PHYSFS_getRealDir(args);
  582. if (rc)
  583. printf("Found at [%s].\n", rc);
  584. else
  585. printf("Not found.\n");
  586. return 1;
  587. } /* cmd_getrealdir */
  588. static int cmd_exists(char *args)
  589. {
  590. int rc;
  591. if (*args == '\"')
  592. {
  593. args++;
  594. args[strlen(args) - 1] = '\0';
  595. } /* if */
  596. rc = PHYSFS_exists(args);
  597. printf("File %sexists.\n", rc ? "" : "does not ");
  598. return 1;
  599. } /* cmd_exists */
  600. static int cmd_isdir(char *args)
  601. {
  602. int rc;
  603. if (*args == '\"')
  604. {
  605. args++;
  606. args[strlen(args) - 1] = '\0';
  607. } /* if */
  608. rc = PHYSFS_isDirectory(args);
  609. printf("File %s a directory.\n", rc ? "is" : "is NOT");
  610. return 1;
  611. } /* cmd_isdir */
  612. static int cmd_issymlink(char *args)
  613. {
  614. int rc;
  615. if (*args == '\"')
  616. {
  617. args++;
  618. args[strlen(args) - 1] = '\0';
  619. } /* if */
  620. rc = PHYSFS_isSymbolicLink(args);
  621. printf("File %s a symlink.\n", rc ? "is" : "is NOT");
  622. return 1;
  623. } /* cmd_issymlink */
  624. static int cmd_cat(char *args)
  625. {
  626. PHYSFS_File *f;
  627. if (*args == '\"')
  628. {
  629. args++;
  630. args[strlen(args) - 1] = '\0';
  631. } /* if */
  632. f = PHYSFS_openRead(args);
  633. if (f == NULL)
  634. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  635. else
  636. {
  637. if (do_buffer_size)
  638. {
  639. if (!PHYSFS_setBuffer(f, do_buffer_size))
  640. {
  641. printf("failed to set file buffer. Reason: [%s].\n",
  642. PHYSFS_getLastError());
  643. PHYSFS_close(f);
  644. return 1;
  645. } /* if */
  646. } /* if */
  647. while (1)
  648. {
  649. char buffer[128];
  650. PHYSFS_sint64 rc;
  651. PHYSFS_sint64 i;
  652. rc = PHYSFS_readBytes(f, buffer, sizeof (buffer));
  653. for (i = 0; i < rc; i++)
  654. fputc((int) buffer[i], stdout);
  655. if (rc < sizeof (buffer))
  656. {
  657. printf("\n\n");
  658. if (!PHYSFS_eof(f))
  659. {
  660. printf("\n (Error condition in reading. Reason: [%s])\n\n",
  661. PHYSFS_getLastError());
  662. } /* if */
  663. PHYSFS_close(f);
  664. return 1;
  665. } /* if */
  666. } /* while */
  667. } /* else */
  668. return 1;
  669. } /* cmd_cat */
  670. #define CRC32_BUFFERSIZE 512
  671. static int cmd_crc32(char *args)
  672. {
  673. PHYSFS_File *f;
  674. if (*args == '\"')
  675. {
  676. args++;
  677. args[strlen(args) - 1] = '\0';
  678. } /* if */
  679. f = PHYSFS_openRead(args);
  680. if (f == NULL)
  681. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  682. else
  683. {
  684. PHYSFS_uint8 buffer[CRC32_BUFFERSIZE];
  685. PHYSFS_uint32 crc = -1;
  686. PHYSFS_sint64 bytesread;
  687. while ((bytesread = PHYSFS_readBytes(f, buffer, CRC32_BUFFERSIZE)) > 0)
  688. {
  689. PHYSFS_uint32 i, bit;
  690. for (i = 0; i < bytesread; i++)
  691. {
  692. for (bit = 0; bit < 8; bit++, buffer[i] >>= 1)
  693. crc = (crc >> 1) ^ (((crc ^ buffer[i]) & 1) ? 0xEDB88320 : 0);
  694. } /* for */
  695. } /* while */
  696. if (bytesread < 0)
  697. {
  698. printf("error while reading. Reason: [%s].\n",
  699. PHYSFS_getLastError());
  700. return 1;
  701. } /* if */
  702. PHYSFS_close(f);
  703. crc ^= -1;
  704. printf("CRC32 for %s: 0x%08X\n", args, crc);
  705. } /* else */
  706. return 1;
  707. } /* cmd_crc32 */
  708. static int cmd_filelength(char *args)
  709. {
  710. PHYSFS_File *f;
  711. if (*args == '\"')
  712. {
  713. args++;
  714. args[strlen(args) - 1] = '\0';
  715. } /* if */
  716. f = PHYSFS_openRead(args);
  717. if (f == NULL)
  718. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  719. else
  720. {
  721. PHYSFS_sint64 len = PHYSFS_fileLength(f);
  722. if (len == -1)
  723. printf("failed to determine length. Reason: [%s].\n", PHYSFS_getLastError());
  724. else
  725. printf(" (cast to int) %d bytes.\n", (int) len);
  726. PHYSFS_close(f);
  727. } /* else */
  728. return 1;
  729. } /* cmd_filelength */
  730. #define WRITESTR "The cat sat on the mat.\n\n"
  731. static int cmd_append(char *args)
  732. {
  733. PHYSFS_File *f;
  734. if (*args == '\"')
  735. {
  736. args++;
  737. args[strlen(args) - 1] = '\0';
  738. } /* if */
  739. f = PHYSFS_openAppend(args);
  740. if (f == NULL)
  741. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  742. else
  743. {
  744. size_t bw;
  745. PHYSFS_sint64 rc;
  746. if (do_buffer_size)
  747. {
  748. if (!PHYSFS_setBuffer(f, do_buffer_size))
  749. {
  750. printf("failed to set file buffer. Reason: [%s].\n",
  751. PHYSFS_getLastError());
  752. PHYSFS_close(f);
  753. return 1;
  754. } /* if */
  755. } /* if */
  756. bw = strlen(WRITESTR);
  757. rc = PHYSFS_writeBytes(f, WRITESTR, bw);
  758. if (rc != bw)
  759. {
  760. printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
  761. (int) rc, (int) bw, PHYSFS_getLastError());
  762. } /* if */
  763. else
  764. {
  765. printf("Successful.\n");
  766. } /* else */
  767. PHYSFS_close(f);
  768. } /* else */
  769. return 1;
  770. } /* cmd_append */
  771. static int cmd_write(char *args)
  772. {
  773. PHYSFS_File *f;
  774. if (*args == '\"')
  775. {
  776. args++;
  777. args[strlen(args) - 1] = '\0';
  778. } /* if */
  779. f = PHYSFS_openWrite(args);
  780. if (f == NULL)
  781. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  782. else
  783. {
  784. size_t bw;
  785. PHYSFS_sint64 rc;
  786. if (do_buffer_size)
  787. {
  788. if (!PHYSFS_setBuffer(f, do_buffer_size))
  789. {
  790. printf("failed to set file buffer. Reason: [%s].\n",
  791. PHYSFS_getLastError());
  792. PHYSFS_close(f);
  793. return 1;
  794. } /* if */
  795. } /* if */
  796. bw = strlen(WRITESTR);
  797. rc = PHYSFS_writeBytes(f, WRITESTR, bw);
  798. if (rc != bw)
  799. {
  800. printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
  801. (int) rc, (int) bw, PHYSFS_getLastError());
  802. } /* if */
  803. else
  804. {
  805. printf("Successful.\n");
  806. } /* else */
  807. PHYSFS_close(f);
  808. } /* else */
  809. return 1;
  810. } /* cmd_write */
  811. static char* modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
  812. {
  813. time_t t = (time_t) modtime;
  814. char *str = ctime(&t);
  815. strncpy(modstr, str, strsize);
  816. modstr[strsize-1] = '\0';
  817. return modstr;
  818. } /* modTimeToStr */
  819. static int cmd_getlastmodtime(char *args)
  820. {
  821. PHYSFS_Stat statbuf;
  822. if (!PHYSFS_stat(args, &statbuf))
  823. printf("Failed to determine. Reason: [%s].\n", PHYSFS_getLastError());
  824. else
  825. {
  826. char modstr[64];
  827. modTimeToStr(statbuf.modtime, modstr, sizeof (modstr));
  828. printf("Last modified: %s (%ld).\n", modstr, (long) statbuf.modtime);
  829. } /* else */
  830. return 1;
  831. } /* cmd_getLastModTime */
  832. static int cmd_stat(char *args)
  833. {
  834. PHYSFS_Stat stat;
  835. char timestring[65];
  836. if (*args == '\"')
  837. {
  838. args++;
  839. args[strlen(args) - 1] = '\0';
  840. } /* if */
  841. if(!PHYSFS_stat(args, &stat))
  842. {
  843. printf("failed to stat. Reason [%s].\n", PHYSFS_getLastError());
  844. return 1;
  845. } /* if */
  846. printf("Filename: %s\n", args);
  847. printf("Size %d\n",(int) stat.filesize);
  848. if(stat.filetype == PHYSFS_FILETYPE_REGULAR)
  849. printf("Type: File\n");
  850. else if(stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
  851. printf("Type: Directory\n");
  852. else if(stat.filetype == PHYSFS_FILETYPE_SYMLINK)
  853. printf("Type: Symlink\n");
  854. else
  855. printf("Type: Unknown\n");
  856. printf("Created at: %s", modTimeToStr(stat.createtime, timestring, 64));
  857. printf("Last modified at: %s", modTimeToStr(stat.modtime, timestring, 64));
  858. printf("Last accessed at: %s", modTimeToStr(stat.accesstime, timestring, 64));
  859. printf("Readonly: %s\n", stat.readonly ? "true" : "false");
  860. return 1;
  861. } /* cmd_filelength */
  862. /* must have spaces trimmed prior to this call. */
  863. static int count_args(const char *str)
  864. {
  865. int retval = 0;
  866. int in_quotes = 0;
  867. if (str != NULL)
  868. {
  869. for (; *str != '\0'; str++)
  870. {
  871. if (*str == '\"')
  872. in_quotes = !in_quotes;
  873. else if ((*str == ' ') && (!in_quotes))
  874. retval++;
  875. } /* for */
  876. retval++;
  877. } /* if */
  878. return retval;
  879. } /* count_args */
  880. static int cmd_help(char *args);
  881. typedef struct
  882. {
  883. const char *cmd;
  884. int (*func)(char *args);
  885. int argcount;
  886. const char *usage;
  887. } command_info;
  888. static const command_info commands[] =
  889. {
  890. { "quit", cmd_quit, 0, NULL },
  891. { "q", cmd_quit, 0, NULL },
  892. { "help", cmd_help, 0, NULL },
  893. { "init", cmd_init, 1, "<argv0>" },
  894. { "deinit", cmd_deinit, 0, NULL },
  895. { "addarchive", cmd_addarchive, 2, "<archiveLocation> <append>" },
  896. { "mount", cmd_mount, 3, "<archiveLocation> <mntpoint> <append>" },
  897. { "mountmem", cmd_mount_mem, 3, "<archiveLocation> <mntpoint> <append>" },
  898. { "mounthandle", cmd_mount_handle, 3, "<archiveLocation> <mntpoint> <append>" },
  899. { "removearchive", cmd_removearchive, 1, "<archiveLocation>" },
  900. { "unmount", cmd_removearchive, 1, "<archiveLocation>" },
  901. { "enumerate", cmd_enumerate, 1, "<dirToEnumerate>" },
  902. { "ls", cmd_enumerate, 1, "<dirToEnumerate>" },
  903. { "getlasterror", cmd_getlasterror, 0, NULL },
  904. { "getdirsep", cmd_getdirsep, 0, NULL },
  905. { "getcdromdirs", cmd_getcdromdirs, 0, NULL },
  906. { "getsearchpath", cmd_getsearchpath, 0, NULL },
  907. { "getbasedir", cmd_getbasedir, 0, NULL },
  908. { "getuserdir", cmd_getuserdir, 0, NULL },
  909. { "getwritedir", cmd_getwritedir, 0, NULL },
  910. { "setwritedir", cmd_setwritedir, 1, "<newWriteDir>" },
  911. { "permitsymlinks", cmd_permitsyms, 1, "<1or0>" },
  912. { "setsaneconfig", cmd_setsaneconfig, 5, "<org> <appName> <arcExt> <includeCdRoms> <archivesFirst>" },
  913. { "mkdir", cmd_mkdir, 1, "<dirToMk>" },
  914. { "delete", cmd_delete, 1, "<dirToDelete>" },
  915. { "getrealdir", cmd_getrealdir, 1, "<fileToFind>" },
  916. { "exists", cmd_exists, 1, "<fileToCheck>" },
  917. { "isdir", cmd_isdir, 1, "<fileToCheck>" },
  918. { "issymlink", cmd_issymlink, 1, "<fileToCheck>" },
  919. { "cat", cmd_cat, 1, "<fileToCat>" },
  920. { "filelength", cmd_filelength, 1, "<fileToCheck>" },
  921. { "stat", cmd_stat, 1, "<fileToStat>" },
  922. { "append", cmd_append, 1, "<fileToAppend>" },
  923. { "write", cmd_write, 1, "<fileToCreateOrTrash>" },
  924. { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>" },
  925. { "setbuffer", cmd_setbuffer, 1, "<bufferSize>" },
  926. { "stressbuffer", cmd_stressbuffer, 1, "<bufferSize>" },
  927. { "crc32", cmd_crc32, 1, "<fileToHash>" },
  928. { NULL, NULL, -1, NULL }
  929. };
  930. static void output_usage(const char *intro, const command_info *cmdinfo)
  931. {
  932. if (cmdinfo->argcount == 0)
  933. printf("%s \"%s\" (no arguments)\n", intro, cmdinfo->cmd);
  934. else
  935. printf("%s \"%s %s\"\n", intro, cmdinfo->cmd, cmdinfo->usage);
  936. } /* output_usage */
  937. static int cmd_help(char *args)
  938. {
  939. const command_info *i;
  940. printf("Commands:\n");
  941. for (i = commands; i->cmd != NULL; i++)
  942. output_usage(" -", i);
  943. return 1;
  944. } /* output_cmd_help */
  945. static void trim_command(const char *orig, char *copy)
  946. {
  947. const char *i;
  948. char *writeptr = copy;
  949. int spacecount = 0;
  950. int have_first = 0;
  951. for (i = orig; *i != '\0'; i++)
  952. {
  953. if (*i == ' ')
  954. {
  955. if ((*(i + 1) != ' ') && (*(i + 1) != '\0'))
  956. {
  957. if ((have_first) && (!spacecount))
  958. {
  959. spacecount++;
  960. *writeptr = ' ';
  961. writeptr++;
  962. } /* if */
  963. } /* if */
  964. } /* if */
  965. else
  966. {
  967. have_first = 1;
  968. spacecount = 0;
  969. *writeptr = *i;
  970. writeptr++;
  971. } /* else */
  972. } /* for */
  973. *writeptr = '\0';
  974. /*
  975. printf("\n command is [%s].\n", copy);
  976. */
  977. } /* trim_command */
  978. static int process_command(char *complete_cmd)
  979. {
  980. const command_info *i;
  981. char *cmd_copy;
  982. char *args;
  983. int rc = 1;
  984. if (complete_cmd == NULL) /* can happen if user hits CTRL-D, etc. */
  985. {
  986. printf("\n");
  987. return 0;
  988. } /* if */
  989. cmd_copy = (char *) malloc(strlen(complete_cmd) + 1);
  990. if (cmd_copy == NULL)
  991. {
  992. printf("\n\n\nOUT OF MEMORY!\n\n\n");
  993. return 0;
  994. } /* if */
  995. trim_command(complete_cmd, cmd_copy);
  996. args = strchr(cmd_copy, ' ');
  997. if (args != NULL)
  998. {
  999. *args = '\0';
  1000. args++;
  1001. } /* else */
  1002. if (cmd_copy[0] != '\0')
  1003. {
  1004. for (i = commands; i->cmd != NULL; i++)
  1005. {
  1006. if (strcmp(i->cmd, cmd_copy) == 0)
  1007. {
  1008. if ((i->argcount >= 0) && (count_args(args) != i->argcount))
  1009. output_usage("usage:", i);
  1010. else
  1011. rc = i->func(args);
  1012. break;
  1013. } /* if */
  1014. } /* for */
  1015. if (i->cmd == NULL)
  1016. printf("Unknown command. Enter \"help\" for instructions.\n");
  1017. #if (defined PHYSFS_HAVE_READLINE)
  1018. add_history(complete_cmd);
  1019. if (history_file)
  1020. {
  1021. fprintf(history_file, "%s\n", complete_cmd);
  1022. fflush(history_file);
  1023. } /* if */
  1024. #endif
  1025. } /* if */
  1026. free(cmd_copy);
  1027. return rc;
  1028. } /* process_command */
  1029. static void open_history_file(void)
  1030. {
  1031. #if (defined PHYSFS_HAVE_READLINE)
  1032. #if 0
  1033. const char *envr = getenv("TESTPHYSFS_HISTORY");
  1034. if (!envr)
  1035. return;
  1036. #else
  1037. char envr[256];
  1038. strcpy(envr, PHYSFS_getUserDir());
  1039. strcat(envr, ".testphys_history");
  1040. #endif
  1041. if (access(envr, F_OK) == 0)
  1042. {
  1043. char buf[512];
  1044. FILE *f = fopen(envr, "r");
  1045. if (!f)
  1046. {
  1047. printf("\n\n"
  1048. "Could not open history file [%s] for reading!\n"
  1049. " Will not have past history available.\n\n",
  1050. envr);
  1051. return;
  1052. } /* if */
  1053. do
  1054. {
  1055. if (fgets(buf, sizeof (buf), f) == NULL)
  1056. break;
  1057. if (buf[strlen(buf) - 1] == '\n')
  1058. buf[strlen(buf) - 1] = '\0';
  1059. add_history(buf);
  1060. } while (!feof(f));
  1061. fclose(f);
  1062. } /* if */
  1063. history_file = fopen(envr, "ab");
  1064. if (!history_file)
  1065. {
  1066. printf("\n\n"
  1067. "Could not open history file [%s] for appending!\n"
  1068. " Will not be able to record this session's history.\n\n",
  1069. envr);
  1070. } /* if */
  1071. #endif
  1072. } /* open_history_file */
  1073. int main(int argc, char **argv)
  1074. {
  1075. char *buf = NULL;
  1076. int rc = 0;
  1077. #if (defined __MWERKS__)
  1078. extern tSIOUXSettings SIOUXSettings;
  1079. SIOUXSettings.asktosaveonclose = 0;
  1080. SIOUXSettings.autocloseonquit = 1;
  1081. SIOUXSettings.rows = 40;
  1082. SIOUXSettings.columns = 120;
  1083. #endif
  1084. printf("\n");
  1085. if (!PHYSFS_init(argv[0]))
  1086. {
  1087. printf("PHYSFS_init() failed!\n reason: %s.\n", PHYSFS_getLastError());
  1088. return 1;
  1089. } /* if */
  1090. output_versions();
  1091. output_archivers();
  1092. open_history_file();
  1093. printf("Enter commands. Enter \"help\" for instructions.\n");
  1094. fflush(stdout);
  1095. do
  1096. {
  1097. #if (defined PHYSFS_HAVE_READLINE)
  1098. buf = readline("> ");
  1099. #else
  1100. int i;
  1101. buf = (char *) malloc(512);
  1102. memset(buf, '\0', 512);
  1103. printf("> ");
  1104. fflush(stdout);
  1105. for (i = 0; i < 511; i++)
  1106. {
  1107. int ch = fgetc(stdin);
  1108. if (ch == EOF)
  1109. {
  1110. strcpy(buf, "quit");
  1111. break;
  1112. } /* if */
  1113. else if ((ch == '\n') || (ch == '\r'))
  1114. {
  1115. buf[i] = '\0';
  1116. break;
  1117. } /* else if */
  1118. else if (ch == '\b')
  1119. {
  1120. if (i > 0)
  1121. i--;
  1122. } /* else if */
  1123. else
  1124. {
  1125. buf[i] = (char) ch;
  1126. } /* else */
  1127. } /* for */
  1128. #endif
  1129. rc = process_command(buf);
  1130. fflush(stdout);
  1131. if (buf != NULL)
  1132. free(buf);
  1133. } while (rc);
  1134. if (!PHYSFS_deinit())
  1135. printf("PHYSFS_deinit() failed!\n reason: %s.\n", PHYSFS_getLastError());
  1136. if (history_file)
  1137. fclose(history_file);
  1138. /*
  1139. printf("\n\ntest_physfs written by ryan c. gordon.\n");
  1140. printf(" it makes you shoot teh railgun bettar.\n");
  1141. */
  1142. return 0;
  1143. } /* main */
  1144. /* end of test_physfs.c ... */