Imported Upstream version 2.6.0
[debian/amanda] / server-src / amcleanupdisk.c
index 924e3cdee93ef245970cd81edb8c8d303788fa35..a67154cbbf5657db027e1334de3f62e2558b2e15 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amcleanupdisk.c,v 1.22 2006/07/25 18:27:57 martinea Exp $
+ * $Id: amcleanupdisk.c 7238 2007-07-06 20:03:37Z dustin $
  */
 #include "amanda.h"
 
 #include "infofile.h"
 #include "server_util.h"
 
-sl_t *holding_list;
-char *datestamp;
+/* Utility funcitons */
 
-/* local functions */
-int main(int argc, char **argv);
-void check_holdingdisk(char *diskdir, char *datestamp);
-void check_disks(void);
-
-int
-main(
-    int                main_argc,
-    char **    main_argv)
+/* Call open_diskfile() with the diskfile from the configuration
+ */
+static void
+init_diskfile(void)
 {
-    struct passwd *pw;
-    char *dumpuser;
-    disklist_t diskq;
-    char *conffile;
-    char *conf_diskfile;
-    char *conf_infofile;
-
-    safe_fd(-1, 0);
-    safe_cd();
-
-    set_pname("amcleanupdisk");
-
-    dbopen(DBG_SUBDIR_SERVER);
-
-    /* Don't die when child closes pipe */
-    signal(SIGPIPE, SIG_IGN);
-
-    if(main_argc < 2) {
-       error("Usage: amcleanupdisk%s <config>", versionsuffix());
-       /*NOTREACHED*/
-    }
-
-    config_name = main_argv[1];
+    char *conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+    disklist_t diskq; /* never used, but required by read_diskfile */
 
-    config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
-
-    conffile = stralloc2(config_dir, CONFFILE_NAME);
-    if(read_conffile(conffile)) {
-       error("errors processing config file \"%s\"", conffile);
-       /*NOTREACHED*/
-    }
-    amfree(conffile);
-
-    dbrename(config_name, DBG_SUBDIR_SERVER);
-
-    conf_diskfile = getconf_str(CNF_DISKFILE);
-    if (*conf_diskfile == '/') {
-       conf_diskfile = stralloc(conf_diskfile);
-    } else {
-       conf_diskfile = stralloc2(config_dir, conf_diskfile);
-    }
     if (read_diskfile(conf_diskfile, &diskq) < 0) {
-       error("could not load disklist %s", conf_diskfile);
+       error(_("could not load disklist %s"), conf_diskfile);
        /*NOTREACHED*/
     }
     amfree(conf_diskfile);
+}
 
-    conf_infofile = getconf_str(CNF_INFOFILE);
-    if (*conf_infofile == '/') {
-       conf_infofile = stralloc(conf_infofile);
-    } else {
-       conf_infofile = stralloc2(config_dir, conf_infofile);
-    }
+/* Call open_infofile() with the infofile from the configuration
+ */
+static void
+init_infofile(void)
+{
+    char *conf_infofile = config_dir_relative(getconf_str(CNF_INFOFILE));
     if (open_infofile(conf_infofile) < 0) {
-       error("could not open info db \"%s\"", conf_infofile);
+       error(_("could not open info db \"%s\""), conf_infofile);
        /*NOTREACHED*/
     }
     amfree(conf_infofile);
+}
 
