Imported Upstream version 3.1.0
[debian/amanda] / ndmp-src / ndmos.h
diff --git a/ndmp-src/ndmos.h b/ndmp-src/ndmos.h
new file mode 100644 (file)
index 0000000..a1180f0
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * 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:
+ *
+ *     This is the #include file for the Operating System
+ *     (O/S) specific portion of the NDMJOBLIB library.
+ *     By O/S we mean the programming environment including
+ *     compilers, header files, as well the host O/S APIs.
+ *     O/S specific is clear and concise, so that's how we refer
+ *     to the hosting environment.
+ *
+ *     This file, ndmos.h, essentially #include's the right
+ *     ndmos_xxx.h for the hosting environment. The companion
+ *     source C files, ndmos_xxx*.c, are similarly selected by
+ *     ndmos.c.
+ *
+ *       (hacked in Amanda to just #include ndmos_glib.h and then follow up
+ *       with the usual defaults)
+ *
+ *     The strategy for separating the O/S specific and O/S
+ *     generic portions of NDMJOBLIB has four key points:
+ *
+ *       1) Isolate O/S specific portions in separate
+ *          files which can be developed, contributed,
+ *          and maintained independently of the overall
+ *          source base.
+ *
+ *       2) NEVER NEVER #ifdef based on O/S or programming
+ *          environment in the O/S generic portions. These
+ *          make collective maintenance and integration
+ *          too difficult.
+ *
+ *       3) Use O/S specific #define macros (NDMOS_...)
+ *          and C functions (ndmos_...) as wrappers around
+ *          the portions that vary between environments
+ *          and applications.
+ *
+ *       4) Use generic, objective-oriented #ifdef's to isolate
+ *          and omit functionality which may not be wanted in
+ *          all applications.
+ *
+ *     There are templates in ndmos_xxx.h and ndmos_xxx.c
+ *     to get started on a new O/S specific portion.
+ *     Send contributions to the current keeper of NDMJOB.
+ *     Contact ndmp-tech@ndmp.org for details.
+ *
+ *     >>>  DO NOT MODIFY THIS FILE OR ANY GENERIC  <<<
+ *     >>>  PORTION OF NDMJOBLIB FOR THE SAKE OF A  <<<
+ *     >>>  HOSTING ENVIRONMENT OR APPLICATION.     <<<
+ *
+ *     If you discover additional isolation requirements,
+ *     raise the issue on ndmp-tech@ndmp.org. Propose new
+ *     #define NDMOS_ macros to address them. Then, submit
+ *     the proposal with required changes to the current
+ *     keeper of NDMJOB. Changes to the generic portion which
+ *     use #ifdef's based on anything other than NDMOS_
+ *     macros will be summarily rejected.
+ *
+ *     There are four sections of this file:
+ *       1) Establish identities for various O/S platforms
+ *       2) Try to auto-recognize the environment
+ *       3) #include the right O/S specific ndmos_xxx.h
+ *       4) Establish default #define-itions for macros
+ *          left undefined
+ */
+
+
+#ifndef _NDMOS_H
+#define _NDMOS_H
+
+/* set up the appropriate macros for use in various version-printing
+ * functions */
+#define NDMOS_IDENT(A,B,C,D)   (((A)<<24)+((B)<<16)+((C)<<8)+(D))
+#define NDMOS_ID_GLIB          NDMOS_IDENT('G','l','i','b')
+#define NDMOS_ID NDMOS_ID_GLIB
+
+/* unconditionally include ndmos_glib.h */
+#include "ndmos_glib.h"
+
+/*
+ * From here down, pre-processor symbols are #define'd to defaults
+ * if not already #define'd in the O/S specific header file.
+ *
+ * Application Program Interfaces (APIs). The macros give the
+ * O/S specific header a chance to use casts or different functions.
+ *
+ * NDMOS_API_BCOPY             -- memory copy
+ * NDMOS_API_BZERO             -- zero-fill memory
+ * NDMOS_API_MALLOC            -- memory allocator, no initialization
+ * NDMOS_API_FREE              -- memory deallocator
+ * NDMOS_API_STRTOLL           -- convert strings to long long
+ * NDMOS_API_STRDUP            -- malloc() and strcpy()
+ * NDMOS_API_STREND            -- return pointer to end of string
+ *
+ * Important constants that sometimes vary between O/S's.
+ *
+ * NDMOS_CONST_ALIGN           -- alignment for memory allocation
+ * NDMOS_CONST_EWOULDBLOCK     -- errno when async I/O would stall
+ * NDMOS_CONST_TAPE_REC_MAX    -- maximum tape record length
+ * NDMOS_CONST_TAPE_REC_MIN    -- minimum tape record length
+ * NDMOS_CONST_PATH_MAX                -- maximum path name length
+ * NDMOS_CONST_NDMJOBLIB_REVISION -- String for in-house change level
+ *                                Convention "0" if no changes
+ *                                from released source. If changes,
+ *                                the initials of local keeper with
+ *                                sequence number or date code.
+ * NDMOS_CONST_VENDOR_NAME     -- String for server_info_reply.vendor_name
+ * NDMOS_CONST_PRODUCT_NAME    -- String for server_info_reply.product_name
+ * NDMOS_CONST_PRODUCT_REVISION        -- String for product change level
+ *                                By "product" we mean the program
+ *                                enclosing this NDMJOBLIB library.
+ * NDMOS_CONST_NDMOS_REVISION  -- String for ndmos_xxx change level
+ *
+ * Macros for certain small operations which can vary.
+ *
+ * NDMOS_MACRO_NEW             -- allocate a data structure, wrapper
+ *                                around NDMOS_API_MALLOC() with casts
+ * NDMOS_MACRO_NEWN            -- allocate a vector of data structs
+ * NDMOS_MACRO_ZEROFILL                -- zero-fill data structure, wrapper
+ *                                around NDMOS_API_BZERO()
+ * NDMOS_MACRO_SRAND           -- wrapper around srand(3), for MD5
+ * NDMOS_MACRO_RAND            -- wrapper around rand(3), for MD5
+ * NDMOS_MACRO_OK_TAPE_REC_LEN -- Uses NDMOS_CONST_TAPE_REC_MIN/MAX
+ * NDMOS_MACRO_SET_SOCKADDR    -- Sets struct sockaddr_in with
+ *                                respect to NDMOS_OPTION_HAVE_SIN_LEN
+ *
+ * The NDMOS_MACRO_xxx_ADDITIONS macros allow additional O/S
+ * specific members to key structures in ndmagents.h
+ *
+ * NDMOS_MACRO_CONTROL_AGENT_ADDITIONS -- struct ndm_control_agent
+ * NDMOS_MACRO_DATA_AGENT_ADDITIONS    -- struct ndm_data_agent
+ * NDMOS_MACRO_ROBOT_AGENT_ADDITIONS   -- struct ndm_robot_agent
+ * NDMOS_MACRO_SESSION_ADDITIONS       -- struct ndm_session
+ * NDMOS_MACRO_TAPE_AGENT_ADDITIONS    -- struct ndm_tape_agent
+ *
+ * All NDMOS_OPTION_... parameters are either #define'd or #undef'ed.
+ * They are solely interpretted in #ifdef's and #ifndef's, and the
+ * value of the definition means nothing. These _OPTIONS_'s can be set
+ * on the command line (-D) in the Makefile, or in the O/S specific
+ * header file.
+ *
+ * NDMOS_OPTION_NO_NDMP2       -- omit NDMPv2 support
+ * NDMOS_OPTION_NO_NDMP3       -- omit NDMPv3 support
+ * NDMOS_OPTION_NO_NDMP4       -- omit NDMPv4 support
+ *
+ * NDMOS_OPTION_NO_CONTROL_AGENT -- omit CONTROL agent features
+ * NDMOS_OPTION_NO_DATA_AGENT  -- omit DATA agent features
+ * NDMOS_OPTION_NO_ROBOT_AGENT -- omit ROBOT agent features
+ * NDMOS_OPTION_NO_TAPE_AGENT  -- omit TAPE agent features
+ *     For some purposes, an all-in-one is overkill, or perhaps
+ *     impractical. Everything is carefully constructed so
+ *     that certain agents can be omitted without disturbing
+ *     the rest. The two most obvious uses are to either
+ *     keep or omit just the CONTROL agent.
+ *
+ * NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN
+ *     The NDMP specification says that both TAPE and SCSI can not
+ *     be open at the same time. Then the workflow docs suggest
+ *     a separate process for the ROBOT agent to get around the
+ *     restriction. #define'ing this breaks the spec and allows
+ *     both to be open.
+ *
+ * NDMOS_OPTION_HAVE_SIN_LEN
+ *     In preparation for IPv6, some O/Ss use a sin_len field to
+ *     indicate the length of the address. This _OPTION_ affects
+ *     the standard NDMOS_MACRO_SET_SOCKADDR.
+ *
+ * NDMOS_OPTION_TAPE_SIMULATOR
+ *     Early in bring-up on a new system, it's a little easier to
+ *     get started by using the tape simulator. It represents
+ *     an idealized MTIO-type tape subsystem, and uses a disk
+ *     file to represent the tape. As the real O/S specific tape
+ *     subsystem interface is implemented (ndmos_tape_...()), the
+ *     tape simulator serves as a reference for correct implementation.
+ *
+ * NDMOS_OPTION_ROBOT_SIMULATOR
+ *     Similarly, for testing multi-tape operations, it's easier to
+ *     get started by using the robot simulator. It represents a simple
+ *     robot with ten slots and two drives.  It operates on a directory,
+ *     and uses rename() to load and unload tapes.  It operates in concert
+ *     with the tape simulator.  The robot name is a directory, and it
+ *     creates drives named 'drive0', 'drive1', etc. in that directory
+ *
+ * NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL -- use common poll() code
+ * NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL   -- use common select() code
+ *     These two _OPTION_'s choose common code to implement
+ *     ndmos_chan_poll(). The select() and poll() functions are
+ *     fairly common and consistent among various O/S's to detect
+ *     ready I/O. Only one can be defined. If the common code
+ *     doesn't work out, don't define either _OPTION_ and implement
+ *     ndmos_chan_poll() in the O/S specific C source file.
+ */
+
+/*
+ * Constants
+ */
+#ifndef NDMOS_CONST_ALIGN
+#define NDMOS_CONST_ALIGN              sizeof(unsigned long long)
+#endif /* !NDMOS_CONST_ALIGN */
+
+#ifndef NDMOS_CONST_TAPE_REC_MIN
+#define NDMOS_CONST_TAPE_REC_MIN       1
+#endif /* !NDMOS_CONST_TAPE_REC_MIN */
+
+#ifndef NDMOS_CONST_TAPE_REC_MAX
+#define NDMOS_CONST_TAPE_REC_MAX       (256*1024)
+#endif /* !NDMOS_CONST_TAPE_REC_MAX */
+
+#ifndef NDMOS_CONST_PATH_MAX
+#define NDMOS_CONST_PATH_MAX           (1024)
+#endif /* !NDMOS_CONST_PATH_MAX */
+
+#ifndef NDMOS_CONST_EWOULDBLOCK
+#ifdef EWOULDBLOCK
+#define NDMOS_CONST_EWOULDBLOCK                EWOULDBLOCK
+#else /* EWOULDBLOCK */
+#define NDMOS_CONST_EWOULDBLOCK                EAGAIN
+#endif /* EWOULDBLOCK */
+#endif /* !NDMOS_CONST_EWOULDBLOCK */
+
+#ifndef NDMOS_CONST_NDMJOBLIB_REVISION
+#define NDMOS_CONST_NDMJOBLIB_REVISION "1.4a"
+#endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */
+
+#ifndef NDMOS_CONST_VENDOR_NAME
+#define NDMOS_CONST_VENDOR_NAME "PublicDomain"
+#endif /* !NDMOS_CONST_VENDOR_NAME */
+
+#ifndef NDMOS_CONST_PRODUCT_NAME
+#define NDMOS_CONST_PRODUCT_NAME "NDMJOB"
+#endif /* !NDMOS_CONST_PRODUCT_NAME */
+
+#ifndef NDMOS_CONST_PRODUCT_REVISION
+#define NDMOS_CONST_PRODUCT_REVISION "1.4a"
+#endif /* !NDMOS_CONST_PRODUCT_REVISION */
+
+#ifndef NDMOS_CONST_NDMOS_REVISION
+#define NDMOS_CONST_NDMOS_REVISION "0"
+#endif /* !NDMOS_CONST_NDMOS_REVISION */
+
+
+
+
+/*
+ * Application Program Interfaces (APIs)
+ */
+#ifndef NDMOS_API_BZERO
+#define NDMOS_API_BZERO(P,N)   (void)bzero((void*)(P),(N))
+#endif /* !NDMOS_API_BZERO */
+
+#ifndef NDMOS_API_BCOPY
+#define NDMOS_API_BCOPY(S,D,N) (void)bcopy((void*)(S),(void*)(D),(N))
+#endif /* !NDMOS_API_BCOPY */
+
+#ifndef NDMOS_API_MALLOC
+#define NDMOS_API_MALLOC(N)    malloc(N)
+#endif /* !NDMOS_API_MALLOC */
+
+#ifndef NDMOS_API_FREE
+#define NDMOS_API_FREE(P)      free((void*)(P))
+#endif /* !NDMOS_API_FREE */
+
+#ifndef NDMOS_API_STRTOLL
+#define NDMOS_API_STRTOLL(P,PP,BASE) strtoll(P,PP,BASE)
+#endif /* !NDMOS_API_STRTOLL */
+
+#ifndef NDMOS_API_STRDUP
+#define NDMOS_API_STRDUP(S)    strdup(S)
+#endif /* !NDMOS_API_STRDUP */
+
+#ifndef NDMOS_API_STREND
+extern char *ndml_strend(char *s);     /* ndml_util.c */
+#define NDMOS_API_STREND(S)    ndml_strend(S)
+#endif /* !NDMOS_API_STREND */
+
+
+
+
+/*
+ * Macros
+ */
+#ifndef NDMOS_MACRO_NEW
+#define NDMOS_MACRO_NEW(T)     ((T *) NDMOS_API_MALLOC(sizeof (T)))
+#endif /* !NDMOS_MACRO_NEW */
+
+#ifndef NDMOS_MACRO_NEWN
+#define NDMOS_MACRO_NEWN(T,N)  ((T *) NDMOS_API_MALLOC(sizeof (T) * (N)))
+#endif /* !NDMOS_MACRO_NEWN */
+
+#ifndef NDMOS_MACRO_ZEROFILL
+#define NDMOS_MACRO_ZEROFILL(P)        NDMOS_API_BZERO(P,sizeof *(P))
+#endif /* !NDMOS_MACRO_ZEROFILL */
+
+#ifndef NDMOS_MACRO_SRAND
+#define NDMOS_MACRO_SRAND() srand(time(0))
+#endif /* !NDMOS_MACRO_SRAND */
+
+#ifndef NDMOS_MACRO_RAND
+#define NDMOS_MACRO_RAND() rand()
+#endif /* !NDMOS_MACRO_RAND */
+
+#ifndef NDMOS_MACRO_OK_TAPE_REC_LEN
+#define NDMOS_MACRO_OK_TAPE_REC_LEN(LEN) \
+       (NDMOS_CONST_TAPE_REC_MIN <= (LEN) \
+        && (LEN) <= NDMOS_CONST_TAPE_REC_MAX)
+#endif /* !NDMOS_MACRO_OK_TAPE_REC_LEN */
+
+#ifndef NDMOS_MACRO_SET_SOCKADDR
+#ifdef NDMOS_OPTION_HAVE_SIN_LEN
+#define NDMOS_MACRO_SET_SOCKADDR(SA,INADDR,PORT) \
+       ( NDMOS_MACRO_ZEROFILL (SA), \
+         ((struct sockaddr_in *)(SA))->sin_len = sizeof *(SA), \
+         ((struct sockaddr_in *)(SA))->sin_family = AF_INET, \
+         ((struct sockaddr_in *)(SA))->sin_addr.s_addr = htonl(INADDR), \
+         ((struct sockaddr_in *)(SA))->sin_port = htons(PORT))
+#else /* NDMOS_OPTION_HAVE_SIN_LEN */
+#define NDMOS_MACRO_SET_SOCKADDR(SA,INADDR,PORT) \
+       ( NDMOS_MACRO_ZEROFILL (SA), \
+         ((struct sockaddr_in *)(SA))->sin_family = AF_INET, \
+         ((struct sockaddr_in *)(SA))->sin_addr.s_addr = htonl(INADDR), \
+         ((struct sockaddr_in *)(SA))->sin_port = htons(PORT))
+#endif /* NDMOS_OPTION_HAVE_SIN_LEN */
+#endif /* !NDMOS_MACRO_SET_SOCKADDR */
+
+
+
+
+/*
+ * Composite effects
+ */
+
+#ifdef NDMOS_OPTION_NO_DATA_AGENT
+#ifdef NDMOS_OPTION_NO_TAPE_AGENT
+#ifdef NDMOS_OPTION_NO_ROBOT_AGENT
+#define NDMOS_EFFECT_NO_SERVER_AGENTS
+#endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
+#endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
+#endif /* !NDMOS_OPTION_NO_DATA_AGENT */
+
+#ifdef NDMOS_OPTION_NO_NDMP3
+#ifdef NDMOS_OPTION_NO_NDMP4
+#define NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4
+#endif /* !NDMOS_OPTION_NO_NDMP3 */
+#endif /* !NDMOS_OPTION_NO_NDMP4 */
+
+/* check for a conflict: robot sim requires tape sim */
+#ifdef NDMOS_OPTION_ROBOT_SIMULATOR
+#ifndef NDMOS_OPTION_TAPE_SIMULATOR
+#error robot simulator requires the tape simulator
+#endif /* NDMOS_OPTION_TAPE_SIMULATOR */
+#ifdef NDMOS_COMMON_SCSI_INTERFACE
+#error robot simulator and ndmos scsi interface are incompatible
+#endif
+#endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
+
+/*
+ * simulator fields
+ */
+
+#ifdef NDMOS_OPTION_TAPE_SIMULATOR
+#define NDMOS_MACRO_TAPE_AGENT_ADDITIONS \
+       int                     tape_fd; \
+       char                    drive_name[PATH_MAX]; \
+       int                     weof_on_close; \
+       int                     sent_leom;
+#endif /* NDMOS_OPTION_TAPE_SIMULATOR */
+
+#ifdef NDMOS_OPTION_ROBOT_SIMULATOR
+#define NDMOS_MACRO_ROBOT_AGENT_ADDITIONS \
+           char sim_dir[PATH_MAX];
+#endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
+
+#endif /* _NDMOS_H */