2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1998 University of Maryland at College Park
4 * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of U.M. not be used in advertising or
12 * publicity pertaining to distribution of the software without specific,
13 * written prior permission. U.M. makes no representations about the
14 * suitability of this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
17 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
19 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Authors: the Amanda Development Team. Its members are listed in a
25 * file named AUTHORS, in the root directory of this distribution.
29 * $Id: amfeatures.c,v 1.24 2006/07/19 17:46:07 martinea Exp $
31 * Feature test related code.
35 #include "amfeatures.h"
38 *=====================================================================
39 * Initialize the base feature set for this version of Amanda.
41 * am_feature_t *am_init_feature_set()
44 * exit: dynamically allocated feature set structure
45 *=====================================================================
49 am_init_feature_set(void)
53 if ((f = am_allocate_feature_set()) != NULL) {
55 * Whenever a new feature is added, a new line usually needs
56 * to be added here to show that we support it.
58 am_add_feature(f, have_feature_support);
59 am_add_feature(f, fe_options_auth);
61 am_add_feature(f, fe_selfcheck_req);
62 am_add_feature(f, fe_selfcheck_req_device);
63 am_add_feature(f, fe_selfcheck_rep);
64 am_add_feature(f, fe_sendsize_req_no_options);
65 am_add_feature(f, fe_sendsize_req_options);
66 am_add_feature(f, fe_sendsize_req_device);
67 am_add_feature(f, fe_sendsize_rep);
68 am_add_feature(f, fe_sendbackup_req);
69 am_add_feature(f, fe_sendbackup_req_device);
70 am_add_feature(f, fe_sendbackup_rep);
71 am_add_feature(f, fe_noop_req);
72 am_add_feature(f, fe_noop_rep);
74 am_add_feature(f, fe_program_dump);
75 am_add_feature(f, fe_program_gnutar);
76 am_add_feature(f, fe_program_application_api);
78 am_add_feature(f, fe_options_compress_fast);
79 am_add_feature(f, fe_options_compress_best);
80 am_add_feature(f, fe_options_srvcomp_fast);
81 am_add_feature(f, fe_options_srvcomp_best);
82 am_add_feature(f, fe_options_no_record);
83 am_add_feature(f, fe_options_bsd_auth);
84 am_add_feature(f, fe_options_index);
85 am_add_feature(f, fe_options_exclude_file);
86 am_add_feature(f, fe_options_exclude_list);
87 am_add_feature(f, fe_options_multiple_exclude);
88 am_add_feature(f, fe_options_optional_exclude);
89 am_add_feature(f, fe_options_include_file);
90 am_add_feature(f, fe_options_include_list);
91 am_add_feature(f, fe_options_multiple_include);
92 am_add_feature(f, fe_options_optional_include);
93 am_add_feature(f, fe_options_kencrypt);
95 am_add_feature(f, fe_req_options_maxdumps);
96 am_add_feature(f, fe_req_options_hostname);
97 am_add_feature(f, fe_req_options_features);
99 am_add_feature(f, fe_rep_options_features);
101 am_add_feature(f, fe_amindexd_fileno_in_OLSD);
102 am_add_feature(f, fe_amindexd_fileno_in_ORLD);
103 am_add_feature(f, fe_amidxtaped_fsf);
104 am_add_feature(f, fe_amidxtaped_label);
105 am_add_feature(f, fe_amidxtaped_device);
106 am_add_feature(f, fe_amidxtaped_host);
107 am_add_feature(f, fe_amidxtaped_disk);
108 am_add_feature(f, fe_amidxtaped_datestamp);
109 am_add_feature(f, fe_amidxtaped_header);
110 am_add_feature(f, fe_amidxtaped_config);
112 am_add_feature(f, fe_recover_splits);
113 am_add_feature(f, fe_amidxtaped_exchange_features);
114 am_add_feature(f, fe_partial_estimate);
115 am_add_feature(f, fe_calcsize_estimate);
116 am_add_feature(f, fe_selfcheck_calcsize);
117 am_add_feature(f, fe_options_compress_cust);
118 am_add_feature(f, fe_options_srvcomp_cust);
119 am_add_feature(f, fe_options_encrypt_cust);
120 am_add_feature(f, fe_options_encrypt_serv_cust);
121 am_add_feature(f, fe_options_client_decrypt_option);
122 am_add_feature(f, fe_options_server_decrypt_option);
124 am_add_feature(f, fe_amindexd_marshall_in_OLSD);
125 am_add_feature(f, fe_amindexd_marshall_in_ORLD);
126 am_add_feature(f, fe_amindexd_marshall_in_DHST);
128 am_add_feature(f, fe_amrecover_FEEDME);
129 am_add_feature(f, fe_amrecover_timestamp);
131 am_add_feature(f, fe_interface_quoted_text);
133 am_add_feature(f, fe_program_star);
135 am_add_feature(f, fe_amindexd_options_hostname);
136 am_add_feature(f, fe_amindexd_options_features);
137 am_add_feature(f, fe_amindexd_options_auth);
139 am_add_feature(f, fe_amidxtaped_options_hostname);
140 am_add_feature(f, fe_amidxtaped_options_features);
141 am_add_feature(f, fe_amidxtaped_options_auth);
143 am_add_feature(f, fe_amrecover_message);
144 am_add_feature(f, fe_amrecover_feedme_tape);
146 am_add_feature(f, fe_req_options_config);
148 am_add_feature(f, fe_rep_sendsize_quoted_error);
149 am_add_feature(f, fe_req_xml);
150 am_add_feature(f, fe_pp_script);
151 am_add_feature(f, fe_amindexd_DLE);
152 am_add_feature(f, fe_amrecover_dle_in_header);
153 am_add_feature(f, fe_xml_estimate);
154 am_add_feature(f, fe_xml_property_priority);
155 am_add_feature(f, fe_sendsize_rep_warning);
156 am_add_feature(f, fe_xml_estimatelist);
157 am_add_feature(f, fe_xml_level_server);
158 am_add_feature(f, fe_xml_data_path);
159 am_add_feature(f, fe_xml_directtcp_list);
160 am_add_feature(f, fe_amidxtaped_datapath);
161 am_add_feature(f, fe_sendbackup_noop);
162 am_add_feature(f, fe_amrecover_origsize_in_header);
163 am_add_feature(f, fe_amidxtaped_abort);
164 am_add_feature(f, fe_amrecover_correct_disk_quoting);
165 am_add_feature(f, fe_amindexd_quote_label);
166 am_add_feature(f, fe_amrecover_receive_unfiltered);
167 am_add_feature(f, fe_application_client_name);
168 am_add_feature(f, fe_script_client_name);
169 am_add_feature(f, fe_dumptype_property);
175 *=====================================================================
176 * Set a default feature set for client that doesn't have noop service.
177 * This is all the features available in 2.4.2p2.
180 * exit: dynamically allocated feature set
181 *=====================================================================
185 am_set_default_feature_set(void)
189 if ((f = am_allocate_feature_set()) != NULL) {
191 am_add_feature(f, fe_selfcheck_req);
192 am_add_feature(f, fe_selfcheck_rep);
193 am_add_feature(f, fe_sendsize_req_no_options);
194 am_add_feature(f, fe_sendsize_rep);
195 am_add_feature(f, fe_sendbackup_req);
196 am_add_feature(f, fe_sendbackup_rep);
198 am_add_feature(f, fe_program_dump);
199 am_add_feature(f, fe_program_gnutar);
201 am_add_feature(f, fe_options_compress_fast);
202 am_add_feature(f, fe_options_compress_best);
203 am_add_feature(f, fe_options_srvcomp_fast);
204 am_add_feature(f, fe_options_srvcomp_best);
205 am_add_feature(f, fe_options_no_record);
206 am_add_feature(f, fe_options_bsd_auth);
207 am_add_feature(f, fe_options_index);
208 am_add_feature(f, fe_options_exclude_file);
209 am_add_feature(f, fe_options_exclude_list);
210 am_add_feature(f, fe_options_kencrypt);
212 am_add_feature(f, fe_req_options_maxdumps);
213 am_add_feature(f, fe_req_options_hostname);
214 am_add_feature(f, fe_req_options_features);
216 am_add_feature(f, fe_rep_options_sendbackup_options);
222 *=====================================================================
223 * Allocate space for a feature set.
225 * am_feature_t *am_allocate_feature_set()
228 * exit: dynamically allocated feature set structure
229 *=====================================================================
233 am_allocate_feature_set(void)
236 am_feature_t *result;
238 result = (am_feature_t *)alloc(SIZEOF(*result));
239 memset(result, 0, SIZEOF(*result));
240 nbytes = (((size_t)last_feature) + 8) >> 3;
241 result->size = nbytes;
242 result->bytes = (unsigned char *)alloc(nbytes);
243 memset(result->bytes, 0, nbytes);
248 *=====================================================================
249 * Release space allocated to a feature set.
251 * void am_release_feature_set(am_feature_t *f)
253 * entry: f = feature set to release
255 *=====================================================================
259 am_release_feature_set(
270 *=====================================================================
271 * Add a feature to a feature set.
273 * int am_add_feature(am_feature_t *f, am_feature_e n)
275 * entry: f = feature set to add to
277 * exit: non-zero if feature added, else zero (e.g. if the feature
278 * is beyond what is currently supported)
279 *=====================================================================
291 if (f != NULL && (int)n >= 0) {
292 byte = ((size_t)n) >> 3;
293 if (byte < f->size) {
294 bit = ((int)n) & 0x7;
295 f->bytes[byte] = (unsigned char)((int)f->bytes[byte] | (unsigned char)(1 << bit));
303 *=====================================================================
304 * Remove a feature from a feature set.
306 * int am_remove_feature(am_feature_t *f, am_feature_e n)
308 * entry: f = feature set to remove from
309 * n = feature to remove
310 * exit: non-zero if feature removed, else zero (e.g. if the feature
311 * is beyond what is currently supported)
312 *=====================================================================
324 if (f != NULL && (int)n >= 0) {
325 byte = ((size_t)n) >> 3;
326 if (byte < f->size) {
327 bit = ((int)n) & 0x7;
328 f->bytes[byte] = (unsigned char)((int)f->bytes[byte] & (unsigned char)~(1 << bit));
336 *=====================================================================
337 * Return true if a given feature is available.
339 * int am_has_feature(am_feature_t *f, am_feature_e n)
341 * entry: f = feature set to test
342 * n = feature to test
343 * exit: non-zero if feature is enabled
344 *=====================================================================
356 if (f != NULL && (int)n >= 0) {
357 byte = ((size_t)n) >> 3;
358 if (byte < f->size) {
359 bit = ((int)n) & 0x7;
360 result = ((f->bytes[byte] & (1 << bit)) != 0);
367 *=====================================================================
368 * Convert a feature set to string.
370 * char *am_feature_to_string(am_feature_t *f)
372 * entry: f = feature set to convet
373 * exit: dynamically allocated string
374 *=====================================================================
378 am_feature_to_string(
385 result = stralloc(_("UNKNOWNFEATURE"));
387 result = alloc((f->size * 2) + 1);
388 for (i = 0; i < f->size; i++) {
389 g_snprintf(result + (i * 2), 2 + 1, "%02x", f->bytes[i]);
391 result[i * 2] = '\0';
397 *=====================================================================
398 * Convert a sting back to a feature set.
400 * am_feature_t *am_string_to_feature(char *s)
402 * entry: s = string to convert
403 * exit: dynamically allocated feature set
405 * Note: if the string is longer than the list of features we support,
406 * the remaining input features are ignored. If it is shorter, the
407 * missing features are disabled.
409 * If the string is not formatted properly (not a multiple of two bytes),
412 * Conversion stops at the first non-hex character.
413 *=====================================================================
417 am_string_to_feature(
420 am_feature_t *f = NULL;
425 if (s != NULL && strcmp(s,"UNKNOWNFEATURE") != 0) {
426 f = am_allocate_feature_set();
427 for (i = 0; i < f->size && (ch1 = *s++) != '\0'; i++) {
430 } else if (ch1 >= 'a' && ch1 <= 'f') {
433 } else if (ch1 >= 'A' && ch1 <= 'F') {
442 } else if (ch2 >= 'a' && ch2 <= 'f') {
445 } else if (ch2 >= 'A' && ch2 <= 'F') {
448 } else if (ch2 == '\0') {
449 g_warning("odd number of digits in amfeature string; truncating");
454 f->bytes[i] = (unsigned char)((ch1 << 4) | ch2);
460 g_warning("Bad feature string '%s'", orig);
461 am_release_feature_set(f);