X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Ffind.c;h=6891d00539a5e1c84a4a6b4028ffc94483f0a138;hb=d28952249e392eb31bc8eecc53f6c477f30c617b;hp=dadbd5738ba0f7b6d844f25d5816ad13177f7ce6;hpb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;p=debian%2Famanda diff --git a/server-src/find.c b/server-src/find.c index dadbd57..6891d00 100644 --- a/server-src/find.c +++ b/server-src/find.c @@ -1,6 +1,7 @@ /* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1998 University of Maryland at College Park + * Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved. * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its @@ -40,13 +41,15 @@ #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, char * logfile); static char *find_sort_order = NULL; +static GStringChunk *string_chunk = NULL; find_result_t * find_dump(disklist_t* diskqp) { char *conf_logdir, *logfile = NULL; @@ -56,6 +59,9 @@ find_result_t * find_dump(disklist_t* diskqp) { find_result_t *output_find = NULL; gboolean *tape_seen = NULL; + if (string_chunk == NULL) { + string_chunk = g_string_chunk_new(32768); + } conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); maxtape = lookup_nb_tape(); tape_seen = g_new0(gboolean, maxtape+1); @@ -224,6 +230,10 @@ search_holding_disk( holding_file_list = holding_get_files(NULL, 1); + if (string_chunk == NULL) { + string_chunk = g_string_chunk_new(32768); + } + for(e = holding_file_list; e != NULL; e = e->next) { dumpfile_t file; @@ -262,24 +272,26 @@ search_holding_disk( if(find_match(file.name,file.disk)) { 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->timestamp = g_string_chunk_insert_const(string_chunk, file.datestamp); + new_output_find->write_timestamp = g_string_chunk_insert_const(string_chunk, "00000000000000"); + new_output_find->hostname = g_string_chunk_insert_const(string_chunk, file.name); + new_output_find->diskname = g_string_chunk_insert_const(string_chunk, file.disk); new_output_find->level=file.dumplevel; - new_output_find->label=stralloc(holding_file); + new_output_find->label=g_string_chunk_insert_const(string_chunk, holding_file); new_output_find->partnum = -1; new_output_find->totalparts = -1; new_output_find->filenum=0; if (file.is_partial) { - new_output_find->status=stralloc("PARTIAL"); - new_output_find->dump_status=stralloc("PARTIAL"); + new_output_find->status="PARTIAL"; + new_output_find->dump_status="PARTIAL"; } else { - new_output_find->status=stralloc("OK"); - new_output_find->dump_status=stralloc("OK"); + new_output_find->status="OK"; + new_output_find->dump_status="OK"; } - new_output_find->message=stralloc(""); + new_output_find->message=""; new_output_find->kb = holding_file_size(holding_file, 1); + new_output_find->bytes = 0; + new_output_find->orig_kb = file.orig_size; *output_find=new_output_find; @@ -287,7 +299,7 @@ search_holding_disk( dumpfile_free_data(&file); } - g_slist_free_full(holding_file_list); + slist_free_full(holding_file_list, g_free); } static int @@ -402,10 +414,9 @@ print_find_result( 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; @@ -413,16 +424,12 @@ print_find_result( 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) { - char *qlabel = quote_string(output_find_result->label); - len=strlen(qlabel); - amfree(qlabel); + len = len_quote_string(output_find_result->label); if((int)len > max_len_label) max_len_label = (int)len; } @@ -517,14 +524,6 @@ free_find_result( output_find_result; 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); - amfree(output_find_result->status); - amfree(output_find_result->dump_status); - amfree(output_find_result->message); prev = output_find_result; } amfree(prev); @@ -540,7 +539,7 @@ find_match( return (dp && dp->todo); } -char * +static char * find_nicedate( char *datestamp) { @@ -576,6 +575,17 @@ find_nicedate( 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, @@ -617,9 +627,10 @@ parse_taper_datestamp_log( return 0; } *label = s - 1; - skip_non_whitespace(s, ch); + skip_quoted_string(s, ch); s[-1] = '\0'; + *label = unquote_string(*label); return 1; } @@ -627,7 +638,7 @@ parse_taper_datestamp_log( static gboolean logfile_has_tape(char * label, char * datestamp, char * logfile) { FILE * logf; - char * ck_datestamp, *ck_label; + char * ck_datestamp, *ck_label = NULL; if((logf = fopen(logfile, "r")) == NULL) { error(_("could not open logfile %s: %s"), logfile, strerror(errno)); /*NOTREACHED*/ @@ -641,9 +652,11 @@ static gboolean logfile_has_tape(char * label, char * datestamp, logfile, curstr); } else if(strcmp(ck_datestamp, datestamp) == 0 && strcmp(ck_label, label) == 0) { + amfree(ck_label); afclose(logf); return TRUE; } + amfree(ck_label); } } @@ -695,11 +708,12 @@ search_logfile( 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 *ck_datestamp, *datestamp; + char *ck_datestamp=NULL; + char *datestamp; char *s; int ch; disk_t *dp; @@ -709,17 +723,18 @@ search_logfile( 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 bytes; 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); + if (string_chunk == NULL) { + string_chunk = g_string_chunk_new(32768); + } 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); @@ -732,6 +747,8 @@ search_logfile( filenum = (off_t)0; while(get_logline(logf)) { if (curlog == L_START && curprog == P_TAPER) { + amfree(ck_label); + ck_datestamp = NULL; if(parse_taper_datestamp_log(curstr, &ck_datestamp, &ck_label) == 0) { g_printf(_("strange log line in %s \"start taper %s\"\n"), @@ -742,6 +759,7 @@ search_logfile( if (strcmp(datestamp, ck_datestamp) != 0) { g_printf(_("Log file %s stamped %s, expecting %s!\n"), logfile, ck_datestamp, datestamp); + amfree(ck_label); break; } } @@ -755,12 +773,15 @@ search_logfile( found_something = TRUE; } amfree(current_label); - current_label = g_strdup(ck_label); + current_label = ck_label; + ck_label = NULL; if (datestamp == NULL) { datestamp = g_strdup(ck_datestamp); } filenum = (off_t)0; } + if (!datestamp) + continue; if (right_label && (curlog == L_SUCCESS || curlog == L_CHUNK || curlog == L_PART || curlog == L_PARTPARTIAL) && @@ -787,15 +808,19 @@ search_logfile( } if (curlog == L_PART || curlog == L_PARTPARTIAL) { - char * part_label = s - 1; + char *part_label; + char *qpart_label = s - 1; taper_part++; - skip_non_whitespace(s, ch); + skip_quoted_string(s, ch); s[-1] = '\0'; - if (!g_hash_table_lookup(valid_label, part_label)) + part_label = unquote_string(qpart_label); + if (!g_hash_table_lookup(valid_label, part_label)) { + amfree(part_label); continue; + } amfree(current_label); - current_label = stralloc(part_label); + current_label = part_label; skip_whitespace(s, ch); if(ch == '\0') { @@ -854,26 +879,37 @@ search_logfile( level = atoi(date); date = stralloc(datestamp); partnum = 1; - totalparts =1; + totalparts = 1; } else { if (curprog == P_TAPER && (curlog == L_CHUNK || curlog == L_PART || curlog == L_PARTPARTIAL || curlog == L_PARTIAL || curlog == L_DONE)) { + char *s1, ch1; skip_whitespace(s, ch); number = s - 1; skip_non_whitespace(s, ch); - s[-1] = '\0'; - sscanf(number, "%d/%d", &partnum, &totalparts); - if (partnum > maxparts) - maxparts = partnum; - if (totalparts > maxparts) - maxparts = totalparts; + s1 = &s[-1]; + ch1 = *s1; + skip_whitespace(s, ch); + if (*(s-1) != '[') { + *s1 = ch1; + sscanf(number, "%d/%d", &partnum, &totalparts); + if (partnum > maxparts) + maxparts = partnum; + if (totalparts > maxparts) + maxparts = totalparts; + } else { /* nparts is not in all PARTIAL lines */ + partnum = 1; + totalparts = 1; + s = number + 1; + } + } else { + skip_whitespace(s, ch); } - skip_whitespace(s, ch); if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) { - g_printf(_("strange log line in %s \"%s\"\n"), - logfile, curstr); + g_printf(_("Fstrange log line in %s \"%s\"\n"), + logfile, s-1); continue; } skip_integer(s, ch); @@ -886,69 +922,90 @@ search_logfile( 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 { - regfree(®ex); - bzero(®ex, sizeof(regex)); - /* the .* at the end of this captures the old {wr: .. } statistics */ - 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 && + strcmp(rest, "bytes") != 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; + } + if (strcmp(rest, "kb") == 0) { + kb = atof(s - 1); + bytes = 0; + } else { + bytes = atof(s - 1); + kb = bytes / 1024; + } + 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; + bytes = 0; + orig_kb = 0; + *rest_undo = ' '; } - if (strncmp(rest, "error ", 6) == 0) rest += 6; - if (strncmp(rest, "config ", 7) == 0) rest += 7; - 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 ) { @@ -965,25 +1022,37 @@ search_logfile( 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); + maxparts = partnum; + if (maxparts < totalparts) + maxparts = totalparts; + for (a_part_find = part_find; + a_part_find; + a_part_find = a_part_find->next) { + if (maxparts < a_part_find->partnum) + maxparts = a_part_find->partnum; + if (maxparts < a_part_find->totalparts) + maxparts = a_part_find->totalparts; + } + new_output_find->timestamp = g_string_chunk_insert_const(string_chunk, date); + new_output_find->write_timestamp = g_string_chunk_insert_const(string_chunk, datestamp); + new_output_find->hostname=g_string_chunk_insert_const(string_chunk, host); + new_output_find->diskname=g_string_chunk_insert_const(string_chunk, disk); new_output_find->level=level; new_output_find->partnum = partnum; new_output_find->totalparts = totalparts; - new_output_find->label=stralloc(current_label); + new_output_find->label=g_string_chunk_insert_const(string_chunk, current_label); new_output_find->status=NULL; new_output_find->dump_status=NULL; - new_output_find->message=stralloc(""); + new_output_find->message=""; new_output_find->filenum=filenum; new_output_find->sec=sec; new_output_find->kb=kb; + new_output_find->bytes=bytes; new_output_find->orig_kb=orig_kb; new_output_find->next=NULL; if (curlog == L_SUCCESS) { - new_output_find->status = stralloc("OK"); - new_output_find->dump_status = stralloc("OK"); + new_output_find->status = "OK"; + new_output_find->dump_status = "OK"; new_output_find->next = *output_find; new_output_find->partnum = 1; /* L_SUCCESS is pre-splitting */ *output_find = new_output_find; @@ -996,13 +1065,11 @@ search_logfile( 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) - a_part_find->dump_status = stralloc("PARTIAL"); + a_part_find->dump_status = "PARTIAL"; else { - a_part_find->dump_status = stralloc("FAIL"); - amfree(a_part_find->message); - a_part_find->message = stralloc(rest); + a_part_find->dump_status = "FAIL"; + a_part_find->message = g_string_chunk_insert_const(string_chunk, rest); } } } else { @@ -1020,16 +1087,12 @@ search_logfile( 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) { - a_part_find->dump_status = - stralloc("OK"); + a_part_find->dump_status = "OK"; } else { - a_part_find->dump_status = - stralloc("FAIL"); - amfree(a_part_find->message); + a_part_find->dump_status = "FAIL"; a_part_find->message = - stralloc("Missing part"); + g_string_chunk_insert_const(string_chunk, "Missing part"); } } } @@ -1062,11 +1125,11 @@ search_logfile( free_find_result(&new_output_find); } else { /* part line */ if (curlog == L_PART || curlog == L_CHUNK) { - new_output_find->status=stralloc("OK"); - new_output_find->dump_status=stralloc("OK"); + new_output_find->status = "OK"; + new_output_find->dump_status = "OK"; } else { /* PARTPARTIAL */ - new_output_find->status=stralloc("PARTIAL"); - new_output_find->dump_status=stralloc("PARTIAL"); + new_output_find->status = "PARTIAL"; + new_output_find->dump_status = "PARTIAL"; } /* Add to part_find list */ if (part_find) { @@ -1083,16 +1146,17 @@ search_logfile( amfree(key); } else if(curlog == L_FAIL) { + char *status_failed; /* print other failures too -- this is a hack to ensure that failures which * did not make it to tape are also listed in the output of 'amadmin x find'; * 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->timestamp = stralloc(date); + new_output_find->timestamp = g_string_chunk_insert_const(string_chunk, 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->hostname=g_string_chunk_insert_const(string_chunk, host); + new_output_find->diskname=g_string_chunk_insert_const(string_chunk, disk); new_output_find->level=level; new_output_find->label=NULL; new_output_find->partnum=partnum; @@ -1100,15 +1164,18 @@ search_logfile( new_output_find->filenum=0; new_output_find->sec=sec; new_output_find->kb=kb; - new_output_find->kb=orig_kb; - new_output_find->status=vstralloc( + new_output_find->bytes=bytes; + new_output_find->orig_kb=orig_kb; + status_failed = vstralloc( "FAILED (", program_str[(int)curprog], ") ", rest, NULL); - new_output_find->dump_status=stralloc(""); - new_output_find->message=stralloc(""); + new_output_find->status = g_string_chunk_insert_const(string_chunk, status_failed); + amfree(status_failed); + new_output_find->dump_status=""; + new_output_find->message=""; *output_find=new_output_find; found_something = TRUE; maxparts = -1; @@ -1162,19 +1229,20 @@ dumps_match( 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->timestamp = cur_result->timestamp; + curmatch->write_timestamp = cur_result->write_timestamp; + curmatch->hostname = cur_result->hostname; + curmatch->diskname = cur_result->diskname; curmatch->level = cur_result->level; - curmatch->label = cur_result->label? stralloc(cur_result->label) : NULL; + curmatch->label = cur_result->label? cur_result->label : NULL; curmatch->filenum = cur_result->filenum; curmatch->sec = cur_result->sec; curmatch->kb = cur_result->kb; + curmatch->bytes = cur_result->bytes; 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->status = cur_result->status; + curmatch->dump_status = cur_result->dump_status; + curmatch->message = cur_result->message; curmatch->partnum = cur_result->partnum; curmatch->totalparts = cur_result->totalparts; curmatch->next = matches; @@ -1240,16 +1308,16 @@ dumps_match_dumpspecs( 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->timestamp = cur_result->timestamp; + curmatch->write_timestamp = cur_result->write_timestamp; + curmatch->hostname = cur_result->hostname; + curmatch->diskname = cur_result->diskname; curmatch->level = cur_result->level; - curmatch->label = cur_result->label? stralloc(cur_result->label) : NULL; + curmatch->label = cur_result->label? 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->status = cur_result->status; + curmatch->dump_status = cur_result->dump_status; + curmatch->message = cur_result->message; curmatch->partnum = cur_result->partnum; curmatch->totalparts = cur_result->totalparts;