/filesystems/unixfs/ancientfs/ancientfs_mainx.c

http://macfuse.googlecode.com/ · C · 420 lines · 388 code · 22 blank · 10 comment · 25 complexity · 41daf9c2278cdefe8a98630373984840 MD5 · raw file

  1. /*
  2. * Ancient UNIX File Systems for MacFUSE
  3. * Amit Singh
  4. * http://osxbook.com
  5. */
  6. #include "unixfs.h"
  7. #include "ancientfs.h"
  8. #include <errno.h>
  9. #include <stddef.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <ctype.h>
  15. #include <fcntl.h>
  16. #if __linux__ || (__FreeBSD__ < 10)
  17. #define __USE_GNU 1
  18. #define __private_extern__
  19. #endif
  20. #include <dlfcn.h>
  21. static const char* PROGNAME = "ancientfs";
  22. static const char* PROGVERS = "1.0";
  23. static struct filesystems {
  24. int isalias;
  25. char* fstypename;
  26. char* fstypename_canonical;
  27. uint32_t flags;
  28. char* description;
  29. uint32_t magicoffset;
  30. char magicbytes[32];
  31. char magiclen;
  32. } filesystems[] = {
  33. {
  34. 0, "v1tap", "tap",
  35. ANCIENTFS_UNIX_V1 | ANCIENTFS_GENTAPE,
  36. "DECtape 'tap' tape archive; UNIX V1",
  37. 0, { 0 }, 0,
  38. },
  39. {
  40. 0, "v2tap", "tap",
  41. ANCIENTFS_UNIX_V2 | ANCIENTFS_GENTAPE,
  42. "DECtape 'tap' tape archive; UNIX V2",
  43. 0, { 0 }, 0,
  44. },
  45. {
  46. 0, "v3tap", "tap",
  47. ANCIENTFS_UNIX_V3 | ANCIENTFS_GENTAPE,
  48. "DECtape 'tap' tape archive; UNIX V3",
  49. 0, { 0 }, 0,
  50. },
  51. {
  52. 0, "ntap", "tap",
  53. ANCIENTFS_GENTAPE,
  54. "DECtape/magtape 'tap' tape archive; 1970 epoch",
  55. 0, { 0 }, 0,
  56. },
  57. {
  58. 0, "tp", "tp",
  59. ANCIENTFS_GENTAPE,
  60. "DECtape/magtape 'tp' tape archive",
  61. 0, { 0 }, 0,
  62. },
  63. {
  64. 0, "itp", "itp",
  65. ANCIENTFS_GENTAPE,
  66. "UNIX 'itp' tape archive",
  67. 0, { 0 }, 0,
  68. },
  69. { 0, "dtp", "dtp",
  70. ANCIENTFS_GENTAPE,
  71. "UNIX 'dtp' tape archive",
  72. 0, { 0 }, 0,
  73. },
  74. { 0, "dump", "dump",
  75. 0,
  76. "Incremental file system dump (512-byte blocks, V7/bsd)",
  77. 0, { 0 }, 0,
  78. },
  79. { 1, "dump512" , "dump",
  80. 0,
  81. "Incremental file system dump (512-byte blocks, V7/bsd)",
  82. 0, { 0 }, 0,
  83. },
  84. { 0, "dump1k", "dump1024",
  85. ANCIENTFS_DUMP1KB,
  86. "Incremental file system dump (1024-byte blocks, V7/bsd)",
  87. 0, { 0 }, 0,
  88. },
  89. { 0, "dump-vn", "dumpvn",
  90. 0,
  91. "Incremental file system dump (512-byte blocks, bsd-vn)",
  92. 0, { 0 }, 0,
  93. },
  94. { 0, "dump1k-vn", "dumpvn1024",
  95. ANCIENTFS_DUMP1KB,
  96. "Incremental file system dump (1024-byte blocks, bsd-vn)",
  97. 0, { 0 }, 0,
  98. },
  99. {
  100. 0, "v1ar", "voar",
  101. ANCIENTFS_UNIX_V1,
  102. "Very old (0177555) archive (.a) from First Edition UNIX",
  103. 0, { 0x6d, 0xff }, 2,
  104. },
  105. {
  106. 0, "v2ar", "voar",
  107. ANCIENTFS_UNIX_V2,
  108. "Very old (0177555) archive (.a) from Second Edition UNIX",
  109. 0, { 0x6d, 0xff }, 2,
  110. },
  111. {
  112. 0, "v3ar", "voar",
  113. ANCIENTFS_UNIX_V3,
  114. "Very old (0177555) archive (.a) from Third Edition UNIX",
  115. 0, { 0x6d, 0xff }, 2,
  116. },
  117. {
  118. 1, "ar", "voar",
  119. 0,
  120. "Very old (0177555) archive (.a)",
  121. 0, { 0x6d, 0xff }, 2,
  122. },
  123. {
  124. 1, "ar", "oar",
  125. 0,
  126. "Old (0177545) archive (.a)",
  127. 0, { 0x65, 0xff }, 2,
  128. },
  129. {
  130. 1, "ar", "oar",
  131. 0,
  132. "Old (0177545) archive (.a)",
  133. 0, { 0xff, 0x65 }, 2,
  134. },
  135. {
  136. 0, "ar", "ar",
  137. 0,
  138. "Current (!<arch>\\n), old (0177545), or very old (0177555)\n"
  139. " archive (.a); use (v1|v2|v3)ar for UNIX V1/V2/V3 "
  140. "archives",
  141. 0, { 0x21, 0x3c, 0x61, 0x72, 0x63, 0x68, 0x3e, 0x0a }, 8,
  142. },
  143. {
  144. 0, "bcpio", "bcpio",
  145. 0,
  146. "Binary cpio archive (old); may be byte-swapped",
  147. 0, { 0x71, 0xc7 }, 2,
  148. },
  149. {
  150. 1, "bcpio", "bcpio",
  151. 0,
  152. "Binary cpio archive (old); may be byte-swapped",
  153. 0, { 0xc7, 0x71 }, 2,
  154. },
  155. {
  156. 0, "cpio_odc", "cpio_odc",
  157. 0,
  158. "ASCII (odc) cpio archive",
  159. 0, { 0x30, 0x37, 0x30, 0x37, 0x30, 0x37 }, 6,
  160. },
  161. {
  162. 0, "cpio_newc", "cpio_newc",
  163. 0,
  164. "New ASCII (newc) cpio archive",
  165. 0, { 0x30, 0x37, 0x30, 0x37, 0x30, 0x31 }, 6,
  166. },
  167. {
  168. 0, "cpio_newcrc", "cpio_newc",
  169. ANCIENTFS_NEWCRC,
  170. "New ASCII (newc) cpio archive with checksum",
  171. 0, { 0x30, 0x37, 0x30, 0x37, 0x30, 0x32 }, 6,
  172. },
  173. {
  174. 0, "tar", "tar",
  175. 0,
  176. "ustar, pre-POSIX ustar, or V7 tar archive",
  177. 257, { 0x75, 0x73, 0x74, 0x61, 0x72, 0x0 }, 6, /* POSIX ustar */
  178. },
  179. {
  180. 1, "tar", "tar",
  181. 0,
  182. "ustar, pre-POSIX ustar, or V7 tar archive",
  183. 257, { 0x75, 0x73, 0x74, 0x61, 0x72, 0x20 }, 6, /* pre-POSIX ustar */
  184. },
  185. {
  186. 1, "tar", "tar",
  187. 0,
  188. "ustar, pre-POSIX ustar, or V7 tar archive",
  189. 0, { 0 }, 0, /* V7 tar */
  190. },
  191. {
  192. 0, "v1", "v123",
  193. ANCIENTFS_UNIX_V1,
  194. "First Edition UNIX file system",
  195. 0, { 0 }, 0,
  196. },
  197. {
  198. 0, "v2", "v123",
  199. ANCIENTFS_UNIX_V2,
  200. "Second Edition UNIX file system",
  201. 0, { 0 }, 0,
  202. },
  203. {
  204. 0, "v3", "v123",
  205. ANCIENTFS_UNIX_V3,
  206. "Third Edition UNIX file system",
  207. 0, { 0 }, 0,
  208. },
  209. {
  210. 0, "v4", "v456",
  211. ANCIENTFS_UNIX_V4,
  212. "Fourth Edition UNIX file system",
  213. 0, { 0 }, 0,
  214. },
  215. {
  216. 0, "v5", "v456",
  217. ANCIENTFS_UNIX_V5,
  218. "Fifth Edition UNIX file system",
  219. 0, { 0 }, 0,
  220. },
  221. {
  222. 0, "v6", "v456",
  223. ANCIENTFS_UNIX_V6,
  224. "Sixth Edition UNIX file system",
  225. 0, { 0 }, 0,
  226. },
  227. {
  228. 0, "v7", "v7",
  229. 0,
  230. "Seventh Edition UNIX file system",
  231. 0, { 0 }, 0,
  232. },
  233. {
  234. 0, "v10", "v10",
  235. ANCIENTFS_UNIX_V10,
  236. "Tenth Edition UNIX file system",
  237. 0, { 0 }, 0,
  238. },
  239. {
  240. 0, "32v", "32v",
  241. 0,
  242. "UNIX/32V file system",
  243. 0, { 0 }, 0,
  244. },
  245. {
  246. 1, "32/v", "32v",
  247. 0,
  248. "UNIX/32V file system",
  249. 0, { 0 }, 0,
  250. },
  251. {
  252. 1, "2.9bsd", "29bsd",
  253. 0,
  254. "BSD file system (V7-style with fixed-length file names)",
  255. 0, { 0 }, 0,
  256. },
  257. {
  258. 1, "29bsd", "29bsd",
  259. 0,
  260. "BSD file system (V7-style with fixed-length file names;\n"
  261. " e.g. 2.9BSD or 4.0BSD)",
  262. 0, { 0 }, 0,
  263. },
  264. {
  265. 0, "bsd", "29bsd",
  266. 0,
  267. "BSD file system (V7-style with fixed-length file names;\n"
  268. " e.g. 2.9BSD or 4.0BSD)",
  269. 0, { 0 }, 0,
  270. },
  271. {
  272. 1, "2.11bsd", "211bsd",
  273. 0,
  274. "BSD file system (pre 'fast-file-system' \"UFS\" with\n"
  275. " variable-length file names; e.g. 2.11BSD "
  276. "for PDP-11)",
  277. 0, { 0 }, 0,
  278. },
  279. {
  280. 1, "211bsd", "211bsd",
  281. 0,
  282. "BSD file system (pre 'fast-file-system' \"UFS\" with\n"
  283. " variable-length file names; e.g. 2.11BSD "
  284. "for PDP-11)",
  285. 0, { 0 }, 0,
  286. },
  287. {
  288. 0, "bsd-vn", "211bsd",
  289. 0,
  290. "BSD file system (pre 'fast-file-system' \"UFS\" with\n"
  291. " variable-length file names; e.g. 2.11BSD "
  292. "for PDP-11)",
  293. 0, { 0 }, 0,
  294. },
  295. /* done */
  296. { 0, NULL, NULL, 0 },
  297. };
  298. __private_extern__
  299. void
  300. unixfs_usage(void)
  301. {
  302. fprintf(stderr,
  303. "AncientFS (%s): a MacFUSE file system to mount ancient Unix disks and tapes\n"
  304. "Amit Singh <http://osxbook.com>\n"
  305. "usage:\n"
  306. " %s [--force] [--fsendian pdp|big|little] --dmg DMG --type TYPE MOUNTPOINT [MacFUSE args...]\n"
  307. "where:\n"
  308. " . DMG is an ancient Unix disk or tape image of a valid type\n"
  309. " . TYPE is one of the following:\n\n",
  310. PROGVERS, PROGNAME);
  311. int i;
  312. for (i = 0; filesystems[i].fstypename != NULL; i++) {
  313. if (!filesystems[i].isalias)
  314. fprintf(stderr, " %-11s %s\n", filesystems[i].fstypename,
  315. filesystems[i].description);
  316. }
  317. fprintf(stderr, "\n");
  318. fprintf(stderr, "%s",
  319. " . --force attempts mounting even if there are warnings or errors\n"
  320. );
  321. }
  322. __private_extern__
  323. struct unixfs*
  324. unixfs_preflight(char* dmg, char** type, struct unixfs** unixfsp)
  325. {
  326. int i;
  327. *unixfsp = NULL;
  328. if (!type)
  329. goto out;
  330. int fd;
  331. char buf[512];
  332. if (!dmg) {
  333. fprintf(stderr, "no image specified\n");
  334. goto out;
  335. }
  336. if ((fd = open(dmg, O_RDONLY)) < 0) {
  337. fprintf(stderr, "failed to open %s\n", dmg);
  338. goto out;
  339. }
  340. if (read(fd, buf, 512) != 512) {
  341. close(fd);
  342. fprintf(stderr, "failed to read data from %s\n", dmg);
  343. }
  344. close(fd);
  345. if (!*type) {
  346. /* no type; try some matching */
  347. for (i = 0; filesystems[i].fstypename != NULL; i++) {
  348. if (filesystems[i].magiclen == 0)
  349. continue;
  350. /* ok, got something; try */
  351. if (memcmp(filesystems[i].magicbytes,
  352. (char*)&buf[filesystems[i].magicoffset],
  353. filesystems[i].magiclen) == 0) {
  354. *type = filesystems[i].fstypename;
  355. goto findhandler;
  356. }
  357. }
  358. goto out;
  359. }
  360. findhandler:
  361. for (i = 0; filesystems[i].fstypename != NULL; i++) {
  362. if (strcasecmp(*type, filesystems[i].fstypename) == 0) {
  363. /* If this has a non-zero magic length, must do magic too. */
  364. if (filesystems[i].magiclen) {
  365. if (memcmp(filesystems[i].magicbytes,
  366. (char*)&buf[filesystems[i].magicoffset],
  367. filesystems[i].magiclen) != 0) {
  368. /* not this one */
  369. continue;
  370. }
  371. }
  372. char symb[255];
  373. snprintf(symb, 255, "%s_%s", "unixfs",
  374. filesystems[i].fstypename_canonical);
  375. void* impl = dlsym(RTLD_DEFAULT, symb);
  376. if (impl != NULL) {
  377. *unixfsp = (struct unixfs*)impl;
  378. (*unixfsp)->flags = filesystems[i].flags;
  379. break;
  380. }
  381. }
  382. }
  383. out:
  384. return *unixfsp;
  385. }
  386. __private_extern__
  387. void
  388. unixfs_postflight(char* fsname, char* volname, char* extra_args)
  389. {
  390. #if __APPLE__
  391. snprintf(extra_args, UNIXFS_ARGLEN,
  392. "-oro,defer_permissions,daemon_timeout=5,"
  393. "volname=%s,fsname=%s File System",
  394. volname, fsname);
  395. #else
  396. snprintf(extra_args, UNIXFS_ARGLEN, "-oro");
  397. #endif
  398. }