Imported Upstream version 2.5.1
[debian/amanda] / server-src / find.c
index 2f8c950f062b68bdbd84069911f6ad0cb3087463..5a9310f6bb1211f8958f289ab1f1d84987d19a43 100644 (file)
@@ -25,7 +25,7 @@
  *                        University of Maryland at College Park
  */
 /*
- * $Id: find.c,v 1.23 2006/01/15 21:01:00 martinea Exp $
+ * $Id: find.c,v 1.33 2006/07/06 13:13:15 martinea Exp $
  *
  * controlling process for the Amanda backup system
  */
 #include "holding.h"
 #include "find.h"
 
-void find P((int argc, char **argv));
-int find_match P((char *host, char *disk));
-int search_logfile P((find_result_t **output_find, char *label, int datestamp, int datestamp_aux, char *logfile));
-void search_holding_disk P((find_result_t **output_find));
-void strip_failed_chunks P((find_result_t *output_find));
-char *find_nicedate P((int datestamp));
-static int find_compare P((const void *, const void *));
-static int parse_taper_datestamp_log P((char *, int *, char **));
+int find_match(char *host, char *disk);
+int search_logfile(find_result_t **output_find, char *label, char *datestamp, char *logfile);
+void search_holding_disk(find_result_t **output_find);
+void strip_failed_chunks(find_result_t **output_find);
+char *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 int seen_chunk_of(find_result_t *output_find, char *date, char *host, char *disk, int level);
 
 static char *find_sort_order = NULL;
 int dynamic_disklist = 0;
 disklist_t* find_diskqp = NULL;
 
-find_result_t *find_dump(dyna_disklist, diskqp)
-int dyna_disklist;
-disklist_t* diskqp;
+find_result_t *
+find_dump(
+    int dyna_disklist,
+    disklist_t* diskqp)
 {
     char *conf_logdir, *logfile = NULL;
-    int tape, maxtape, seq, logs;
+    int tape, maxtape, logs;
+    unsigned seq;
     tape_t *tp;
     find_result_t *output_find = NULL;
 
@@ -69,11 +71,9 @@ disklist_t* diskqp;
     maxtape = lookup_nb_tape();
 
     for(tape = 1; tape <= maxtape; tape++) {
-       char ds_str[NUM_STR_SIZE];
 
        tp = lookup_tapepos(tape);
        if(tp == NULL) continue;
-       snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
 
        /* search log files */
 
@@ -84,28 +84,28 @@ disklist_t* diskqp;
        for(seq = 0; 1; seq++) {
            char seq_str[NUM_STR_SIZE];
 
-           snprintf(seq_str, sizeof(seq_str), "%d", seq);
+           snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
            logfile = newvstralloc(logfile,
-                       conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+                       conf_logdir, "/log.", tp->datestamp, ".", seq_str, NULL);
            if(access(logfile, R_OK) != 0) break;
-           logs += search_logfile(&output_find, tp->label, tp->datestamp, seq, logfile);
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
        }
 
        /* search old-style amflush log, if any */
 
        logfile = newvstralloc(logfile,
-                              conf_logdir, "/log.", ds_str, ".amflush", NULL);
+                              conf_logdir, "/log.", tp->datestamp, ".amflush", NULL);
        if(access(logfile,R_OK) == 0) {
-           logs += search_logfile(&output_find, tp->label, tp->datestamp, 1000, logfile);
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
        }
 
        /* search old-style main log, if any */
 
-       logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+       logfile = newvstralloc(logfile, conf_logdir, "/log.", tp->datestamp, NULL);
        if(access(logfile,R_OK) == 0) {
-           logs += search_logfile(&output_find, tp->label, tp->datestamp, -1, logfile);
+           logs += search_logfile(&output_find, tp->label, tp->datestamp, logfile);
        }
-       if(logs == 0 && tp->datestamp != 0)
+       if(logs == 0 && strcmp(tp->datestamp,"0") != 0)
            printf("Warning: no log files found for tape %s written %s\n",
                   tp->label, find_nicedate(tp->datestamp));
     }
@@ -114,15 +114,17 @@ disklist_t* diskqp;
 
     search_holding_disk(&output_find);
 
-    strip_failed_chunks(output_find);
+    strip_failed_chunks(&output_find);
     
     return(output_find);
 }
 
