PageRenderTime 35ms CodeModel.GetById 16ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/filesystems/unixfs/ancientfs/ancientfs_tap.h

http://macfuse.googlecode.com/
C++ Header | 187 lines | 128 code | 39 blank | 20 comment | 22 complexity | c16174db13494bbadb894ba11d8a207b MD5 | raw file
  1/*
  2 * Ancient UNIX File Systems for MacFUSE
  3 * Amit Singh
  4 * http://osxbook.com
  5 */
  6
  7#ifndef _ANCIENTFS_TAP_H_
  8#define _ANCIENTFS_TAP_H_
  9
 10#include "unixfs_internal.h"
 11#include "ancientfs.h"
 12
 13#define BSIZE   512
 14
 15#define ROOTINO  1
 16#define DIRSIZ   14
 17#define PATHSIZ  32
 18
 19struct filsys
 20{
 21    uint32_t s_fsize;
 22    uint32_t s_files;
 23    uint32_t s_directories;
 24    uint32_t s_lastino;
 25    struct inode* s_rootip;
 26};
 27
 28struct dinode_tap {
 29    uint8_t  di_path[PATHSIZ]; /* if di_path[0] == 0, the entry is empty */
 30    uint8_t  di_mode;  /* type and permissions */
 31    uint8_t  di_uid;   /* owner's id */
 32    uint16_t di_size;  /* file's size */
 33    uint32_t di_mtime; /* file's modification time */
 34    uint16_t di_addr;  /* tape block of the start of the file's contents */
 35    uint8_t  di_unused[20];
 36    uint16_t di_cksum; /* sum of the 32 words of the directory is 0 */
 37} __attribute__((packed));
 38
 39#define INOPB 8
 40
 41struct tap_node_info {
 42    struct inode* ti_self;
 43    uint8_t ti_name[DIRSIZ];
 44    struct tap_node_info* ti_parent;
 45    struct tap_node_info* ti_children;
 46    struct tap_node_info* ti_next_sibling;
 47};
 48
 49/* flags */
 50#define ILOCK   01
 51#define IUPD    02
 52#define IACC    04
 53#define IMOUNT  010
 54#define IWANT   020
 55#define ITEXT   040
 56
 57/* modes */
 58#define IALLOC  0100000 /* i-node is allocated */
 59#define IFMT    060000
 60#define IFDIR   040000  /* directory */
 61#define IMOD    020000  /* file has been modified (always on) */
 62#define ILARG   010000  /* large file */
 63/* v1/v2/v3 modes */
 64#define ISUID   000040  /* set user ID on execution */
 65#define IEXEC   000020  /* executable */
 66#define IRUSR   000010  /* read, owner */
 67#define IWUSR   000004  /* write, owner */
 68#define IROTH   000002  /* read, non-owner */
 69#define IWOTH   000001  /* write, non-owner */
 70
 71#include <sys/stat.h>
 72
 73static inline mode_t
 74ancientfs_tap_mode(mode_t mode, uint32_t flags)
 75{
 76    mode_t newmode = 0;
 77
 78    mode = mode & ~(IALLOC | ILARG);
 79
 80    if ((flags & ANCIENTFS_UNIX_V1) ||
 81        (flags & ANCIENTFS_UNIX_V2) ||
 82        (flags & ANCIENTFS_UNIX_V3))
 83        goto tap;
 84
 85    /* ntap */
 86
 87    /* we synthesize directories ourselves, so mode is OK as it is */
 88    if (S_ISDIR(mode))
 89        return mode;
 90
 91    /* translate ntap mode bits */
 92
 93    if ((mode & IFMT) == IFDIR)
 94        newmode |= S_IFDIR;
 95    else
 96        newmode |= S_IFREG;
 97
 98    if (mode & 040)
 99        newmode |= S_IRUSR;
100    if (mode & 020)
101        newmode |= S_IWUSR;
102    if (mode & 010)
103        newmode |= S_IXUSR;
104    if (mode & 004)
105        newmode |= S_IROTH;
106    if (mode & 002)
107        newmode |= S_IWOTH;
108    if (mode & 001)
109        newmode |= S_IXOTH;
110
111    return newmode;
112
113tap:
114
115    /* we synthesize directories ourselves, so mode is OK as it is */
116    if (S_ISDIR(mode))
117        return mode;
118
119    /* translate tap mode bits */
120
121    if ((mode & IFMT) == IFDIR)
122        newmode |= S_IFDIR;
123    else
124        newmode |= S_IFREG;
125
126    if (mode & ISUID)
127        newmode |= S_ISUID;
128
129    if (mode & IEXEC)
130        newmode |= S_IXUSR;
131
132    if (mode & IRUSR)
133        newmode |= S_IRUSR;
134
135    if (mode & IWUSR)
136        newmode |= S_IWUSR;
137
138    if (mode & IROTH) {
139        newmode |= S_IROTH;
140        if (mode & IEXEC)
141            newmode |= S_IXOTH;
142    }
143
144    if (mode & IWOTH)
145        newmode |= S_IWOTH;
146
147    return newmode;
148}
149
150static inline int
151ancientfs_tap_cksum(uint8_t* de, fs_endian_t e, uint32_t flags)
152{
153    uint16_t* p = (uint16_t*)de;
154    uint16_t cksum = 0;
155    int i = 0;
156    for (i = 0; i < 32; i++, p++)
157        cksum += fs16_to_host(e, *p);
158    return cksum;
159}
160
161/*
162 * v1 00:00 Jan 1, 1971 /60
163 * v2 00:00 Jan 1, 1971 /60
164 * v3 00:00 Jan 1, 1972 /60
165 *
166 * modern 00:00 Jan 1, 1970 full seconds
167 */
168static inline uint32_t
169ancientfs_tap_time(uint32_t t, uint32_t flags)
170{
171    if (!(flags & (ANCIENTFS_UNIX_V1 | ANCIENTFS_UNIX_V2 | ANCIENTFS_UNIX_V3)))
172        return t;
173
174    uint32_t cvt = t;
175
176    cvt = cvt / 60; /* times were measured in sixtieths of a second */
177
178    uint32_t epoch_years = (flags & ANCIENTFS_UNIX_V1) ? 1 :
179                           (flags & ANCIENTFS_UNIX_V2) ? 1 :
180                           (flags & ANCIENTFS_UNIX_V3) ? 2 : 0;
181
182    cvt += (epoch_years * 365 * 24 * 3600); /* epoch fixup */
183
184    return cvt;
185}
186
187#endif /* _ANCIENTFS_TAP_H_ */