2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1991-1999 University of Maryland at College Park
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.
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.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
27 * $Id: server_util.c,v 1.17 2006/05/25 01:47:20 johnfranks Exp $
32 #include "server_util.h"
38 #include "pipespawn.h"
43 const char *cmdstr[] = {
44 "BOGUS", "QUIT", "QUITTING", "DONE", "PARTIAL",
45 "START", "FILE-DUMP", "PORT-DUMP", "CONTINUE", "ABORT",/* dumper cmds */
46 "FAILED", "TRY-AGAIN", "NO-ROOM", "RQ-MORE-DISK", /* dumper results */
47 "ABORT-FINISHED", "BAD-COMMAND", /* dumper results */
48 "START-TAPER", "FILE-WRITE", "NEW-TAPE", "NO-NEW-TAPE",
50 "PARTDONE", "PORT-WRITE", "DUMPER-STATUS", /* taper cmds */
51 "PORT", "TAPE-ERROR", "TAPER-OK", /* taper results */
63 struct cmdargs *cmdargs = g_new0(struct cmdargs, 1);
66 g_printf("%s> ", get_pname());
73 line = stralloc("QUIT");
76 dbprintf(_("getcmd: %s\n"), line);
78 cmdargs->argv = split_quoted_strings(line);
79 cmdargs->argc = g_strv_length(cmdargs->argv);
84 if (cmdargs->argc < 1) {
88 for(cmd_i=BOGUS; cmdstr[cmd_i] != NULL; cmd_i++)
89 if(strcmp(cmdargs->argv[0], cmdstr[cmd_i]) == 0) {
99 SELECT_ARG_TYPE ready;
108 nfound = select(1, &ready, NULL, NULL, &to);
109 if (nfound && FD_ISSET(0, &ready)) {
118 struct cmdargs *cmdargs)
123 g_strfreev(cmdargs->argv);
127 printf_arglist_function1(void putresult, cmd_t, result, const char *, format)
131 arglist_start(argp, format);
132 dbprintf(_("putresult: %d %s\n"), result, cmdstr[result]);
133 g_printf("%s ", cmdstr[result]);
134 g_vprintf(format, argp);
140 amhost_get_security_conf(
144 if(!string || !*string)
147 if(strcmp(string, "krb5principal")==0)
148 return(getconf_str(CNF_KRB5PRINCIPAL));
149 else if(strcmp(string, "krb5keytab")==0)
150 return(getconf_str(CNF_KRB5KEYTAB));
152 if(!arg || !((am_host_t *)arg)->disks) return(NULL);
154 if(strcmp(string, "amandad_path")==0)
155 return ((am_host_t *)arg)->disks->amandad_path;
156 else if(strcmp(string, "client_username")==0)
157 return ((am_host_t *)arg)->disks->client_username;
158 else if(strcmp(string, "ssh_keys")==0)
159 return ((am_host_t *)arg)->disks->ssh_keys;
170 char *hostinfodir, *old_hostinfodir, *Xhostinfodir;
171 char *diskdir, *old_diskdir, *Xdiskdir;
172 char *infofile, *old_infofile, *Xinfofile;
176 if (stat(infodir, &statbuf) != 0) {
180 for (dp = dl->head; dp != NULL; dp = dp->next) {
181 hostinfodir = sanitise_filename(dp->host->hostname);
182 diskdir = sanitise_filename(dp->name);
183 infofile = vstralloc(infodir, "/", hostinfodir, "/", diskdir,
185 if (stat(infofile, &statbuf) == -1 && errno == ENOENT) {
186 old_hostinfodir = old_sanitise_filename(dp->host->hostname);
187 old_diskdir = old_sanitise_filename(dp->name);
188 old_infofile = vstralloc(infodir, old_hostinfodir, "/",
189 old_diskdir, "/info", NULL);
190 if (stat(old_infofile, &statbuf) == 0) {
193 while (diskp != NULL) {
194 Xhostinfodir = sanitise_filename(diskp->host->hostname);
195 Xdiskdir = sanitise_filename(diskp->name);
196 Xinfofile = vstralloc(infodir, "/", Xhostinfodir, "/",
197 Xdiskdir, "/info", NULL);
198 if (strcmp(old_infofile, Xinfofile) == 0) {
206 if (other_dle_match == 0) {
207 if(mkpdir(infofile, (mode_t)0755, (uid_t)-1,
209 *errmsg = vstralloc("Can't create directory for ",
213 if(copy_file(infofile, old_infofile, errmsg) == -1)
227 pp_script_t *pp_script,
228 execute_on_t execute_on,
234 int scriptin, scriptout, scripterr;
241 char level_number[NUM_STR_SIZE];
243 if ((pp_script_get_execute_on(pp_script) & execute_on) == 0)
245 if (pp_script_get_execute_where(pp_script) != ES_SERVER)
248 plugin = pp_script_get_plugin(pp_script);
249 k = property_argv_size(pp_script_get_property(pp_script));
250 argvchild = g_new0(char *, 16+k);
251 cmd = vstralloc(APPLICATION_DIR, "/", plugin, NULL);
253 argvchild[i++] = plugin;
255 switch (execute_on) {
256 case EXECUTE_ON_PRE_DLE_AMCHECK:
257 argvchild[i++] = "PRE-DLE-AMCHECK"; break;
258 case EXECUTE_ON_PRE_HOST_AMCHECK:
259 argvchild[i++] = "PRE-HOST-AMCHECK"; break;
260 case EXECUTE_ON_POST_DLE_AMCHECK:
261 argvchild[i++] = "POST-DLE-AMCHECK"; break;
262 case EXECUTE_ON_POST_HOST_AMCHECK:
263 argvchild[i++] = "POST-HOST-AMCHECK"; break;
264 case EXECUTE_ON_PRE_DLE_ESTIMATE:
265 argvchild[i++] = "PRE-DLE-ESTIMATE"; break;
266 case EXECUTE_ON_PRE_HOST_ESTIMATE:
267 argvchild[i++] = "PRE-HOST-ESTIMATE"; break;
268 case EXECUTE_ON_POST_DLE_ESTIMATE:
269 argvchild[i++] = "POST-DLE-ESTIMATE"; break;
270 case EXECUTE_ON_POST_HOST_ESTIMATE:
271 argvchild[i++] = "POST-HOST-ESTIMATE"; break;
272 case EXECUTE_ON_PRE_DLE_BACKUP:
273 argvchild[i++] = "PRE-DLE-BACKUP"; break;
274 case EXECUTE_ON_PRE_HOST_BACKUP:
275 argvchild[i++] = "PRE-HOST-BACKUP"; break;
276 case EXECUTE_ON_POST_DLE_BACKUP:
277 argvchild[i++] = "POST-DLE-BACKUP"; break;
278 case EXECUTE_ON_POST_HOST_BACKUP:
279 argvchild[i++] = "POST-HOST-BACKUP"; break;
280 case EXECUTE_ON_PRE_RECOVER:
281 case EXECUTE_ON_POST_RECOVER:
282 case EXECUTE_ON_PRE_LEVEL_RECOVER:
283 case EXECUTE_ON_POST_LEVEL_RECOVER:
284 case EXECUTE_ON_INTER_LEVEL_RECOVER:
286 // ERROR these script can't be executed on server.
291 argvchild[i++] = "--execute-where";
292 argvchild[i++] = "server";
295 argvchild[i++] = "--config";
296 argvchild[i++] = config;
298 if (dp->host->hostname) {
299 argvchild[i++] = "--host";
300 argvchild[i++] = dp->host->hostname;
303 argvchild[i++] = "--disk";
304 argvchild[i++] = dp->name;
307 argvchild[i++] = "--device";
308 argvchild[i++] = dp->device;
311 g_snprintf(level_number, SIZEOF(level_number), "%d", level);
312 argvchild[i++] = "--level";
313 argvchild[i++] = level_number;
316 i += property_add_to_argv(&argvchild[i], pp_script_get_property(pp_script));
317 argvchild[i++] = NULL;
319 scripterr = fileno(stderr);
320 scriptpid = pipespawnv(cmd, STDIN_PIPE|STDOUT_PIPE, 0, &scriptin,
321 &scriptout, &scripterr, argvchild);
324 streamout = fdopen(scriptout, "r");
326 while((line = agets(streamout)) != NULL) {
327 dbprintf("script: %s\n", line);
331 waitpid(scriptpid, NULL, 0);
337 execute_on_t execute_on,
342 GSList *pp_scriptlist;
344 for (pp_scriptlist = dp->pp_scriptlist; pp_scriptlist != NULL;
345 pp_scriptlist = pp_scriptlist->next) {
346 run_server_script(pp_scriptlist->data, execute_on, config, dp, level);
355 char *amcleanup_program;
356 char *amcleanup_options[4];
358 switch(amcleanup_pid = fork()) {
362 case 0: /* child process */
363 amcleanup_program = vstralloc(sbindir, "/", "amcleanup", versionsuffix(), NULL);
364 amcleanup_options[0] = amcleanup_program;
365 amcleanup_options[1] = "-p";
366 amcleanup_options[2] = config_name;
367 amcleanup_options[3] = NULL;
368 execve(amcleanup_program, amcleanup_options, safe_env());
369 error("exec %s: %s", amcleanup_program, strerror(errno));
374 waitpid(amcleanup_pid, NULL, 0);
386 log = fopen(logfile, "r");
388 return stralloc("UNKNOWN");
390 while(fgets(line, 1024, log)) {
391 if (strncmp_const(line, "INFO ") == 0) {
395 skip_non_whitespace(s, ch);
397 skip_whitespace(s, ch);
398 skip_non_whitespace(s, ch);
400 skip_whitespace(s, ch);
401 if (strncmp_const(s-1, "pid ") == 0) {
402 process_name = stralloc(process_name);
409 return stralloc("UNKNOWN");