chiark / gitweb /
Commit 2.4.5-5 as unpacked
[inn-innduct.git] / storage / timecaf / caf.h
1 /* $Revision: 5558 $
2 ** Declarations needed for handling CAF (Crunched Article Files)
3 ** Written by Richard Todd (rmtodd@mailhost.ecn.uoknor.edu) 3/24/96
4 */
5
6
7 /*
8 ** Format of a crunched article file:
9 ** Header:
10 */
11
12 typedef struct _CAFHEADER {
13     char        Magic[4]; /* Magic Number "CRMT" */
14     ARTNUM      Low; /* lowest article in the file */
15     ARTNUM      NumSlots; /* number of articles there are room for in the TOC */
16     ARTNUM      High; /* last article actually present in the file */
17     size_t      Free; /* amount of space currently unused (freed by cancels/expires) */
18     off_t       StartDataBlock; /* offset of first article data block. */
19     unsigned int BlockSize; /* unit of allocation for CAF files. */
20     size_t      FreeZoneTabSize; /* amount of space taken up by the free zone table. */
21     size_t      FreeZoneIndexSize; /* size taken up by the "index" part of the free zone table. */
22     time_t      LastCleaned; /* note time of last cleaning. */
23     int         spare[3];
24 } CAFHEADER;
25
26 #define CAF_MAGIC "CRMT"
27 #define CAF_MAGIC_LEN 4
28 #define CAF_DEFAULT_BLOCKSIZE 512
29
30 /*
31 ** then the table of free blocks.  The table is FreeZoneTabSize bytes
32 ** long.  First comes a "first-level" or "index" bitmap, taking up the
33 ** space from the end of the CAFHEADER to the end of the first
34 ** block, i.e. FreeZoneIndexBytes. The rest of the table is a big  bitmap
35 ** listing free blocks in the 'data' portion of the CAF file.
36 **
37 ** In the "index" bitmap: LSB of bitmap byte 0 is 1 if there are any 1s 
38 ** (free blocks) listed in the first block of the big bitmap, and 0 if there
39 ** are no 1s in that block.  The remaining bits of the index bitmap 
40 ** correspond to the remaining blocks of the big bitmap accordingly.
41 ** The idea is that from the index bitmap one can tell which part of the 
42 ** main bitmap is likely to have free blocks w/o having to read the entire 
43 ** main bitmap.
44 **
45 ** As for the main bitmap, each bit is 1 if the corresponding data
46 ** block (BlockSize bytes) is free.  LSB of bitmap byte 0 corresponds
47 ** to the block @ offset StartDataBlock, and all the rest follow on
48 ** accordingly.  
49 **
50 ** Note that the main part of the bitmap is *always* FreeZoneIndexByte*8
51 ** blocks long, no matter how big the CAF file is.  The table of free blocks
52 ** is almost always sparse.  Also note that blocks past EOF in the CAF file
53 ** are *not* considered free.  If the CAF article write routines fail to 
54 ** find free space in the fre block bitmaps, they will always attempt to 
55 ** extend the CAF file instead. 
56 */
57
58 #define CAF_DEFAULT_FZSIZE (512-sizeof(CAFHEADER))
59
60 /*
61 ** (Note: the CAFBITMAP structure isn't what's actually stored on disk
62 ** in the free bitmap region, this is just a convenient structure to
63 ** keep the bitmap size and StartBlockOffset together with the bitmap
64 ** w/o having keep passing the original CAFHEADER to every routine
65 ** that wants it.  The bitmap structure contains the first (index) bitmap,
66 ** as well as pointers to structures for each block of the main bitmap that
67 ** has been read into memory.
68 */
69
70 typedef struct _CAFBITMAP {
71     off_t StartDataBlock;
72     off_t MaxDataBlock; /* can only handle offsets < this with this bitmap. */
73     size_t FreeZoneTabSize;
74     size_t FreeZoneIndexSize;
75     size_t BytesPerBMB; /* size of chunk, in bytes, that any given BMBLK can map. */
76     unsigned int BlockSize;
77     unsigned int NumBMB; /* size of Blocks array. */
78     struct _CAFBMB **Blocks;
79     char *Bits;
80 } CAFBITMAP;
81
82 typedef struct _CAFBMB {
83     off_t StartDataBlock;
84     off_t MaxDataBlock;
85     int Dirty; /* 1 if this BMB has had any bits changed. */
86     char *BMBBits;
87 } CAFBMB;
88
89 /* 
90 ** Next in the file are the TOC (Table of Contents) entries.  Each TOC
91 ** entry describes an article. 
92 */
93
94 typedef struct _CAFTOCENT {
95     off_t  Offset;
96     size_t Size;
97     time_t ModTime;
98 } CAFTOCENT;
99
100 /*
101 ** and then after the NumSlots TOC Entries, the actual articles, one after
102 ** another, always starting at offsets == 0 mod BlockSize
103 */
104
105 /*
106 ** Number of slots to put in TOC by default.  Can be raised if we ever get 
107 ** more than 256K articles in a newsgroup (frightening thought).
108 */
109
110 #define CAF_DEFAULT_TOC_SIZE (256 * 1024)
111
112 /*
113 ** Default name for CAF file in the news spool dir for a given newsgroup.
114 */
115 #define CAF_NAME "CF"
116
117 extern int CAFOpenArtRead(const char *cfpath, ARTNUM art, size_t *len);
118 extern int CAFOpenArtWrite(char *cfpath, ARTNUM *art, int WaitLock, size_t size);
119 extern int CAFStartWriteFd(int fd, ARTNUM *art, size_t size);
120 extern int CAFFinishWriteFd(int fd);
121 extern int CAFFinishArtWrite(int fd);
122 extern int CAFCreateCAFFile(char *cfpath, ARTNUM lowart, ARTNUM tocsize, size_t cfsize, int nolink, char *temppath);
123 extern const char *CAFErrorStr(void);
124 extern CAFTOCENT *CAFReadTOC(char *cfpath, CAFHEADER *ch);
125 extern int CAFRemoveMultArts(char *cfpath, unsigned int narts, ARTNUM *arts);
126 extern int CAFStatArticle(char *path, ARTNUM art, struct stat *st);
127
128 #ifdef CAF_INNARDS
129 /* functions used internally by caf.c, and by the cleaner program, and cafls
130    but probably aren't useful/desirable to be used by others. */
131 extern int CAFOpenReadTOC(char *cfpath, CAFHEADER *ch, CAFTOCENT **tocpp);
132 extern int CAFReadHeader(int fd, CAFHEADER *h);
133 extern off_t CAFRoundOffsetUp(off_t offt, unsigned int bsize);
134 extern CAFBITMAP * CAFReadFreeBM(int fd, CAFHEADER *h);
135 extern void CAFDisposeBitmap(CAFBITMAP *cbm);
136 /*
137 ** note! CAFIsBlockFree needs the fd, since blocks of the free bitmap may 
138 ** need to be fetched from disk.
139 */
140 extern int CAFIsBlockFree(CAFBITMAP *bm, int fd, off_t block);
141 #endif
142
143 extern int caf_error; /* last error encountered by library. */
144 extern int caf_errno; /* saved value of errno here if I/O error hit by lib. */
145
146 #define CAF_ERR_IO 1            /* generic I/O error, check caf_errno for details */
147 #define CAF_ERR_BADFILE 2       /* corrupt file */
148 #define CAF_ERR_ARTNOTHERE 3    /* article not in the database */
149 #define CAF_ERR_CANTCREATECAF 4 /* can't create the CAF file, see errno. */
150 #define CAF_ERR_FILEBUSY 5      /* file locked by someone else. */
151 #define CAF_ERR_ARTWONTFIT 6    /* outside the range in the TOC */
152 #define CAF_ERR_ARTALREADYHERE 7 /* tried to create an article that was already here. */
153 #define CAF_ERR_BOGUSPATH 8     /* pathname not parseable. */