+ amfree(datestamp);
+ amfree(current_label);
+
+ return found_something;
+}
+
+
+/*
+ * Return the set of dumps that match *all* of the given patterns (we consider
+ * an empty pattern to match .*, though). If 'ok' is true, will only match
+ * dumps with SUCCESS status.
+ *
+ * Returns a newly allocated list of results, where all strings are also newly
+ * allocated. Apparently some part of Amanda leaks under this condition.
+ */
+find_result_t *
+dumps_match(
+ find_result_t *output_find,
+ char *hostname,
+ char *diskname,
+ char *datestamp,
+ char *level,
+ int ok)
+{
+ find_result_t *cur_result;
+ find_result_t *matches = NULL;
+
+ for(cur_result=output_find;
+ cur_result;
+ cur_result=cur_result->next) {
+ char level_str[NUM_STR_SIZE];
+ g_snprintf(level_str, SIZEOF(level_str), "%d", cur_result->level);
+ if((!hostname || *hostname == '\0' || match_host(hostname, cur_result->hostname)) &&
+ (!diskname || *diskname == '\0' || match_disk(diskname, cur_result->diskname)) &&
+ (!datestamp || *datestamp== '\0' || match_datestamp(datestamp, cur_result->timestamp)) &&
+ (!level || *level== '\0' || match_level(level, level_str)) &&
+ (!ok || !strcmp(cur_result->status, "OK")) &&
+ (!ok || !strcmp(cur_result->dump_status, "OK"))){
+
+ find_result_t *curmatch = g_new0(find_result_t, 1);
+ memcpy(curmatch, cur_result, SIZEOF(find_result_t));
+
+ curmatch->timestamp = stralloc(cur_result->timestamp);
+ curmatch->write_timestamp = stralloc(cur_result->write_timestamp);
+ curmatch->hostname = stralloc(cur_result->hostname);
+ curmatch->diskname = stralloc(cur_result->diskname);
+ curmatch->level = cur_result->level;
+ curmatch->label = cur_result->label? stralloc(cur_result->label) : NULL;
+ curmatch->filenum = cur_result->filenum;
+ curmatch->sec = cur_result->sec;
+ curmatch->kb = cur_result->kb;
+ curmatch->orig_kb = cur_result->orig_kb;
+ curmatch->status = stralloc(cur_result->status);
+ curmatch->dump_status = stralloc(cur_result->dump_status);
+ curmatch->message = stralloc(cur_result->message);
+ curmatch->partnum = cur_result->partnum;
+ curmatch->totalparts = cur_result->totalparts;
+ curmatch->next = matches;
+ matches = curmatch;
+ }
+ }
+
+ return(matches);
+}
+
+/*
+ * Return the set of dumps that match one or more of the given dumpspecs,
+ * If 'ok' is true, only dumps with a SUCCESS status will be matched.
+ *
+ * Returns a newly allocated list of results, where all strings are also newly
+ * allocated. Apparently some part of Amanda leaks under this condition.
+ */
+find_result_t *
+dumps_match_dumpspecs(
+ find_result_t *output_find,
+ GSList *dumpspecs,
+ int ok)
+{
+ find_result_t *cur_result;
+ find_result_t *matches = NULL;
+ GSList *dumpspec;
+ dumpspec_t *ds;
+
+ for(cur_result=output_find;
+ cur_result;
+ cur_result=cur_result->next) {
+ char level_str[NUM_STR_SIZE];
+ char *zeropad_ts = NULL;
+ char *zeropad_w_ts = NULL;
+ g_snprintf(level_str, SIZEOF(level_str), "%d", cur_result->level);
+
+ /* get the timestamp padded to full width */
+ if (strlen(cur_result->timestamp) < 14) {
+ zeropad_ts = g_new0(char, 15);
+ memset(zeropad_ts, '0', 14);
+ memcpy(zeropad_ts, cur_result->timestamp, strlen(cur_result->timestamp));
+ }
+ if (strlen(cur_result->write_timestamp) < 14) {
+ zeropad_w_ts = g_new0(char, 15);
+ memset(zeropad_w_ts, '0', 14);
+ memcpy(zeropad_w_ts, cur_result->write_timestamp, strlen(cur_result->write_timestamp));
+ }
+
+ for (dumpspec = dumpspecs; dumpspec; dumpspec = dumpspec->next) {
+ ds = (dumpspec_t *)dumpspec->data;
+ if((!ds->host || *ds->host == '\0' || match_host(ds->host, cur_result->hostname)) &&
+ (!ds->disk || *ds->disk == '\0' || match_disk(ds->disk, cur_result->diskname)) &&
+ (!ds->datestamp || *ds->datestamp== '\0'
+ || match_datestamp(ds->datestamp, cur_result->timestamp)
+ || (zeropad_ts && match_datestamp(ds->datestamp, zeropad_ts))) &&
+ (!ds->write_timestamp || *ds->write_timestamp== '\0'
+ || match_datestamp(ds->write_timestamp, cur_result->write_timestamp)
+ || (zeropad_w_ts && match_datestamp(ds->write_timestamp, zeropad_w_ts))) &&
+ (!ds->level || *ds->level== '\0' || match_level(ds->level, level_str)) &&
+ (!ok || !strcmp(cur_result->status, "OK")) &&
+ (!ok || !strcmp(cur_result->dump_status, "OK"))) {
+
+ find_result_t *curmatch = alloc(SIZEOF(find_result_t));
+ memcpy(curmatch, cur_result, SIZEOF(find_result_t));
+
+ curmatch->timestamp = stralloc(cur_result->timestamp);
+ curmatch->write_timestamp = stralloc(cur_result->write_timestamp);
+ curmatch->hostname = stralloc(cur_result->hostname);
+ curmatch->diskname = stralloc(cur_result->diskname);
+ curmatch->level = cur_result->level;
+ curmatch->label = cur_result->label? stralloc(cur_result->label) : NULL;
+ curmatch->filenum = cur_result->filenum;
+ curmatch->status = stralloc(cur_result->status);
+ curmatch->dump_status = stralloc(cur_result->dump_status);
+ curmatch->message = stralloc(cur_result->message);
+ curmatch->partnum = cur_result->partnum;
+ curmatch->totalparts = cur_result->totalparts;
+
+ curmatch->next = matches;
+ matches = curmatch;
+ break;
+ }
+ }
+
+ amfree(zeropad_ts);
+ }
+
+ return(matches);