Merge commit 'upstream/3.1.0'
[debian/amanda] / server-src / changer.c
diff --git a/server-src/changer.c b/server-src/changer.c
deleted file mode 100644 (file)
index ad9a832..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Amanda, The Advanced Maryland Automatic Network Disk Archiver
- * Copyright (c) 1991-1998 University of Maryland at College Park
- * All Rights Reserved.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of U.M. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  U.M. makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: the Amanda Development Team.  Its members are listed in a
- * file named AUTHORS, in the root directory of this distribution.
- */
-/*
- * $Id: changer.c,v 1.36 2006/08/24 01:57:16 paddy_s Exp $
- *
- * interface routines for tape changers
- */
-#include "amanda.h"
-#include "util.h"
-#include "conffile.h"
-#include "version.h"
-
-#include "changer.h"
-
-/*
- * If we don't have the new-style wait access functions, use our own,
- * compatible with old-style BSD systems at least.  Note that we don't
- * care about the case w_stopval == WSTOPPED since we don't ask to see
- * stopped processes, so should never get them from wait.
- */
-#ifndef WEXITSTATUS
-#   define WEXITSTATUS(r)       (((union wait *) &(r))->w_retcode)
-#   define WTERMSIG(r)          (((union wait *) &(r))->w_termsig)
-
-#   undef  WIFSIGNALED
-#   define WIFSIGNALED(r)       (((union wait *) &(r))->w_termsig != 0)
-#endif
-
-
-int changer_debug = 0;
-char *changer_resultstr = NULL;
-
-static pid_t tpchanger_pid = -1;
-static int tpchanger_stdout = -1;
-static int tpchanger_stdin = -1;
-
-/* local functions */
-static int changer_command(char *cmd, char *arg);
-static int report_bad_resultstr(char *cmd);
-static int run_changer_command(char *cmd, char *arg, char **slotstr, char **rest);
-
-int
-changer_init(void)
-{
-    return strcmp(getconf_str(CNF_TPCHANGER), "") != 0;
-}
-
-
-static int
-report_bad_resultstr(char *cmd)
-{
-    char *s;
-
-    s = vstrallocf(_("<error> badly formed result from changer command %s: \"%s\""),
-                 cmd, changer_resultstr);
-    amfree(changer_resultstr);
-    changer_resultstr = s;
-    return 2;
-}
-
-static int
-run_changer_command(
-    char *     cmd,
-    char *     arg,
-    char **    slotstr,
-    char **    rest)
-{
-    int exitcode;
-    char *result_copy;
-    char *slot;
-    char *s;
-    int ch;
-
-    if (slotstr) {
-        *slotstr = NULL;
-    }
-    if (rest) {
-        *rest = NULL;
-    }
-    exitcode = changer_command(cmd, arg);
-    s = changer_resultstr;
-    ch = *s++;
-
-    skip_whitespace(s, ch);
-    if(ch == '\0') return report_bad_resultstr(cmd);
-    slot = s - 1;
-    skip_non_whitespace(s, ch);
-    s[-1] = '\0';
-    if (slotstr) {
-        *slotstr = newstralloc(*slotstr, slot);
-    }
-    s[-1] = (char)ch;
-
-    skip_whitespace(s, ch);
-    if (rest) {
-        *rest = s - 1;
-    }
-
-    if(exitcode) {
-       if(ch == '\0') return report_bad_resultstr(cmd);
-       result_copy = stralloc(s - 1);
-       amfree(changer_resultstr);
-       changer_resultstr = result_copy;
-       return exitcode;
-    }
-    return 0;
-}
-
-int
-changer_reset(
-    char **    slotstr)
-{
-    char *rest;
-
-    return run_changer_command("-reset", (char *) NULL, slotstr, &rest);
-}
-
-int
-changer_clean(
-    char **    slotstr)
-{
-    char *rest;
-
-    return run_changer_command("-clean", (char *) NULL, slotstr, &rest);
-}
-
-int
-changer_eject(
-    char **    slotstr)
-{
-    char *rest;
-
-    return run_changer_command("-eject", (char *) NULL, slotstr, &rest);
-}
-
-int
-changer_loadslot(
-    char *inslotstr,
-    char **outslotstr,
-    char **devicename)
-{
-    char *rest;
-    int rc;
-
-    rc = run_changer_command("-slot", inslotstr, outslotstr, &rest);
-
-    if(rc) return rc;
-    if(*rest == '\0') return report_bad_resultstr("-slot");
-
-    *devicename = newstralloc(*devicename, rest);
-    return 0;
-}
-
-
-/*
- * This function is somewhat equal to changer_info with one additional
- * parameter, to get information, if the changer is able to search for
- * tapelabels himself. E.g. Barcodereader
- * The changer_script answers with an additional parameter, if it is able
- * to search. This one should be 1, if it is able to search, and 0 if it
- * knows about the extension. If the additional answer is omitted, the
- * changer is not able to search for a tape. 
- */
-
-int
-changer_query(
-    int *      nslotsp,
-    char **    curslotstr,
-    int *      backwardsp,
-    int *      searchable)
-{
-    char *rest;
-    int rc;
-
-    rc = run_changer_command("-info", (char *) NULL, curslotstr, &rest);
-    if(rc) return rc;
-
-    dbprintf(_("changer_query: changer return was %s\n"),rest);
-    if (sscanf(rest, "%d %d %d", nslotsp, backwardsp, searchable) != 3) {
-      if (sscanf(rest, "%d %d", nslotsp, backwardsp) != 2) {
-        return report_bad_resultstr("-info");
-      } else {
-        *searchable = 0;
-      }
-    }
-    dbprintf(_("changer_query: searchable = %d\n"),*searchable);
-    return 0;
-}
-
-int
-changer_info(
-    int *      nslotsp,
-    char **    curslotstr,
-    int *      backwardsp)
-{
-    char *rest;
-    int rc;
-
-    rc = run_changer_command("-info", (char *) NULL, curslotstr, &rest);
-    if(rc) return rc;
-
-    if (sscanf(rest, "%d %d", nslotsp, backwardsp) != 2) {
-       return report_bad_resultstr("-info");
-    }
-    return 0;
-}
-
-
-/* ---------------------------- */
-
-/*
- * This function first uses searchlabel and changer_search, if
- * the library is able to find a tape itself. If it is not, or if 
- * the tape could not be found, then the normal scan is done.
- *
- * See interface documentation in changer.h.
- */
-
-void
-changer_find(
-     void *    user_data,
-     int       (*user_init)(void *, int, int, int, int),
-     int       (*user_slot)(void *, int, char *, char *),
-     char *    searchlabel)
-{
-    char *slotstr, *device = NULL, *curslotstr = NULL;
-    int nslots, checked, backwards, rc, done, searchable;
-
-    rc = changer_query(&nslots, &curslotstr, &backwards, &searchable);
-
-    if (rc != 0) {
-        /* Problem with the changer script. Bail. */
-        g_fprintf(stderr, _("Changer problem: %s\n"), changer_resultstr);
-        amfree(curslotstr);
-        return;
-    }
-
-    done = user_init(user_data, rc, nslots, backwards, searchable);
-    amfree(curslotstr);
-   
-    if (searchlabel != NULL)
-    {
-      dbprintf(_("changer_find: looking for %s changer is searchable = %d\n"),
-               searchlabel, searchable);
-    } else {
-      dbprintf(_("changer_find: looking for NULL changer is searchable = %d\n"),
-               searchable);
-    }
-
-    if ((searchlabel!=NULL) && searchable && !done){
-      rc=changer_search(searchlabel, &curslotstr, &device);
-      if(rc == 0)
-        done = user_slot(user_data, rc, curslotstr, device);
-    }
-    slotstr = "current";
-    checked = 0;
-
-    while(!done && checked < nslots) {
-       rc = changer_loadslot(slotstr, &curslotstr, &device);
-       if(rc > 0)
-           done = user_slot(user_data, rc, curslotstr, device);
-       else if(!done)
-           done = user_slot(user_data, 0,  curslotstr, device);
-       amfree(curslotstr);
-       amfree(device);
-
-       checked += 1;
-       slotstr = "next";
-    }
-}
-
-/* ---------------------------- */
-
-void
-changer_current(
-    void *     user_data,
-    int                (*user_init)(void *, int, int, int, int),
-    int                (*user_slot)(void *, int, char *, char *))
-{
-    char *device = NULL, *curslotstr = NULL;
-    int nslots, backwards, rc, done, searchable;
-
-    rc = changer_query(&nslots, &curslotstr, &backwards, &searchable);
-    done = user_init(user_data, rc, nslots, backwards, searchable);
-    amfree(curslotstr);
-
-    rc = changer_loadslot("current", &curslotstr, &device);
-    if(rc > 0) {
-       done = user_slot(user_data, rc, curslotstr, device);
-    } else if(!done) {
-       done = user_slot(user_data, 0,  curslotstr, device);
-    }
-    amfree(curslotstr);
-    amfree(device);
-}
-
-/* ---------------------------- */
-
-static int
-start_chg_glue(void)
-{
-    int stdin_pipe[2] = { -1, -1 };
-    int stdout_pipe[2] = { -1, -1 };
-    char *chg_glue;
-
-    /* is it already running? */
-    if (tpchanger_pid != -1)
-       return 1;
-
-    if (pipe(stdin_pipe) == -1 || pipe(stdout_pipe) == -1) {
-       changer_resultstr = vstrallocf(
-                       _("<error> could not make pipe: %s"), strerror(errno));
-       goto error;
-    }
-
-    switch(tpchanger_pid = fork()) {
-    case -1:
-       changer_resultstr = vstrallocf(
-                       _("<error> could not fork: %s"), strerror(errno));
-       goto error;
-
-    case 0:
-       debug_dup_stderr_to_debug();
-       if(dup2(stdin_pipe[0], 0) == -1) {
-           changer_resultstr = vstrallocf(
-                       _("<error> could not dup2: %s"), strerror(errno));
-           goto child_err;
-       }
-
-       if(dup2(stdout_pipe[1], 1) == -1) {
-           changer_resultstr = vstrallocf(
-                       _("<error> could not dup2: %s"), strerror(errno));
-           goto child_err;
-       }
-       safe_fd(-1, 0);
-
-       chg_glue = g_strdup_printf("%s/chg-glue", amlibexecdir);
-
-       execl(chg_glue, chg_glue, get_config_name(), NULL);
-       changer_resultstr = vstrallocf(
-                       _("<error> could not exec \"chg-glue\": %s"), strerror(errno));
-       goto child_err;
-
-child_err:
-       (void)full_write(stdout_pipe[1], changer_resultstr, strlen(changer_resultstr));
-       exit(1);
-
-    default:
-       aclose(stdin_pipe[0]);
-       aclose(stdout_pipe[1]);
-
-       tpchanger_stdout = stdout_pipe[0];
-       tpchanger_stdin = stdin_pipe[1];
-
-       return 1;
-    }
-
-error:
-    aclose(stdin_pipe[0]);
-    aclose(stdin_pipe[1]);
-    aclose(stdout_pipe[0]);
-    aclose(stdout_pipe[1]);
-
-    return 0;
-}
-
-static int
-changer_command(
-     char *cmd,
-     char *arg)
-{
-    int exitcode = 0;
-    char *cmdstr = NULL;
-
-    amfree(changer_resultstr);
-
-    if (!start_chg_glue()) {
-       exitcode = 2;
-       goto failed;
-    }
-
-    cmdstr = vstralloc(cmd,
-                      arg ? " " : "",
-                      arg ? arg : "",
-                      "\n",
-                      NULL);
-
-    g_debug("changer: >> %s %s", cmd, arg? arg : "");
-
-    /* write the command to chg_glue */
-    if (full_write(tpchanger_stdin, cmdstr, strlen(cmdstr)) != strlen(cmdstr)) {
-        changer_resultstr = g_strdup("<error> chg-glue exited unexpectedly");
-       exitcode = 2;
-       goto failed;
-    }
-
-    /* read the first line of the response */
-    changer_resultstr = areads(tpchanger_stdout);
-    if (!changer_resultstr || !*changer_resultstr) {
-        changer_resultstr = g_strdup("<error> unexpected EOF");
-        exitcode = 2;
-        goto failed;
-    }
-    g_debug("changer: << %s", changer_resultstr);
-
-    if (strncmp_const(changer_resultstr, "EXITSTATUS ") != 0) {
-       report_bad_resultstr(cmd);
-       exitcode = 2;
-       goto failed;
-    }
-    exitcode = atoi(changer_resultstr + strlen("EXITSTATUS "));
-
-    /* and the second */
-    changer_resultstr = areads(tpchanger_stdout);
-    if (!changer_resultstr) {
-        changer_resultstr = g_strdup("<error> unexpected EOF");
-        exitcode = 2;
-        goto failed;
-    }
-    g_debug("changer: << %s", changer_resultstr);
-
-failed:
-    if (exitcode != 0) {
-       g_debug("changer: ERROR %s", changer_resultstr);
-    }
-
-    amfree(cmdstr);
-
-    return exitcode;
-}
-
-
-/*
- * This function commands the changerscript to look for a tape named
- * searchlabel. If is found, the changerscript answers with the device,
- * in which the tape can be accessed.
- */
-
-int
-changer_search(
-    char *     searchlabel,
-    char **    outslotstr,
-    char **    devicename)
-{
-    char *rest;
-    int rc;
-
-    dbprintf("changer_search: %s\n",searchlabel);
-    rc = run_changer_command("-search", searchlabel, outslotstr, &rest);
-    if(rc) return rc;
-
-    if(*rest == '\0') return report_bad_resultstr("-search");
-
-    *devicename = newstralloc(*devicename, rest);
-    return 0;
-}
-
-
-/*
- * Because barcodelabel are short, and may not be the same as the 
- * amandalabels, the changerscript should be informed, which tapelabel
- * is associated with a tape. This function should be called after 
- * giving a label for a tape. (Maybe also, when the label and the associated
- * slot is known. e.g. during library scan.
- */
-
-int
-changer_label(
-    char *     slotsp, 
-    char *     labelstr)
-{
-    int rc;
-    char *rest=NULL;
-    char *slotstr;
-    char *curslotstr = NULL;
-    int nslots, backwards, searchable;
-
-    dbprintf(_("changer_label: %s for slot %s\n"),labelstr,slotsp);
-    rc = changer_query(&nslots, &curslotstr, &backwards,&searchable);
-    amfree(curslotstr);
-
-    if ((rc == 0) && (searchable == 1)){
-       dbprintf(_("changer_label: calling changer -label %s\n"),labelstr);
-       rc = run_changer_command("-label", labelstr, &slotstr, &rest);
-       amfree(slotstr);
-    }
-
-    if(rc) return rc;
-
-    return 0;
-}