2 * Copyright (c) 2005 Zmanda Inc. All Rights Reserved.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Contact information: Zmanda Inc, 505 N Mathlida Ave, Suite 120
19 * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
21 * Author: Dustin J. Mitchell <dustin@zmanda.com>
26 * Utility routines for handling command lines.
42 rv = calloc(1, sizeof(*rv));
44 if (host) rv->host = stralloc(host);
45 if (disk) rv->disk = stralloc(disk);
46 if (datestamp) rv->datestamp = stralloc(datestamp);
55 if (!dumpspec) return;
56 if (dumpspec->host) free(dumpspec->host);
57 if (dumpspec->disk) free(dumpspec->disk);
58 if (dumpspec->datestamp) free(dumpspec->datestamp);
64 dumpspec_list_t *dumpspec_list)
66 dumpspec_t *dumpspec = (dumpspec_t *)dumpspec_list;
70 next = dumpspec->next;
71 dumpspec_free(dumpspec);
77 cmdline_parse_dumpspecs(
81 dumpspec_t *dumpspec = NULL, *t;
85 enum { ARG_GET_HOST, ARG_GET_DISK, ARG_GET_DATE } arg_state = ARG_GET_HOST;
87 while (optind < argc) {
88 name = argv[optind++];
92 && (errstr=validate_regexp(name)) != NULL) {
93 fprintf(stderr, _("%s: bad hostname regex \"%s\": %s\n"),
94 get_pname(), name, errstr);
97 t = dumpspec_new(name, NULL, NULL);
98 t->next = (dumpspec_t *)dumpspec;
100 arg_state = ARG_GET_DISK;
105 && (errstr=validate_regexp(name)) != NULL) {
106 fprintf(stderr, _("%s: bad diskname regex \"%s\": %s\n"),
107 get_pname(), name, errstr);
110 dumpspec->disk = stralloc(name);
111 arg_state = ARG_GET_DATE;
116 && (errstr=validate_regexp(name)) != NULL) {
117 fprintf(stderr, _("%s: bad datestamp regex \"%s\": %s\n"),
118 get_pname(), name, errstr);
121 dumpspec->datestamp = stralloc(name);
122 arg_state = ARG_GET_HOST;
127 if (dumpspec == NULL)
128 dumpspec = dumpspec_new("", "", "");
129 return (dumpspec_list_t *)dumpspec;
132 dumpspec_free_list((dumpspec_list_t *)dumpspec);
137 cmdline_format_dumpspec(
138 dumpspec_t *dumpspec)
140 if (!dumpspec) return NULL;
141 return cmdline_format_dumpspec_components(
144 dumpspec->datestamp);
147 /* Quote str for shell interpretation, being conservative.
148 * Any non-alphanumeric charcacters other than '.' and '/'
149 * trigger surrounding single quotes, and single quotes and
150 * backslashes within those single quotes are escaped.
153 quote_dumpspec_string(char *str)
158 int need_single_quotes = 0;
160 for (p = str; *p; p++) {
161 if (!isalnum(*p) && *p != '.' && *p != '/') need_single_quotes=1;
162 if (*p == '\'' || *p == '\\') len++; /* extra byte for '\' */
165 if (need_single_quotes) len += 2;
167 q = rv = malloc(len+1);
168 if (need_single_quotes) *(q++) = '\'';
169 for (p = str; *p; p++) {
170 if (*p == '\'' || *p == '\\') *(q++) = '\\';
173 if (need_single_quotes) *(q++) = '\'';
180 cmdline_format_dumpspec_components(
187 host = host? quote_dumpspec_string(host):NULL;
188 disk = disk? quote_dumpspec_string(disk):NULL;
189 datestamp = datestamp? quote_dumpspec_string(datestamp):NULL;
194 rv = newvstralloc(rv, rv, " ", disk, NULL);
197 rv = newvstralloc(rv, rv, " ", datestamp, NULL);
202 if (disk) amfree(disk);
203 if (datestamp) amfree(datestamp);
209 cmdline_match_holding(
210 dumpspec_list_t *dumpspec_list)
219 sl_t *matching_files = new_sl();
221 holding_set_verbosity(0);
222 holding_files = holding_get_files(NULL, NULL, 1);
224 for (he = holding_files->first; he != NULL; he = he->next) {
225 filetype = holding_file_read_header(he->name, &host, &disk, NULL, &datestamp);
226 if (filetype != F_DUMPFILE) continue;
227 for (de = (dumpspec_t *)dumpspec_list; de != NULL; de = de->next) {
228 if (de->host && !match_host(de->host, host)) continue;
229 if (de->disk && !match_disk(de->disk, disk)) continue;
230 if (de->datestamp && !match_datestamp(de->datestamp, datestamp)) continue;
231 matching_files = insert_sort_sl(matching_files, he->name);
236 return matching_files;