1 /*
2  * Copyright (c) 1998,1999,2000
3  *	Traakan, Inc., Los Altos, CA
4  *	All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice unmodified, this list of conditions, and the following
11  *    disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 /*
30  * Project:  NDMJOB
31  * Ident:    $Id: $
32  *
33  * Description:
34  *
35  */
36 
37 
38 #include "ndmagents.h"
39 
40 
41 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
42 
43 
44 #define RETERR if (errcnt++ >= errskip) return errcnt;
45 #define ERROR(S) { if (errbuf) strcpy(errbuf, (S)); RETERR }
46 
47 
48 /*
49  * To just check a job:
50  *	rc = ndma_job_audit (job, 0, 0);
51  *	if (rc) { "error" }
52  *
53  * To display everything wrong with a job:
54  *	i = n_err = 0;
55  *	do {
56  *		n_err = ndma_job_audit (job, errbuf, i);
57  *		if (n_err) display (errbuf);
58  *		i++;
59  *	} while (i < n_err);
60  *
61  *	if (n_err) { "error" }
62  */
63 
64 int
ndma_job_audit(struct ndm_job_param * job,char * errbuf,int errskip)65 ndma_job_audit (struct ndm_job_param *job, char *errbuf, int errskip)
66 {
67 	int		errcnt = 0;
68 	char *		audit_what;
69 
70 	switch (job->operation) {
71 	default:
72 		ERROR ("invalid operatiton")
73 		return -1;
74 
75 	case NDM_JOB_OP_BACKUP:		audit_what = "DfbBmM";	break;
76 	case NDM_JOB_OP_EXTRACT:	audit_what = "DfbBmM";	break;
77 	case NDM_JOB_OP_TOC:		audit_what = "DfbBmM";	break;
78 	case NDM_JOB_OP_QUERY_AGENTS:	audit_what = "";	break;
79 	case NDM_JOB_OP_INIT_LABELS:	audit_what = "TfmM";	break;
80 	case NDM_JOB_OP_LIST_LABELS:	audit_what = "TfM";	break;
81 	case NDM_JOB_OP_REMEDY_ROBOT:	audit_what = "";	break;
82 	case NDM_JOB_OP_TEST_TAPE:	audit_what = "TfM";	break;
83 	case NDM_JOB_OP_TEST_MOVER:	audit_what = "TfbM";	break;
84 	case NDM_JOB_OP_TEST_DATA:	audit_what = "DB";	break;
85 	case NDM_JOB_OP_REWIND_TAPE:	audit_what = "Tf";	break;
86 	case NDM_JOB_OP_EJECT_TAPE:	audit_what = "Tf";	break;
87 	case NDM_JOB_OP_MOVE_TAPE:	audit_what = "Rr@";	break;
88 	case NDM_JOB_OP_IMPORT_TAPE:	audit_what = "Rr@";	break;
89 	case NDM_JOB_OP_EXPORT_TAPE:	audit_what = "Rr@";	break;
90 	case NDM_JOB_OP_LOAD_TAPE:	audit_what = "Rr@";	break;
91 	case NDM_JOB_OP_UNLOAD_TAPE:	audit_what = "Rr";	break;
92 	case NDM_JOB_OP_INIT_ELEM_STATUS: audit_what = "Rr";	break;
93 	}
94 
95 	while (*audit_what) switch (*audit_what++) {
96 	case 'D':	/* DATA agent provided */
97 		if (job->data_agent.conn_type == NDMCONN_TYPE_NONE)
98 			ERROR("missing DATA agent")
99 		break;
100 
101 	case 'T':	/* TAPE agent provided (use DATA if given) */
102 		if (job->data_agent.conn_type == NDMCONN_TYPE_NONE
103 		 && job->tape_agent.conn_type == NDMCONN_TYPE_NONE)
104 			ERROR("missing TAPE or DATA agent")
105 		break;
106 
107 	case 'R':	/* ROBOT agent provided (use TAPE or DATA if given) */
108 		if (job->data_agent.conn_type == NDMCONN_TYPE_NONE
109 		 && job->tape_agent.conn_type == NDMCONN_TYPE_NONE
110 		 && job->robot_agent.conn_type == NDMCONN_TYPE_NONE)
111 			ERROR("missing ROBOT, TAPE or DATA agent")
112 		break;
113 
114 	case 'B':	/* Backup type */
115 		if (!job->bu_type)
116 			ERROR("missing bu_type")
117 		break;
118 
119 	case 'b':	/* block (record) size */
120 		if (!job->record_size)
121 			ERROR("missing record size")
122 		break;
123 
124 	case 'f':	/* tape file */
125 		if (!job->tape_device)
126 			ERROR("missing tape device")
127 		break;
128 
129 	case 'm':	/* media entry/ies */
130 		if (job->media_tab.n_media < 1)
131 			ERROR("missing media entry")
132 		break;
133 
134 	case 'M':	/* ? */
135 		errcnt += ndma_job_media_audit (job, errbuf, errskip-errcnt);
136 		break;
137 
138 	case 'r':	/* robot file/device name */
139 		if (!job->have_robot)
140 			ERROR ("missing robot SCSI address");
141 		break;
142 
143 	case '@':	/* from and/or to address */
144 		if (job->operation == NDM_JOB_OP_MOVE_TAPE
145 		 || job->operation == NDM_JOB_OP_EXPORT_TAPE
146 		 || job->operation == NDM_JOB_OP_LOAD_TAPE) {
147 			if (!job->from_addr_given)
148 				ERROR ("missing 'from' slot address");
149 		}
150 		if (job->operation == NDM_JOB_OP_MOVE_TAPE
151 		 || job->operation == NDM_JOB_OP_IMPORT_TAPE) {
152 			if (!job->to_addr_given)
153 				ERROR ("missing 'to' slot address");
154 		}
155 		break;
156 
157 	default:
158 		ERROR ("INTERNAL BOTCH")
159 		return -2;
160 	}
161 
162 	if (job->robot_agent.conn_type != NDMCONN_TYPE_NONE
163 	 && !job->have_robot
164 	 && job->operation != NDM_JOB_OP_QUERY_AGENTS) {
165 		ERROR ("robot agent, but no robot")
166 	}
167 
168 	return errcnt;
169 }
170 
171 int
ndma_job_media_audit(struct ndm_job_param * job,char * errbuf,int errskip)172 ndma_job_media_audit (struct ndm_job_param *job, char *errbuf, int errskip)
173 {
174 	struct ndm_media_table *mtab = &job->media_tab;
175 	int			n_media =  mtab->n_media;
176 	struct ndmmedia *	me;
177 	struct ndmmedia *	me2;
178 	int			errcnt = 0;
179 	int			i, j;
180 
181 	if (job->have_robot) {
182 		for (i = 0; i < n_media; i++) {
183 			me = &mtab->media[i];
184 			if (!me->valid_slot) {
185 				if (errbuf) {
186 				    sprintf (errbuf,
187 					"media #%d missing slot address",
188 					i+1);
189 				}
190 				RETERR
191 				continue;
192 			}
193 			for (j = i+1; j < n_media; j++) {
194 				me2 = &mtab->media[j];
195 				if (! me2->valid_slot)
196 					continue;
197 				if (me->slot_addr == me2->slot_addr) {
198 				    if (errbuf) {
199 				        sprintf (errbuf,
200 					  "media #%d dup slot addr w/ #%d",
201 					  i+1, j+1);
202 				    }
203 				    RETERR
204 				}
205 			}
206 		}
207 	} else {
208 		if (n_media > 1) {
209 			ERROR ("no robot, too many media")
210 		}
211 
212 		for (i = 0; i < n_media; i++) {
213 			me = &mtab->media[i];
214 			if (me->valid_slot) {
215 				if (errbuf) {
216 				    sprintf (errbuf,
217 					"media #%d slot address, but no robot",
218 					i+1);
219 				}
220 				RETERR
221 			}
222 		}
223 	}
224 
225 	if (job->operation == NDM_JOB_OP_INIT_LABELS) {
226 		for (i = 0; i < n_media; i++) {
227 			me = &mtab->media[i];
228 			if (! me->valid_label) {
229 				if (errbuf) {
230 				    sprintf (errbuf,
231 					"media #%d missing label",
232 					i+1);
233 				}
234 				RETERR
235 			}
236 		}
237 	}
238 
239 	return 0;
240 }
241 
242 void
ndma_job_auto_adjust(struct ndm_job_param * job)243 ndma_job_auto_adjust (struct ndm_job_param *job)
244 {
245 	if (job->media_tab.n_media == 0
246 	 && !job->have_robot
247 	 && job->operation != NDM_JOB_OP_INIT_LABELS) {
248 		/* synthesize one media table entry */
249 		NDMOS_MACRO_ZEROFILL (&job->media_tab.media[0]);
250 		job->media_tab.n_media = 1;
251 	}
252 }
253 
254 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
255