Imported Upstream version 3.3.2
[debian/amanda] / amar-src / amar.h
1 /*
2  * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  */
20
21 #include <glib.h>
22
23 /* A note regarding error handling in this module.  Amar returns errors via the
24  * Glib GError mechanism.  Most functions return a boolean, where TRUE
25  * indicates success, and FALSE indicates an error which is indicated in the
26  * 'error' parameter.
27  *
28  * Fatal programming errors are handled with assertions and error exits; any
29  * fatal format or system errors are handled via GError.  Some format errors
30  * (e.g., missing EOAs at the end of a file) are handled without any
31  * acknowledgement.
32  *
33  * The domain for amar errors is that returned from amar_error_quark, and error
34  * codes are system error codes (e.g., EINVAL, ENOSPC). */
35
36 GQuark amar_error_quark(void);
37
38 /* opaque types for archives, files, and attributes */
39
40 typedef struct amar_s amar_t;
41 typedef struct amar_file_s amar_file_t;
42 typedef struct amar_attr_s amar_attr_t;
43
44 /* Application attribute IDs should start at AMAR_ATTR_APP_START */
45
46 enum {
47     /* internal-use only attributes */
48     AMAR_ATTR_FILENAME = 0,
49     AMAR_ATTR_EOF = 1,
50
51     /* anything above this value can be used by the application */
52     AMAR_ATTR_APP_START = 16,
53     AMAR_ATTR_GENERIC_DATA = AMAR_ATTR_APP_START,
54 };
55
56 /* Create an object to read/write an amanda archive on the file descriptor fd.
57  * @param fd: file descriptor of the file, it must already be opened
58  * @mode: O_RDONLY for reading, O_WRONLY for writing
59  * @returns: NULL on error
60  */
61 amar_t *amar_new(int fd, mode_t mode, GError **error);
62
63 /* Finish writing to this fd.  All buffers are flushed, but the file descriptor
64  * is not closed -- the user must close it. */
65 gboolean amar_close(amar_t *archive, GError **error);
66
67 /* create a new 'file' object on the archive.  The filename is treated as a
68  * binary blob, but if filename_len is zero, then its length will be calculated
69  * with strlen().  A zero-length filename_buf is not allowed.
70  *
71  * Note that a header record will only be written if header_offset is non-NULL,
72  * as this represents a location to which a reader could seek.
73  *
74  * @param archive: the archive containing this file
75  * @param filename_buf: filename to include in the file
76  * @param filename_len: length of the filename_buf, or 0 to calculate
77  * @param header_offset (output): offset of the header record preceding
78  *      this file; pass NULL to ignore.
79  * @returns: NULL on error, otherwise a file object
80  */
81 amar_file_t *amar_new_file(
82             amar_t *archive,
83             char *filename_buf,
84             gsize filename_len,
85             off_t *header_offset,
86             GError **error);
87
88 /* Flush all buffer the 'file' object and write a record with ID=2 */
89 gboolean amar_file_close(
90             amar_file_t *file,
91             GError **error);
92
93 /* create a new 'attribute' object with attrid attached to the file
94  *
95  * @returns: NULL on error, otherwise an attribute object
96  */
97 amar_attr_t *amar_new_attr(
98             amar_file_t *file,
99             uint16_t attrid,
100             GError **error);
101
102 /* flush all buffers and mark the end of the attribute */
103 gboolean amar_attr_close(
104             amar_attr_t *attribute,
105             GError **error);
106
107 /* Add 'size' byte of data from 'data' to the attribute.  If this is the
108  * last data in this attribute, set eoa to TRUE.  This will save space by
109  * writing and end-of-attribute indication in this record, instead of adding
110  * an empty EOA record.
111  */
112 gboolean amar_attr_add_data_buffer(
113             amar_attr_t *attribute,
114             gpointer data,
115             gsize size,
116             gboolean eoa,
117             GError **error);
118
119 /* This function reads from the file descriptor 'fd' until EOF and adds
120  * the resulting data to the attribute.  The end of the attribute is
121  * flagged appropriately if EOA is true.
122  *
123  * @param attribute: the attribute for the data
124  * @param fd: the file descriptor from which to read
125  * @param eoa: add an EOA bit to the end?
126  * @returns: number of bytes read from fd, or -1 on error
127  */
128 off_t amar_attr_add_data_fd(
129             amar_attr_t *attribute,
130             int fd,
131             gboolean eoa,
132             GError **error);
133
134 /* When reading files, the handling of each attribute can be configured
135  * separately.  Some attributes may always be short enough to fit in memory,
136  * and in this case the archive interface will take care of assembling any
137  * fragments for you.  Some attributes should be ignored, while others
138  * will call a function for each fragment.
139  *
140  * There are a a number of xx_data options available here, that deserve some
141  * disambiguation.
142  *  - user_data is global to the entire read operation (it is a parameter to
143  *    amar_read)
144  *  - file_data is specific to the current file; it is set by the start_file
145  *    callback and freed by the finish_file callback.
146  *  - attrid_data is specific this the current attribute ID, across all files;
147  *    it comes from the amar_attr_handling_t struct.
148  *  - attr_data is specific to the current instance of the particular
149  *    attribute.  It points to a NULL pointer on the first call to the fragment
150  *    callback, and can be set at that time.  It should be freed when the EOA
151  *    argument is TRUE.
152  *
153  * @param user_data: the pointer passed to amar_read
154  * @param filenum: the file number for this record
155  * @param file_data: the file_data pointer returned from the start_file callback
156  * @param attrid: the attribute id for this record
157  * @param attrid_data: the data from the handling array
158  * @param attr_data (in/out): data for this attribute; this will be the same
159  *        pointer for every callback for a particular instance of an attribute.
160  *        Any resources should be freed when eoa is true.
161  * @param data: the data for this fragment
162  * @param size: the size of data
163  * @param eoa: TRUE iff this is the last fragment for this attribute
164  * @param truncated: TRUE if this attribute is likely to be incomplete (e.g.,
165  *        in an error situation)
166  * @returns: FALSE if the amar_read call should be aborted
167  */
168 typedef gboolean (*amar_fragment_callback_t)(
169         gpointer user_data,
170         uint16_t filenum,
171         gpointer file_data,
172         uint16_t attrid,
173         gpointer attrid_data,
174         gpointer *attr_data,
175         gpointer data,
176         gsize size,
177         gboolean eoa,
178         gboolean truncated);
179
180 /* amar_read takes an array of this struct, terminated by an entry
181  * with attrid 0.  This final entry is used as the "catchall" for attributes
182  * not matching any other array entries. */
183 typedef struct amar_attr_handling_s {
184     uint16_t attrid;
185
186     /* if nonzero, this is the minimum size fragment that will be passed to the
187      * callback.  Use SIZE_MAX for no limit, although this may result in
188      * excessive memory use while parsing a malicious or corrupt archive. */
189     gsize min_size;
190
191     /* if non-NULL, this function will be called for each fragment
192      * with this attribute ID */
193     amar_fragment_callback_t callback;
194
195     /* this value is passed as the attr_data parameter to the callback */
196     gpointer attrid_data;
197 } amar_attr_handling_t;
198
199 /* This function is called for each new file, and can decide whether to ignore
200  * the file, or set up file-specific data.
201  *
202  * @param user_data: the pointer passed to amar_read
203  * @param filenum: the file number for this record
204  * @param filename_buf: the filename of this file
205  * @param filename_len: the length of the filename
206  * @param ignore (output): if set to TRUE, ignore all attributes for this file.
207  * @param file_data (output): space to store file-specific data
208  * @returns: FALSE if the amar_read call should be aborted
209  */
210 typedef gboolean (*amar_file_start_callback_t)(
211         gpointer user_data,
212         uint16_t filenum,
213         gpointer filename_buf,
214         gsize filename_len,
215         gboolean *ignore,
216         gpointer *file_data);
217
218 /* This function is called for each new file, and can decide whether to ignore
219  * the file, or set up file-specific data.
220  *
221  * @param user_data: the pointer passed to amar_read
222  * @param filenum: the file number for this record
223  * @param file_data (output): space to store file-specific data
224  * @param truncated: TRUE if this file is likely to be incomplete (e.g.,
225  *        in an error situation, or at an early EOF)
226  * @returns: FALSE if the amar_read call should be aborted
227  */
228 typedef gboolean (*amar_file_finish_callback_t)(
229         gpointer user_data,
230         uint16_t filenum,
231         gpointer *file_data,
232         gboolean truncated);
233
234 /* This function actually performs the read operation, calling all of the
235  * above callbacks.  If any of the callbacks return FALSE, this function
236  * returns FALSE but does not set its error parameter.
237  *
238  * @param user_data: passed to all callbacks
239  * @param handling_array: array giving handling information
240  * @param file_start_cb: callback for file starts
241  * @param file_finish_cb: callback for file finishs
242  * @param error (output): the error result
243  * @returns: FALSE on error or an early exit, otherwise TRUE
244  */
245 gboolean amar_read(
246         amar_t *archive,
247         gpointer user_data,
248         amar_attr_handling_t *handling_array,
249         amar_file_start_callback_t file_start_cb,
250         amar_file_finish_callback_t file_finish_cb,
251         GError **error);