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  *      This is the #include file for the Operating System
36  *      (O/S) specific portion of the NDMJOBLIB library.
37  *      By O/S we mean the programming environment including
38  *      compilers, header files, as well the host O/S APIs.
39  *      O/S specific is clear and concise, so that's how we refer
40  *      to the hosting environment.
41  *
42  *      This file, ndmos.h, essentially #include's the right
43  *      ndmos_xxx.h for the hosting environment. The companion
44  *      source C files, ndmos_xxx*.c, are similarly selected by
45  *      ndmos.c.
46  *
47  *      The strategy for separating the O/S specific and O/S
48  *      generic portions of NDMJOBLIB has four key points:
49  *
50  *        1) Isolate O/S specific portions in separate
51  *           files which can be developed, contributed,
52  *           and maintained independently of the overall
53  *           source base.
54  *
55  *        2) NEVER NEVER #ifdef based on O/S or programming
56  *           environment in the O/S generic portions. These
57  *           make collective maintenance and integration
58  *           too difficult.
59  *
60  *        3) Use O/S specific #define macros (NDMOS_...)
61  *           and C functions (ndmos_...) as wrappers around
62  *           the portions that vary between environments
63  *           and applications.
64  *
65  *        4) Use generic, objective-oriented #ifdef's to isolate
66  *           and omit functionality which may not be wanted in
67  *           all applications.
68  *
69  *      There are templates in ndmos_xxx.h and ndmos_xxx.c
70  *      to get started on a new O/S specific portion.
71  *      Send contributions to the current keeper of NDMJOB.
72  *      Contact ndmp-tech@ndmp.org for details.
73  *
74  *      >>>  DO NOT MODIFY THIS FILE OR ANY GENERIC  <<<
75  *      >>>  PORTION OF NDMJOBLIB FOR THE SAKE OF A  <<<
76  *      >>>  HOSTING ENVIRONMENT OR APPLICATION.     <<<
77  *
78  *      If you discover additional isolation requirements,
79  *      raise the issue on ndmp-tech@ndmp.org. Propose new
80  *      #define NDMOS_ macros to address them. Then, submit
81  *      the proposal with required changes to the current
82  *      keeper of NDMJOB. Changes to the generic portion which
83  *      use #ifdef's based on anything other than NDMOS_
84  *      macros will be summarily rejected.
85  *
86  *      There are four sections of this file:
87  *        1) Establish identities for various O/S platforms
88  *        2) Try to auto-recognize the environment
89  *        3) #include the right O/S specific ndmos_xxx.h
90  *        4) Establish default #define-itions for macros
91  *           left undefined
92  */
93 
94 
95 #ifndef _NDMOS_H
96 #define _NDMOS_H
97 
98 /*
99  * Silence compiler for known warnings.
100  */
101 #ifdef __clang__
102 #pragma clang diagnostic ignored "-Wunused-const-variable"
103 #pragma clang diagnostic ignored "-Wformat"
104 #pragma clang diagnostic ignored "-Wenum-conversion"
105 #elif __GNUC__
106 #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 402
107 #pragma GCC diagnostic ignored "-Wunused-variable"
108 #pragma GCC diagnostic ignored "-Wformat"
109 #pragma GCC diagnostic ignored "-Wenum-compare"
110 #if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
111 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
112 #endif
113 #endif
114 #elif __SUNPRO_C
115 #pragma error_messages(off, E_ENUM_TYPE_MISMATCH_OP, E_ENUM_TYPE_MISMATCH_ARG, \
116                        E_STATEMENT_NOT_REACHED)
117 #endif
118 
119 /*
120  * Operating system idents
121  */
122 #define NDMOS_IDENT(A, B, C, D) (((A) << 24) + ((B) << 16) + ((C) << 8) + (D))
123 
124 #define NDMOS_ID_FREEBSD NDMOS_IDENT('F', 'B', 's', 'd')
125 #define NDMOS_ID_SOLARIS NDMOS_IDENT('S', 'o', 'l', 'a')
126 #define NDMOS_ID_LINUX NDMOS_IDENT('L', 'n', 'u', 'x')
127 #define NDMOS_ID_IRIX NDMOS_IDENT('I', 'R', 'I', 'X')
128 #define NDMOS_ID_HPUX NDMOS_IDENT('H', 'P', 'U', 'X')
129 #define NDMOS_ID_ULTRIX NDMOS_IDENT('U', 'l', 't', 'r')
130 #define NDMOS_ID_TRU64 NDMOS_IDENT('T', 'R', 'U', 64)
131 #define NDMOS_ID_AIX NDMOS_IDENT('A', 'I', 'X', 0)
132 
133 /*
134  * Only explicitly include config.h when we are doing standalone
135  * compiling of the lib when included from Bareos there is no need
136  * to re-include config.h as that config file is not protected against
137  * multiple including. So we just test to see if include/bareos.h is not
138  * already included as that leaves a nice fingerprint.
139  */
140 #ifndef BAREOS_INCLUDE_BAREOS_H_
141 #include "include/config.h"
142 #endif
143 
144 /*
145  * If NDMOS_ID isn't set, try to autorecognize the OS based
146  * on standard CPP symbols.
147  */
148 #ifndef NDMOS_ID
149 #ifdef HAVE_FREEBSD_OS
150 #define NDMOS_ID NDMOS_ID_FREEBSD
151 #endif
152 
153 #ifdef HAVE_SUN_OS
154 #define NDMOS_ID NDMOS_ID_SOLARIS
155 #endif
156 
157 #ifdef HAVE_LINUX_OS
158 #define NDMOS_ID NDMOS_ID_LINUX
159 #endif
160 #endif /* !NDMOS_ID */
161 
162 /*
163  * Do we got it?
164  */
165 #ifndef NDMOS_ID
166 @ @ @ @You need to use - DNDMOS_ID = NDMOS_ID_xxxx
167 #endif
168 
169 
170 /*
171  * Based on NDMOS_ID, #include the right O/S specific header file
172  */
173 #if NDMOS_ID == NDMOS_ID_FREEBSD
174 #include "ndmos_freebsd.h"
175 #endif
176 
177 #if NDMOS_ID == NDMOS_ID_SOLARIS
178 #include "ndmos_solaris.h"
179 #endif
180 
181 #if NDMOS_ID == NDMOS_ID_LINUX
182 #include "ndmos_linux.h"
183 #endif
184 
185 
186 /*
187  * From here down, pre-processor symbols are #define'd to defaults
188  * if not already #define'd in the O/S specific header file.
189  *
190  * Application Program Interfaces (APIs). The macros give the
191  * O/S specific header a chance to use casts or different functions.
192  *
193  * NDMOS_API_BCOPY              -- memory copy
194  * NDMOS_API_BZERO              -- zero-fill memory
195  * NDMOS_API_MALLOC             -- memory allocator, no initialization
196  * NDMOS_API_FREE               -- memory deallocator
197  * NDMOS_API_STRTOLL            -- convert strings to long long
198  * NDMOS_API_STRDUP             -- malloc() and strcpy()
199  * NDMOS_API_STREND             -- return pointer to end of string
200  *
201  * Important constants that sometimes vary between O/S's.
202  *
203  * NDMOS_CONST_ALIGN            -- alignment for memory allocation
204  * NDMOS_CONST_EWOULDBLOCK      -- errno when async I/O would stall
205  * NDMOS_CONST_TAPE_REC_MAX     -- maximum tape record length
206  * NDMOS_CONST_TAPE_REC_MIN     -- minimum tape record length
207  * NDMOS_CONST_PATH_MAX         -- maximum path name length
208  * NDMOS_CONST_NDMJOBLIB_REVISION -- String for in-house change level
209  *                                 Convention "0" if no changes
210  *                                 from released source. If changes,
211  *                                 the initials of local keeper with
212  *                                 sequence number or date code.
213  * NDMOS_CONST_VENDOR_NAME      -- String for server_info_reply.vendor_name
214  * NDMOS_CONST_PRODUCT_NAME     -- String for server_info_reply.product_name
215  * NDMOS_CONST_PRODUCT_REVISION -- String for product change level
216  *                                 By "product" we mean the program
217  *                                 enclosing this NDMJOBLIB library.
218  * NDMOS_CONST_NDMOS_REVISION   -- String for ndmos_xxx change level
219  *
220  * Macros for certain small operations which can vary.
221  *
222  * NDMOS_MACRO_NEW              -- allocate a data structure, wrapper
223  *                                 around NDMOS_API_MALLOC() with casts
224  * NDMOS_MACRO_NEWN             -- allocate a vector of data structs
225  * NDMOS_MACRO_ZEROFILL         -- zero-fill data structure, wrapper
226  *                                 around NDMOS_API_BZERO()
227  * NDMOS_MACRO_ZEROFILL_SIZE    -- zero-fill data structure, wrapper
228  *                                 around NDMOS_API_BZERO()
229  * NDMOS_MACRO_SRAND            -- wrapper around srand(3), for MD5
230  * NDMOS_MACRO_RAND             -- wrapper around rand(3), for MD5
231  * NDMOS_MACRO_OK_TAPE_REC_LEN  -- Uses NDMOS_CONST_TAPE_REC_MIN/MAX
232  * NDMOS_MACRO_SET_SOCKADDR     -- Sets struct sockaddr_in with
233  *                                 respect to NDMOS_OPTION_HAVE_SIN_LEN
234  *
235  * The NDMOS_MACRO_xxx_ADDITIONS macros allow additional O/S
236  * specific members to key structures in ndmagents.h
237  *
238  * NDMOS_MACRO_CONTROL_AGENT_ADDITIONS  -- struct ndm_control_agent
239  * NDMOS_MACRO_DATA_AGENT_ADDITIONS     -- struct ndm_data_agent
240  * NDMOS_MACRO_ROBOT_AGENT_ADDITIONS    -- struct ndm_robot_agent
241  * NDMOS_MACRO_SESSION_ADDITIONS        -- struct ndm_session
242  * NDMOS_MACRO_TAPE_AGENT_ADDITIONS     -- struct ndm_tape_agent
243  *
244  * All NDMOS_OPTION_... parameters are either #define'd or #undef'ed.
245  * They are solely interpretted in #ifdef's and #ifndef's, and the
246  * value of the definition means nothing. These _OPTIONS_'s can be set
247  * on the command line (-D) in the Makefile, or in the O/S specific
248  * header file.
249  *
250  * NDMOS_OPTION_NO_NDMP2        -- omit NDMPv2 support
251  * NDMOS_OPTION_NO_NDMP3        -- omit NDMPv3 support
252  * NDMOS_OPTION_NO_NDMP4        -- omit NDMPv4 support
253  *
254  * NDMOS_OPTION_NO_CONTROL_AGENT -- omit CONTROL agent features
255  * NDMOS_OPTION_NO_DATA_AGENT   -- omit DATA agent features
256  * NDMOS_OPTION_NO_ROBOT_AGENT  -- omit ROBOT agent features
257  * NDMOS_OPTION_NO_TAPE_AGENT   -- omit TAPE agent features
258  * NDMOS_OPTION_NO_TEST_AGENTS  -- omit any agent test features
259  *      For some purposes, an all-in-one is overkill, or perhaps
260  *      impractical. Everything is carefully constructed so
261  *      that certain agents can be omitted without disturbing
262  *      the rest. The two most obvious uses are to either
263  *      keep or omit just the CONTROL agent.
264  *
265  * NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN
266  *      The NDMP specification says that both TAPE and SCSI can not
267  *      be open at the same time. Then the workflow docs suggest
268  *      a separate process for the ROBOT agent to get around the
269  *      restriction. #define'ing this breaks the spec and allows
270  *      both to be open.
271  *
272  * NDMOS_OPTION_HAVE_SIN_LEN
273  *      In preparation for IPv6, some O/Ss use a sin_len field to
274  *      indicate the length of the address. This _OPTION_ affects
275  *      the standard NDMOS_MACRO_SET_SOCKADDR.
276  *
277  * NDMOS_OPTION_TAPE_SIMULATOR
278  *      Early in bring-up on a new system, it's a little easier to
279  *      get started by using the tape simulator. It represents
280  *      an idealized MTIO-type tape subsystem, and uses a disk
281  *      file to represent the tape. As the real O/S specific tape
282  *      subsystem interface is implemented (ndmos_tape_...()), the
283  *      tape simulator serves as a reference for correct implementation.
284  *
285  * NDMOS_OPTION_ROBOT_SIMULATOR
286  *      Similarly, for testing multi-tape operations, it's easier to
287  *      get started by using the robot simulator. It represents a simple
288  *      robot with ten slots and two drives.  It operates on a directory,
289  *      and uses rename() to load and unload tapes.  It operates in concert
290  *      with the tape simulator.  The robot name is a directory, and it
291  *      creates drives named 'drive0', 'drive1', etc. in that directory
292  *
293  * NDMOS_OPTION_GAP_SIMULATOR
294  *      Implement the spinnaker GAP simulator in the tape simulator.
295  *      When you want a clean tape stream in the tape simulator disable
296  *      this option and the output should only contain the info from
297  *      the data agent no fancy Begin Of Tape (BOT) simulation etc.
298  *
299  * NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL -- use common select() code
300  * NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL   -- use common poll() code
301  *      These two _OPTION_'s choose common code to implement
302  *      ndmos_chan_poll(). The select() and poll() functions are
303  *      fairly common and consistent among various O/S's to detect
304  *      ready I/O. Only one can be defined. If the common code
305  *      doesn't work out, don't define either _OPTION_ and implement
306  *      ndmos_chan_poll() in the O/S specific C source file.
307  *
308  * NDMOS_OPTION_USE_GETHOSTBYNAME -- use gethostbyname() code
309  * NDMOS_OPTION_USE_GETADDRINFO   -- use getaddrinfo() code
310  *      These two _OPTION_'s choose common code to implement
311  *      the lookup of a host. getaddrinfo() is the new interface
312  *      and gethostbyname() is deprecated by POSIX so should only
313  *      be used when there is no support for getaddrinfo()
314  */
315 
316 #if HAVE_POLL
317 #define NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL 1
318 #else
319 #define NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL 1
320 #endif
321 
322 #if HAVE_GETADDRINFO
323 #define NDMOS_OPTION_USE_GETADDRINFO 1
324 #else
325 #define NDMOS_OPTION_USE_GETHOSTBYNAME 1
326 #endif
327 
328 #define NDMOS_OPTION_TAPE_SIMULATOR 1
329 #define NDMOS_OPTION_ROBOT_SIMULATOR 1
330 #define NDMOS_OPTION_GAP_SIMULATOR 1
331 
332 /*
333  * Constants
334  */
335 #ifndef NDMOS_CONST_ALIGN
336 #define NDMOS_CONST_ALIGN sizeof(uint64_t)
337 #endif /* !NDMOS_CONST_ALIGN */
338 
339 #ifndef NDMOS_CONST_TAPE_REC_MIN
340 #define NDMOS_CONST_TAPE_REC_MIN 1
341 #endif /* !NDMOS_CONST_TAPE_REC_MIN */
342 
343 #ifndef NDMOS_CONST_TAPE_REC_MAX
344 #define NDMOS_CONST_TAPE_REC_MAX (1024 * 1024)
345 #endif /* !NDMOS_CONST_TAPE_REC_MAX */
346 
347 #ifndef NDMOS_CONST_PATH_MAX
348 #define NDMOS_CONST_PATH_MAX (1024)
349 #endif /* !NDMOS_CONST_PATH_MAX */
350 
351 #ifndef NDMOS_CONST_EWOULDBLOCK
352 #ifdef EWOULDBLOCK
353 #define NDMOS_CONST_EWOULDBLOCK EWOULDBLOCK
354 #else /* EWOULDBLOCK */
355 #define NDMOS_CONST_EWOULDBLOCK EAGAIN
356 #endif /* EWOULDBLOCK */
357 #endif /* !NDMOS_CONST_EWOULDBLOCK */
358 
359 #ifndef NDMOS_CONST_NDMJOBLIB_REVISION
360 #define NDMOS_CONST_NDMJOBLIB_REVISION "1.4a"
361 #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */
362 
363 #ifndef NDMOS_CONST_VENDOR_NAME
364 #define NDMOS_CONST_VENDOR_NAME "PublicDomain"
365 #endif /* !NDMOS_CONST_VENDOR_NAME */
366 
367 #ifndef NDMOS_CONST_PRODUCT_NAME
368 #define NDMOS_CONST_PRODUCT_NAME "NDMJOB"
369 #endif /* !NDMOS_CONST_PRODUCT_NAME */
370 
371 #ifndef NDMOS_CONST_PRODUCT_REVISION
372 #define NDMOS_CONST_PRODUCT_REVISION "1.4a"
373 #endif /* !NDMOS_CONST_PRODUCT_REVISION */
374 
375 #ifndef NDMOS_CONST_NDMOS_REVISION
376 #define NDMOS_CONST_NDMOS_REVISION "0"
377 #endif /* !NDMOS_CONST_NDMOS_REVISION */
378 
379 
380 /*
381  * Application Program Interfaces (APIs)
382  */
383 #ifndef NDMOS_API_BZERO
384 #define NDMOS_API_BZERO(P, N) (void)bzero((void*)(P), (N))
385 #endif /* !NDMOS_API_BZERO */
386 
387 #ifndef NDMOS_API_BCOPY
388 #define NDMOS_API_BCOPY(S, D, N) (void)bcopy((void*)(S), (void*)(D), (N))
389 #endif /* !NDMOS_API_BCOPY */
390 
391 #ifndef NDMOS_API_MALLOC
392 #define NDMOS_API_MALLOC(N) malloc(N)
393 #endif /* !NDMOS_API_MALLOC */
394 
395 #ifndef NDMOS_API_FREE
396 #define NDMOS_API_FREE(P) free((void*)(P))
397 #endif /* !NDMOS_API_FREE */
398 
399 #ifndef NDMOS_API_STRTOLL
400 #define NDMOS_API_STRTOLL(P, PP, BASE) strtoll(P, PP, BASE)
401 #endif /* !NDMOS_API_STRTOLL */
402 
403 #ifndef NDMOS_API_STRDUP
404 #define NDMOS_API_STRDUP(S) strdup(S)
405 #endif /* !NDMOS_API_STRDUP */
406 
407 #ifndef NDMOS_API_STREND
408 
409 #ifdef __cplusplus
410     extern "C"
411 {
412 #endif
413 
414   extern char* ndml_strend(char* s); /* ndml_util.c */
415 
416 #ifdef __cplusplus
417 }
418 #endif
419 
420 #define NDMOS_API_STREND(S) ndml_strend(S)
421 #endif /* !NDMOS_API_STREND */
422 
423 
424 /*
425  * Macros
426  */
427 #ifndef NDMOS_MACRO_NEW
428 #define NDMOS_MACRO_NEW(T) ((T*)NDMOS_API_MALLOC(sizeof(T)))
429 #endif /* !NDMOS_MACRO_NEW */
430 
431 #ifndef NDMOS_MACRO_NEWN
432 #define NDMOS_MACRO_NEWN(T, N) ((T*)NDMOS_API_MALLOC(sizeof(T) * (N)))
433 #endif /* !NDMOS_MACRO_NEWN */
434 
435 #ifndef NDMOS_MACRO_FREE
436 #define NDMOS_MACRO_FREE(T) free(T)
437 #endif
438 
439 #ifndef NDMOS_MACRO_ZEROFILL
440 #define NDMOS_MACRO_ZEROFILL(P) NDMOS_API_BZERO(P, sizeof *(P))
441 #endif /* !NDMOS_MACRO_ZEROFILL */
442 
443 #ifndef NDMOS_MACRO_ZEROFILL_SIZE
444 #define NDMOS_MACRO_ZEROFILL_SIZE(P, N) NDMOS_API_BZERO(P, N)
445 #endif /* !NDMOS_MACRO_ZEROFILL_SIZE */
446 
447 #ifndef NDMOS_MACRO_SRAND
448 #define NDMOS_MACRO_SRAND() srand(time(0))
449 #endif /* !NDMOS_MACRO_SRAND */
450 
451 #ifndef NDMOS_MACRO_RAND
452 #define NDMOS_MACRO_RAND() rand()
453 #endif /* !NDMOS_MACRO_RAND */
454 
455 #ifndef NDMOS_MACRO_OK_TAPE_REC_LEN
456 #define NDMOS_MACRO_OK_TAPE_REC_LEN(LEN) \
457   (NDMOS_CONST_TAPE_REC_MIN <= (LEN) && (LEN) <= NDMOS_CONST_TAPE_REC_MAX)
458 #endif /* !NDMOS_MACRO_OK_TAPE_REC_LEN */
459 
460 #ifndef NDMOS_MACRO_SET_SOCKADDR
461 #ifdef NDMOS_OPTION_HAVE_SIN_LEN
462 #define NDMOS_MACRO_SET_SOCKADDR(SA, INADDR, PORT)               \
463   (NDMOS_MACRO_ZEROFILL(SA),                                     \
464    ((struct sockaddr_in*)(SA))->sin_len = sizeof *(SA),          \
465    ((struct sockaddr_in*)(SA))->sin_family = AF_INET,            \
466    ((struct sockaddr_in*)(SA))->sin_addr.s_addr = htonl(INADDR), \
467    ((struct sockaddr_in*)(SA))->sin_port = htons(PORT))
468 #else /* NDMOS_OPTION_HAVE_SIN_LEN */
469 #define NDMOS_MACRO_SET_SOCKADDR(SA, INADDR, PORT)               \
470   (NDMOS_MACRO_ZEROFILL(SA),                                     \
471    ((struct sockaddr_in*)(SA))->sin_family = AF_INET,            \
472    ((struct sockaddr_in*)(SA))->sin_addr.s_addr = htonl(INADDR), \
473    ((struct sockaddr_in*)(SA))->sin_port = htons(PORT))
474 #endif /* NDMOS_OPTION_HAVE_SIN_LEN */
475 #endif /* !NDMOS_MACRO_SET_SOCKADDR */
476 
477 
478 /*
479  * Composite effects
480  */
481 
482 #ifdef NDMOS_OPTION_NO_DATA_AGENT
483 #ifdef NDMOS_OPTION_NO_TAPE_AGENT
484 #ifdef NDMOS_OPTION_NO_ROBOT_AGENT
485 #define NDMOS_EFFECT_NO_SERVER_AGENTS
486 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
487 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
488 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
489 
490 #ifdef NDMOS_OPTION_NO_NDMP3
491 #ifdef NDMOS_OPTION_NO_NDMP4
492 #define NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4
493 #endif /* !NDMOS_OPTION_NO_NDMP3 */
494 #endif /* !NDMOS_OPTION_NO_NDMP4 */
495 
496 /* check for a conflict: robot sim requires tape sim */
497 #ifdef NDMOS_OPTION_ROBOT_SIMULATOR
498 #ifndef NDMOS_OPTION_TAPE_SIMULATOR
499 #error robot simulator requires the tape simulator
500 #endif /* NDMOS_OPTION_TAPE_SIMULATOR */
501 #ifdef NDMOS_COMMON_SCSI_INTERFACE
502 #error robot simulator and ndmos scsi interface are incompatible
503 #endif
504 #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
505 
506 /*
507  * simulator fields
508  */
509 
510 #ifdef NDMOS_OPTION_TAPE_SIMULATOR
511 #define NDMOS_MACRO_TAPE_AGENT_ADDITIONS \
512   int32_t tape_fd;                       \
513   char* drive_name;                      \
514   int32_t weof_on_close;                 \
515   int32_t sent_leom;
516 #endif /* NDMOS_OPTION_TAPE_SIMULATOR */
517 
518 #ifdef NDMOS_OPTION_ROBOT_SIMULATOR
519 #undef NDMOS_MACRO_ROBOT_AGENT_ADDITIONS
520 #define NDMOS_MACRO_ROBOT_AGENT_ADDITIONS char* sim_dir;
521 #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
522 
523 #endif /* _NDMOS_H */
524