/*
* Copyright (c) 1998,1999,2000
* Traakan, Inc., Los Altos, CA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Project: NDMJOB
* Ident: $Id: $
*
* Description:
*
*/
#include "ndmagents.h"
#ifndef NDMOS_OPTION_NO_CONTROL_AGENT
#define RETERR if (errcnt++ >= errskip) return errcnt;
#define ERROR(S) { if (errbuf) strcpy(errbuf, (S)); RETERR }
/*
* To just check a job:
* rc = ndma_job_audit (job, 0, 0);
* if (rc) { "error" }
*
* To display everything wrong with a job:
* i = n_err = 0;
* do {
* n_err = ndma_job_audit (job, errbuf, i);
* if (n_err) display (errbuf);
* i++;
* } while (i < n_err);
*
* if (n_err) { "error" }
*/
int
ndma_job_audit (struct ndm_job_param *job, char *errbuf, int errskip)
{
int errcnt = 0;
char * audit_what;
switch (job->operation) {
default:
ERROR ("invalid operatiton")
return -1;
case NDM_JOB_OP_BACKUP: audit_what = "DfbBmM"; break;
case NDM_JOB_OP_EXTRACT: audit_what = "DfbBmM"; break;
case NDM_JOB_OP_TOC: audit_what = "DfbBmM"; break;
case NDM_JOB_OP_QUERY_AGENTS: audit_what = ""; break;
case NDM_JOB_OP_INIT_LABELS: audit_what = "TfmM"; break;
case NDM_JOB_OP_LIST_LABELS: audit_what = "TfM"; break;
case NDM_JOB_OP_REMEDY_ROBOT: audit_what = ""; break;
case NDM_JOB_OP_TEST_TAPE: audit_what = "TfM"; break;
case NDM_JOB_OP_TEST_MOVER: audit_what = "TfbM"; break;
case NDM_JOB_OP_TEST_DATA: audit_what = "DB"; break;
case NDM_JOB_OP_REWIND_TAPE: audit_what = "Tf"; break;
case NDM_JOB_OP_EJECT_TAPE: audit_what = "Tf"; break;
case NDM_JOB_OP_MOVE_TAPE: audit_what = "Rr@"; break;
case NDM_JOB_OP_IMPORT_TAPE: audit_what = "Rr@"; break;
case NDM_JOB_OP_EXPORT_TAPE: audit_what = "Rr@"; break;
case NDM_JOB_OP_LOAD_TAPE: audit_what = "Rr@"; break;
case NDM_JOB_OP_UNLOAD_TAPE: audit_what = "Rr"; break;
case NDM_JOB_OP_INIT_ELEM_STATUS: audit_what = "Rr"; break;
}
while (*audit_what) switch (*audit_what++) {
case 'D': /* DATA agent provided */
if (job->data_agent.conn_type == NDMCONN_TYPE_NONE)
ERROR("missing DATA agent")
break;
case 'T': /* TAPE agent provided (use DATA if given) */
if (job->data_agent.conn_type == NDMCONN_TYPE_NONE
&& job->tape_agent.conn_type == NDMCONN_TYPE_NONE)
ERROR("missing TAPE or DATA agent")
break;
case 'R': /* ROBOT agent provided (use TAPE or DATA if given) */
if (job->data_agent.conn_type == NDMCONN_TYPE_NONE
&& job->tape_agent.conn_type == NDMCONN_TYPE_NONE
&& job->robot_agent.conn_type == NDMCONN_TYPE_NONE)
ERROR("missing ROBOT, TAPE or DATA agent")
break;
case 'B': /* Backup type */
if (!job->bu_type)
ERROR("missing bu_type")
break;
case 'b': /* block (record) size */
if (!job->record_size)
ERROR("missing record size")
break;
case 'f': /* tape file */
if (!job->tape_device)
ERROR("missing tape device")
break;
case 'm': /* media entry/ies */
if (job->media_tab.n_media < 1)
ERROR("missing media entry")
break;
case 'M': /* ? */
errcnt += ndma_job_media_audit (job, errbuf, errskip-errcnt);
break;
case 'r': /* robot file/device name */
if (!job->have_robot)
ERROR ("missing robot SCSI address");
break;
case '@': /* from and/or to address */
if (job->operation == NDM_JOB_OP_MOVE_TAPE
|| job->operation == NDM_JOB_OP_EXPORT_TAPE
|| job->operation == NDM_JOB_OP_LOAD_TAPE) {
if (!job->from_addr_given)
ERROR ("missing 'from' slot address");
}
if (job->operation == NDM_JOB_OP_MOVE_TAPE
|| job->operation == NDM_JOB_OP_IMPORT_TAPE) {
if (!job->to_addr_given)
ERROR ("missing 'to' slot address");
}
break;
default:
ERROR ("INTERNAL BOTCH")
return -2;
}
if (job->robot_agent.conn_type != NDMCONN_TYPE_NONE
&& !job->have_robot
&& job->operation != NDM_JOB_OP_QUERY_AGENTS) {
ERROR ("robot agent, but no robot")
}
return errcnt;
}
int
ndma_job_media_audit (struct ndm_job_param *job, char *errbuf, int errskip)
{
struct ndm_media_table *mtab = &job->media_tab;
int n_media = mtab->n_media;
struct ndmmedia * me;
struct ndmmedia * me2;
int errcnt = 0;
int i, j;
if (job->have_robot) {
for (i = 0; i < n_media; i++) {
me = &mtab->media[i];
if (!me->valid_slot) {
if (errbuf) {
sprintf (errbuf,
"media #%d missing slot address",
i+1);
}
RETERR
continue;
}
for (j = i+1; j < n_media; j++) {
me2 = &mtab->media[j];
if (! me2->valid_slot)
continue;
if (me->slot_addr == me2->slot_addr) {
if (errbuf) {
sprintf (errbuf,
"media #%d dup slot addr w/ #%d",
i+1, j+1);
}
RETERR
}
}
}
} else {
if (n_media > 1) {
ERROR ("no robot, too many media")
}
for (i = 0; i < n_media; i++) {
me = &mtab->media[i];
if (me->valid_slot) {
if (errbuf) {
sprintf (errbuf,
"media #%d slot address, but no robot",
i+1);
}
RETERR
}
}
}
if (job->operation == NDM_JOB_OP_INIT_LABELS) {
for (i = 0; i < n_media; i++) {
me = &mtab->media[i];
if (! me->valid_label) {
if (errbuf) {
sprintf (errbuf,
"media #%d missing label",
i+1);
}
RETERR
}
}
}
return 0;
}
void
ndma_job_auto_adjust (struct ndm_job_param *job)
{
if (job->media_tab.n_media == 0
&& !job->have_robot
&& job->operation != NDM_JOB_OP_INIT_LABELS) {
/* synthesize one media table entry */
NDMOS_MACRO_ZEROFILL (&job->media_tab.media[0]);
job->media_tab.n_media = 1;
}
}
#endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */