Exemplo n.º 1
0
Arquivo: find.c Projeto: hangie/amanda
/* Returns TRUE if the given logfile mentions the given tape. */
static gboolean logfile_has_tape(char * label, char * datestamp,
                                 char * logfile) {
    FILE * logf;
    char * ck_datestamp, *ck_label = NULL;
    if((logf = fopen(logfile, "r")) == NULL) {
	error(_("could not open logfile %s: %s"), logfile, strerror(errno));
	/*NOTREACHED*/
    }

    while(get_logline(logf)) {
	if(curlog == L_START && curprog == P_TAPER) {
	    if(parse_taper_datestamp_log(curstr,
					 &ck_datestamp, &ck_label) == 0) {
		g_printf(_("strange log line \"start taper %s\" curstr='%s'\n"),
                         logfile, curstr);
	    } else if(g_str_equal(ck_datestamp, datestamp)
		      && g_str_equal(ck_label, label)) {
		amfree(ck_label);
                afclose(logf);
                return TRUE;
	    }
	    amfree(ck_label);
	}
    }

    afclose(logf);
    return FALSE;
}
Exemplo n.º 2
0
int
main(
    int		argc,
    char **	argv)
{
    char *logfname;
    char *conf_logdir;
    FILE *logfile;
    config_overrides_t *cfg_ovr = NULL;
    char *cfg_opt = NULL;

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */  
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda"); 

    safe_fd(-1, 0);

    set_pname("amlogroll");

    dbopen(DBG_SUBDIR_SERVER);

    add_amanda_log_handler(amanda_log_stderr);

    /* Process options */
    cfg_ovr = extract_commandline_config_overrides(&argc, &argv);

    if (argc >= 2) {
	cfg_opt = argv[1];
    }

    /* read configuration files */

    set_config_overrides(cfg_ovr);
    config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, cfg_opt);

    if (config_errors(NULL) >= CFGERR_WARNINGS) {
	config_print_errors();
	if (config_errors(NULL) >= CFGERR_ERRORS) {
	    g_critical(_("errors processing config file"));
	}
    }

    safe_cd(); /* must happen after config_init */

    check_running_as(RUNNING_AS_DUMPUSER);

    dbrename(get_config_name(), DBG_SUBDIR_SERVER);

    conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR));
    logfname = vstralloc(conf_logdir, "/", "log", NULL);
    amfree(conf_logdir);

    if((logfile = fopen(logfname, "r")) == NULL) {
	error(_("could not open log %s: %s"), logfname, strerror(errno));
	/*NOTREACHED*/
    }
    amfree(logfname);

    add_amanda_log_handler(amanda_log_trace_log);

    while(get_logline(logfile)) {
	if(curlog == L_START) {
	    handle_start();
	    if(datestamp != NULL) {
		break;
	    }
	}
    }
    afclose(logfile);
 
    log_rename(datestamp);

    amfree(datestamp);

    dbclose();

    return 0;
}
Exemplo n.º 3
0
Arquivo: find.c Projeto: hangie/amanda
/* WARNING: Function accesses globals find_diskqp, curlog, curlog, curstr,
 * dynamic_disklist */
