lintian doesn't like orphan packages with uploaders...
[debian/amanda] / server-src / tapefile.c
index 1b2e7c6e1323d2194452009c1954cd4a0ded03b9..35cbef231c1619a5c7e8f90f6bba25650ec61ef1 100644 (file)
@@ -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
@@ -29,6 +30,7 @@
  * routines to read and write the amanda active tape list
  */
 #include "amanda.h"
+#include "match.h"
 #include "tapefile.h"
 #include "conffile.h"
 
@@ -49,9 +51,15 @@ read_tapelist(
     char *line = NULL;
     int status = 0;
 
-    tape_list = NULL;
+    clear_tapelist();
     if((tapef = fopen(tapefile,"r")) == NULL) {
-       return 1;
+       if (errno == ENOENT) {
+           /* no tapelist is equivalent to an empty tapelist */
+           return 0;
+       } else {
+           g_debug("Error opening '%s': %s", tapefile, strerror(errno));
+           return 1;
+       }
     }
 
     while((line = agets(tapef)) != NULL) {
@@ -92,14 +100,22 @@ write_tapelist(
     }
 
     for(tp = tape_list; tp != NULL; tp = tp->next) {
-       fprintf(tapef, "%s %s", tp->datestamp, tp->label);
-       if(tp->reuse) fprintf(tapef, " reuse");
-       else fprintf(tapef, " no-reuse");
-       fprintf(tapef, "\n");
+       g_fprintf(tapef, "%s %s", tp->datestamp, tp->label);
+       if(tp->reuse) g_fprintf(tapef, " reuse");
+       else g_fprintf(tapef, " no-reuse");
+       if (tp->barcode)
+           g_fprintf(tapef, " BARCODE:%s", tp->barcode);
+       if (tp->meta)
+           g_fprintf(tapef, " META:%s", tp->meta);
+       if (tp->blocksize)
+           g_fprintf(tapef, " BLOCKSIZE:%jd", (intmax_t)tp->blocksize);
+       if (tp->comment)
+           g_fprintf(tapef, " #%s", tp->comment);
+       g_fprintf(tapef, "\n");
     }
 
     if (fclose(tapef) == EOF) {
-       fprintf(stderr,"error [closing %s: %s]", newtapefile, strerror(errno));
+       g_fprintf(stderr,_("error [closing %s: %s]"), newtapefile, strerror(errno));
        amfree(newtapefile);
        return 1;
     }
@@ -117,6 +133,9 @@ clear_tapelist(void)
     for(tp = tape_list; tp; tp = next) {
        amfree(tp->label);
        amfree(tp->datestamp);
+       amfree(tp->barcode);
+       amfree(tp->meta);
+       amfree(tp->comment);
        next = tp->next;
        amfree(tp);
     }
@@ -125,7 +144,7 @@ clear_tapelist(void)
 
 tape_t *
 lookup_tapelabel(
-    char *label)
+    const char *label)
 {
     tape_t *tp;
 
@@ -174,6 +193,15 @@ lookup_nb_tape(void)
     return pos;
 }
 
+
+char *
+get_last_reusable_tape_label(
+     int skip)
+{
+    tape_t *tp = lookup_last_reusable_tape(skip);
+    return (tp != NULL) ? tp->label : NULL;
+}
+
 tape_t *
 lookup_last_reusable_tape(
      int skip)
@@ -251,6 +279,9 @@ remove_tapelabel(
        }
        amfree(tp->datestamp);
        amfree(tp->label);
+       amfree(tp->meta);
+       amfree(tp->comment);
+       amfree(tp->barcode);
        amfree(tp);
     }
 }
