Imported Upstream version 3.2.0
[debian/amanda] / server-src / amcleanupdisk.c
index 657ad0103cb7e4c751c271f3ca0bf1a906928ed8..2ba6fb0d82b8f1181261416d7b6c302fc4b0b1dc 100644 (file)
  * file named AUTHORS, in the root directory of this distribution.
  */
 /*
- * $Id: amcleanupdisk.c,v 1.1.2.6.4.3.2.2 2002/11/05 01:59:23 martinea Exp $
+ * $Id: amcleanupdisk.c 7238 2007-07-06 20:03:37Z dustin $
  */
 #include "amanda.h"
 
 #include "conffile.h"
 #include "diskfile.h"
 #include "clock.h"
-#include "version.h"
 #include "holding.h"
 #include "infofile.h"
 #include "server_util.h"
 
-sl_t *holding_list;
-char *datestamp;
+/* Utility funcitons */
 
-/* local functions */
-int main P((int argc, char **argv));
-void check_holdingdisk P((char *diskdir, char *datestamp));
-void check_disks P((void));
-
-int main(main_argc, main_argv)
-int main_argc;
-char **main_argv;
+/* Call open_infofile() with the infofile from the configuration
+ */
+static void
+init_infofile(void)
 {
-    struct passwd *pw;
-    char *dumpuser;
-    int fd;
-    disklist_t *diskqp;
-    char *conffile;
-    char *conf_diskfile;
-    char *conf_infofile;
-
-    for(fd = 3; fd < FD_SETSIZE; fd++) {
-       /*
-        * Make sure nobody spoofs us with a lot of extra open files
-        * that would cause an open we do to get a very high file
-        * descriptor, which in turn might be used as an index into
-        * an array (e.g. an fd_set).
-        */
-       close(fd);
-    }
-
-    safe_cd();
-
-    set_pname("amcleanupdisk");
-
-    if(main_argc != 2) {
-       error("Usage: amcleanupdisk%s <confdir>", versionsuffix());
-    }
-
-    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);
-    }
-    amfree(conffile);
-    conf_diskfile = getconf_str(CNF_DISKFILE);
-    if (*conf_diskfile == '/') {
-       conf_diskfile = stralloc(conf_diskfile);
-    } else {
-       conf_diskfile = stralloc2(config_dir, conf_diskfile);
-    }
-    if((diskqp = read_diskfile(conf_diskfile)) == NULL) {
-       error("could not load disklist %s", conf_diskfile);
-    }
-    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)) {
-       error("could not open info db \"%s\"", conf_infofile);
+    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);
-
-    datestamp = construct_datestamp(NULL);
-
-    dumpuser = getconf_str(CNF_DUMPUSER);
-    if((pw = getpwnam(dumpuser)) == NULL) {
-       error("dumpuser %s not found in password file", dumpuser);
-    }
-    if(pw->pw_uid != getuid()) {
-       error("must run amcleanupdisk as user %s", dumpuser);
-    }
-
-    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(diskdir, datestamp)
-char *diskdir, *datestamp;
+/* 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)
 {
-    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;
-    int dl, l;
 
-    dirname = vstralloc(diskdir, "/", datestamp, NULL);
-    dl = strlen(dirname);
+    dbprintf(_("Corrupted dump of DLE %s:%s found; setting force-no-bump.\n"),
+       hostname, disk);
 
-    if((workdir = opendir(dirname)) == NULL) {
-       amfree(dirname);
-       return;
+    get_info(hostname, disk, &info);
+    CLR(info.command, FORCE_BUMP);
+    SET(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));
     }
+}
 
-    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;
-       }
+int
+main(
+    int                argc,
+    char **    argv)
+{
+    FILE *verbose_output = NULL;
+    char *cfg_opt = NULL;
+    char *conf_diskfile;
+    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();
 
-       tmpname = newvstralloc(tmpname,
-                              dirname, "/", entry->d_name,
-                              NULL);
+    set_pname("amcleanupdisk");
 
-       destname = newstralloc(destname, tmpname);
-       destname[dl + 1 + l - 4] = '\0';
+    dbopen(DBG_SUBDIR_SERVER);
 
-       amfree(hostname);
-       amfree(diskname);
-       filetype = get_amanda_names(tmpname, &hostname, &diskname, &level);
-       if(filetype != F_DUMPFILE) {
-           continue;
-       }
+    if(argc < 2) {
+       error(_("Usage: amcleanupdisk <config>"));
+       /*NOTREACHED*/
+    }
 
-       dp = lookup_disk(hostname, diskname);
+    /* parse options */
+    if (argc >= 2 && strcmp(argv[1], "-v") == 0) {
+       verbose_output = stderr;
+       cfg_opt = argv[2];
+    } else {
+       cfg_opt = argv[1];
+    }
 
-       if (dp == NULL) {
-           continue;
-       }
+    config_init(CONFIG_INIT_EXPLICIT_NAME,
+               cfg_opt);
 
-       if(level < 0 || level > 9) {
-           continue;
-       }
+    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);
 
-       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));
-           }
-       } else {
-           fprintf(stderr,"rename_tmp_holding(%s) failed\n", destname);
+    if (config_errors(NULL) >= CFGERR_WARNINGS) {
+       config_print_errors();
+       if (config_errors(NULL) >= CFGERR_ERRORS) {
+           g_critical(_("errors processing config file"));
        }
     }
-    closedir(workdir);
 
-    /* try to zap the potentially empty working dir */
-    /* ignore any errors -- it either works or it doesn't */
-    (void) rmdir(dirname);
+    check_running_as(RUNNING_AS_DUMPUSER);
 
-    amfree(diskname);
-    amfree(hostname);
-    amfree(destname);
-    amfree(dirname);
-}
+    dbrename(get_config_name(), DBG_SUBDIR_SERVER);
 
+    init_infofile();
 
-void check_disks()
-{
-    holdingdisk_t *hdisk;
-    sle_t *dir;
+    /* actually perform the cleanup */
+    holding_cleanup(corrupt_dle, verbose_output);
 
-    for(dir = holding_list->first; dir !=NULL; dir = dir->next) {
-       for(hdisk = getconf_holdingdisks(); hdisk != NULL; hdisk = hdisk->next)
-           check_holdingdisk(hdisk->diskdir, dir->name);
-    }
+    close_infofile();
+    return 0;
 }
+