+/*
+ * 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 key #include file for the NDMP protocol
+ * layer of NDMJOBLIB.
+ *
+ * There are multiple version of NDMP. This gathers them together.
+ * Under control of #ifdef NDMOS_OPTION_NO_NDMPx specific versions
+ * may be omitted. At this time, NDMPv2 and NDMPv3 are deployed.
+ * NDMPv1 was defined but not widely deployed, and deemed irrelavent.
+ * NDMPv4 is under consideration.
+ *
+ * NDMP is defined using RPC protocol specification
+ * files (.x files). NDMP does not really use the RPC
+ * layer, but it does use the RPC XDR (External Data
+ * Representation) layer.
+ *
+ * The original NDMP .x files are cosmetically transformed for
+ * NDMJOBLIB. The original NDMPv2 and NDMPv3 .x files use names
+ * like ndmp_name and ndmp_config_get_host_info_reply. These
+ * changed between versions even though they have the same name.
+ * Data structures which didn't change, like ndmp_pval, caused
+ * compile-time agony. For example, xdr_ndmp_pval() would be
+ * multiply defined at ld(1)-time. The first approach considered
+ * and rejected to resolve this was to make a unified, all
+ * versions .x file. It was rejected because it becomes difficult,
+ * even impractical, to integrate new versions and to omit old ones.
+ * The approach taken was to transform the names to reflect protocol
+ * version. This same approach was adopted by NFS for NFSv3 and
+ * NFSv4. Now there is an ndmp2_pval and an ndmp3_pval, and the
+ * compiler is happy. When it's defined, there will be an ndmp4_pval.
+ *
+ * There are two pseudo-versions of the protocol here: NDMPv0
+ * and NDMPv9. These are used for internal convenience. These
+ * are also defined using .x files because it's easy to
+ * cut-n-paste from the official .x files. Neither NDMPv0
+ * nor NDMPv9 may be omitted.
+ *
+ * NDMPv0 is the NDMP protocol subset used before the protocol
+ * version negotiation is complete. This subset of the protocol
+ * must necessarily remain immutable and constant for all time.
+ * NDMPv0 is the over-the-wire protocol until the version is
+ * negotiated.
+ *
+ * NDMPv9 is an internal representation of the protocol and
+ * isolates higher layers of NDMJOB from most variations between
+ * protocol version. NDMPv9 makes it a little easier to add
+ * new versions and omit older ones. NDMPv9 is never used
+ * over-the-wire, and therefor there are no XDR routines.
+ *
+ * There are three primary elements of this layer:
+ *
+ * 1) Header files which define each version of the protocol.
+ * These are generated from files (.x files) by rpcgen(1).
+ *
+ * 2) XDR routines which convert to/from the over-the-wire
+ * protocol and internal data structures. These are
+ * also generated by rpcgen(1). There are also
+ * tables of XDR routines.
+ *
+ * 3) Support for pretty-printing the protocol data structures.
+ * Maybe someday rpcgen(1) will generate these, too.
+ */
+
+
+/*
+ * PROTOCOL VERSIONS
+ ****************************************************************
+ *
+ */
+
+#include "ndmp0.h"
+
+#ifndef NDMOS_OPTION_NO_NDMP2
+#include "ndmp2.h"
+#endif /* !NDMOS_OPTION_NO_NDMP2 */
+
+#ifndef NDMOS_OPTION_NO_NDMP3
+#include "ndmp3.h"
+#endif /* !NDMOS_OPTION_NO_NDMP3 */
+
+#ifndef NDMOS_OPTION_NO_NDMP4
+#include "ndmp4.h"
+#endif /* !NDMOS_OPTION_NO_NDMP4 */
+
+#include "ndmp9.h"
+
+
+
+
+/*
+ * Protocol ammendments. These are important constants
+ * omitted from the spec and .x files.
+ */
+#include "ndmp_ammend.h"
+
+
+
+
+/*
+ * XDR MESSAGE TABLES
+ ****************************************************************
+ *
+ * Table for binding a ndmp_message to appropriate XDR routines.
+ */
+
+struct ndmp_xdr_message_table {
+ int msg;
+ int (*xdr_request)();
+ int (*xdr_reply)();
+};
+
+extern struct ndmp_xdr_message_table ndmp0_xdr_message_table[];
+
+#ifndef NDMOS_OPTION_NO_NDMP2
+extern struct ndmp_xdr_message_table ndmp2_xdr_message_table[];
+#endif /* !NDMOS_OPTION_NO_NDMP2 */
+
+#ifndef NDMOS_OPTION_NO_NDMP3
+extern struct ndmp_xdr_message_table ndmp3_xdr_message_table[];
+#endif /* !NDMOS_OPTION_NO_NDMP3 */
+
+#ifndef NDMOS_OPTION_NO_NDMP4
+extern struct ndmp_xdr_message_table ndmp4_xdr_message_table[];
+#endif /* !NDMOS_OPTION_NO_NDMP4 */
+
+/* Note: no ndmp9 XDRs */
+
+extern struct ndmp_xdr_message_table *
+ ndmp_xmt_lookup (int protocol_version, int msg);
+
+
+
+
+/*
+ * ENUM STRING TABLES
+ ****************************************************************
+ */
+
+struct ndmp_enum_str_table {
+ char * name;
+ int value;
+};
+
+extern char * ndmp_enum_to_str (int val, struct ndmp_enum_str_table *table);
+extern int ndmp_enum_from_str (int *valp, char *str,
+ struct ndmp_enum_str_table *table);
+
+
+#include "ndmp0_enum_strs.h"
+
+#ifndef NDMOS_OPTION_NO_NDMP2
+#include "ndmp2_enum_strs.h"
+#endif /* !NDMOS_OPTION_NO_NDMP2 */
+
+#ifndef NDMOS_OPTION_NO_NDMP3
+#include "ndmp3_enum_strs.h"
+#endif /* !NDMOS_OPTION_NO_NDMP3 */
+
+#ifndef NDMOS_OPTION_NO_NDMP4
+#include "ndmp4_enum_strs.h"
+#endif /* !NDMOS_OPTION_NO_NDMP4 */
+
+#include "ndmp9_enum_strs.h"
+
+
+
+
+/*
+ * MULTI-VERSION ENUM TO STRING CONVERTERS
+ ****************************************************************
+ */
+
+extern char * ndmp_message_to_str (int protocol_version, int msg);
+extern char * ndmp_error_to_str (int protocol_version, int msg);
+
+
+
+
+/*
+ * PRETTY PRINTERS
+ ****************************************************************
+ *
+ * The ndmp[v]_pp_... (pretty printer) routines are debugging aids.
+ * They pretty much implement an NDMP snooping package.
+ *
+ * All routines return -1 for an error. Otherwise, they
+ * return the number of lines required to print the entire
+ * data structure. A return of 0 indicates a void data
+ * structure. lineno parameter begins at 0.
+ *
+ * Line number 0 is usually usable as a summary.
+ * Three levels of increasing detail are easy:
+ * 1) Just ndmp_pp_header()
+ * 2) ndmp_pp_header() and ndmp_pp_{request|reply} w/ lineno=0
+ * 3) ndmp_pp_header() and ndmp_pp_{request|reply} all lines
+ */
+
+
+extern int ndmp_pp_header (int vers, void *data, char *buf);
+extern int ndmp_pp_request (int vers, int msg,
+ void *data, int lineno, char *buf);
+extern int ndmp_pp_reply (int vers, int msg,
+ void *data, int lineno, char *buf);
+
+extern int ndmp0_pp_header (void *data, char *buf);
+extern int ndmp0_pp_request (ndmp0_message msg,
+ void *data, int lineno, char *buf);
+extern int ndmp0_pp_reply (ndmp0_message msg,
+ void *data, int lineno, char *buf);
+
+#ifndef NDMOS_OPTION_NO_NDMP2
+extern int ndmp2_pp_header (void *data, char *buf);
+extern int ndmp2_pp_request (ndmp2_message msg,
+ void *data, int lineno, char *buf);
+extern int ndmp2_pp_reply (ndmp2_message msg,
+ void *data, int lineno, char *buf);
+#endif /* !NDMOS_OPTION_NO_NDMP2 */
+
+#ifndef NDMOS_OPTION_NO_NDMP3
+extern int ndmp3_pp_header (void *data, char *buf);
+extern int ndmp3_pp_request (ndmp3_message msg,
+ void *data, int lineno, char *buf);
+extern int ndmp3_pp_reply (ndmp3_message msg,
+ void *data, int lineno, char *buf);
+#endif /* !NDMOS_OPTION_NO_NDMP3 */
+
+#ifndef NDMOS_OPTION_NO_NDMP4
+extern int ndmp4_pp_header (void *data, char *buf);
+extern int ndmp4_pp_request (ndmp4_message msg,
+ void *data, int lineno, char *buf);
+extern int ndmp4_pp_reply (ndmp4_message msg,
+ void *data, int lineno, char *buf);
+#endif /* !NDMOS_OPTION_NO_NDMP4 */
+
+
+#define NDMP_PP_AS(T) ((T *)data)
+
+#define NDMP_PP_WITH(T) { T * p = ((T *)data);
+#define NDMP_PP_ENDWITH }