File: amar.h

package info (click to toggle)
amanda 1%3A3.3.1-4
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 22,360 kB
  • sloc: ansic: 214,899; perl: 58,075; sh: 16,954; xml: 13,853; makefile: 2,228; awk: 431; lex: 405; yacc: 343; tcl: 118; sql: 19; sed: 16; php: 2
file content (251 lines) | stat: -rw-r--r-- 9,667 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/*
 * Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
 */

#include <glib.h>

/* A note regarding error handling in this module.  Amar returns errors via the
 * Glib GError mechanism.  Most functions return a boolean, where TRUE
 * indicates success, and FALSE indicates an error which is indicated in the
 * 'error' parameter.
 *
 * Fatal programming errors are handled with assertions and error exits; any
 * fatal format or system errors are handled via GError.  Some format errors
 * (e.g., missing EOAs at the end of a file) are handled without any
 * acknowledgement.
 *
 * The domain for amar errors is that returned from amar_error_quark, and error
 * codes are system error codes (e.g., EINVAL, ENOSPC). */

GQuark amar_error_quark(void);

/* opaque types for archives, files, and attributes */

typedef struct amar_s amar_t;
typedef struct amar_file_s amar_file_t;
typedef struct amar_attr_s amar_attr_t;

/* Application attribute IDs should start at AMAR_ATTR_APP_START */

enum {
    /* internal-use only attributes */
    AMAR_ATTR_FILENAME = 0,
    AMAR_ATTR_EOF = 1,

    /* anything above this value can be used by the application */
    AMAR_ATTR_APP_START = 16,
    AMAR_ATTR_GENERIC_DATA = AMAR_ATTR_APP_START,
};

/* Create an object to read/write an amanda archive on the file descriptor fd.
 * @param fd: file descriptor of the file, it must already be opened
 * @mode: O_RDONLY for reading, O_WRONLY for writing
 * @returns: NULL on error
 */
amar_t *amar_new(int fd, mode_t mode, GError **error);

/* Finish writing to this fd.  All buffers are flushed, but the file descriptor
 * is not closed -- the user must close it. */
gboolean amar_close(amar_t *archive, GError **error);

/* create a new 'file' object on the archive.  The filename is treated as a
 * binary blob, but if filename_len is zero, then its length will be calculated
 * with strlen().  A zero-length filename_buf is not allowed.
 *
 * Note that a header record will only be written if header_offset is non-NULL,
 * as this represents a location to which a reader could seek.
 *
 * @param archive: the archive containing this file
 * @param filename_buf: filename to include in the file
 * @param filename_len: length of the filename_buf, or 0 to calculate
 * @param header_offset (output): offset of the header record preceding
 *	this file; pass NULL to ignore.
 * @returns: NULL on error, otherwise a file object
 */
amar_file_t *amar_new_file(
	    amar_t *archive,
	    char *filename_buf,
	    gsize filename_len,
	    off_t *header_offset,
	    GError **error);

/* Flush all buffer the 'file' object and write a record with ID=2 */
gboolean amar_file_close(
	    amar_file_t *file,
	    GError **error);

/* create a new 'attribute' object with attrid attached to the file
 *
 * @returns: NULL on error, otherwise an attribute object
 */
amar_attr_t *amar_new_attr(
	    amar_file_t *file,
	    uint16_t attrid,
	    GError **error);

/* flush all buffers and mark the end of the attribute */
gboolean amar_attr_close(
	    amar_attr_t *attribute,
	    GError **error);

/* Add 'size' byte of data from 'data' to the attribute.  If this is the
 * last data in this attribute, set eoa to TRUE.  This will save space by
 * writing and end-of-attribute indication in this record, instead of adding
 * an empty EOA record.
 */
gboolean amar_attr_add_data_buffer(
	    amar_attr_t *attribute,
	    gpointer data,
	    gsize size,
	    gboolean eoa,
	    GError **error);

/* This function reads from the file descriptor 'fd' until EOF and adds
 * the resulting data to the attribute.  The end of the attribute is
 * flagged appropriately if EOA is true.
 *
 * @param attribute: the attribute for the data
 * @param fd: the file descriptor from which to read
 * @param eoa: add an EOA bit to the end?
 * @returns: number of bytes read from fd, or -1 on error
 */
off_t amar_attr_add_data_fd(
	    amar_attr_t *attribute,
	    int fd,
	    gboolean eoa,
	    GError **error);

