Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndma_comm_job.c
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
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
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
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 */