-    datestamp = construct_datestamp(NULL);
+/* A callback for holding_cleanup to mark corrupt DLEs with force_no_bump
+ * for their next run.
+ *
+ * @param hostname: hostname of DLE
+ * @param disk: disk of DLE
+ */
+static void
+corrupt_dle(
+    char *hostname,
+    char *disk)
+{
+    info_t info;
 
-    dumpuser = getconf_str(CNF_DUMPUSER);
-    if((pw = getpwnam(dumpuser)) == NULL) {
-       error("dumpuser %s not found in password file", dumpuser);
-       /*NOTREACHED*/
-    }
+    dbprintf(_("Corrupted dump of DLE %s:%s found; setting force-no-bump.\n"),
+       hostname, disk);
 
-    if(pw->pw_uid != getuid()) {
-       error("must run amcleanupdisk as user %s", dumpuser);
-       /*NOTREACHED*/
+    get_info(hostname, disk, &info);
+    info.command &= ~FORCE_BUMP;
+    info.command |= FORCE_NO_BUMP;
+    if(put_info(hostname, disk, &info)) {
+       dbprintf(_("could not put info record for %s:%s: %s"),
+             hostname, disk, strerror(errno));
     }
-
-    holding_list = pick_all_datestamp(1);
-
-    check_disks();
-
-    close_infofile();
-
-    free_sl(holding_list);
-    holding_list = NULL;
-    amfree(config_dir);
-    return 0;
 }
 
-
-void
-check_holdingdisk(
-    char *     diskdir,
-    char *     datestamp)
+int
+main(
+    int                argc,
+    char **    argv)
 {
-    DIR *workdir;
-    struct dirent *entry;
-    char *dirname = NULL;
-    char *tmpname = NULL;
-    char *destname = NULL;
-    char *hostname = NULL;
-    char *diskname = NULL;
-    disk_t *dp;
-    filetype_t filetype;
-    info_t info;
-    int level;
-    size_t dl, l;
+    FILE *verbose_output = 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"); 
 
-    dirname = vstralloc(diskdir, "/", datestamp, NULL);
-    dl = strlen(dirname);
+    safe_fd(-1, 0);
+    safe_cd();
+
+    set_pname("amcleanupdisk");
+
+    dbopen(DBG_SUBDIR_SERVER);
 
-    if((workdir = opendir(dirname)) == NULL) {
-       amfree(dirname);
-       return;
+    if(argc < 2) {
+       error(_("Usage: amcleanupdisk%s <config>"), versionsuffix());
+       /*NOTREACHED*/
     }
 
-    while((entry = readdir(workdir)) != NULL) {
-       if(is_dot_or_dotdot(entry->d_name)) {
-           continue;
-       }
-
-       if((l = strlen(entry->d_name)) < 7 ) {
-           continue;
-       }
-
-       if(strncmp(&entry->d_name[l-4],".tmp",4) != 0) {
-           continue;
-       }
-
-       tmpname = newvstralloc(tmpname,
-                              dirname, "/", entry->d_name,
-                              NULL);
-
-       destname = newstralloc(destname, tmpname);
-       destname[dl + 1 + l - 4] = '\0';
-
-       amfree(hostname);
-       amfree(diskname);
-       filetype = holding_file_read_header(tmpname, &hostname, &diskname, &level, NULL);
-       amfree(tmpname);
-       if(filetype != F_DUMPFILE) {
-           continue;
-       }
-
-       dp = lookup_disk(hostname, diskname);
-
-       if (dp == NULL) {
-           continue;
-       }
-
-       if(level < 0 || level > 9) {
-           continue;
-       }
-
-       if(rename_tmp_holding(destname, 0)) {
-           get_info(dp->host->hostname, dp->name, &info);
-           info.command &= ~FORCE_BUMP;
-           info.command |= FORCE_NO_BUMP;
-           if(put_info(dp->host->hostname, dp->name, &info)) {
-               error("could not put info record for %s:%s: %s",
-                     dp->host->hostname, dp->name, strerror(errno));
-               /*NOTREACHED*/
-           }
-       } else {
-           fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
-       }
+    /* parse options */
+    if (argc >= 2 && strcmp(argv[1], "-v") == 0) {
+       verbose_output = stderr;
+       cfg_opt = argv[2];
+    } else {
+       cfg_opt = argv[1];
     }
-    closedir(workdir);
 
-    /* try to zap the potentially empty working dir */
-    /* ignore any errors -- it either works or it doesn't */
-    (void) rmdir(dirname);
+    config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_FATAL,
+               cfg_opt);
 
-    amfree(diskname);
-    amfree(hostname);
-    amfree(destname);
-    amfree(dirname);
-}
+    check_running_as(RUNNING_AS_DUMPUSER);
 
+    dbrename(config_name, DBG_SUBDIR_SERVER);
 
-void
-check_disks(void)
-{
-    holdingdisk_t *hdisk;
-    sle_t *dir;
+    init_diskfile();
+    init_infofile();
 
-    for(dir = holding_list->first; dir !=NULL; dir = dir->next) {
-       for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
-           check_holdingdisk(holdingdisk_get_diskdir(hdisk), dir->name);
-    }
+    /* actually perform the cleanup */
+    holding_cleanup(corrupt_dle, verbose_output);
+
+    close_infofile();
+    return 0;
 }
+