X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Ftapefile.c;h=b4212e5894238b47bc4d49e9801938ba26f4d78e;hb=cd0b924f27312d57bd42f6c4fae2b795139e2d0b;hp=6d2b86453cf9667fd21e126deb50436256bf9f72;hpb=3ab887b9bc819a846c75dd7f2ee5d41fac22b19f;p=debian%2Famanda diff --git a/server-src/tapefile.c b/server-src/tapefile.c index 6d2b864..b4212e5 100644 --- a/server-src/tapefile.c +++ b/server-src/tapefile.c @@ -24,42 +24,54 @@ * file named AUTHORS, in the root directory of this distribution. */ /* - * $Id: tapefile.c,v 1.15.2.6.6.7 2003/10/24 13:44:49 martinea Exp $ + * $Id: tapefile.c,v 1.37 2006/07/21 00:25:52 martinea Exp $ * * routines to read and write the amanda active tape list */ #include "amanda.h" +#include "match.h" #include "tapefile.h" #include "conffile.h" static tape_t *tape_list = NULL; /* local functions */ -static tape_t *parse_tapeline P((int *status, char *line)); -static tape_t *insert P((tape_t *list, tape_t *tp)); -static time_t stamp2time P((int datestamp)); +static tape_t *parse_tapeline(int *status, char *line); +static tape_t *insert(tape_t *list, tape_t *tp); +static time_t stamp2time(char *datestamp); - - -int read_tapelist(tapefile) -char *tapefile; +int +read_tapelist( + char *tapefile) { tape_t *tp; FILE *tapef; int pos; char *line = NULL; - int status; + int status = 0; tape_list = NULL; 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) { + if (line[0] == '\0') { + amfree(line); + continue; + } tp = parse_tapeline(&status, line); amfree(line); - if(tp == NULL && status != 0) return 1; - if(tp != NULL) tape_list = insert(tape_list, tp); + if(tp == NULL && status != 0) + return 1; + if(tp != NULL) + tape_list = insert(tape_list, tp); } afclose(tapef); @@ -70,8 +82,9 @@ char *tapefile; return 0; } -int write_tapelist(tapefile) -char *tapefile; +int +write_tapelist( + char *tapefile) { tape_t *tp; FILE *tapef; @@ -86,14 +99,21 @@ char *tapefile; } for(tp = tape_list; tp != NULL; tp = tp->next) { - fprintf(tapef, "%d %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->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; } rc = rename(newtapefile, tapefile); @@ -102,20 +122,23 @@ char *tapefile; return(rc != 0); } -void clear_tapelist() +void +clear_tapelist(void) { tape_t *tp, *next; for(tp = tape_list; tp; tp = next) { amfree(tp->label); + amfree(tp->datestamp); next = tp->next; amfree(tp); } tape_list = NULL; } -tape_t *lookup_tapelabel(label) -char *label; +tape_t * +lookup_tapelabel( + const char *label) { tape_t *tp; @@ -127,8 +150,9 @@ char *label; -tape_t *lookup_tapepos(pos) -int pos; +tape_t * +lookup_tapepos( + int pos) { tape_t *tp; @@ -139,18 +163,20 @@ int pos; } -tape_t *lookup_tapedate(datestamp) -int datestamp; +tape_t * +lookup_tapedate( + char *datestamp) { tape_t *tp; for(tp = tape_list; tp != NULL; tp = tp->next) { - if(tp->datestamp == datestamp) return tp; + if(strcmp(tp->datestamp, datestamp) == 0) return tp; } return NULL; } -int lookup_nb_tape() +int +lookup_nb_tape(void) { tape_t *tp; int pos=0; @@ -161,8 +187,18 @@ int lookup_nb_tape() return pos; } -tape_t *lookup_last_reusable_tape(skip) - int skip; + +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) { tape_t *tp, **tpsave; int count=0; @@ -176,12 +212,12 @@ tape_t *lookup_last_reusable_tape(skip) * caller. If skip is zero, the oldest is returned, if it is * one, the next oldest, two, the next to next oldest and so on. */ - tpsave = alloc((skip + 1) * sizeof (*tpsave)); + tpsave = alloc((skip + 1) * SIZEOF(*tpsave)); for(s = 0; s <= skip; s++) { tpsave[s] = NULL; } for(tp = tape_list; tp != NULL; tp = tp->next) { - if(tp->reuse == 1 && tp->datestamp > 0 && match (labelstr, tp->label)) { + if(tp->reuse == 1 && strcmp(tp->datestamp,"0") != 0 && match (labelstr, tp->label)) { count++; for(s = skip; s > 0; s--) { tpsave[s] = tpsave[s - 1]; @@ -197,14 +233,15 @@ tape_t *lookup_last_reusable_tape(skip) return tp; } -int reusable_tape(tp) - tape_t *tp; +int +reusable_tape( + tape_t *tp) { int count = 0; if(tp == NULL) return 0; if(tp->reuse == 0) return 0; - if(tp->datestamp == 0) return 1; + if( strcmp(tp->datestamp,"0") == 0) return 1; while(tp != NULL) { if(tp->reuse == 1) count++; tp = tp->prev; @@ -212,8 +249,9 @@ int reusable_tape(tp) return (count >= getconf_int(CNF_TAPECYCLE)); } -void remove_tapelabel(label) -char *label; +void +remove_tapelabel( + char *label) { tape_t *tp, *prev, *next; @@ -221,35 +259,41 @@ char *label; if(tp != NULL) { prev = tp->prev; next = tp->next; + /*@ignore@*/ if(prev != NULL) prev->next = next; else /* begin of list */ tape_list = next; if(next != NULL) next->prev = prev; + /*@end@*/ while (next != NULL) { next->position--; next = next->next; } + amfree(tp->datestamp); amfree(tp->label); amfree(tp); } } -tape_t *add_tapelabel(datestamp, label) -int datestamp; -char *label; +tape_t * +add_tapelabel( + char *datestamp, + 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 = (tape_t *) alloc(SIZEOF(tape_t)); - new->datestamp = datestamp; + 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; @@ -266,7 +310,8 @@ char *label; return new; } -int guess_runs_from_tapelist() +int +guess_runs_from_tapelist(void) { tape_t *tp; int i, ntapes, tape_ndays, dumpcycle, runtapes, runs; @@ -283,7 +328,7 @@ int guess_runs_from_tapelist() if((tp = lookup_tapepos(i)) == NULL) break; tape_time = stamp2time(tp->datestamp); - tape_ndays = days_diff(tape_time, today); + tape_ndays = (int)days_diff(tape_time, today); if(tape_ndays < dumpcycle) ntapes++; else break; @@ -305,16 +350,17 @@ int guess_runs_from_tapelist() return runs; } -static tape_t *parse_tapeline(status, line) -int *status; -char *line; +static tape_t * +parse_tapeline( + int *status, + char *line) { tape_t *tp = NULL; char *s, *s1; int ch; *status = 0; - tp = (tape_t *) alloc(sizeof(tape_t)); + tp = (tape_t *) alloc(SIZEOF(tape_t)); tp->prev = NULL; tp->next = NULL; @@ -327,74 +373,192 @@ char *line; amfree(tp); return NULL; } - if (sscanf(s - 1, "%d", &tp->datestamp) != 1) { - amfree(tp); - *status = 1; - return NULL; - } - skip_integer(s, ch); + s1 = s - 1; + skip_non_whitespace(s, ch); + s[-1] = '\0'; + tp->datestamp = stralloc(s1); skip_whitespace(s, ch); s1 = s - 1; skip_non_whitespace(s, ch); s[-1] = '\0'; tp->label = stralloc(s1); + 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); + } else { + tp->barcode = NULL; + } + + 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); + } else { + tp->meta = NULL; + } + + if (*(s - 1) == '#') { + tp->comment = stralloc(s); /* skip leading '#' */ + } else { + tp->comment = NULL; + } return tp; } /* insert in reversed datestamp order */ -static tape_t *insert(list, tp) -tape_t *list, *tp; +/*@ignore@*/ +static tape_t * +insert( + tape_t *list, + tape_t *tp) { tape_t *prev, *cur; prev = NULL; cur = list; - while(cur != NULL && cur->datestamp >= tp->datestamp) { + while(cur != NULL && strcmp(cur->datestamp, tp->datestamp) >= 0) { prev = cur; cur = cur->next; } tp->prev = prev; tp->next = cur; - if(prev == NULL) list = tp; - else prev->next = tp; - if(cur !=NULL) cur->prev = tp; + if(prev == NULL) { + list = tp; +#ifndef __lint + } else { + prev->next = tp; +#endif + } + if(cur !=NULL) + cur->prev = tp; return list; } +/*@end@*/ - -static time_t stamp2time(datestamp) -int datestamp; /* - * Converts datestamp (an int of the form YYYYMMDD) into a real time_t value. + * Converts datestamp (an char of the form YYYYMMDD or YYYYMMDDHHMMSS) into a real + * time_t value. * Since the datestamp contains no timezone or hh/mm/ss information, the * value is approximate. This is ok for our purposes, since we round off * scheduling calculations to the nearest day. */ + +static time_t +stamp2time( + char *datestamp) { - struct tm tm; + struct tm *tm; time_t now; + char date[9]; + int dateint; + strncpy(date, datestamp, 8); + date[8] = '\0'; + dateint = atoi(date); now = time(0); - tm = *localtime(&now); /* initialize sec/min/hour & gmtoff */ + tm = localtime(&now); /* initialize sec/min/hour & gmtoff */ + + if (!tm) { + tm = alloc(SIZEOF(struct tm)); + tm->tm_sec = 0; + tm->tm_min = 0; + tm->tm_hour = 0; + tm->tm_wday = 0; + tm->tm_yday = 0; + tm->tm_isdst = 0; + } + + + tm->tm_year = ( dateint / 10000) - 1900; + tm->tm_mon = ((dateint % 10000) / 100) - 1; + tm->tm_mday = ((dateint % 100) ); + + return mktime(tm); +} - tm.tm_year = ( datestamp / 10000) - 1900; - tm.tm_mon = ((datestamp % 10000) / 100) - 1; - tm.tm_mday = ((datestamp % 100) ); +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; + } - return mktime(&tm); + 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); + } }