@@ -258,18 +289,20 @@ remove_tapelabel(
 tape_t *
 add_tapelabel(
     char *datestamp,
-    char *label)
+    char *label,
+    char *comment)
 {
     tape_t *cur, *new;
 
     /* insert a new record to the front of the list */
 
-    new = (tape_t *) alloc(SIZEOF(tape_t));
+    new = g_new0(tape_t, 1);
 
     new->datestamp = stralloc(datestamp);
     new->position = 0;
     new->reuse = 1;
     new->label = stralloc(label);
+    new->comment = comment? stralloc(comment) : NULL;
 
     new->prev  = NULL;
     if(tape_list != NULL) tape_list->prev = new;
@@ -334,21 +367,21 @@ parse_tapeline(
     tape_t *tp = NULL;
     char *s, *s1;
     int ch;
+    char *cline;
 
     *status = 0;
-    tp = (tape_t *) alloc(SIZEOF(tape_t));
-
-    tp->prev = NULL;
-    tp->next = NULL;
 
     s = line;
     ch = *s++;
 
     skip_whitespace(s, ch);
     if(ch == '\0') {
-       amfree(tp);
        return NULL;
     }
+
+    cline = g_strdup(line);
+    tp = g_new0(tape_t, 1);
+
     s1 = s - 1;
     skip_non_whitespace(s, ch);
     s[-1] = '\0';
@@ -362,14 +395,49 @@ parse_tapeline(
 
     skip_whitespace(s, ch);
     tp->reuse = 1;
-#define sc "reuse"
-    if(strncmp(s - 1, sc, SIZEOF(sc)-1) == 0)
+    if(strncmp_const(s - 1, "reuse") == 0) {
        tp->reuse = 1;
-#undef sc
-#define sc "no-reuse"
-    if(strncmp(s - 1, sc, SIZEOF(sc)-1) == 0)
+       s1 = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       skip_whitespace(s, ch);
+    }
+    if(strncmp_const(s - 1, "no-reuse") == 0) {
        tp->reuse = 0;
-#undef sc
+       s1 = s - 1;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       skip_whitespace(s, ch);
+    }
+
+    if (strncmp_const(s - 1, "BARCODE:") == 0) {
+       s1 = s - 1 + 8;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       skip_whitespace(s, ch);
+       tp->barcode = stralloc(s1);
+    }
+
+    if (strncmp_const(s - 1, "META:") == 0) {
+       s1 = s - 1 + 5;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       skip_whitespace(s, ch);
+       tp->meta = stralloc(s1);
+    }
+
+    if (strncmp_const(s - 1, "BLOCKSIZE:") == 0) {
+       s1 = s - 1 + 10;
+       skip_non_whitespace(s, ch);
+       s[-1] = '\0';
+       skip_whitespace(s, ch);
+       tp->blocksize = atol(s1);
+    }
+    if (*(s - 1) == '#') {
+       tp->comment = stralloc(s); /* skip leading '#' */
+    } else if (*(s-1)) {
+       g_critical("Bogus line in the tapelist file: %s", cline);
+    }
 
     return tp;
 }
@@ -447,3 +515,62 @@ stamp2time(
 
     return mktime(tm);
 }
+
+char *
+list_new_tapes(
+    int nb)
+{
+    tape_t *lasttp, *iter;
+    char *result = NULL;
+
+    /* Find latest reusable new tape */
+    lasttp = lookup_tapepos(lookup_nb_tape());
+    while (lasttp && lasttp->reuse == 0)
+       lasttp = lasttp->prev;
+
+    if(lasttp && nb > 0 && strcmp(lasttp->datestamp,"0") == 0) {
+       int c = 0;
+       iter = lasttp;
+       /* count the number of tapes we *actually* used */
+       while(iter && nb > 0 && strcmp(iter->datestamp,"0") == 0) {
+           if (iter->reuse) {
+               c++;
+               nb--;
+           }
+           iter = iter->prev;
+       }
+
+       if(c == 1) {
+           result = g_strdup_printf(
+                       _("The next new tape already labelled is: %s."),
+                       lasttp->label);
+       } else {
+           result = g_strdup_printf(
+                       _("The next %d new tapes already labelled are: %s"),
+                       c, lasttp->label);
+           iter = lasttp->prev;
+           c--;
+           while(iter && c > 0 && strcmp(iter->datestamp,"0") == 0) {
+               if (iter->reuse) {
+                   result = vstrextend(&result, ", ", iter->label, NULL);
+                   c--;
+               }
+               iter = iter->prev;
+           }
+       }
+    }
+    return result;
+}
+
+void
+print_new_tapes(
+    FILE *output,
+    int   nb)
+{
+    char *result = list_new_tapes(nb);
+
+    if (result) {
+       g_fprintf(output,"%s\n", result);
+       amfree(result);
+    }
+}