-char **find_log()
+char **
+find_log(void)
 {
     char *conf_logdir, *logfile = NULL;
-    int tape, maxtape, seq, logs;
+    int tape, maxtape, logs;
+    unsigned seq;
     tape_t *tp;
     char **output_find_log = NULL;
     char **current_log;
@@ -135,15 +137,13 @@ char **find_log()
     }
     maxtape = lookup_nb_tape();
 
-    output_find_log = alloc((maxtape*5+10) * sizeof(char *));
+    output_find_log = alloc((maxtape*5+10) * SIZEOF(char *));
     current_log = output_find_log;
 
     for(tape = 1; tape <= maxtape; tape++) {
-       char ds_str[NUM_STR_SIZE];
 
        tp = lookup_tapepos(tape);
        if(tp == NULL) continue;
-       snprintf(ds_str, sizeof(ds_str), "%d", tp->datestamp);
 
        /* search log files */
 
@@ -154,12 +154,12 @@ char **find_log()
        for(seq = 0; 1; seq++) {
            char seq_str[NUM_STR_SIZE];
 
-           snprintf(seq_str, sizeof(seq_str), "%d", seq);
+           snprintf(seq_str, SIZEOF(seq_str), "%u", seq);
            logfile = newvstralloc(logfile,
-                       conf_logdir, "/log.", ds_str, ".", seq_str, NULL);
+                       conf_logdir, "/log.", tp->datestamp, ".", seq_str, NULL);
            if(access(logfile, R_OK) != 0) break;
-           if( search_logfile(NULL, tp->label, tp->datestamp, seq, logfile)) {
-               *current_log = vstralloc("log.", ds_str, ".", seq_str, NULL);
+           if( search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+               *current_log = vstralloc("log.", tp->datestamp, ".", seq_str, NULL);
                current_log++;
                logs++;
                break;
@@ -169,10 +169,10 @@ char **find_log()
        /* search old-style amflush log, if any */
 
        logfile = newvstralloc(logfile,
-                              conf_logdir, "/log.", ds_str, ".amflush", NULL);
+                              conf_logdir, "/log.", tp->datestamp, ".amflush", NULL);
        if(access(logfile,R_OK) == 0) {
-           if( search_logfile(NULL, tp->label, tp->datestamp, 1000, logfile)) {
-               *current_log = vstralloc("log.", ds_str, ".amflush", NULL);
+           if( search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+               *current_log = vstralloc("log.", tp->datestamp, ".amflush", NULL);
                current_log++;
                logs++;
            }
@@ -180,15 +180,15 @@ char **find_log()
 
        /* search old-style main log, if any */
 
-       logfile = newvstralloc(logfile, conf_logdir, "/log.", ds_str, NULL);
+       logfile = newvstralloc(logfile, conf_logdir, "/log.", tp->datestamp, NULL);
        if(access(logfile,R_OK) == 0) {
-           if(search_logfile(NULL, tp->label, tp->datestamp, -1, logfile)) {
-               *current_log = vstralloc("log.", ds_str, NULL);
+           if(search_logfile(NULL, tp->label, tp->datestamp, logfile)) {
+               *current_log = vstralloc("log.", tp->datestamp, NULL);
                current_log++;
                logs++;
            }
        }
-       if(logs == 0 && tp->datestamp != 0)
+       if(logs == 0 && strcmp(tp->datestamp,"0") != 0)
            printf("Warning: no log files found for tape %s written %s\n",
                   tp->label, find_nicedate(tp->datestamp));
     }
@@ -201,21 +201,21 @@ char **find_log()
 /*
  * Remove CHUNK entries from dumps that ultimately failed from our report.
  */
-void strip_failed_chunks(output_find)
-find_result_t *output_find;
+void strip_failed_chunks(
+    find_result_t **output_find)
 {
     find_result_t *cur, *prev = NULL, *failed = NULL, *failures = NULL;
 
     /* Generate a list of failures */
-    for(cur=output_find; cur; cur=cur->next) {
-       if(!cur->hostname || !cur->diskname) continue;
+    for(cur=*output_find; cur; cur=cur->next) {
+       if(!cur->hostname  || !cur->diskname ||
+          !cur->timestamp || !cur->label)
+           continue;
 
        if(strcmp(cur->status, "OK")){
-           failed = alloc(sizeof(find_result_t));
-           memcpy(failed, cur, sizeof(find_result_t));
+           failed = alloc(SIZEOF(find_result_t));
+           memcpy(failed, cur, SIZEOF(find_result_t));
            failed->next = failures;
-           failed->diskname = stralloc(cur->diskname);
-           failed->hostname = stralloc(cur->hostname);
            failures = failed;
        }
     }
@@ -223,45 +223,54 @@ find_result_t *output_find;
     /* Now if a CHUNK matches the parameters of a failed dump, remove it */
     for(failed=failures; failed; failed=failed->next) {
        prev = NULL;
-       for(cur=output_find; cur; cur=cur->next) {
-           if(!cur->hostname || !cur->diskname ||
-                 !strcmp(cur->partnum, "--") || strcmp(cur->status, "OK")){
+       cur = *output_find;
+       while (cur != NULL) {
+           find_result_t *next = cur->next;
+           if(!cur->hostname  || !cur->diskname || 
+              !cur->timestamp || !cur->label    || !cur->partnum ||
+              !strcmp(cur->partnum, "--") || strcmp(cur->status, "OK")) {
                prev = cur;
-               continue;
+               cur = next;
            }
-
-           if(!strcmp(cur->hostname, failed->hostname) &&
+           else if(!strcmp(cur->hostname, failed->hostname) &&
                 !strcmp(cur->diskname, failed->diskname) &&
-                cur->datestamp == failed->datestamp &&
-                cur->datestamp_aux == failed->datestamp_aux &&
+                !strcmp(cur->timestamp, failed->timestamp) &&
+                !strcmp(cur->label, failed->label) &&
                 cur->level == failed->level){
-               find_result_t *next = cur->next;
                amfree(cur->diskname);
                amfree(cur->hostname);
-               next = cur->next;
-               amfree(cur);
-               if(prev){
+               amfree(cur->label);
+               amfree(cur->timestamp);
+               amfree(cur->partnum);
+               amfree(cur->status);
+               cur = next;
+               if (prev) {
+                   amfree(prev->next);
                    prev->next = next;
-                   cur = prev;
+               } else {
+                   amfree(*output_find);
+                   *output_find = next;
                }
-               else output_find = next;
            }
-            else prev = cur;
+            else {
+               prev = cur;
+               cur = next;
+           }
+
        }
     }
 
     for(failed=failures; failed;) {
        find_result_t *fai = failed->next;
-       amfree(failed->diskname);
-       amfree(failed->hostname);
        fai = failed->next;
        amfree(failed);
        failed=fai;
     }
 }
 
-void search_holding_disk(output_find)
-find_result_t **output_find;
+void
+search_holding_disk(
+    find_result_t **output_find)
 {
     holdingdisk_t *hdisk;
     sl_t  *holding_list;
@@ -272,15 +281,19 @@ find_result_t **output_find;
     char *diskname = NULL;
     DIR *workdir;
     struct dirent *entry;
-    int level;
+    int level = 0;
     disk_t *dp;
+    int fd;
+    ssize_t result;
+    char buf[DISK_BLOCK_BYTES];
+    dumpfile_t file;
 
     holding_list = pick_all_datestamp(1);
 
     for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next) {
        for(dir = holding_list->first; dir != NULL; dir = dir->next) {
            sdirname = newvstralloc(sdirname,
-                                   hdisk->diskdir, "/", dir->name,
+                                   holdingdisk_get_diskdir(hdisk), "/", dir->name,
                                    NULL);
            if((workdir = opendir(sdirname)) == NULL) {
                continue;
@@ -303,6 +316,21 @@ find_result_t **output_find;
                }
                if(level < 0 || level > 9)
                    continue;
+               if ((fd = open(destname, O_RDONLY)) == -1) {
+                   continue;
+               }
+               if((result = read(fd, &buf, DISK_BLOCK_BYTES)) <= 0) {
+                   continue;
+               }
+               close(fd);
+
+               parse_file_header(buf, &file, (size_t)result);
+               if (strcmp(file.name, hostname) != 0 ||
+                   strcmp(file.disk, diskname) != 0 ||
+                   file.dumplevel != level ||
+                   !match_datestamp(file.datestamp, dir->name)) {
+                   continue;
+               }
 
                dp = NULL;
                for(;;) {
@@ -319,23 +347,9 @@ find_result_t **output_find;
 
                if(find_match(hostname,diskname)) {
                    find_result_t *new_output_find =
-                       alloc(sizeof(find_result_t));
+                       alloc(SIZEOF(find_result_t));
                    new_output_find->next=*output_find;
-                   if(strlen(dir->name) == 8) {
-                       new_output_find->datestamp=atoi(dir->name);
-                       new_output_find->timestamp=stralloc2(dir->name, "000000");
-                   }
-                   else if(strlen(dir->name) == 14) {
-                       char *name = stralloc(dir->name);
-                       name[8] = '\0';
-                       new_output_find->datestamp=atoi(name);
-                       new_output_find->timestamp=stralloc(dir->name);
-                       amfree(name);
-                   }
-                   else {
-                       error("Bad date\n");
-                   }
-                   new_output_find->datestamp_aux=1001;
+                   new_output_find->timestamp=stralloc(file.datestamp);
                    new_output_find->hostname=hostname;
                    hostname = NULL;
                    new_output_find->diskname=diskname;
@@ -359,16 +373,17 @@ find_result_t **output_find;
     amfree(diskname);
 }
 
-static int find_compare(i1, j1)
-const void *i1;
-const void *j1;
+static int
+find_compare(
+    const void *i1,
+    const void *j1)
 {
     int compare=0;
     find_result_t **i = (find_result_t **)i1;
     find_result_t **j = (find_result_t **)j1;
 
-    int nb_compare=strlen(find_sort_order);
-    int k;
+    size_t nb_compare=strlen(find_sort_order);
+    size_t k;
 
     for(k=0;k<nb_compare;k++) {
        switch (find_sort_order[k]) {
@@ -380,19 +395,17 @@ const void *j1;
                   break;
        case 'K' : compare=strcmp((*j)->diskname,(*i)->diskname);
                   break;
-       case 'd' : compare=(*i)->datestamp - (*j)->datestamp;
-                  if (compare == 0)
-                       compare = (*i)->datestamp_aux - (*j)->datestamp_aux;
+       case 'd' : compare=strcmp((*i)->timestamp,(*j)->timestamp);
                   break;
-       case 'D' : compare=(*j)->datestamp - (*i)->datestamp;
-                  if (compare == 0)
-                       compare = (*j)->datestamp_aux - (*i)->datestamp_aux;
+       case 'D' : compare=strcmp((*j)->timestamp,(*i)->timestamp);
                   break;
        case 'l' : compare=(*j)->level - (*i)->level;
                   break;
-       case 'f' : compare=(*i)->filenum - (*j)->filenum;
+       case 'f' : compare=((*i)->filenum == (*j)->filenum) ? 0 :
+                          (((*i)->filenum < (*j)->filenum) ? -1 : 1);
                   break;
-       case 'F' : compare=(*j)->filenum - (*i)->filenum;
+       case 'F' : compare=((*j)->filenum == (*i)->filenum) ? 0 :
+                          (((*j)->filenum < (*i)->filenum) ? -1 : 1);
                   break;
        case 'L' : compare=(*i)->level - (*j)->level;
                   break;
@@ -421,14 +434,15 @@ const void *j1;
     return 0;
 }
 
-void sort_find_result(sort_order, output_find)
-char *sort_order;
-find_result_t **output_find;
+void
+sort_find_result(
+    char *sort_order,
+    find_result_t **output_find)
 {
     find_result_t *output_find_result;
     find_result_t **array_find_result = NULL;
-    int nb_result=0;
-    int no_result;
+    size_t nb_result=0;
+    size_t no_result;
 
     find_sort_order = sort_order;
     /* qsort core dump if nothing to sort */
@@ -443,7 +457,7 @@ find_result_t **output_find;
     }
 
     /* put the list in an array */
-    array_find_result=alloc(nb_result * sizeof(find_result_t *));
+    array_find_result=alloc(nb_result * SIZEOF(find_result_t *));
     for(output_find_result=*output_find,no_result=0;
        output_find_result;
        output_find_result=output_find_result->next,no_result++) {
@@ -451,7 +465,7 @@ find_result_t **output_find;
     }
 
     /* sort the array */
-    qsort(array_find_result,nb_result,sizeof(find_result_t *),
+    qsort(array_find_result,nb_result,SIZEOF(find_result_t *),
          find_compare);
 
     /* put the sorted result in the list */
@@ -464,8 +478,9 @@ find_result_t **output_find;
     amfree(array_find_result);
 }
 
-void print_find_result(output_find)
-find_result_t *output_find;
+void
+print_find_result(
+    find_result_t *output_find)
 {
     find_result_t *output_find_result;
     int max_len_datestamp = 4;
@@ -476,29 +491,35 @@ find_result_t *output_find;
     int max_len_filenum   = 4;
     int max_len_part      = 4;
     int max_len_status    = 6;
-    int len;
+    size_t len;
 
     for(output_find_result=output_find;
        output_find_result;
        output_find_result=output_find_result->next) {
 
-       len=strlen(find_nicedate(output_find_result->datestamp));
-       if(len>max_len_datestamp) max_len_datestamp=len;
+       len=strlen(find_nicedate(output_find_result->timestamp));
+       if((int)len > max_len_datestamp)
+           max_len_datestamp=(int)len;
 
        len=strlen(output_find_result->hostname);
-       if(len>max_len_hostname) max_len_hostname=len;
+       if((int)len > max_len_hostname)
+           max_len_hostname = (int)len;
 
        len=strlen(output_find_result->diskname);
-       if(len>max_len_diskname) max_len_diskname=len;
+       if((int)len > max_len_diskname)
+           max_len_diskname = (int)len;
 
        len=strlen(output_find_result->label);
-       if(len>max_len_label) max_len_label=len;
+       if((int)len > max_len_label)
+           max_len_label = (int)len;
 
        len=strlen(output_find_result->status);
-       if(len>max_len_status) max_len_status=len;
+       if((int)len > max_len_status)
+           max_len_status = (int)len;
 
        len=strlen(output_find_result->partnum);
-       if(len>max_len_part) max_len_part=len;
+       if((int)len > max_len_part)
+           max_len_part = (int)len;
     }
 
     /*
@@ -523,24 +544,30 @@ find_result_t *output_find;
         for(output_find_result=output_find;
                output_find_result;
                output_find_result=output_find_result->next) {
+           char *qdiskname;
 
-           printf("%-*s %-*s %-*s %*d %-*s %*d %*s %-*s\n",
+           qdiskname = quote_string(output_find_result->diskname);
+           /*@ignore@*/
+           printf("%-*s %-*s %-*s %*d %-*s %*" OFF_T_RFMT " %*s %-*s\n",
                    max_len_datestamp, 
-                       find_nicedate(output_find_result->datestamp),
+                       find_nicedate(output_find_result->timestamp),
                    max_len_hostname,  output_find_result->hostname,
-                   max_len_diskname,  output_find_result->diskname,
+                   max_len_diskname,  qdiskname,
                    max_len_level,     output_find_result->level,
                    max_len_label,     output_find_result->label,
-                   max_len_filenum,   output_find_result->filenum,
+                   max_len_filenum,   (OFF_T_FMT_TYPE)output_find_result->filenum,
                    max_len_part,      output_find_result->partnum,
                    max_len_status,    output_find_result->status
                    );
+           /*@end@*/
+           amfree(qdiskname);
        }
     }
 }
 
-void free_find_result(output_find)
-find_result_t **output_find;
+void
+free_find_result(
+    find_result_t **output_find)
 {
     find_result_t *output_find_result, *prev;
 
@@ -548,7 +575,8 @@ find_result_t **output_find;
     for(output_find_result=*output_find;
            output_find_result;
            output_find_result=output_find_result->next) {
-       if(prev != NULL) amfree(prev);
+       amfree(prev);
+       amfree(output_find_result->timestamp);
        amfree(output_find_result->hostname);
        amfree(output_find_result->diskname);
        amfree(output_find_result->label);
@@ -557,36 +585,60 @@ find_result_t **output_find;
        amfree(output_find_result->timestamp);
        prev = output_find_result;
     }
-    if(prev != NULL) amfree(prev);
-    output_find = NULL;
+    amfree(prev);
+    *output_find = NULL;
 }
 
-int find_match(host, disk)
-char *host, *disk;
+int
+find_match(
+    char *host,
+    char *disk)
 {
     disk_t *dp = lookup_disk(host,disk);
     return (dp && dp->todo);
 }
 
-char *find_nicedate(datestamp)
-int datestamp;
+char *
+find_nicedate(
+    char *datestamp)
 {
     static char nice[20];
     int year, month, day;
-
-    year  = datestamp / 10000;
-    month = (datestamp / 100) % 100;
-    day   = datestamp % 100;
-
-    snprintf(nice, sizeof(nice), "%4d-%02d-%02d", year, month, day);
+    int hours, minutes, seconds;
+    char date[9], atime[7];
+    int  numdate, numtime;
+
+    strncpy(date, datestamp, 8);
+    date[8] = '\0';
+    numdate = atoi(date);
+    year  = numdate / 10000;
+    month = (numdate / 100) % 100;
+    day   = numdate % 100;
+
+    if(strlen(datestamp) <= 8) {
+       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d",
+               year, month, day);
+    }
+    else {
+       strncpy(atime, &(datestamp[8]), 6);
+       atime[6] = '\0';
+       numtime = atoi(atime);
+       hours = numtime / 10000;
+       minutes = (numtime / 100) % 100;
+       seconds = numtime % 100;
+
+       snprintf(nice, SIZEOF(nice), "%4d-%02d-%02d %02d:%02d:%02d",
+               year, month, day, hours, minutes, seconds);
+    }
 
     return nice;
 }
 
-static int parse_taper_datestamp_log(logline, datestamp, label)
-char *logline;
-int *datestamp;
-char **label;
+static int
+parse_taper_datestamp_log(
+    char *logline,
+    char **datestamp,
+    char **label)
 {
     char *s;
     int ch;
@@ -599,28 +651,30 @@ char **label;
        return 0;
     }
 #define sc "datestamp"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
        return 0;
     }
-    s += sizeof(sc)-1;
+    s += SIZEOF(sc)-1;
     ch = s[-1];
 #undef sc
 
     skip_whitespace(s, ch);
-    if(ch == '\0' || sscanf(s - 1, "%d", datestamp) != 1) {
+    if(ch == '\0') {
        return 0;
     }
-    skip_integer(s, ch);
+    *datestamp = s - 1;
+    skip_non_whitespace(s, ch);
+    s[-1] = '\0';
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
        return 0;
     }
 #define sc "label"
-    if(strncmp(s - 1, sc, sizeof(sc)-1) != 0) {
+    if(strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
        return 0;
     }
-    s += sizeof(sc)-1;
+    s += SIZEOF(sc)-1;
     ch = s[-1];
 #undef sc
 
@@ -640,10 +694,13 @@ char **label;
  * This is so we can interpret the final SUCCESS entry for a split dump as 
  * 'list its parts' instead.  Return 1 if we have, 0 if not.
  */
-int seen_chunk_of(output_find, date, host, disk, level)
-find_result_t *output_find;
-int date, level;
-char *host, *disk;
+int
+seen_chunk_of(
+    find_result_t *output_find,
+    char *date,
+    char *host,
+    char *disk,
+    int level)
 {
     find_result_t *cur;
 
@@ -652,7 +709,7 @@ char *host, *disk;
     for(cur=output_find; cur; cur=cur->next) {
        if(atoi(cur->partnum) < 1 || !cur->hostname || !cur->diskname) continue;
 
-       if(cur->datestamp == date && strcmp(cur->hostname, host) == 0 &&
+       if(strcmp(cur->timestamp, date) == 0 && strcmp(cur->hostname, host) == 0 &&
                strcmp(cur->diskname, disk) == 0 && cur->level == level){
            return(1);
        }
@@ -666,26 +723,33 @@ char *host, *disk;
 /* else                                                                */
 /*     add to output_find all the dump for this label          */
 /*     return the number of dump added.                        */
-int search_logfile(output_find, label, datestamp, datestamp_aux, logfile)
-find_result_t **output_find;
-char *label, *logfile;
-int datestamp, datestamp_aux;
+int
+search_logfile(
+    find_result_t **output_find,
+    char *label,
+    char *datestamp,
+    char *logfile)
 {
     FILE *logf;
     char *host, *host_undo;
-    char *disk, *disk_undo;
+    char *disk, *qdisk, *disk_undo;
+    char *date, *date_undo;
     char *partnum=NULL, *partnum_undo;
-    int   datestampI;
     char *rest;
-    char *ck_label;
-    int level, filenum, ck_datestamp, tapematch;
-    int passlabel, ck_datestamp2;
+    char *ck_label=NULL;
+    int level = 0; 
+    int tapematch;
+    off_t filenum;
+    int passlabel;
+    char *ck_datestamp, *ck_datestamp2;
     char *s;
     int ch;
     disk_t *dp;
 
-    if((logf = fopen(logfile, "r")) == NULL)
+    if((logf = fopen(logfile, "r")) == NULL) {
        error("could not open logfile %s: %s", logfile, strerror(errno));
+       /*NOTREACHED*/
+    }
 
     /* check that this log file corresponds to the right tape */
     tapematch = 0;
@@ -693,8 +757,9 @@ int datestamp, datestamp_aux;
        if(curlog == L_START && curprog == P_TAPER) {
            if(parse_taper_datestamp_log(curstr,
                                         &ck_datestamp, &ck_label) == 0) {
-               printf("strange log line \"start taper %s\"\n", curstr);
-           } else if(ck_datestamp == datestamp
+               printf("strange log line \"start taper %s\" curstr='%s'\n",
+                   logfile, curstr);
+           } else if(strcmp(ck_datestamp, datestamp) == 0
                      && strcmp(ck_label, label) == 0) {
                tapematch = 1;
            }
@@ -714,7 +779,7 @@ int datestamp, datestamp_aux;
        return 0;
     }
 
-    filenum = 0;
+    filenum = (off_t)0;
     passlabel = 1;
     while(get_logline(logf) && passlabel) {
        if((curlog == L_SUCCESS || curlog == L_CHUNK) &&
@@ -724,7 +789,8 @@ int datestamp, datestamp_aux;
        if(curlog == L_START && curprog == P_TAPER) {
            if(parse_taper_datestamp_log(curstr,
                                         &ck_datestamp2, &ck_label) == 0) {
-               printf("strange log line \"start taper %s\"\n", curstr);
+               printf("strange log line in %s \"start taper %s\"\n",
+                   logfile, curstr);
            } else if (strcmp(ck_label, label)) {
                passlabel = !passlabel;
            }
@@ -736,7 +802,8 @@ int datestamp, datestamp_aux;
 
            skip_whitespace(s, ch);
            if(ch == '\0') {
-               printf("strange log line \"%s\"\n", curstr);
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
            host = s - 1;
@@ -746,24 +813,30 @@ int datestamp, datestamp_aux;
 
            skip_whitespace(s, ch);
            if(ch == '\0') {
-               printf("strange log line \"%s\"\n", curstr);
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
-           disk = s - 1;
-           skip_non_whitespace(s, ch);
+           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' || sscanf(s - 1, "%d", &datestampI) != 1) {
-               printf("strange log line \"%s\"\n", curstr);
+           if(ch == '\0') {
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
-           skip_integer(s, ch);
+           date = s - 1;
+           skip_non_whitespace(s, ch);
+           date_undo = s - 1;
+           *date_undo = '\0';
 
-           if(datestampI < 100)  { /* old log didn't have datestamp */
-               level = datestampI;
-               datestampI = datestamp;
+           if(strlen(date) < 3) { /* old log didn't have datestamp */
+               level = atoi(date);
+               date = stralloc(datestamp);
            }
            else {
                if(curlog == L_CHUNK){
@@ -775,7 +848,8 @@ int datestamp, datestamp_aux;
                }
                skip_whitespace(s, ch);
                if(ch == '\0' || sscanf(s - 1, "%d", &level) != 1) {
-                   printf("strange log line \"%s\"\n", curstr);
+                   printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                    continue;
                }
                skip_integer(s, ch);
@@ -783,7 +857,8 @@ int datestamp, datestamp_aux;
 
            skip_whitespace(s, ch);
            if(ch == '\0') {
-               printf("strange log line \"%s\"\n", curstr);
+               printf("strange log line in %s \"%s\"\n",
+                   logfile, curstr);
                continue;
            }
            rest = s - 1;
@@ -800,15 +875,12 @@ int datestamp, datestamp_aux;
                enqueue_disk(find_diskqp, dp);
            }
             if(find_match(host, disk) && (curlog != L_SUCCESS ||
-               !seen_chunk_of(*output_find,datestampI,host,disk,level))){
+               !seen_chunk_of(*output_find, date, host, disk, level))) {
                if(curprog == P_TAPER) {
                    find_result_t *new_output_find =
-                       (find_result_t *)alloc(sizeof(find_result_t));
+                       (find_result_t *)alloc(SIZEOF(find_result_t));
                    new_output_find->next=*output_find;
-                   new_output_find->datestamp=datestampI;
-                   new_output_find->timestamp = alloc(15);
-                   snprintf(new_output_find->timestamp, 15, "%d000000", datestampI);
-                   new_output_find->datestamp_aux=datestamp_aux;
+                   new_output_find->timestamp = stralloc(date);
                    new_output_find->hostname=stralloc(host);
                    new_output_find->diskname=stralloc(disk);
                    new_output_find->level=level;
@@ -823,12 +895,9 @@ int datestamp, datestamp_aux;
                }
                else if(curlog == L_FAIL) {     /* print other failures too */
                    find_result_t *new_output_find =
-                       (find_result_t *)alloc(sizeof(find_result_t));
+                       (find_result_t *)alloc(SIZEOF(find_result_t));
                    new_output_find->next=*output_find;
-                   new_output_find->datestamp=datestamp;
-                   new_output_find->datestamp_aux=datestamp_aux;
-                   new_output_find->timestamp = alloc(15);
-                   snprintf(new_output_find->timestamp, 15, "%d000000", datestamp);
+                   new_output_find->timestamp = stralloc(date);
                    new_output_find->hostname=stralloc(host);
                    new_output_find->diskname=stralloc(disk);
                    new_output_find->level=level;
@@ -844,6 +913,7 @@ int datestamp, datestamp_aux;
                    *output_find=new_output_find;
                }
            }
+           amfree(disk);
        }
     }
     afclose(logf);
@@ -856,13 +926,14 @@ int datestamp, datestamp_aux;
  * an empty pattern to match .*, though).  If 'ok' is true, will only match
  * dumps with SUCCESS status.
  */
-find_result_t *dumps_match(output_find,hostname,diskname,datestamp,level,ok)
-find_result_t *output_find;
-char *hostname;
-char *diskname;
-char *datestamp;
-char *level;
-int ok;
+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;
@@ -870,18 +941,16 @@ int ok;
     for(cur_result=output_find;
        cur_result;
        cur_result=cur_result->next) {
-       char date_str[NUM_STR_SIZE];
        char level_str[NUM_STR_SIZE];
-       snprintf(date_str, sizeof(date_str), "%d", cur_result->datestamp);
-       snprintf(level_str, sizeof(level_str), "%d", cur_result->level);
+       snprintf(level_str, SIZEOF(level_str), "%d", cur_result->level);
        if((*hostname == '\0' || match_host(hostname, cur_result->hostname)) &&
           (*diskname == '\0' || match_disk(diskname, cur_result->diskname)) &&
-          (*datestamp== '\0' || match_datestamp(datestamp, date_str)) &&
+          (*datestamp== '\0' || match_datestamp(datestamp, cur_result->timestamp)) &&
           (*level== '\0' || match_level(level, level_str)) &&
           (!ok || !strcmp(cur_result->status, "OK"))){
 
-           find_result_t *curmatch = alloc(sizeof(find_result_t));
-           memcpy(curmatch, cur_result, sizeof(find_result_t));
+           find_result_t *curmatch = alloc(SIZEOF(find_result_t));
+           memcpy(curmatch, cur_result, SIZEOF(find_result_t));
 
 /*
            curmatch->hostname = stralloc(cur_result->hostname);
@@ -899,12 +968,13 @@ int ok;
     return(matches);
 }
 
-find_result_t *dump_exist(output_find, hostname, diskname, datestamp, level)
-find_result_t *output_find;
-char *hostname;
-char *diskname;
-int datestamp;
-int level;
+find_result_t *
+dump_exist(
+    find_result_t *output_find,
+    char *hostname,
+    char *diskname,
+    char *datestamp,
+    int level)
 {
     find_result_t *output_find_result;
 
@@ -913,7 +983,7 @@ int level;
        output_find_result=output_find_result->next) {
        if( !strcmp(output_find_result->hostname, hostname) &&
            !strcmp(output_find_result->diskname, diskname) &&
-           output_find_result->datestamp == datestamp &&
+           !strcmp(output_find_result->timestamp, datestamp) &&
            output_find_result->level == level) {
 
            return output_find_result;