#include "cmdline.h"
int find_match(char *host, char *disk);
-char *find_nicedate(char *datestamp);
+static char *find_nicedate(char *datestamp);
+static int len_find_nicedate(char *datestamp);
static int find_compare(const void *, const void *);
static int parse_taper_datestamp_log(char *logline, char **datestamp, char **level);
static gboolean logfile_has_tape(char * label, char * datestamp,
tape_t *tp, *tp1;
find_result_t *output_find = NULL;
gboolean *tape_seen = NULL;
- GSList *label_list;
conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR));
maxtape = lookup_nb_tape();
tp = lookup_tapepos(tape);
if(tp == NULL) continue;
- /* find all tape with the same datestamp
- add them to label_list */
- label_list = NULL;
+ /* find all tape with the same datestamp */
for (tape1 = tape; tape1 <= maxtape; tape1++) {
tp1 = lookup_tapepos(tape1);
if (tp1 == NULL) continue;
continue;
tape_seen[tape1] = 1;
- label_list = g_slist_append(label_list, tp1->label);
}
/* search log files */
logs ++;
}
}
- if (logs == 0 && strcmp(tp->datestamp,"0") != 0) {
- GSList *l_label;
- for (l_label = label_list; l_label != NULL ; l_label = l_label->next) {
- g_fprintf(stderr,
- _("Warning: no log files found for tape %s written %s\n"),
- (char *)l_label->data, find_nicedate(tp->datestamp));
- }
- }
- g_slist_free(label_list);
}
g_free(tape_seen);
amfree(logfile);
find_result_t *new_output_find = g_new0(find_result_t, 1);
new_output_find->next=*output_find;
new_output_find->timestamp = stralloc(file.datestamp);
+ new_output_find->write_timestamp = stralloc("00000000000000");
new_output_find->hostname = stralloc(file.name);
new_output_find->diskname = stralloc(file.disk);
new_output_find->level=file.dumplevel;
dumpfile_free_data(&file);
}
- g_slist_free_full(holding_file_list);
-}
-
-static char *
-get_write_timestamp(char *tapelabel)
-{
- tape_t *tp;
-
- if (!tapelabel || !(tp = lookup_tapelabel(tapelabel)))
- return "0";
-
- return tp->datestamp;
+ slist_free_full(holding_file_list, g_free);
}
static int
case 'b' : compare=compare_possibly_null_strings(i->label,
j->label);
break;
- case 'w': compare=strcmp(get_write_timestamp(i->label),
- get_write_timestamp(j->label));
+ case 'w': compare=strcmp(i->write_timestamp, j->write_timestamp);
break;
case 'p' :
compare=i->partnum - j->partnum;
for(output_find_result=output_find;
output_find_result;
output_find_result=output_find_result->next) {
- char *qdiskname;
char *s;
- len=strlen(find_nicedate(output_find_result->timestamp));
+ len=len_find_nicedate(output_find_result->timestamp);
if((int)len > max_len_datestamp)
max_len_datestamp=(int)len;
if((int)len > max_len_hostname)
max_len_hostname = (int)len;
- qdiskname=quote_string(output_find_result->diskname);
- len=strlen(qdiskname);
- amfree(qdiskname);
+ len = len_quote_string(output_find_result->diskname);
if((int)len > max_len_diskname)
max_len_diskname = (int)len;
if (output_find_result->label != NULL) {
- len=strlen(output_find_result->label);
+ len = len_quote_string(output_find_result->label);
if((int)len > max_len_label)
max_len_label = (int)len;
}
len=strlen(s);
if((int)len > max_len_part)
max_len_part = (int)len;
+ amfree(s);
}
/*
char *status;
qdiskname = quote_string(output_find_result->diskname);
- formatted_label = output_find_result->label;
- if (formatted_label == NULL)
- formatted_label = "";
+ if (output_find_result->label == NULL)
+ formatted_label = stralloc("");
+ else
+ formatted_label = quote_string(output_find_result->label);
if (strcmp(output_find_result->status, "OK") != 0 ||
strcmp(output_find_result->dump_status, "OK") != 0) {
amfree(s);
/*@end@*/
amfree(qdiskname);
+ amfree(formatted_label);
}
}
}
output_find_result=output_find_result->next) {
amfree(prev);
amfree(output_find_result->timestamp);
+ amfree(output_find_result->write_timestamp);
amfree(output_find_result->hostname);
amfree(output_find_result->diskname);
amfree(output_find_result->label);
return (dp && dp->todo);
}
-char *
+static char *
find_nicedate(
char *datestamp)
{
return nice;
}
+static int
+len_find_nicedate(
+ char *datestamp)
+{
+ if(strlen(datestamp) <= 8) {
+ return 10;
+ } else {
+ return 19;
+ }
+}
+
static int
parse_taper_datestamp_log(
char *logline,
return TRUE;
}
-
/* WARNING: Function accesses globals find_diskqp, curlog, curlog, curstr,
* dynamic_disklist */
gboolean
char *number;
int fileno;
char *current_label = stralloc("");
- char *rest;
+ char *rest, *rest_undo;
char *ck_label=NULL;
int level = 0;
off_t filenum;
char *s;
int ch;
disk_t *dp;
- find_result_t *part_find = NULL; /* List for all part of a DLE */
+ GHashTable* valid_label;
+ GHashTable* part_by_dle;
+ find_result_t *part_find;
find_result_t *a_part_find;
gboolean right_label = FALSE;
gboolean found_something = FALSE;
- regex_t regex;
- int reg_result;
- regmatch_t pmatch[4];
double sec;
off_t kb;
off_t orig_kb;
+ int taper_part = 0;
g_return_val_if_fail(output_find != NULL, 0);
g_return_val_if_fail(logfile != NULL, 0);
+ valid_label = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ part_by_dle = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
datestamp = g_strdup(passed_datestamp);
if((logf = fopen(logfile, "r")) == NULL) {
}
right_label = volume_matches(label, ck_label, ck_datestamp);
+ if (right_label && ck_label) {
+ g_hash_table_insert(valid_label, g_strdup(ck_label),
+ GINT_TO_POINTER(1));
+ }
if (label && datestamp && right_label) {
found_something = TRUE;
}
if (datestamp == NULL) {
datestamp = g_strdup(ck_datestamp);
}
+ filenum = (off_t)0;
}
if (right_label &&
(curlog == L_SUCCESS ||
curlog == L_CHUNK || curlog == L_PART || curlog == L_PARTPARTIAL) &&
curprog == P_TAPER) {
filenum++;
+ } else if (right_label && curlog == L_PARTIAL && curprog == P_TAPER &&
+ taper_part == 0) {
+ filenum++;
}
partnum = -1;
totalparts = -1;
if (curlog == L_PART || curlog == L_PARTPARTIAL) {
char * part_label = s - 1;
+ taper_part++;
skip_non_whitespace(s, ch);
s[-1] = '\0';
- if (!right_label)
+ if (!g_hash_table_lookup(valid_label, part_label))
continue;
+ amfree(current_label);
+ current_label = stralloc(part_label);
- if (strcmp(current_label, part_label) != 0) {
- g_printf("PART label %s doesn't match START label %s\n",
- part_label, current_label);
- continue;
- }
skip_whitespace(s, ch);
if(ch == '\0') {
g_printf("strange log line in %s \"%s\"\n",
logfile, curstr);
continue;
}
+ } else {
+ taper_part = 0;
}
host = s - 1;
partnum = 1;
totalparts =1;
} else {
- if (curlog == L_CHUNK || curlog == L_PART ||
- curlog == L_PARTPARTIAL || curlog == L_DONE){
+ if (curprog == P_TAPER &&
+ (curlog == L_CHUNK || curlog == L_PART ||
+ curlog == L_PARTPARTIAL || curlog == L_PARTIAL ||
+ curlog == L_DONE)) {
skip_whitespace(s, ch);
number = s - 1;
skip_non_whitespace(s, ch);
continue;
}
rest = s - 1;
- if((s = strchr(s, '\n')) != NULL) {
- *s = '\0';
- }
-
- /* extract sec, kb, kps, orig-kb from 'rest', if present. This isn't the stone age
- * anymore, so we'll just do it the easy way (a regex) */
- bzero(®ex, sizeof(regex));
- reg_result = regcomp(®ex,
- "\\[sec ([0-9.]+) kb ([0-9]+) kps [0-9.]+ orig-kb ([0-9]+)\\]", REG_EXTENDED);
- if (reg_result != 0) {
- error("Error compiling regular expression for parsing log lines");
- /* NOTREACHED */
- }
-
- /* an error here just means the line wasn't found -- not fatal. */
- reg_result = regexec(®ex, rest, sizeof(pmatch)/sizeof(*pmatch), pmatch, 0);
- if (reg_result == 0) {
- char *str;
-
- str = find_regex_substring(rest, pmatch[1]);
- sec = atof(str);
- amfree(str);
-
- str = find_regex_substring(rest, pmatch[2]);
- kb = OFF_T_ATOI(str);
- amfree(str);
-
- str = find_regex_substring(rest, pmatch[3]);
- orig_kb = OFF_T_ATOI(str);
- amfree(str);
- } else {
- bzero(®ex, sizeof(regex));
- reg_result = regcomp(®ex,
- "\\[sec ([0-9.]+) kb ([0-9]+) kps [0-9.]+\\]", REG_EXTENDED);
- if (reg_result != 0) {
- error("Error compiling regular expression for parsing log lines");
- /* NOTREACHED */
+ skip_non_whitespace(s, ch);
+ rest_undo = s - 1;
+ *rest_undo = '\0';
+ if (strcmp(rest, "[sec") == 0) {
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ g_printf(_("strange log line in %s \"%s\"\n"),
+ logfile, curstr);
+ continue;
+ }
+ sec = atof(s - 1);
+ skip_non_whitespace(s, ch);
+ skip_whitespace(s, ch);
+ rest = s - 1;
+ skip_non_whitespace(s, ch);
+ rest_undo = s - 1;
+ *rest_undo = '\0';
+ if (strcmp(rest, "kb") != 0) {
+ g_printf(_("Bstrange log line in %s \"%s\"\n"),
+ logfile, curstr);
+ continue;
}
- /* an error here just means the line wasn't found -- not fatal. */
- reg_result = regexec(®ex, rest, sizeof(pmatch)/sizeof(*pmatch), pmatch, 0);
- if (reg_result == 0) {
- char *str;
-
- str = find_regex_substring(rest, pmatch[1]);
- sec = atof(str);
- amfree(str);
+ skip_whitespace(s, ch);
+ if (ch == '\0') {
+ g_printf(_("strange log line in %s \"%s\"\n"),
+ logfile, curstr);
+ continue;
+ }
+ kb = atof(s - 1);
+ skip_non_whitespace(s, ch);
+ skip_whitespace(s, ch);
+ rest = s - 1;
+ skip_non_whitespace(s, ch);
+ rest_undo = s - 1;
+ *rest_undo = '\0';
+ if (strcmp(rest, "kps") != 0) {
+ g_printf(_("Cstrange log line in %s \"%s\"\n"),
+ logfile, curstr);
+ continue;
+ }
- str = find_regex_substring(rest, pmatch[2]);
- kb = OFF_T_ATOI(str);
- amfree(str);
+ skip_whitespace(s, ch);
+ if (ch == '\0') {
+ g_printf(_("strange log line in %s \"%s\"\n"),
+ logfile, curstr);
+ continue;
+ }
+ /* kps = atof(s - 1); */
+ skip_non_whitespace(s, ch);
+ skip_whitespace(s, ch);
+ rest = s - 1;
+ skip_non_whitespace(s, ch);
+ rest_undo = s - 1;
+ *rest_undo = '\0';
+ if (strcmp(rest, "orig-kb") != 0) {
orig_kb = 0;
} else {
- sec = 0;
- kb = 0;
- orig_kb = 0;
+
+ skip_whitespace(s, ch);
+ if(ch == '\0') {
+ g_printf(_("strange log line in %s \"%s\"\n"),
+ logfile, curstr);
+ continue;
+ }
+ orig_kb = atof(s - 1);
}
+ } else {
+ sec = 0;
+ kb = 0;
+ orig_kb = 0;
+ *rest_undo = ' ';
}
- regfree(®ex);
+
+ if (strncmp(rest, "error", 5) == 0) rest += 6;
+ if (strncmp(rest, "config", 6) == 0) rest += 7;
dp = lookup_disk(host,disk);
if ( dp == NULL ) {
}
if (find_match(host, disk)) {
if(curprog == P_TAPER) {
+ char *key = g_strdup_printf(
+ "HOST:%s DISK:%s: DATE:%s LEVEL:%d",
+ host, disk, date, level);
find_result_t *new_output_find = g_new0(find_result_t, 1);
+ part_find = g_hash_table_lookup(part_by_dle, key);
new_output_find->timestamp = stralloc(date);
+ new_output_find->write_timestamp = stralloc(datestamp);
new_output_find->hostname=stralloc(host);
new_output_find->diskname=stralloc(disk);
new_output_find->level=level;
new_output_find->status = stralloc("OK");
new_output_find->dump_status = stralloc("OK");
new_output_find->next = *output_find;
+ new_output_find->partnum = 1; /* L_SUCCESS is pre-splitting */
*output_find = new_output_find;
found_something = TRUE;
} else if (curlog == L_CHUNKSUCCESS || curlog == L_DONE ||
/* result line */
if (curlog == L_PARTIAL || curlog == L_FAIL) {
/* set dump_status of each part */
- for (a_part_find = part_find; a_part_find;
+ for (a_part_find = part_find;
+ a_part_find;
a_part_find = a_part_find->next) {
amfree(a_part_find->dump_status);
if (curlog == L_PARTIAL)
if (maxparts > -1) { /* format with part */
/* must check if all part are there */
int num_part = maxparts;
- for (a_part_find = part_find; a_part_find;
+ for (a_part_find = part_find;
+ a_part_find;
a_part_find = a_part_find->next) {
if (a_part_find->partnum == num_part &&
strcmp(a_part_find->status, "OK") == 0)
num_part--;
}
/* set dump_status of each part */
- for (a_part_find = part_find; a_part_find;
+ for (a_part_find = part_find;
+ a_part_find;
a_part_find = a_part_find->next) {
amfree(a_part_find->dump_status);
if (num_part == 0) {
}
}
if (curlog == L_DONE) {
- for (a_part_find = part_find; a_part_find;
+ for (a_part_find = part_find;
+ a_part_find;
a_part_find = a_part_find->next) {
if (a_part_find->totalparts == -1) {
a_part_find->totalparts = maxparts;
part_find = NULL;
maxparts = -1;
found_something = TRUE;
+ g_hash_table_remove(part_by_dle, key);
}
free_find_result(&new_output_find);
} else { /* part line */
new_output_find->dump_status=stralloc("PARTIAL");
}
/* Add to part_find list */
- new_output_find->next = part_find;
- part_find = new_output_find;
+ if (part_find) {
+ new_output_find->next = part_find;
+ part_find = new_output_find;
+ } else {
+ new_output_find->next = NULL;
+ part_find = new_output_find;
+ }
+ g_hash_table_insert(part_by_dle, g_strdup(key),
+ part_find);
found_something = TRUE;
}
+ amfree(key);
}
else if(curlog == L_FAIL) {
/* print other failures too -- this is a hack to ensure that failures which
* users that do not want this information (e.g., Amanda::DB::Catalog) should
* filter dumps with a NULL label. */
find_result_t *new_output_find = g_new0(find_result_t, 1);
- new_output_find->next=*output_find;
+ new_output_find->next = *output_find;
new_output_find->timestamp = stralloc(date);
+ new_output_find->write_timestamp = g_strdup("00000000000000"); /* dump was not written.. */
new_output_find->hostname=stralloc(host);
new_output_find->diskname=stralloc(disk);
new_output_find->level=level;
}
}
- /* This could propably be completely removed */
- if (part_find != NULL) {
- if (label) {
- /* parse log file until PARTIAL/DONE/SUCCESS/FAIL from taper */
- while(get_logline(logf)) {
- if (curprog == P_TAPER &&
- (curlog == L_DONE || curlog == L_SUCCESS ||
- curlog == L_PARTIAL || curlog == L_FAIL)) {
- break;
- }
- }
- }
- for (a_part_find = part_find; a_part_find;
- a_part_find = a_part_find->next) {
- if (curlog == L_PARTIAL)
- a_part_find->status = stralloc("PARTIAL");
- else if (curlog == L_FAIL)
- a_part_find->status = stralloc("FAIL");
- else if (curlog == L_DONE || curlog == L_SUCCESS) {
- if (a_part_find->totalparts == -1) {
- a_part_find->totalparts = maxparts;
- }
- }
- }
- for (a_part_find = part_find;
- a_part_find->next != NULL;
- a_part_find=a_part_find->next) {
- }
- /* merge part_find to *output_find */
- a_part_find->next = *output_find;
- *output_find = part_find;
- part_find = NULL;
- maxparts = -1;
- }
-
+ g_hash_table_destroy(valid_label);
afclose(logf);
amfree(datestamp);
amfree(current_label);
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;
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)) &&
+ (!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"))) {
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;
break;
}
}
+
+ amfree(zeropad_ts);
}
return(matches);