1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #ifndef _h_cctree_priv_
28 #define _h_cctree_priv_
29 
30 #ifndef _h_klib_container_
31 #include <klib/container.h>
32 #endif
33 
34 #ifndef _h_klib_text_
35 #include <klib/text.h>
36 #endif
37 
38 #ifndef _h_kfs_directory_
39 #include <kfs/directory.h>
40 #endif
41 
42 #define STORE_ID_IN_NODE 1
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 
49 /*--------------------------------------------------------------------------
50  * forwards
51  */
52 typedef struct BSTree CCTree;
53 typedef struct CCName CCName;
54 
55 
56 /*--------------------------------------------------------------------------
57  * CCType
58  *  enum describing entry type
59  */
60 enum CCType
61 {
62     ccFile,
63     ccContFile,
64     ccArcFile,
65     ccChunkFile,
66     ccContainer,
67     ccArchive,
68     ccSymlink,
69     ccHardlink,
70     ccDirectory,
71     ccCached,
72     ccReplaced  /* a name attached to a replaced file (name twice in tar for example) */
73 };
74 
75 
76 /*--------------------------------------------------------------------------
77  * CCFileNode
78  *  a node with a size and modification timestamp
79  *  has a file type determined by magic/etc.
80  *  has an md5 checksum
81  *
82  *  how would an access mode be used? access mode of a file is
83  *  whatever the filesystem says it is, and within an archive,
84  *  it's read-only based upon access mode of outer file...
85  */
86 typedef struct CCFileNode CCFileNode;
87 struct CCFileNode
88 {
89     uint64_t expected;  /* size expected (0 if not known) */
90 /* #define SIZE_UNKNOWN    (UINT64_MAX) */
91 #define SIZE_UNKNOWN    ((uint64_t)(int64_t)-1)
92     uint64_t size;      /* actual size */
93     uint64_t lines;     /* linecount if ASCII */
94     uint32_t crc32;
95 #if STORE_ID_IN_NODE
96     uint32_t id;
97 #endif
98     rc_t rc;
99     bool err;          /* errors found while reading/parsing */
100     char ftype [ 252 ];
101     uint8_t _md5 [ 32 ];
102     SLList logs;
103 };
104 
105 
106 /* Make
107  *  creates an object with provided properties
108  *  md5 digest needs to be filled in afterward
109  */
110 rc_t CCFileNodeMake ( CCFileNode **n, uint64_t expected );
111 
112 /* Whack
113  */
114 #define CCFileNodeWhack( self ) \
115     free ( self )
116 
117 
118 /*--------------------------------------------------------------------------
119  * CCArcFileNode
120  *  a file with an offset into another file
121  */
122 typedef struct CCArcFileNode CCArcFileNode;
123 struct CCArcFileNode
124 {
125     CCFileNode dad;
126     uint64_t offset;
127 };
128 
129 /* Make
130  *  creates an object with provided properties
131  *  md5 digest needs to be filled in afterward
132  */
133 rc_t CCArcFileNodeMake ( CCArcFileNode **n,
134     uint64_t offset, uint64_t size );
135 
136 /* Whack
137  */
138 #define CCArcFileNodeWhack( self ) \
139     free ( self )
140 
141 
142 /*--------------------------------------------------------------------------
143  * CChunkFileNode
144  *  a file with one or more chunks (offset/size) into another file
145  */
146 typedef struct CChunk CChunk;
147 struct CChunk
148 {
149     SLNode n;
150     uint64_t offset;
151     uint64_t size;
152 };
153 
154 typedef struct CChunkFileNode CChunkFileNode;
155 struct CChunkFileNode
156 {
157     CCFileNode dad;
158     SLList chunks;
159 };
160 
161 /* Make
162  *  creates an object with provided properties
163  *  md5 digest needs to be filled in afterward
164  */
165 rc_t CChunkFileNodeMake ( CChunkFileNode **n, uint64_t size );
166 
167 /* AddChunk
168  *  adds a chunk to the chunk file
169  */
170 rc_t CChunkFileNodeAddChunk ( CChunkFileNode *self,
171     uint64_t offset, uint64_t size );
172 
173 /* Whack
174  */
175 void CChunkFileNodeWhack ( CChunkFileNode *self );
176 
177 
178 /*--------------------------------------------------------------------------
179  * CCCachedFileNode
180  *  a file wrapper with cached file name
181  */
182 typedef struct CCCachedFileNode CCCachedFileNode;
183 struct CCCachedFileNode
184 {
185     /* cached name */
186     String cached;
187 
188     /* container CCFileNode */
189     void *entry;
190     uint32_t type;
191 };
192 
193 /* Make
194  *  creates a cached file wrapper
195  */
196 rc_t CCCachedFileNodeMake ( CCCachedFileNode **n,
197     const char *path, enum CCType type, const void *entry );
198 
199 /* Whack
200  */
201 void CCCachedFileNodeWhack ( CCCachedFileNode *self );
202 
203 
204 /*--------------------------------------------------------------------------
205  * CCSymlinkNode
206  *  a directory entry with a substitution path
207  */
208 typedef struct CCSymlinkNode CCSymlinkNode;
209 struct CCSymlinkNode
210 {
211     String path;
212 };
213 
214 /* Make
215  *  creates a symlink object
216  */
217 rc_t CCSymlinkNodeMake ( CCSymlinkNode **n, const char *path );
218 
219 /* Whack
220  */
221 #define CCSymlinkNodeWhack( self ) \
222     free ( self )
223 
224 
225 /*--------------------------------------------------------------------------
226  * CCTree
227  *  a binary search tree with CCNodes
228  */
229 
230 /* Make
231  *  make a root tree or sub-directory
232  */
233 rc_t CCTreeMake ( CCTree **t );
234 
235 /* Insert
236  *  create an entry into a tree
237  *  parses path into required sub-directories
238  *
239  *  "mtime" [ IN ] - modification timestamp
240  *
241  *  "type" [ IN ] and "entry" [ IN ] - typed entry
242  *
243  *  "path" [ IN ] - vararg-style path of the entry, relative
244  *  to "self".
245  *
246  * NB - '..' is not allowed in this implementation.
247  */
248 rc_t CCTreeInsert ( CCTree *self, KTime_t mtime,
249     enum CCType type, const void *entry, const char *path, ... );
250 
251 /* Find
252  *  find a named node
253  *  returns NULL if not found
254  */
255 const CCName *CCTreeFind ( const CCTree *self, const char *path, ... );
256 
257 
258 /* Link
259  *  create a symlink to existing node
260  */
261 rc_t CCTreeLink ( CCTree *self, KTime_t mtime,
262     const char *targ, const char *alias );
263 
264 
265 /* Whack
266  */
267 void CCTreeWhack ( CCTree *self );
268 
269 /* Dump
270  *  dump tree using provided callback function
271  *
272  *  "write" [ IN, NULL OKAY ] and "out" [ IN, OPAQUE ] - callback function
273  *  for writing. if "write" is NULL, print to stdout.
274  */
275 rc_t CCTreeDump ( const CCTree *self,
276                   rc_t ( * write ) ( void *out, const void *buffer, size_t bytes ),
277                   void *out, SLList * logs );
278 
279 
280 /*--------------------------------------------------------------------------
281  * CCContainerNode
282  *  its entry is a container file, i.e. an archive or else processed
283  *  with some sort of envelope such as compression. its sub nodes
284  *  are the contents and have their own names.
285  */
286 typedef struct CCContainerNode CCContainerNode;
287 struct CCContainerNode
288 {
289     /* contents */
290     CCTree sub;
291 
292     /* container CCFileNode */
293     void *entry;
294     uint32_t type;
295 };
296 
297 /* Make
298  *  creates an archive object
299  */
300 rc_t CCContainerNodeMake ( CCContainerNode **n,
301     enum CCType type, const void *entry );
302 
303 /* Whack
304  */
305 void CCContainerNodeWhack ( CCContainerNode *self );
306 
307 
308 /*--------------------------------------------------------------------------
309  * CCReplacedNode
310  * its entry is any other type.  when a name shows up twice in a tar file
311  * the first version is replaced.
312  */
313 typedef struct CCReplacedNode CCReplacedNode;
314 struct CCReplacedNode
315 {
316     /* container CCFileNode */
317     void *entry;
318     uint32_t type;
319 };
320 
321 /* Make
322  */
323 rc_t CCReplacedNodeMake ( CCReplacedNode **n,
324     enum CCType type, const void *entry );
325 
326 /* Whack
327  */
328 void CCReplacedNodeWhack ( CCReplacedNode *self );
329 
330 
331 
332 /*--------------------------------------------------------------------------
333  * CCName
334  *  an entry name in a CCTree
335  */
336 struct CCName
337 {
338     BSTNode n;
339     CCName *dad;
340     KTime_t mtime;
341     void *entry;
342     String name;
343     uint32_t type;
344 };
345 
346 
347 #ifdef __cplusplus
348 }
349 #endif
350 
351 #endif /* _h_cctree_priv_ */
352