PageRenderTime 68ms CodeModel.GetById 31ms app.highlight 34ms RepoModel.GetById 1ms app.codeStats 0ms

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