gboolean
search_logfile(
    find_result_t **output_find,
    const char *label,
    const char *passed_datestamp,
    const char *logfile,
    disklist_t * dynamic_disklist)
{
    FILE *logf;
    char *host, *host_undo;
    char *disk = NULL, *qdisk, *disk_undo;
    char *date, *date_undo;
    int  partnum;
    int  totalparts;
    int  maxparts = -1;
    char *number;
    int fileno;
    char *current_label;
    char *rest, *rest_undo;
    char *ck_label=NULL;
    int level = 0;
    off_t filenum;
    char *ck_datestamp=NULL;
    char *datestamp;
    char *s;
    int ch;
    disk_t *dp;
    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;
    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);

    current_label = g_strdup("");
    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);

    if((logf = fopen(logfile, "r")) == NULL) {
	error(_("could not open logfile %s: %s"), logfile, strerror(errno));
	/*NOTREACHED*/
    }

    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"),
                         logfile, curstr);
                continue;
	    }
            if (datestamp != NULL) {
                if (!g_str_equal(datestamp, ck_datestamp)) {
                    g_printf(_("Log file %s stamped %s, expecting %s!\n"),
                             logfile, ck_datestamp, datestamp);
		    amfree(ck_label);
                    break;
                }
            }

            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;
	    }
            amfree(current_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) &&
	    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_SUCCESS || curlog == L_CHUNKSUCCESS ||
	    curlog == L_DONE    || curlog == L_FAIL ||
	    curlog == L_CHUNK   || curlog == L_PART || curlog == L_PARTIAL ||
	    curlog == L_PARTPARTIAL ) {
	    s = curstr;
	    ch = *s++;

	    skip_whitespace(s, ch);
	    if(ch == '\0') {
		g_printf(_("strange log line in %s \"%s\"\n"),
		    logfile, curstr);
		continue;
	    }

	    if (curlog == L_PART || curlog == L_PARTPARTIAL) {
		char *part_label;
		char *qpart_label = s - 1;
		taper_part++;
		skip_quoted_string(s, ch);
		s[-1] = '\0';

		part_label = unquote_string(qpart_label);
		if (!g_hash_table_lookup(valid_label, part_label)) {
		    amfree(part_label);
		    continue;
		}
		amfree(current_label);
		current_label = part_label;

		skip_whitespace(s, ch);
		if(ch == '\0') {
		    g_printf("strange log line in %s \"%s\"\n",
			   logfile, curstr);
		    continue;
		}

		number = s - 1;
		skip_non_whitespace(s, ch);
		s[-1] = '\0';
		fileno = atoi(number);
		filenum = fileno;
		if (filenum == 0)
		    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;
	    skip_non_whitespace(s, ch);
	    host_undo = s - 1;
	    *host_undo = '\0';

	    skip_whitespace(s, ch);
	    if(ch == '\0') {
		g_printf(_("strange log line in %s \"%s\"\n"),
		    logfile, curstr);
		continue;
	    }
	    qdisk = s - 1;
	    skip_quoted_string(s, ch);
	    disk_undo = s - 1;
	    *disk_undo = '\0';
	    disk = unquote_string(qdisk);

	    skip_whitespace(s, ch);
	    if(ch == '\0') {
		g_printf(_("strange log line in %s \"%s\"\n"),
                         logfile, curstr);
		amfree(disk);
		continue;
	    }
	    date = s - 1;
	    skip_non_whitespace(s, ch);
	    date_undo = s - 1;
	    *date_undo = '\0';

	    if(strlen(date) < 3) { /* old log didn't have datestamp */
		level = atoi(date);
		date = datestamp;
		partnum = 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);
		    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);
		}
		if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
		    g_printf(_("Fstrange log line in %s \"%s\"\n"),
		    logfile, s-1);
		    amfree(disk);
		    continue;
		}
		skip_integer(s, ch);
	    }

	    skip_whitespace(s, ch);
	    if(ch == '\0') {
		g_printf(_("strange log line in %s \"%s\"\n"),
		    logfile, curstr);
		amfree(disk);
		continue;
	    }
	    rest = s - 1;
	    skip_non_whitespace(s, ch);
	    rest_undo = s - 1;
	    *rest_undo = '\0';
	    if (g_str_equal(rest, "[sec")) {
		skip_whitespace(s, ch);
		if(ch == '\0') {
		    g_printf(_("strange log line in %s \"%s\"\n"),
			     logfile, curstr);
		    amfree(disk);
		    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 (!g_str_equal(rest, "kb") &&
		    !g_str_equal(rest, "bytes")) {
		    g_printf(_("Bstrange log line in %s \"%s\"\n"),
			     logfile, curstr);
		    amfree(disk);
		    continue;
		}

		skip_whitespace(s, ch);
		if (ch == '\0') {
		     g_printf(_("strange log line in %s \"%s\"\n"),
			      logfile, curstr);
		     amfree(disk);
		     continue;
		}
		if (g_str_equal(rest, "kb")) {
		    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 (!g_str_equal(rest, "kps")) {
		    g_printf(_("Cstrange log line in %s \"%s\"\n"),
			     logfile, curstr);
		    amfree(disk);
		    continue;
		}

		skip_whitespace(s, ch);
		if (ch == '\0') {
		    g_printf(_("strange log line in %s \"%s\"\n"),
			     logfile, curstr);
		    amfree(disk);
		    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 (!g_str_equal(rest, "orig-kb")) {
		    orig_kb = 0;
		} else {

		    skip_whitespace(s, ch);
		    if(ch == '\0') {
			g_printf(_("strange log line in %s \"%s\"\n"),
				 logfile, curstr);
			amfree(disk);
			continue;
		    }
		    orig_kb = atof(s - 1);
		}
	    } else {
		sec = 0;
		kb = 0;
		bytes = 0;
		orig_kb = 0;
		*rest_undo = ' ';
	    }

	    if (g_str_has_prefix(rest, "error")) rest += 6;
	    if (g_str_has_prefix(rest, "config")) rest += 7;

	    dp = lookup_disk(host,disk);
	    if ( dp == NULL ) {
		if (dynamic_disklist == NULL) {
		    amfree(disk);
		    continue;
		}
		dp = add_disk(dynamic_disklist, host, disk);
		enqueue_disk(dynamic_disklist, dp);
	    }
            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);
		    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=g_string_chunk_insert_const(string_chunk, current_label);
		    new_output_find->status=NULL;
		    new_output_find->dump_status=NULL;
		    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 = "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;
                        found_something = TRUE;
		    } else if (curlog == L_CHUNKSUCCESS || curlog == L_DONE ||
			       curlog == L_PARTIAL      || curlog == L_FAIL) {
			/* result line */
			if (curlog == L_PARTIAL || curlog == L_FAIL) {
			    /* set dump_status of each part */
			    for (a_part_find = part_find;
				 a_part_find;
				 a_part_find = a_part_find->next) {
				if (curlog == L_PARTIAL)
				    a_part_find->dump_status = "PARTIAL";
				else {
				    a_part_find->dump_status = "FAIL";
				    a_part_find->message = g_string_chunk_insert_const(string_chunk, rest);
				}
			    }
			} else {
			    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;
				     a_part_find = a_part_find->next) {
				    if (a_part_find->partnum == num_part &&
					g_str_equal(a_part_find->status, "OK"))
					num_part--;
			        }
				/* set dump_status of each part */
				for (a_part_find = part_find;
				     a_part_find;
				     a_part_find = a_part_find->next) {
				    if (num_part == 0) {
					a_part_find->dump_status = "OK";
				    } else {
					a_part_find->dump_status = "FAIL";
					a_part_find->message =
						g_string_chunk_insert_const(string_chunk, "Missing part");
				    }
				}
			    }
			}
			if (curlog == L_DONE) {
			    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;
				}
				if (a_part_find->orig_kb == 0) {
				    a_part_find->orig_kb = orig_kb;
				}
			    }
			}
			if (part_find) { /* find last element */
			    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;
                            found_something = TRUE;
			    g_hash_table_remove(part_by_dle, key);
			}
			free_find_result(&new_output_find);
		    } else { /* part line */
			if (curlog == L_PART || curlog == L_CHUNK) {
			    new_output_find->status = "OK";
			    new_output_find->dump_status = "OK";
			} else { /* PARTPARTIAL */
			    new_output_find->status = "PARTIAL";
			    new_output_find->dump_status = "PARTIAL";
			}
			/* Add to part_find list */
			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) {
		    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 = g_string_chunk_insert_const(string_chunk, date);
		    new_output_find->write_timestamp = g_strdup("00000000000000"); /* dump was not written.. */
		    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;
		    new_output_find->totalparts=totalparts;
		    new_output_find->filenum=0;
		    new_output_find->sec=sec;
		    new_output_find->kb=kb;
		    new_output_find->bytes=bytes;
		    new_output_find->orig_kb=orig_kb;
		    status_failed = g_strjoin(NULL, 
			 "FAILED (",
			 program_str[(int)curprog],
			 ") ",
			 rest,
			 NULL);
		    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;
		}
	    }
	    amfree(disk);
	}
    }

    g_hash_table_destroy(valid_label);
    afclose(logf);
    amfree(datestamp);
    amfree(current_label);
    amfree(disk);

    return found_something;
}