Imported Upstream version 2.6.1
[debian/amanda] / server-src / amcleanupdisk.c
index c358194d1e2a6aa0d20ad48cddb24b9f3f1df17e..95dd3d377659714614137fbcbdc74770b83b5c4e 100644 (file)
@@ -24,7 +24,7 @@
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amcleanupdisk.c,v 1.22.2.1 2006/10/03 18:57:25 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);
+/* 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);
+       /*NOTREACHED*/
+    }
+    amfree(conf_infofile);
+}
+
+/* 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;
+
+    dbprintf(_("Corrupted dump of DLE %s:%s found; setting force-no-bump.\n"),
+       hostname, disk);
+
+    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));
+    }
+}
 
 int
 main(
-    int                main_argc,
-    char **    main_argv)
+    int                argc,
+    char **    argv)
 {
-    struct passwd *pw;
-    char *dumpuser;
-    disklist_t diskq;
-    char *conffile;
+    FILE *verbose_output = NULL;
+    char *cfg_opt = NULL;
     char *conf_diskfile;
-    char *conf_infofile;
+    disklist_t diskq;
+
+    /*
+     * 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"); 
 
     safe_fd(-1, 0);
     safe_cd();
@@ -63,175 +102,44 @@ main(
 
     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());
+    if(argc < 2) {
+       error(_("Usage: amcleanupdisk%s <config>"), versionsuffix());
        /*NOTREACHED*/
     }
 
-    config_name = main_argv[1];
-
-    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*/
+    /* parse options */
+    if (argc >= 2 && strcmp(argv[1], "-v") == 0) {
+       verbose_output = stderr;
+       cfg_opt = argv[2];
+    } else {
+       cfg_opt = argv[1];
     }
-    amfree(conffile);
 
-    dbrename(config_name, DBG_SUBDIR_SERVER);
+    config_init(CONFIG_INIT_EXPLICIT_NAME,
+               cfg_opt);
 
-    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);
-       /*NOTREACHED*/
-    }
+    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+    read_diskfile(conf_diskfile, &diskq);
+    /* diskq also ends up in a global, used by holding_cleanup */
     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);
-    }
-    if (open_infofile(conf_infofile) < 0) {
-       error("could not open info db \"%s\"", conf_infofile);
-       /*NOTREACHED*/
+    if (config_errors(NULL) >= CFGERR_WARNINGS) {
+       config_print_errors();
+       if (config_errors(NULL) >= CFGERR_ERRORS) {
+           g_critical(_("errors processing config file"));
+       }
     }
-    amfree(conf_infofile);
 
-    datestamp = construct_datestamp(NULL);
+    check_running_as(RUNNING_AS_DUMPUSER);
 
-    dumpuser = getconf_str(CNF_DUMPUSER);
-    if((pw = getpwnam(dumpuser)) == NULL) {
-       error("dumpuser %s not found in password file", dumpuser);
-       /*NOTREACHED*/
-    }
+    dbrename(get_config_name(), DBG_SUBDIR_SERVER);
 
-    if(pw->pw_uid != getuid()) {
-       error("must run amcleanupdisk as user %s", dumpuser);
-       /*NOTREACHED*/
-    }
-
-    holding_list = pick_all_datestamp(1);
+    init_infofile();
 
-    check_disks();
+    /* actually perform the cleanup */
+    holding_cleanup(corrupt_dle, verbose_output);
 
     close_infofile();
-
-    free_sl(holding_list);
-    holding_list = NULL;
-    amfree(config_dir);
     return 0;
 }
 
-
-void
-check_holdingdisk(
-    char *     diskdir,
-    char *     datestamp)
-{
-    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;
-
-    dirname = vstralloc(diskdir, "/", datestamp, NULL);
-    dl = strlen(dirname);
-
-    if((workdir = opendir(dirname)) == NULL) {
-       amfree(dirname);
-       return;
-    }
-
-    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 = get_amanda_names(tmpname, &hostname, &diskname, &level);
-       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);
-       }
-    }
-    closedir(workdir);
-
-    /* try to zap the potentially empty working dir */
-    /* ignore any errors -- it either works or it doesn't */
-    (void) rmdir(dirname);
-
-    amfree(diskname);
-    amfree(hostname);
-    amfree(destname);
-    amfree(dirname);
-}
-
-
-void
-check_disks(void)
-{
-    holdingdisk_t *hdisk;
-    sle_t *dir;
-
-    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);
-    }
-}