]> git.gag.com Git - debian/amanda/blobdiff - server-src/holding.c
Imported Debian patch 2.5.1p3-1
[debian/amanda] / server-src / holding.c
index a734aa9199caa1a2c39f1940bb4b9b34f7bd57da..bcc580ac3c9875c6b1ce0a996dab4813fbab8add 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: holding.c,v 1.17.2.12.4.3.2.10 2003/06/14 13:47:05 martinea Exp $
+ * $Id: holding.c,v 1.56 2006/06/09 23:07:26 martinea Exp $
  *
  * Functions to access holding disk
  */
 #include "util.h"
 #include "holding.h"
 #include "fileheader.h"
-#include "util.h"
 #include "logfile.h"
 
-static sl_t *scan_holdingdisk P((sl_t *holding_list, char *diskdir, int verbose));
+static sl_t *scan_holdingdisk(sl_t *holding_list, char *diskdir, int verbose);
+static sl_t *scan_holdingdir(sl_t *holding_list, holdingdisk_t *holdp, char *datestamp);
 
-int is_dir(fname)
-char *fname;
+int
+is_dir(
+    char *fname)
 {
     struct stat statbuf;
 
@@ -48,22 +49,30 @@ char *fname;
     return (statbuf.st_mode & S_IFDIR) == S_IFDIR;
 }
 
-int is_emptyfile(fname)
-char *fname;
+int
+is_emptyfile(
+    char *fname)
 {
     struct stat statbuf;
 
     if(stat(fname, &statbuf) == -1) return 0;
 
-    return (statbuf.st_mode & S_IFDIR) != S_IFDIR && statbuf.st_size == 0;
+    return ((statbuf.st_mode & S_IFDIR) != S_IFDIR) &&
+               (statbuf.st_size == (off_t)0);
 }
 
-int is_datestr(fname)
-char *fname;
-/* sanity check on datestamp of the form YYYYMMDD */
+
+/*
+ * sanity check on datestamp of the form YYYYMMDD or YYYYMMDDhhmmss
+ */
+
+int
+is_datestr(
+    char *fname)
 {
     char *cp;
-    int ch, num, date, year, month;
+    int ch, num, date, year, month, hour, minute, second;
+    char ymd[9], hms[7];
 
     /* must be 8 digits */
     for(cp = fname; (ch = *cp) != '\0'; cp++) {
@@ -71,27 +80,43 @@ char *fname;
            break;
        }
     }
-    if(ch != '\0' || cp-fname != 8) {
+    if(ch != '\0' || (cp-fname != 8 && cp-fname != 14)) {
        return 0;
     }
 
     /* sanity check year, month, and day */
 
-    num = atoi(fname);
+    strncpy(ymd, fname, 8);
+    ymd[8] = '\0';
+    num = atoi(ymd);
     year = num / 10000;
     month = (num / 100) % 100;
     date = num % 100;
     if(year<1990 || year>2100 || month<1 || month>12 || date<1 || date>31)
        return 0;
 
+    if(cp-fname == 8)
+       return 1;
+
+    /* sanity check hour, minute, and second */
+    strncpy(hms, fname+8, 6);
+    hms[6] = '\0';
+    num = atoi(hms);
+    hour = num / 10000;
+    minute = (num / 100) % 100;
+    second = num % 100;
+    if(hour> 23 || minute>59 || second>59)
+       return 0;
+
     /* yes, we passed all the checks */
 
     return 1;
 }
 
 
-int non_empty(fname)
-char *fname;
+int
+non_empty(
+    char *     fname)
 {
     DIR *dir;
     struct dirent *entry;
@@ -110,10 +135,11 @@ char *fname;
 }
 
 
-sl_t *scan_holdingdisk(holding_list, diskdir, verbose)
-sl_t *holding_list;
-char *diskdir;
-int verbose;
+static sl_t *
+scan_holdingdisk(
+    sl_t *     holding_list,
+    char *     diskdir,
+    int                verbose)
 {
     DIR *topdir;
     struct dirent *workdir;
@@ -131,8 +157,7 @@ int verbose;
     if(verbose)
        printf("Scanning %s...\n", diskdir);
     while((workdir = readdir(topdir)) != NULL) {
-       if(is_dot_or_dotdot(workdir->d_name)
-          || strcmp(workdir->d_name, "lost+found") == 0) {
+       if(is_dot_or_dotdot(workdir->d_name)) {
            continue;
        }
        entryname = newvstralloc(entryname,
@@ -141,15 +166,18 @@ int verbose;
            printf("  %s: ", workdir->d_name);
        }
        if(!is_dir(entryname)) {
-           if(verbose)
+           if(verbose) {
                puts("skipping cruft file, perhaps you should delete it.");
+           }
        } else if(!is_datestr(workdir->d_name)) {
-           if(verbose)
+           if(verbose && (strcmp(workdir->d_name, "lost+found")!=0) ) {
                puts("skipping cruft directory, perhaps you should delete it.");
+           }
        } else {
            holding_list = insert_sort_sl(holding_list, workdir->d_name);
-           if(verbose)
+           if(verbose) {
                puts("found Amanda directory.");
+           }
        }
     }
     closedir(topdir);
@@ -158,10 +186,11 @@ int verbose;
 }
 
 
-sl_t *scan_holdingdir(holding_list, holdp, datestamp)
-sl_t *holding_list;
-holdingdisk_t *holdp;
-char *datestamp;
+static sl_t *
+scan_holdingdir(
+    sl_t *             holding_list,
+    holdingdisk_t *    holdp,
+    char *             datestamp)
 {
     DIR *workdir;
     struct dirent *entry;
@@ -170,7 +199,7 @@ char *datestamp;
     disk_t *dp;
     dumpfile_t file;
 
-    dirname = vstralloc(holdp->diskdir, "/", datestamp, NULL);
+    dirname = vstralloc(holdingdisk_get_diskdir(holdp), "/", datestamp, NULL);
     if((workdir = opendir(dirname)) == NULL) {
        if(errno != ENOENT)
            log_add(L_INFO, "%s: could not open dir: %s",
@@ -178,7 +207,13 @@ char *datestamp;
        amfree(dirname);
        return holding_list;
     }
-    chdir(dirname);
+    if ((chdir(dirname)) == -1) {
+       log_add(L_INFO, "%s: could not chdir: %s",
+                   dirname, strerror(errno));
+       amfree(dirname);
+       return holding_list;
+    }
+
     while((entry = readdir(workdir)) != NULL) {
        if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
            continue;
@@ -219,22 +254,29 @@ char *datestamp;
 }
 
 
-sl_t *get_flush(dateargs, datestamp, amflush, verbose)
-sl_t *dateargs;
-char *datestamp;  /* don't do this date */
-int amflush, verbose;
+
+sl_t *
+get_flush(
+    sl_t *dateargs,
+    char *datestamp,  /* don't do this date */
+    int amflush,
+    int verbose)
 {
     sl_t *holding_list;
     sl_t *date_list;
     sle_t *datearg;
     sle_t *date, *next_date;
     holdingdisk_t *hdisk;
-    char current_dir[1000];
-
-    getcwd(current_dir, 999);
+    char current_dir[PATH_MAX];
 
     holding_list = new_sl();
 
+    if (getcwd(current_dir, SIZEOF(current_dir)-1) == NULL) {
+       log_add(L_INFO, "get_flush: could get current working directory: %s",
+                   strerror(errno));
+       return holding_list;
+    }
+
     if(dateargs) {
        int ok;
 
@@ -270,27 +312,32 @@ int amflush, verbose;
 
     free_sl(date_list);
     date_list = NULL;
-    chdir(current_dir);
+    if (chdir(current_dir) == -1) {
+       log_add(L_INFO, "%s: could not chdir: %s",
+                   current_dir, strerror(errno));
+    }
     return(holding_list);
 }
 
 
-sl_t *pick_all_datestamp(verbose)
-int verbose;
+sl_t *
+pick_all_datestamp(
+    int                verbose)
 {
     sl_t *holding_list = NULL;
     holdingdisk_t *hdisk;
 
     holding_list = new_sl();
     for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
-       holding_list = scan_holdingdisk(holding_list, hdisk->diskdir, verbose);
+       holding_list = scan_holdingdisk(holding_list, holdingdisk_get_diskdir(hdisk), verbose);
 
     return holding_list;
 }
 
 
-sl_t *pick_datestamp(verbose)
-int verbose;
+sl_t *
+pick_datestamp(
+    int                verbose)
 {
     sl_t *holding_list;
     sl_t *r_holding_list = NULL;
@@ -298,8 +345,8 @@ int verbose;
     char **directories = NULL;
     int i;
     char *answer = NULL;
-    char *a;
-    int ch;
+    char *a = NULL;
+    int ch = 0;
     char max_char = '\0', chupper = '\0';
 
     holding_list = pick_all_datestamp(verbose);
@@ -311,7 +358,7 @@ int verbose;
        return holding_list;
     }
     else {
-       directories = alloc((holding_list->nb_element) * sizeof(char *));
+       directories = alloc((holding_list->nb_element) * SIZEOF(char *));
        for(dir = holding_list->first, i=0; dir != NULL; dir = dir->next,i++) {
            directories[i] = dir->name;
        }
@@ -331,16 +378,22 @@ int verbose;
                clearerr(stdin);
                continue;
            }
-           a = answer;
-           while ((ch = *a++) != '\0' && isspace(ch)) {}
-           if(ch == '\0' || strncasecmp(a, "ALL", 3) == 0) {
+
+           if (*answer == '\0' || strncasecmp(answer, "ALL", 3) == 0) {
                break;
            }
+
+           a = answer;
+           while ((ch = *a++) != '\0') {
+               if (!isspace(ch))
+                   break;
+           }
+
            do {
                if (isspace(ch) || ch == ',') {
                    continue;
                }
-               chupper = toupper(ch);
+               chupper = (char)toupper(ch);
                if (chupper < 'A' || chupper > max_char) {
                    free_sl(r_holding_list);
                    r_holding_list = NULL;
@@ -362,25 +415,28 @@ int verbose;
 }
 
 
-filetype_t get_amanda_names(fname, hostname, diskname, level)
-char *fname, **hostname, **diskname;
-int *level;
+filetype_t
+get_amanda_names( char *       fname,
+    char **    hostname,
+    char **    diskname,
+    int *      level)
 {
     dumpfile_t file;
     char buffer[DISK_BLOCK_BYTES];
     int fd;
     *hostname = *diskname = NULL;
 
+    memset(buffer, 0, sizeof(buffer));
     if((fd = open(fname, O_RDONLY)) == -1)
        return F_UNKNOWN;
 
-    if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+    if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) {
        aclose(fd);
        return F_UNKNOWN;
     }
     aclose(fd);
 
-    parse_file_header(buffer,&file,sizeof(buffer));
+    parse_file_header(buffer, &file, SIZEOF(buffer));
     if(file.type != F_DUMPFILE && file.type != F_CONT_DUMPFILE) {
        return file.type;
     }
@@ -392,71 +448,87 @@ int *level;
 }
 
 
-void get_dumpfile(fname, file)
-char *fname;
-dumpfile_t *file;
+void
+get_dumpfile(
+    char *     fname,
+    dumpfile_t *file)
 {
     char buffer[DISK_BLOCK_BYTES];
     int fd;
 
+    memset(buffer, 0, sizeof(buffer));
+
     fh_init(file);
     file->type = F_UNKNOWN;
     if((fd = open(fname, O_RDONLY)) == -1)
        return;
 
-    if(fullread(fd, buffer, sizeof(buffer)) != sizeof(buffer)) {
+    if(fullread(fd, buffer, SIZEOF(buffer)) != (ssize_t)sizeof(buffer)) {
        aclose(fd);
        return;
     }
     aclose(fd);
 
-    parse_file_header(buffer,file,sizeof(buffer));
+    parse_file_header(buffer, file, SIZEOF(buffer));
     return;
 }
 
 
-long size_holding_files(holding_file)
-char *holding_file;
+off_t
+size_holding_files(
+    char *     holding_file,
+    int                strip_headers)
 {
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     char *filename;
-    long size=0;
+    off_t size = (off_t)0;
     struct stat finfo;
 
+    memset(buffer, 0, sizeof(buffer));
     filename = stralloc(holding_file);
     while(filename != NULL && filename[0] != '\0') {
        if((fd = open(filename,O_RDONLY)) == -1) {
            fprintf(stderr,"size_holding_files: open of %s failed: %s\n",filename,strerror(errno));
            amfree(filename);
-           return -1;
+           return (off_t)-1;
+       }
+       if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {
+               parse_file_header(buffer, &file, (size_t)buflen);
        }
-       buflen = fullread(fd, buffer, sizeof(buffer));
-       parse_file_header(buffer, &file, buflen);
        close(fd);
        if(stat(filename, &finfo) == -1) {
            printf("stat %s: %s\n", filename, strerror(errno));
-           finfo.st_size = 0;
+           finfo.st_size = (off_t)0;
+       }
+       size += (finfo.st_size+(off_t)1023)/(off_t)1024;
+       if(strip_headers)
+           size -= (off_t)(DISK_BLOCK_BYTES / 1024);
+       if(buflen > 0) {
+           filename = newstralloc(filename, file.cont_filename);
+       }
+       else {
+           amfree(filename);
        }
-       size += (finfo.st_size+1023)/1024;
-       filename = newstralloc(filename, file.cont_filename);
     }
     amfree(filename);
     return size;
 }
 
 
-int unlink_holding_files( holding_file )
-char *holding_file;
+int
+unlink_holding_files(
+    char *     holding_file)
 {
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     char *filename;
 
+    memset(buffer, 0, sizeof(buffer));
     filename = stralloc(holding_file);
     while(filename != NULL && filename[0] != '\0') {
        if((fd = open(filename,O_RDONLY)) == -1) {
@@ -464,28 +536,36 @@ char *holding_file;
            amfree(filename);
            return 0;
        }
-       buflen = fullread(fd, buffer, sizeof(buffer));
-       parse_file_header(buffer, &file, buflen);
+       if ((buflen = fullread(fd, buffer, SIZEOF(buffer))) > 0) {
+           parse_file_header(buffer, &file, (size_t)buflen);
+       }
        close(fd);
        unlink(filename);
-       filename = newstralloc(filename,file.cont_filename);
+       if(buflen > 0) {
+           filename = newstralloc(filename, file.cont_filename);
+       }
+       else {
+           amfree(filename);
+       }
     }
     amfree(filename);
     return 1;
 }
 
 
-int rename_tmp_holding( holding_file, complete )
-char *holding_file;
-int complete;
+int
+rename_tmp_holding(
+    char *     holding_file,
+    int                complete)
 {
     int fd;
-    int buflen;
+    ssize_t buflen;
     char buffer[DISK_BLOCK_BYTES];
     dumpfile_t file;
     char *filename;
     char *filename_tmp = NULL;
 
+    memset(buffer, 0, sizeof(buffer));
     filename = stralloc(holding_file);
     while(filename != NULL && filename[0] != '\0') {
        filename_tmp = newvstralloc(filename_tmp, filename, ".tmp", NULL);
@@ -495,35 +575,36 @@ int complete;
            amfree(filename_tmp);
            return 0;
        }
-       buflen = fullread(fd, buffer, sizeof(buffer));
-       if (buflen == 0) {
-           fprintf(stderr,"rename_tmp_holding: %s: empty file?\n", filename_tmp);
+       buflen = fullread(fd, buffer, SIZEOF(buffer));
+       close(fd);
+
+       if(rename(filename_tmp, filename) != 0) {
+           fprintf(stderr,
+                   "rename_tmp_holding: could not rename \"%s\" to \"%s\": %s",
+                   filename_tmp, filename, strerror(errno));
+       }
+
+       if (buflen <= 0) {
+           fprintf(stderr,"rename_tmp_holding: %s: empty file?\n", filename);
            amfree(filename);
            amfree(filename_tmp);
-           close(fd);
            return 0;
        }
-       parse_file_header(buffer, &file, buflen);
-       close(fd);
+       parse_file_header(buffer, &file, (size_t)buflen);
        if(complete == 0 ) {
-           if((fd = open(filename_tmp,O_RDWR)) == -1) {
+           if((fd = open(filenameO_RDWR)) == -1) {
                fprintf(stderr, "rename_tmp_holdingX: open of %s failed: %s\n",
-                       filename_tmp, strerror(errno));
+                       filename, strerror(errno));
                amfree(filename);
                amfree(filename_tmp);
                return 0;
 
            }
            file.is_partial = 1;
-           build_header(buffer, &file, sizeof(buffer));
-           fullwrite(fd, buffer, sizeof(buffer));
+           build_header(buffer, &file, SIZEOF(buffer));
+           fullwrite(fd, buffer, SIZEOF(buffer));
            close(fd);
        }
-       if(rename(filename_tmp, filename) != 0) {
-           fprintf(stderr,
-                   "rename_tmp_holding(): could not rename \"%s\" to \"%s\": %s",
-                   filename_tmp, filename, strerror(errno));
-       }
        filename = newstralloc(filename, file.cont_filename);
     }
     amfree(filename);
@@ -532,9 +613,10 @@ int complete;
 }
 
 
-void cleanup_holdingdisk(diskdir, verbose)
-char *diskdir;
-int verbose;
+void
+cleanup_holdingdisk(
+    char *     diskdir,
+    int                verbose)
 {
     DIR *topdir;
     struct dirent *workdir;
@@ -550,12 +632,16 @@ int verbose;
 
     if(verbose)
        printf("Scanning %s...\n", diskdir);
-    chdir(diskdir);
+    if ((chdir(diskdir)) == -1) {
+       log_add(L_INFO, "%s: could not chdir: %s",
+                   diskdir, strerror(errno));
+    }
     while((workdir = readdir(topdir)) != NULL) {
-       if(is_dot_or_dotdot(workdir->d_name)
-          || strcmp(workdir->d_name, "lost+found") == 0) {
+       if(strcmp(workdir->d_name, ".") == 0
+          || strcmp(workdir->d_name, "..") == 0
+          || strcmp(workdir->d_name, "lost+found") == 0)
            continue;
-       }
+
        if(verbose)
            printf("  %s: ", workdir->d_name);
        if(!is_dir(workdir->d_name)) {
@@ -563,7 +649,7 @@ int verbose;
                puts("skipping cruft file, perhaps you should delete it.");
        }
        else if(!is_datestr(workdir->d_name)) {
-           if(verbose)
+           if(verbose && (strcmp(workdir->d_name, "lost+found")!=0) )
                puts("skipping cruft directory, perhaps you should delete it.");
        }
        else if(rmdir(workdir->d_name) == 0) {
@@ -575,8 +661,9 @@ int verbose;
 }
 
 
-int mkholdingdir(diskdir)
-char *diskdir;
+int
+mkholdingdir(
+    char *     diskdir)
 {
     struct stat stat_hdp;
     int success = 1;