test_physfs.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412
  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. PHYSFS_Stat statbuf;
  603. int rc;
  604. if (*args == '\"')
  605. {
  606. args++;
  607. args[strlen(args) - 1] = '\0';
  608. } /* if */
  609. rc = PHYSFS_stat(args, &statbuf);
  610. if (rc)
  611. rc = (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY);
  612. printf("File %s a directory.\n", rc ? "is" : "is NOT");
  613. return 1;
  614. } /* cmd_isdir */
  615. static int cmd_issymlink(char *args)
  616. {
  617. PHYSFS_Stat statbuf;
  618. int rc;
  619. if (*args == '\"')
  620. {
  621. args++;
  622. args[strlen(args) - 1] = '\0';
  623. } /* if */
  624. rc = PHYSFS_stat(args, &statbuf);
  625. if (rc)
  626. rc = (statbuf.filetype == PHYSFS_FILETYPE_SYMLINK);
  627. printf("File %s a symlink.\n", rc ? "is" : "is NOT");
  628. return 1;
  629. } /* cmd_issymlink */
  630. static int cmd_cat(char *args)
  631. {
  632. PHYSFS_File *f;
  633. if (*args == '\"')
  634. {
  635. args++;
  636. args[strlen(args) - 1] = '\0';
  637. } /* if */
  638. f = PHYSFS_openRead(args);
  639. if (f == NULL)
  640. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  641. else
  642. {
  643. if (do_buffer_size)
  644. {
  645. if (!PHYSFS_setBuffer(f, do_buffer_size))
  646. {
  647. printf("failed to set file buffer. Reason: [%s].\n",
  648. PHYSFS_getLastError());
  649. PHYSFS_close(f);
  650. return 1;
  651. } /* if */
  652. } /* if */
  653. while (1)
  654. {
  655. char buffer[128];
  656. PHYSFS_sint64 rc;
  657. PHYSFS_sint64 i;
  658. rc = PHYSFS_readBytes(f, buffer, sizeof (buffer));
  659. for (i = 0; i < rc; i++)
  660. fputc((int) buffer[i], stdout);
  661. if (rc < sizeof (buffer))
  662. {
  663. printf("\n\n");
  664. if (!PHYSFS_eof(f))
  665. {
  666. printf("\n (Error condition in reading. Reason: [%s])\n\n",
  667. PHYSFS_getLastError());
  668. } /* if */
  669. PHYSFS_close(f);
  670. return 1;
  671. } /* if */
  672. } /* while */
  673. } /* else */
  674. return 1;
  675. } /* cmd_cat */
  676. #define CRC32_BUFFERSIZE 512
  677. static int cmd_crc32(char *args)
  678. {
  679. PHYSFS_File *f;
  680. if (*args == '\"')
  681. {
  682. args++;
  683. args[strlen(args) - 1] = '\0';
  684. } /* if */
  685. f = PHYSFS_openRead(args);
  686. if (f == NULL)
  687. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  688. else
  689. {
  690. PHYSFS_uint8 buffer[CRC32_BUFFERSIZE];
  691. PHYSFS_uint32 crc = -1;
  692. PHYSFS_sint64 bytesread;
  693. while ((bytesread = PHYSFS_readBytes(f, buffer, CRC32_BUFFERSIZE)) > 0)
  694. {
  695. PHYSFS_uint32 i, bit;
  696. for (i = 0; i < bytesread; i++)
  697. {
  698. for (bit = 0; bit < 8; bit++, buffer[i] >>= 1)
  699. crc = (crc >> 1) ^ (((crc ^ buffer[i]) & 1) ? 0xEDB88320 : 0);
  700. } /* for */
  701. } /* while */
  702. if (bytesread < 0)
  703. {
  704. printf("error while reading. Reason: [%s].\n",
  705. PHYSFS_getLastError());
  706. return 1;
  707. } /* if */
  708. PHYSFS_close(f);
  709. crc ^= -1;
  710. printf("CRC32 for %s: 0x%08X\n", args, crc);
  711. } /* else */
  712. return 1;
  713. } /* cmd_crc32 */
  714. static int cmd_filelength(char *args)
  715. {
  716. PHYSFS_File *f;
  717. if (*args == '\"')
  718. {
  719. args++;
  720. args[strlen(args) - 1] = '\0';
  721. } /* if */
  722. f = PHYSFS_openRead(args);
  723. if (f == NULL)
  724. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  725. else
  726. {
  727. PHYSFS_sint64 len = PHYSFS_fileLength(f);
  728. if (len == -1)
  729. printf("failed to determine length. Reason: [%s].\n", PHYSFS_getLastError());
  730. else
  731. printf(" (cast to int) %d bytes.\n", (int) len);
  732. PHYSFS_close(f);
  733. } /* else */
  734. return 1;
  735. } /* cmd_filelength */
  736. #define WRITESTR "The cat sat on the mat.\n\n"
  737. static int cmd_append(char *args)
  738. {
  739. PHYSFS_File *f;
  740. if (*args == '\"')
  741. {
  742. args++;
  743. args[strlen(args) - 1] = '\0';
  744. } /* if */
  745. f = PHYSFS_openAppend(args);
  746. if (f == NULL)
  747. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  748. else
  749. {
  750. size_t bw;
  751. PHYSFS_sint64 rc;
  752. if (do_buffer_size)
  753. {
  754. if (!PHYSFS_setBuffer(f, do_buffer_size))
  755. {
  756. printf("failed to set file buffer. Reason: [%s].\n",
  757. PHYSFS_getLastError());
  758. PHYSFS_close(f);
  759. return 1;
  760. } /* if */
  761. } /* if */
  762. bw = strlen(WRITESTR);
  763. rc = PHYSFS_writeBytes(f, WRITESTR, bw);
  764. if (rc != bw)
  765. {
  766. printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
  767. (int) rc, (int) bw, PHYSFS_getLastError());
  768. } /* if */
  769. else
  770. {
  771. printf("Successful.\n");
  772. } /* else */
  773. PHYSFS_close(f);
  774. } /* else */
  775. return 1;
  776. } /* cmd_append */
  777. static int cmd_write(char *args)
  778. {
  779. PHYSFS_File *f;
  780. if (*args == '\"')
  781. {
  782. args++;
  783. args[strlen(args) - 1] = '\0';
  784. } /* if */
  785. f = PHYSFS_openWrite(args);
  786. if (f == NULL)
  787. printf("failed to open. Reason: [%s].\n", PHYSFS_getLastError());
  788. else
  789. {
  790. size_t bw;
  791. PHYSFS_sint64 rc;
  792. if (do_buffer_size)
  793. {
  794. if (!PHYSFS_setBuffer(f, do_buffer_size))
  795. {
  796. printf("failed to set file buffer. Reason: [%s].\n",
  797. PHYSFS_getLastError());
  798. PHYSFS_close(f);
  799. return 1;
  800. } /* if */
  801. } /* if */
  802. bw = strlen(WRITESTR);
  803. rc = PHYSFS_writeBytes(f, WRITESTR, bw);
  804. if (rc != bw)
  805. {
  806. printf("Wrote (%d) of (%d) bytes. Reason: [%s].\n",
  807. (int) rc, (int) bw, PHYSFS_getLastError());
  808. } /* if */
  809. else
  810. {
  811. printf("Successful.\n");
  812. } /* else */
  813. PHYSFS_close(f);
  814. } /* else */
  815. return 1;
  816. } /* cmd_write */
  817. static char* modTimeToStr(PHYSFS_sint64 modtime, char *modstr, size_t strsize)
  818. {
  819. time_t t = (time_t) modtime;
  820. char *str = ctime(&t);
  821. strncpy(modstr, str, strsize);
  822. modstr[strsize-1] = '\0';
  823. return modstr;
  824. } /* modTimeToStr */
  825. static int cmd_getlastmodtime(char *args)
  826. {
  827. PHYSFS_Stat statbuf;
  828. if (!PHYSFS_stat(args, &statbuf))
  829. printf("Failed to determine. Reason: [%s].\n", PHYSFS_getLastError());
  830. else
  831. {
  832. char modstr[64];
  833. modTimeToStr(statbuf.modtime, modstr, sizeof (modstr));
  834. printf("Last modified: %s (%ld).\n", modstr, (long) statbuf.modtime);
  835. } /* else */
  836. return 1;
  837. } /* cmd_getLastModTime */
  838. static int cmd_stat(char *args)
  839. {
  840. PHYSFS_Stat stat;
  841. char timestring[65];
  842. if (*args == '\"')
  843. {
  844. args++;
  845. args[strlen(args) - 1] = '\0';
  846. } /* if */
  847. if(!PHYSFS_stat(args, &stat))
  848. {
  849. printf("failed to stat. Reason [%s].\n", PHYSFS_getLastError());
  850. return 1;
  851. } /* if */
  852. printf("Filename: %s\n", args);
  853. printf("Size %d\n",(int) stat.filesize);
  854. if(stat.filetype == PHYSFS_FILETYPE_REGULAR)
  855. printf("Type: File\n");
  856. else if(stat.filetype == PHYSFS_FILETYPE_DIRECTORY)
  857. printf("Type: Directory\n");
  858. else if(stat.filetype == PHYSFS_FILETYPE_SYMLINK)
  859. printf("Type: Symlink\n");
  860. else
  861. printf("Type: Unknown\n");
  862. printf("Created at: %s", modTimeToStr(stat.createtime, timestring, 64));
  863. printf("Last modified at: %s", modTimeToStr(stat.modtime, timestring, 64));
  864. printf("Last accessed at: %s", modTimeToStr(stat.accesstime, timestring, 64));
  865. printf("Readonly: %s\n", stat.readonly ? "true" : "false");
  866. return 1;
  867. } /* cmd_filelength */
  868. /* must have spaces trimmed prior to this call. */
  869. static int count_args(const char *str)
  870. {
  871. int retval = 0;
  872. int in_quotes = 0;
  873. if (str != NULL)
  874. {
  875. for (; *str != '\0'; str++)
  876. {
  877. if (*str == '\"')
  878. in_quotes = !in_quotes;
  879. else if ((*str == ' ') && (!in_quotes))
  880. retval++;
  881. } /* for */
  882. retval++;
  883. } /* if */
  884. return retval;
  885. } /* count_args */
  886. static int cmd_help(char *args);
  887. typedef struct
  888. {
  889. const char *cmd;
  890. int (*func)(char *args);
  891. int argcount;
  892. const char *usage;
  893. } command_info;
  894. static const command_info commands[] =
  895. {
  896. { "quit", cmd_quit, 0, NULL },
  897. { "q", cmd_quit, 0, NULL },
  898. { "help", cmd_help, 0, NULL },
  899. { "init", cmd_init, 1, "<argv0>" },
  900. { "deinit", cmd_deinit, 0, NULL },
  901. { "addarchive", cmd_addarchive, 2, "<archiveLocation> <append>" },
  902. { "mount", cmd_mount, 3, "<archiveLocation> <mntpoint> <append>" },
  903. { "mountmem", cmd_mount_mem, 3, "<archiveLocation> <mntpoint> <append>" },
  904. { "mounthandle", cmd_mount_handle, 3, "<archiveLocation> <mntpoint> <append>" },
  905. { "removearchive", cmd_removearchive, 1, "<archiveLocation>" },
  906. { "unmount", cmd_removearchive, 1, "<archiveLocation>" },
  907. { "enumerate", cmd_enumerate, 1, "<dirToEnumerate>" },
  908. { "ls", cmd_enumerate, 1, "<dirToEnumerate>" },
  909. { "getlasterror", cmd_getlasterror, 0, NULL },
  910. { "getdirsep", cmd_getdirsep, 0, NULL },
  911. { "getcdromdirs", cmd_getcdromdirs, 0, NULL },
  912. { "getsearchpath", cmd_getsearchpath, 0, NULL },
  913. { "getbasedir", cmd_getbasedir, 0, NULL },
  914. { "getuserdir", cmd_getuserdir, 0, NULL },
  915. { "getwritedir", cmd_getwritedir, 0, NULL },
  916. { "setwritedir", cmd_setwritedir, 1, "<newWriteDir>" },
  917. { "permitsymlinks", cmd_permitsyms, 1, "<1or0>" },
  918. { "setsaneconfig", cmd_setsaneconfig, 5, "<org> <appName> <arcExt> <includeCdRoms> <archivesFirst>" },
  919. { "mkdir", cmd_mkdir, 1, "<dirToMk>" },
  920. { "delete", cmd_delete, 1, "<dirToDelete>" },
  921. { "getrealdir", cmd_getrealdir, 1, "<fileToFind>" },
  922. { "exists", cmd_exists, 1, "<fileToCheck>" },
  923. { "isdir", cmd_isdir, 1, "<fileToCheck>" },
  924. { "issymlink", cmd_issymlink, 1, "<fileToCheck>" },
  925. { "cat", cmd_cat, 1, "<fileToCat>" },
  926. { "filelength", cmd_filelength, 1, "<fileToCheck>" },
  927. { "stat", cmd_stat, 1, "<fileToStat>" },
  928. { "append", cmd_append, 1, "<fileToAppend>" },
  929. { "write", cmd_write, 1, "<fileToCreateOrTrash>" },
  930. { "getlastmodtime", cmd_getlastmodtime, 1, "<fileToExamine>" },
  931. { "setbuffer", cmd_setbuffer, 1, "<bufferSize>" },
  932. { "stressbuffer", cmd_stressbuffer, 1, "<bufferSize>" },
  933. { "crc32", cmd_crc32, 1, "<fileToHash>" },
  934. { NULL, NULL, -1, NULL }
  935. };
  936. static void output_usage(const char *intro, const command_info *cmdinfo)
  937. {
  938. if (cmdinfo->argcount == 0)
  939. printf("%s \"%s\" (no arguments)\n", intro, cmdinfo->cmd);
  940. else
  941. printf("%s \"%s %s\"\n", intro, cmdinfo->cmd, cmdinfo->usage);
  942. } /* output_usage */
  943. static int cmd_help(char *args)
  944. {
  945. const command_info *i;
  946. printf("Commands:\n");
  947. for (i = commands; i->cmd != NULL; i++)
  948. output_usage(" -", i);
  949. return 1;
  950. } /* output_cmd_help */
  951. static void trim_command(const char *orig, char *copy)
  952. {
  953. const char *i;
  954. char *writeptr = copy;
  955. int spacecount = 0;
  956. int have_first = 0;
  957. for (i = orig; *i != '\0'; i++)
  958. {
  959. if (*i == ' ')
  960. {
  961. if ((*(i + 1) != ' ') && (*(i + 1) != '\0'))
  962. {
  963. if ((have_first) && (!spacecount))
  964. {
  965. spacecount++;
  966. *writeptr = ' ';
  967. writeptr++;
  968. } /* if */
  969. } /* if */
  970. } /* if */
  971. else
  972. {
  973. have_first = 1;
  974. spacecount = 0;
  975. *writeptr = *i;
  976. writeptr++;
  977. } /* else */
  978. } /* for */
  979. *writeptr = '\0';
  980. /*
  981. printf("\n command is [%s].\n", copy);
  982. */
  983. } /* trim_command */
  984. static int process_command(char *complete_cmd)
  985. {
  986. const command_info *i;
  987. char *cmd_copy;
  988. char *args;
  989. int rc = 1;
  990. if (complete_cmd == NULL) /* can happen if user hits CTRL-D, etc. */
  991. {
  992. printf("\n");
  993. return 0;
  994. } /* if */
  995. cmd_copy = (char *) malloc(strlen(complete_cmd) + 1);
  996. if (cmd_copy == NULL)
  997. {
  998. printf("\n\n\nOUT OF MEMORY!\n\n\n");
  999. return 0;
  1000. } /* if */
  1001. trim_command(complete_cmd, cmd_copy);
  1002. args = strchr(cmd_copy, ' ');
  1003. if (args != NULL)
  1004. {
  1005. *args = '\0';
  1006. args++;
  1007. } /* else */
  1008. if (cmd_copy[0] != '\0')
  1009. {
  1010. for (i = commands; i->cmd != NULL; i++)
  1011. {
  1012. if (strcmp(i->cmd, cmd_copy) == 0)
  1013. {
  1014. if ((i->argcount >= 0) && (count_args(args) != i->argcount))
  1015. output_usage("usage:", i);
  1016. else
  1017. rc = i->func(args);
  1018. break;
  1019. } /* if */
  1020. } /* for */
  1021. if (i->cmd == NULL)
  1022. printf("Unknown command. Enter \"help\" for instructions.\n");
  1023. #if (defined PHYSFS_HAVE_READLINE)
  1024. add_history(complete_cmd);
  1025. if (history_file)
  1026. {
  1027. fprintf(history_file, "%s\n", complete_cmd);
  1028. fflush(history_file);
  1029. } /* if */
  1030. #endif
  1031. } /* if */
  1032. free(cmd_copy);
  1033. return rc;
  1034. } /* process_command */
  1035. static void open_history_file(void)
  1036. {
  1037. #if (defined PHYSFS_HAVE_READLINE)
  1038. #if 0
  1039. const char *envr = getenv("TESTPHYSFS_HISTORY");
  1040. if (!envr)
  1041. return;
  1042. #else
  1043. char envr[256];
  1044. strcpy(envr, PHYSFS_getUserDir());
  1045. strcat(envr, ".testphys_history");
  1046. #endif
  1047. if (access(envr, F_OK) == 0)
  1048. {
  1049. char buf[512];
  1050. FILE *f = fopen(envr, "r");
  1051. if (!f)
  1052. {
  1053. printf("\n\n"
  1054. "Could not open history file [%s] for reading!\n"
  1055. " Will not have past history available.\n\n",
  1056. envr);
  1057. return;
  1058. } /* if */
  1059. do
  1060. {
  1061. if (fgets(buf, sizeof (buf), f) == NULL)
  1062. break;
  1063. if (buf[strlen(buf) - 1] == '\n')
  1064. buf[strlen(buf) - 1] = '\0';
  1065. add_history(buf);
  1066. } while (!feof(f));
  1067. fclose(f);
  1068. } /* if */
  1069. history_file = fopen(envr, "ab");
  1070. if (!history_file)
  1071. {
  1072. printf("\n\n"
  1073. "Could not open history file [%s] for appending!\n"
  1074. " Will not be able to record this session's history.\n\n",
  1075. envr);
  1076. } /* if */
  1077. #endif
  1078. } /* open_history_file */
  1079. int main(int argc, char **argv)
  1080. {
  1081. char *buf = NULL;
  1082. int rc = 0;
  1083. #if (defined __MWERKS__)
  1084. extern tSIOUXSettings SIOUXSettings;
  1085. SIOUXSettings.asktosaveonclose = 0;
  1086. SIOUXSettings.autocloseonquit = 1;
  1087. SIOUXSettings.rows = 40;
  1088. SIOUXSettings.columns = 120;
  1089. #endif
  1090. printf("\n");
  1091. if (!PHYSFS_init(argv[0]))
  1092. {
  1093. printf("PHYSFS_init() failed!\n reason: %s.\n", PHYSFS_getLastError());
  1094. return 1;
  1095. } /* if */
  1096. output_versions();
  1097. output_archivers();
  1098. open_history_file();
  1099. printf("Enter commands. Enter \"help\" for instructions.\n");
  1100. fflush(stdout);
  1101. do
  1102. {
  1103. #if (defined PHYSFS_HAVE_READLINE)
  1104. buf = readline("> ");
  1105. #else
  1106. int i;
  1107. buf = (char *) malloc(512);
  1108. memset(buf, '\0', 512);
  1109. printf("> ");
  1110. fflush(stdout);
  1111. for (i = 0; i < 511; i++)
  1112. {
  1113. int ch = fgetc(stdin);
  1114. if (ch == EOF)
  1115. {
  1116. strcpy(buf, "quit");
  1117. break;
  1118. } /* if */
  1119. else if ((ch == '\n') || (ch == '\r'))
  1120. {
  1121. buf[i] = '\0';
  1122. break;
  1123. } /* else if */
  1124. else if (ch == '\b')
  1125. {
  1126. if (i > 0)
  1127. i--;
  1128. } /* else if */
  1129. else
  1130. {
  1131. buf[i] = (char) ch;
  1132. } /* else */
  1133. } /* for */
  1134. #endif
  1135. rc = process_command(buf);
  1136. fflush(stdout);
  1137. if (buf != NULL)
  1138. free(buf);
  1139. } while (rc);
  1140. if (!PHYSFS_deinit())
  1141. printf("PHYSFS_deinit() failed!\n reason: %s.\n", PHYSFS_getLastError());
  1142. if (history_file)
  1143. fclose(history_file);
  1144. /*
  1145. printf("\n\ntest_physfs written by ryan c. gordon.\n");
  1146. printf(" it makes you shoot teh railgun bettar.\n");
  1147. */
  1148. return 0;
  1149. } /* main */
  1150. /* end of test_physfs.c ... */