/* When reading files, the handling of each attribute can be configured
 * separately.  Some attributes may always be short enough to fit in memory,
 * and in this case the archive interface will take care of assembling any
 * fragments for you.  Some attributes should be ignored, while others
 * will call a function for each fragment.
 *
 * There are a a number of xx_data options available here, that deserve some
 * disambiguation.
 *  - user_data is global to the entire read operation (it is a parameter to
 *    amar_read)
 *  - file_data is specific to the current file; it is set by the start_file
 *    callback and freed by the finish_file callback.
 *  - attrid_data is specific this the current attribute ID, across all files;
 *    it comes from the amar_attr_handling_t struct.
 *  - attr_data is specific to the current instance of the particular
 *    attribute.  It points to a NULL pointer on the first call to the fragment
 *    callback, and can be set at that time.  It should be freed when the EOA
 *    argument is TRUE.
 *
 * @param user_data: the pointer passed to amar_read
 * @param filenum: the file number for this record
 * @param file_data: the file_data pointer returned from the start_file callback
 * @param attrid: the attribute id for this record
 * @param attrid_data: the data from the handling array
 * @param attr_data (in/out): data for this attribute; this will be the same
 *	  pointer for every callback for a particular instance of an attribute.
 *	  Any resources should be freed when eoa is true.
 * @param data: the data for this fragment
 * @param size: the size of data
 * @param eoa: TRUE iff this is the last fragment for this attribute
 * @param truncated: TRUE if this attribute is likely to be incomplete (e.g.,
 *	  in an error situation)
 * @returns: FALSE if the amar_read call should be aborted
 */
typedef gboolean (*amar_fragment_callback_t)(
	gpointer user_data,
	uint16_t filenum,
	gpointer file_data,
	uint16_t attrid,
	gpointer attrid_data,
	gpointer *attr_data,
	gpointer data,
	gsize size,
	gboolean eoa,
	gboolean truncated);

/* amar_read takes an array of this struct, terminated by an entry
 * with attrid 0.  This final entry is used as the "catchall" for attributes
 * not matching any other array entries. */
typedef struct amar_attr_handling_s {
    uint16_t attrid;

    /* if nonzero, this is the minimum size fragment that will be passed to the
     * callback.  Use SIZE_MAX for no limit, although this may result in
     * excessive memory use while parsing a malicious or corrupt archive. */
    gsize min_size;

    /* if non-NULL, this function will be called for each fragment
     * with this attribute ID */
    amar_fragment_callback_t callback;

    /* this value is passed as the attr_data parameter to the callback */
    gpointer attrid_data;
} amar_attr_handling_t;

/* This function is called for each new file, and can decide whether to ignore
 * the file, or set up file-specific data.
 *
 * @param user_data: the pointer passed to amar_read
 * @param filenum: the file number for this record
 * @param filename_buf: the filename of this file
 * @param filename_len: the length of the filename
 * @param ignore (output): if set to TRUE, ignore all attributes for this file.
 * @param file_data (output): space to store file-specific data
 * @returns: FALSE if the amar_read call should be aborted
 */
typedef gboolean (*amar_file_start_callback_t)(
	gpointer user_data,
	uint16_t filenum,
	gpointer filename_buf,
	gsize filename_len,
	gboolean *ignore,
	gpointer *file_data);

/* This function is called for each new file, and can decide whether to ignore
 * the file, or set up file-specific data.
 *
 * @param user_data: the pointer passed to amar_read
 * @param filenum: the file number for this record
 * @param file_data (output): space to store file-specific data
 * @param truncated: TRUE if this file is likely to be incomplete (e.g.,
 *	  in an error situation, or at an early EOF)
 * @returns: FALSE if the amar_read call should be aborted
 */
typedef gboolean (*amar_file_finish_callback_t)(
	gpointer user_data,
	uint16_t filenum,
	gpointer *file_data,
	gboolean truncated);

/* This function actually performs the read operation, calling all of the
 * above callbacks.  If any of the callbacks return FALSE, this function
 * returns FALSE but does not set its error parameter.
 *
 * @param user_data: passed to all callbacks
 * @param handling_array: array giving handling information
 * @param file_start_cb: callback for file starts
 * @param file_finish_cb: callback for file finishs
 * @param error (output): the error result
 * @returns: FALSE on error or an early exit, otherwise TRUE
 */
gboolean amar_read(
	amar_t *archive,
	gpointer user_data,
	amar_attr_handling_t *handling_array,
	amar_file_start_callback_t file_start_cb,
	amar_file_finish_callback_t file_finish_cb,
	GError **error);