065547dcd4ffedf82eb8ba1c1713c9945d8fbef4
[debian/amanda] / server-src / amtrmlog.c
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: amtrmlog.c,v 1.1.2.3.4.1.2.2 2003/01/01 23:28:53 martinea Exp $
28  *
29  * trims number of index files to only those still in system.  Well
30  * actually, it keeps a few extra, plus goes back to the last level 0
31  * dump.
32  */
33
34 #include "amanda.h"
35 #include "arglist.h"
36 #ifdef HAVE_NETINET_IN_SYSTM_H
37 #include <netinet/in_systm.h>
38 #endif
39 #include "conffile.h"
40 #include "diskfile.h"
41 #include "tapefile.h"
42 #include "find.h"
43 #include "version.h"
44
45 int main(argc, argv)
46 int argc;
47 char **argv;
48 {
49     disklist_t *diskl;
50     int no_keep;                        /* files per system to keep */
51     int fd;
52     char **output_find_log;
53     DIR *dir;
54     struct dirent *adir;
55     char **name;
56     int useful;
57     char *olddir;
58     char *oldfile = NULL, *newfile = NULL;
59     time_t today, date_keep;
60     char *logname = NULL;
61     struct stat stat_log;
62     struct stat stat_old;
63     char *conffile;
64     char *conf_diskfile;
65     char *conf_tapelist;
66     char *conf_logdir;
67     int amtrmidx_debug = 0;
68
69     for(fd = 3; fd < FD_SETSIZE; fd++) {
70         /*
71          * Make sure nobody spoofs us with a lot of extra open files
72          * that would cause an open we do to get a very high file
73          * descriptor, which in turn might be used as an index into
74          * an array (e.g. an fd_set).
75          */
76         close(fd);
77     }
78
79     safe_cd();
80
81     set_pname("amtrmlog");
82
83     if (argc > 1 && strcmp(argv[1], "-t") == 0) {
84         amtrmidx_debug = 1;
85         argc--;
86         argv++;
87     }
88
89     if (argc != 2) {
90         fprintf(stderr, "Usage: %s [-t] <config>\n", argv[0]);
91         return 1;
92     }
93
94     dbopen();
95     dbprintf(("%s: version %s\n", argv[0], version()));
96
97     config_name = argv[1];
98
99     config_dir = vstralloc(CONFIG_DIR, "/", config_name, "/", NULL);
100     conffile = stralloc2(config_dir, CONFFILE_NAME);
101     if(read_conffile(conffile)) {
102         error("errors processing config file \"%s\"", conffile);
103     }
104     amfree(conffile);
105     conf_diskfile = getconf_str(CNF_DISKFILE);
106     if (*conf_diskfile == '/') {
107         conf_diskfile = stralloc(conf_diskfile);
108     } else {
109         conf_diskfile = stralloc2(config_dir, conf_diskfile);
110     }
111     if((diskl = read_diskfile(conf_diskfile)) == NULL) {
112         error("could not load disklist %s", conf_diskfile);
113     }
114     amfree(conf_diskfile);
115     conf_tapelist = getconf_str(CNF_TAPELIST);
116     if (*conf_tapelist == '/') {
117         conf_tapelist = stralloc(conf_tapelist);
118     } else {
119         conf_tapelist = stralloc2(config_dir, conf_tapelist);
120     }
121     if (read_tapelist(conf_tapelist)) {
122         error("could not load tapelist \"%s\"", conf_tapelist);
123     }
124     amfree(conf_tapelist);
125
126     today = time((time_t *)NULL);
127     date_keep = today - (getconf_int(CNF_DUMPCYCLE)*86400);
128
129     output_find_log = find_log(NULL,0,NULL);
130
131     /* determine how many log to keep */
132     no_keep = getconf_int(CNF_TAPECYCLE) * 2;
133     dbprintf(("Keeping %d log file%s\n", no_keep, (no_keep == 1) ? "" : "s"));
134
135     conf_logdir = getconf_str(CNF_LOGDIR);
136     if (*conf_logdir == '/') {
137         conf_logdir = stralloc(conf_logdir);
138     } else {
139         conf_logdir = stralloc2(config_dir, conf_logdir);
140     }
141     olddir = vstralloc(conf_logdir, "/oldlog", NULL);
142     if (mkpdir(olddir, 02700, (uid_t)-1, (gid_t)-1) != 0) {
143         error("could not create parents of %s: %s", olddir, strerror(errno));
144     }
145     if (mkdir(olddir, 02700) != 0 && errno != EEXIST) {
146         error("could not create %s: %s", olddir, strerror(errno));
147     }
148
149     if (stat(olddir,&stat_old) == -1) {
150         error("can't stat oldlog directory \"%s\": %s", olddir, strerror(errno));
151     }
152
153     if (!S_ISDIR(stat_old.st_mode)) {
154         error("Oldlog directory \"%s\" is not a directory", olddir);
155     }
156     if ((dir = opendir(conf_logdir)) == NULL) {
157         error("could not open log directory \"%s\": %s", conf_logdir, strerror(errno));
158     }
159     while ((adir = readdir(dir)) != NULL) {
160         if(strncmp(adir->d_name,"log.",4)==0) {
161             useful = 0;
162             for (name = output_find_log; *name != NULL; name++) {
163                 if(strncmp(adir->d_name, *name, 12) == 0) {
164                     useful = 1;
165                 }
166             }
167             logname = newvstralloc(logname,
168                                    conf_logdir, "/", adir->d_name, NULL);
169             if(stat(logname, &stat_log) == 0) {
170                 if(stat_log.st_mtime > date_keep) {
171                     useful = 1;
172                 }
173             }
174             if(! useful) {
175                 oldfile = newvstralloc(oldfile,
176                                        conf_logdir, "/", adir->d_name, NULL);
177                 newfile = newvstralloc(newfile,
178                                        olddir, "/", adir->d_name, NULL);
179                 if(rename(oldfile, newfile) != 0) {
180                     error("could not rename \"%s\" to \"%s\": %s",
181                           oldfile, newfile, strerror(errno));
182                 }
183             }
184         }
185     }
186     closedir(dir);
187     for (name = output_find_log; *name != NULL; name++) {
188         amfree(*name);
189     }
190     amfree(output_find_log);
191     amfree(logname);
192     amfree(oldfile);
193     amfree(newfile);
194     amfree(olddir);
195     amfree(config_dir);
196     amfree(conf_logdir);
197
198     dbclose();
199
200     return 0;
201 }