/amanda/tags/amanda252/server-src/cmdline.c
C | 237 lines | 179 code | 26 blank | 32 comment | 61 complexity | 5e014df4b04441be92193fe0b95c65e5 MD5 | raw file
- /*
- * Copyright (c) 2005 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 as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * 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, 505 N Mathlida Ave, Suite 120
- * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
- *
- * Author: Dustin J. Mitchell <dustin@zmanda.com>
- */
- /*
- * $Id$
- *
- * Utility routines for handling command lines.
- */
- #include <ctype.h>
- #include "amanda.h"
- #include "cmdline.h"
- #include "holding.h"
- dumpspec_t *
- dumpspec_new(
- char *host,
- char *disk,
- char *datestamp)
- {
- dumpspec_t *rv;
- rv = calloc(1, sizeof(*rv));
- if (!rv) return NULL;
- if (host) rv->host = stralloc(host);
- if (disk) rv->disk = stralloc(disk);
- if (datestamp) rv->datestamp = stralloc(datestamp);
- return rv;
- }
- void
- dumpspec_free(
- dumpspec_t *dumpspec)
- {
- if (!dumpspec) return;
- if (dumpspec->host) free(dumpspec->host);
- if (dumpspec->disk) free(dumpspec->disk);
- if (dumpspec->datestamp) free(dumpspec->datestamp);
- free(dumpspec);
- }
- void
- dumpspec_free_list(
- dumpspec_list_t *dumpspec_list)
- {
- dumpspec_t *dumpspec = (dumpspec_t *)dumpspec_list;
- dumpspec_t *next;
- while (dumpspec) {
- next = dumpspec->next;
- dumpspec_free(dumpspec);
- dumpspec = next;
- }
- }
- dumpspec_list_t *
- cmdline_parse_dumpspecs(
- int argc,
- char **argv)
- {
- dumpspec_t *dumpspec = NULL, *t;
- char *errstr;
- char *name;
- int optind = 0;
- enum { ARG_GET_HOST, ARG_GET_DISK, ARG_GET_DATE } arg_state = ARG_GET_HOST;
- while (optind < argc) {
- name = argv[optind++];
- switch (arg_state) {
- case ARG_GET_HOST:
- if (name[0] != '\0'
- && (errstr=validate_regexp(name)) != NULL) {
- fprintf(stderr, _("%s: bad hostname regex \"%s\": %s\n"),
- get_pname(), name, errstr);
- goto error;
- }
- t = dumpspec_new(name, NULL, NULL);
- t->next = (dumpspec_t *)dumpspec;
- dumpspec = t;
- arg_state = ARG_GET_DISK;
- break;
- case ARG_GET_DISK:
- if (name[0] != '\0'
- && (errstr=validate_regexp(name)) != NULL) {
- fprintf(stderr, _("%s: bad diskname regex \"%s\": %s\n"),
- get_pname(), name, errstr);
- goto error;
- }
- dumpspec->disk = stralloc(name);
- arg_state = ARG_GET_DATE;
- break;
- case ARG_GET_DATE:
- if (name[0] != '\0'
- && (errstr=validate_regexp(name)) != NULL) {
- fprintf(stderr, _("%s: bad datestamp regex \"%s\": %s\n"),
- get_pname(), name, errstr);
- goto error;
- }
- dumpspec->datestamp = stralloc(name);
- arg_state = ARG_GET_HOST;
- break;
- }
- }
- if (dumpspec == NULL)
- dumpspec = dumpspec_new("", "", "");
- return (dumpspec_list_t *)dumpspec;
- error:
- dumpspec_free_list((dumpspec_list_t *)dumpspec);
- return NULL;
- }
- char *
- cmdline_format_dumpspec(
- dumpspec_t *dumpspec)
- {
- if (!dumpspec) return NULL;
- return cmdline_format_dumpspec_components(
- dumpspec->host,
- dumpspec->disk,
- dumpspec->datestamp);
- }
- /* Quote str for shell interpretation, being conservative.
- * Any non-alphanumeric charcacters other than '.' and '/'
- * trigger surrounding single quotes, and single quotes and
- * backslashes within those single quotes are escaped.
- */
- static char *
- quote_dumpspec_string(char *str)
- {
- char *rv;
- char *p, *q;
- int len = 0;
- int need_single_quotes = 0;
- for (p = str; *p; p++) {
- if (!isalnum(*p) && *p != '.' && *p != '/') need_single_quotes=1;
- if (*p == '\'' || *p == '\\') len++; /* extra byte for '\' */
- len++;
- }
- if (need_single_quotes) len += 2;
- q = rv = malloc(len+1);
- if (need_single_quotes) *(q++) = '\'';
- for (p = str; *p; p++) {
- if (*p == '\'' || *p == '\\') *(q++) = '\\';
- *(q++) = *p;
- }
- if (need_single_quotes) *(q++) = '\'';
- *(q++) = '\0';
- return rv;
- }
- char *
- cmdline_format_dumpspec_components(
- char *host,
- char *disk,
- char *datestamp)
- {
- char *rv = NULL;
- host = host? quote_dumpspec_string(host):NULL;
- disk = disk? quote_dumpspec_string(disk):NULL;
- datestamp = datestamp? quote_dumpspec_string(datestamp):NULL;
- if (host) {
- rv = host;
- if (disk) {
- rv = newvstralloc(rv, rv, " ", disk, NULL);
- amfree(disk);
- if (datestamp) {
- rv = newvstralloc(rv, rv, " ", datestamp, NULL);
- amfree(datestamp);
- }
- }
- }
- if (disk) amfree(disk);
- if (datestamp) amfree(datestamp);
- return rv;
- }
- sl_t *
- cmdline_match_holding(
- dumpspec_list_t *dumpspec_list)
- {
- char *host;
- char *disk;
- char *datestamp;
- filetype_t filetype;
- dumpspec_t *de;
- sl_t *holding_files;
- sle_t *he;
- sl_t *matching_files = new_sl();
- holding_set_verbosity(0);
- holding_files = holding_get_files(NULL, 1);
- for (he = holding_files->first; he != NULL; he = he->next) {
- filetype = holding_file_read_header(he->name, &host, &disk, NULL, &datestamp);
- if (filetype != F_DUMPFILE) continue;
- for (de = (dumpspec_t *)dumpspec_list; de != NULL; de = de->next) {
- if (de->host && !match_host(de->host, host)) continue;
- if (de->disk && !match_disk(de->disk, disk)) continue;
- if (de->datestamp && !match_datestamp(de->datestamp, datestamp)) continue;
- matching_files = insert_sort_sl(matching_files, he->name);
- break;
- }
- }
- return matching_files;
- }