Merge branch 'master' into squeeze
[debian/amanda] / ndmp-src / ndmagents.h
diff --git a/ndmp-src/ndmagents.h b/ndmp-src/ndmagents.h
new file mode 100644 (file)
index 0000000..ee10a1a
--- /dev/null
@@ -0,0 +1,1265 @@
+/*
+ * 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:
+ *
+ ********************************************************************
+ *
+ * NDMP Elements of a backup/restore session
+ *
+ *                   +-----+     ###########
+ *                   | Job |----># CONTROL #      +----------------+
+ *                   +-----+     #  Agent  #<---->|FILE/MEDIA INDEX|
+ *                               #         #      +----------------+
+ *                               ###########
+ *                                 |  |  |
+ *                +----------------+  |  +---------------------+
+ *                |           control | connections            |
+ *                V                   V                        V
+ *           ############        ############  +-------+   #########
+ *           #  DATA    #        #  TAPE    #  |       |   # ROBOT #
+ *           #  Agent   #        #  Agent   #  | ROBOT |<-># Agent #
+ *  +-----+  # +------+ # image  # +------+ #  |+-----+|   #       #
+ *  |FILES|====|butype|============|mover |=====|DRIVE||   #       #
+ *  +-----+  # +------+ # stream # +------+ #  |+-----+|   #       #
+ *           ############        ############  +-------+   #########
+ *
+ *
+ ********************************************************************
+ *
+ * NDMAGENTS components overview
+ *
+ *
+ *    "job" -> ndma_client_session()    ndma_server_session()
+ *                   |                           |
+ *     /-------------/                           Q
+ *     |                                         v
+ *     |       +------------------------------------+      +-----------+
+ *     |    /->|           SESSION QUANTUM          |----->| disp conn |
+ *     |    |  +------------------------------------+ \    +-----------+
+ *     |    Q   Q       Q         Q       Q        Q  |         v    |
+ *     |    |   |       |         |       |        |  | +----------+ |
+ *     |  /-----|----+--|----+----|----+--|----+---|----| dispatch | |
+ *     |  | |   |    |  |    |    |    |  |    |   |  | | request  | |
+ *     |  v |   v    v  v    v    v    v  v    v   v  | +----------+ |
+ *     | +-------+  +----+  +------+  +----+  +-----+ |      ^       |
+ *     +>|CONTROL|  |DATA|  |IMAGE |  |TAPE|  |ROBOT| |      |       |
+ *       |       |  |    |->|STREAM|<-|    |  |     | |      |       |
+ *       |       |  |   *====*    *====*   |  |     | |      |  ndmconn_recv()
+ *       | ndmca |  ndmda|  |ndmis |  ndmta|  |ndmra| |      |       |
+ *       +-------+  +----+  +------+  +----+  +-----+ |      |resi   |
+ *              |     | |    |    |       |           |   +------+   |
+ *              \-----|-+----|----+-------+-------------->| call |   |
+ *                    |      |                        |   +------+   |
+ *           formatter|      |image_stream            |      |remo   |
+ *                    v      v                        |      v       v
+ *                   +---------+<---ndmchan_poll()----/     +---------+
+ *                   | ndmchan |<---------------------------| ndmconn |
+ *                   +---------+                            +---------+
+ *                 non-blocking I/O                         XDR wrapper
+ *
+ *   -----> caller/callee
+ *   --Q--> quantum (CPU scheduling)
+ *   ====== image stream shared data structures
+ *
+ ********************************************************************
+ */
+
+
+#include "ndmlib.h"
+
+
+
+/*
+ * VERSION AND RELEASE CONSTANTS -- KEEPER ONLY
+ ****************************************************************
+ *
+ * Revision constants for the source code. These may only be
+ * changed by the keeper of these sources. Contact ndmp-tech@ndmp.org
+ * for a pointer to the latest sources and the current keeper.
+ *
+ * The Version increases every time there is a significant
+ * design change. Significant means new functionality,
+ * reorganization of key data structures, etc. The Release
+ * increases every time the keeper releases an update to
+ * the current version, such as bug fixes or integration
+ * of new contributions.
+ *
+ * There are provisions for a free-form string for revisions
+ * of the O/S specific portions (NDMOS_CONST_NDMOS_REVISION)
+ * and for local revisions (NDMOS_CONST_NDMJOBLIB_REVISION)
+ * which reflect in-house change levels.
+ */
+#define NDMJOBLIB_VERSION      1
+#define NDMJOBLIB_RELEASE      2
+
+
+
+
+struct ndm_session;            /* forward decl */
+
+
+
+
+/*
+ * NDM_ENV_TABLE and NDM_NLIST_TABLE
+ ****************************************************************
+ * Used by DATA and CONTROL agents
+ */
+#ifndef NDM_MAX_ENV
+#define NDM_MAX_ENV            1024
+#endif
+struct ndm_env_table {
+       int                     n_env;
+       ndmp9_pval              env[NDM_MAX_ENV];
+};
+
+#ifndef NDM_MAX_NLIST
+#define NDM_MAX_NLIST          10240
+#endif
+struct ndm_nlist_table {
+       int                     n_nlist;
+       ndmp9_name              nlist[NDM_MAX_NLIST];
+       ndmp9_name              nlist_new[NDM_MAX_NLIST];
+       ndmp9_error             result_err[NDM_MAX_NLIST];
+       unsigned                result_count[NDM_MAX_NLIST];
+};
+
+
+
+
+#ifndef NDMOS_OPTION_NO_CONTROL_AGENT
+/*
+ * CONTROL AGENT
+ ****************************************************************
+ */
+
+#include "smc.h"               /* SCSI Media Changer */
+
+
+#ifndef NDM_MAX_MEDIA
+#define NDM_MAX_MEDIA          40
+#endif
+
+struct ndm_media_table {
+       int                     n_media;
+       struct ndmmedia         media[NDM_MAX_MEDIA];
+};
+
+
+#define NDM_JOB_OP_BACKUP      (0x100 | 'c')
+#define NDM_JOB_OP_EXTRACT     (0x100 | 'x')
+#define NDM_JOB_OP_TOC         (0x100 | 't')
+#define NDM_JOB_OP_QUERY_AGENTS        (0x100 | 'q')
+#define NDM_JOB_OP_INIT_LABELS (0x100 | 'I')
+#define NDM_JOB_OP_LIST_LABELS (0x100 | 'L')
+#define NDM_JOB_OP_REMEDY_ROBOT        (0x100 | 'Z')
+
+/* test operations */
+#define NDM_JOB_OP_TEST_TAPE   (0x200 | 'T')
+#define NDM_JOB_OP_TEST_MOVER  (0x200 | 'M')
+#define NDM_JOB_OP_TEST_DATA   (0x200 | 'D')
+
+/* tape handling operations */
+#define NDM_JOB_OP_REWIND_TAPE (0x300 | 'r')
+#define NDM_JOB_OP_EJECT_TAPE  (0x300 | 'j')
+#define NDM_JOB_OP_MOVE_TAPE   (0x300 | 'm')
+#define NDM_JOB_OP_LOAD_TAPE   (0x300 | 'l')
+#define NDM_JOB_OP_UNLOAD_TAPE (0x300 | 'u')
+#define NDM_JOB_OP_IMPORT_TAPE (0x300 | 'i')
+#define NDM_JOB_OP_EXPORT_TAPE (0x300 | 'e')
+#define NDM_JOB_OP_INIT_ELEM_STATUS (0x300 | 'I')
+
+/* daemon operations */
+#define NDM_JOB_OP_DAEMON 'd'
+#define NDM_JOB_OP_TEST_DAEMON 'D'
+
+struct ndm_job_param {
+       int                     operation;      /* NDM_JOB_OP_... */
+        int                     time_limit;    /* command timeout, 0 is off */
+
+       struct ndmagent         data_agent;     /* DATA AGENT host/pw */
+       char *                  bu_type;        /* e.g. "tar" */
+       struct ndm_env_table    env_tab;        /* for BACKUP+RECOVER ops */
+       struct ndm_nlist_table  nlist_tab;      /* for RECOVER ops */
+       struct ndm_env_table    result_env_tab; /* after BACKUP */
+       struct ndmlog           index_log;      /* to log NDMP_FH_ADD_... */
+
+       struct ndmagent         tape_agent;     /* TAPE AGENT host/pw */
+       char *                  tape_device;    /* eg "/dev/rmt0" */
+       unsigned                tape_timeout;   /* secs total to retry open */
+       unsigned                record_size;    /* in bytes, 10k typical */
+        unsigned long long     last_w_offset;  /* last window offset sent */
+       struct ndmscsi_target   tape_target;    /* unused for now */
+       char *                  tape_tcp;       /* tcp direct */
+       NDM_FLAG_DECL(use_eject)                /* eject upon close (unload) */
+
+       struct ndmagent         robot_agent;    /* ROBOT AGENT host/pw */
+       struct ndmscsi_target   robot_target;   /* SCSI coord of robot */
+       unsigned                robot_timeout;  /* secs total to retry move */
+       NDM_FLAG_DECL(have_robot)               /* yes, we have robot, today */
+       NDM_FLAG_DECL(auto_remedy)              /* if drive loaded, unload */
+       NDM_FLAG_DECL(remedy_all)               /* OP_REMEDY, all drives */
+       NDM_FLAG_DECL(drive_addr_given)
+       NDM_FLAG_DECL(from_addr_given)
+       NDM_FLAG_DECL(to_addr_given)
+       unsigned                drive_addr;     /* 0->first, !0->elem addr */
+       unsigned                from_addr;      /* for MOVE and EXPORT */
+       unsigned                to_addr;        /* for MOVE and IMPORT */
+                                               /* use move for many I/E */
+
+       struct ndm_media_table  media_tab;      /* media to use, params */
+       struct ndm_media_table  result_media_tab; /* results after job */
+
+       unsigned long           n_file_entry;
+       unsigned long           n_dir_entry;
+       unsigned long           n_node_entry;
+       unsigned long long      root_node;
+};
+
+/* ndma_job.c */
+extern int     ndma_job_audit (struct ndm_job_param *job,
+                               char *errbuf, int errskip);
+extern int     ndma_job_media_audit (struct ndm_job_param *job,
+                               char *errbuf, int errskip);
+extern void    ndma_job_auto_adjust (struct ndm_job_param *job);
+
+
+struct ndm_control_agent {
+       /* The JOB, see immediately above */
+       struct ndm_job_param    job;
+       NDM_FLAG_DECL(swap_connect)
+       NDM_FLAG_DECL(has_tcp_addr)
+       NDM_FLAG_DECL(has_local_addr)
+
+       /* DATA agent */
+       ndmp9_data_operation    data_op;
+       ndmp9_data_get_state_reply data_state;
+       NDM_FLAG_DECL(pending_notify_data_read)
+       NDM_FLAG_DECL(pending_notify_data_halted)
+       ndmp9_notify_data_read_request last_notify_data_read;
+       ndmp9_addr              data_addr;
+       int                     recover_log_file_count;
+       int                     recover_log_file_ok;
+       int                     recover_log_file_error;
+
+       /* Image stream */
+       ndmp9_addr              mover_addr;
+       ndmp9_mover_mode        mover_mode;
+
+       /* TAPE Agent */
+       ndmp9_mover_get_state_reply mover_state;
+       NDM_FLAG_DECL(pending_notify_mover_paused)
+       NDM_FLAG_DECL(pending_notify_mover_halted)
+       ndmp9_notify_mover_paused_request last_notify_mover_paused;
+
+       ndmp9_tape_open_mode    tape_mode;
+       ndmp9_tape_get_state_reply tape_state;
+
+       /* Media management, media_table inside of job */
+       int                     cur_media_ix;
+       NDM_FLAG_DECL(media_is_loaded)
+       NDM_FLAG_DECL(is_label_op)
+
+       /* ROBOT Agent */
+       struct smc_ctrl_block   smc_cb;
+       unsigned                drive_addr;
+
+       /* when testing */
+       char *                  active_test;            /* name of test or 0 if no test */
+       char *                  active_test_failed;     /* active test failed */
+       char *                  active_test_warned;     /* active test warned */
+
+       char *                  test_phase;             /* name of sub-series test phase */
+       int                     test_step;              /* test sequence number */
+
+       int                     n_step_pass;            /* per phase test stats */
+       int                     n_step_fail;
+       int                     n_step_warn;
+       int                     n_step_tests;
+
+       int                     total_n_step_pass;      /* total test stats */
+       int                     total_n_step_fail;
+       int                     total_n_step_warn;
+       int                     total_n_step_tests;
+
+#ifdef NDMOS_MACRO_CONTROL_AGENT_ADDITIONS
+       NDMOS_MACRO_CONTROL_AGENT_ADDITIONS
+#endif /* NDMOS_MACRO_CONTROL_AGENT_ADDITIONS */
+};
+
+
+/* ndma_control.c */
+extern int     ndmca_control_agent (struct ndm_session *sess);
+
+/* ndma_cops_backreco.c */
+extern int     ndmca_op_create_backup (struct ndm_session *sess);
+extern int     ndmca_op_recover_files (struct ndm_session *sess);
+extern int     ndmca_op_recover_fh (struct ndm_session *sess);
+extern int     ndmca_monitor_backup (struct ndm_session *sess);
+extern int     ndmca_monitor_get_post_backup_env (struct ndm_session *sess);
+extern int     ndmca_monitor_recover (struct ndm_session *sess);
+extern int     ndmca_backreco_startup (struct ndm_session *sess);
+extern int     ndmca_monitor_startup (struct ndm_session *sess);
+extern int     ndmca_monitor_shutdown (struct ndm_session *sess);
+extern int     ndmca_monitor_get_states (struct ndm_session *sess);
+extern int     ndmca_monitor_load_next (struct ndm_session *sess);
+extern int     ndmca_monitor_seek_tape (struct ndm_session *sess);
+extern int     ndmca_monitor_unload_last_tape (struct ndm_session *sess);
+extern int     ndmca_mon_wait_for_something (struct ndm_session *sess,
+                       int max_delay_secs);
+
+/* ndma_cops_labels.c */
+extern int     ndmca_op_init_labels (struct ndm_session *sess);
+extern int     ndmca_op_list_labels (struct ndm_session *sess);
+
+
+/* ndma_cops_query.c */
+extern int     ndmca_op_query (struct ndm_session *sess);
+extern int     ndmca_opq_data (struct ndm_session *sess);
+extern int     ndmca_opq_tape (struct ndm_session *sess);
+extern int     ndmca_opq_robot (struct ndm_session *sess);
+extern int     ndmca_opq_host_info (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern int     ndmca_opq_get_mover_type (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern int     ndmca_opq_get_butype_attr (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern int     ndmca_opq_get_fs_info (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern int     ndmca_opq_get_tape_info (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern int     ndmca_opq_get_scsi_info (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern void    ndmalogqr (struct ndm_session *sess, char *fmt, ...);
+
+
+/* ndma_cops_robot.c */
+extern int     ndmca_op_robot_remedy (struct ndm_session *sess);
+extern int     ndmca_op_robot_startup (struct ndm_session *sess,
+                       int verify_media_flag);
+extern int     ndmca_op_init_elem_status (struct ndm_session *sess);
+extern int     ndmca_op_rewind_tape (struct ndm_session *sess);
+extern int     ndmca_op_eject_tape (struct ndm_session *sess);
+extern int     ndmca_op_mtio (struct ndm_session *sess,
+                       ndmp9_tape_mtio_op mtio_op);
+
+extern int     ndmca_op_move_tape (struct ndm_session *sess);
+extern int     ndmca_op_import_tape (struct ndm_session *sess);
+extern int     ndmca_op_export_tape (struct ndm_session *sess);
+extern int     ndmca_op_load_tape (struct ndm_session *sess);
+extern int     ndmca_op_unload_tape (struct ndm_session *sess);
+
+
+/* ndma_ctrl_calls.c */
+extern int     ndmca_data_get_state (struct ndm_session *sess);
+extern int     ndmca_data_connect (struct ndm_session *sess);
+extern int     ndmca_data_listen (struct ndm_session *sess);
+extern int     ndmca_data_start_backup (struct ndm_session *sess);
+extern int     ndmca_data_start_recover (struct ndm_session *sess);
+extern int     ndmca_data_start_recover_filehist (struct ndm_session *sess);
+extern int     ndmca_data_abort (struct ndm_session *sess);
+extern int     ndmca_data_get_env (struct ndm_session *sess);
+extern int     ndmca_data_stop (struct ndm_session *sess);
+extern int     ndmca_tape_open (struct ndm_session *sess);
+extern int     ndmca_tape_close (struct ndm_session *sess);
+extern int     ndmca_tape_get_state (struct ndm_session *sess);
+extern int     ndmca_tape_get_state_no_tattle (struct ndm_session *sess);
+extern int     ndmca_tape_mtio (struct ndm_session *sess,
+                       ndmp9_tape_mtio_op op, u_long count, u_long *resid);
+extern int     ndmca_tape_write (struct ndm_session *sess,
+                       char *buf, unsigned count);
+extern int     ndmca_tape_read (struct ndm_session *sess,
+                       char *buf, unsigned count);
+extern int     ndmca_mover_get_state (struct ndm_session *sess);
+extern int     ndmca_mover_listen (struct ndm_session *sess);
+extern int     ndmca_mover_connect (struct ndm_session *sess);
+extern int     ndmca_mover_continue (struct ndm_session *sess);
+extern int     ndmca_mover_abort (struct ndm_session *sess);
+extern int     ndmca_mover_stop (struct ndm_session *sess);
+extern int     ndmca_mover_set_window (struct ndm_session *sess,
+                       unsigned long long offset, unsigned long long length);
+extern int     ndmca_mover_read (struct ndm_session *sess,
+                       unsigned long long offset, unsigned long long length);
+extern int     ndmca_mover_close (struct ndm_session *sess);
+extern int     ndmca_mover_set_record_size (struct ndm_session *sess);
+
+
+/* ndma_ctrl_media.c */
+extern int     ndmca_media_load_first (struct ndm_session *sess);
+extern int     ndmca_media_load_next (struct ndm_session *sess);
+extern int     ndmca_media_unload_last (struct ndm_session *sess);
+extern int     ndmca_media_change (struct ndm_session *sess);
+extern int     ndmca_media_load_seek (struct ndm_session *sess,
+                       unsigned long long pos);
+extern int     ndmca_media_load_current (struct ndm_session *sess);
+extern int     ndmca_media_unload_current (struct ndm_session *sess);
+extern int     ndmca_media_unload_best_effort (struct ndm_session *sess);
+extern int     ndmca_media_open_tape (struct ndm_session *sess);
+extern int     ndmca_media_close_tape (struct ndm_session *sess);
+extern int     ndmca_media_mtio_tape (struct ndm_session *sess,
+                       ndmp9_tape_mtio_op op, u_long count, u_long *resid);
+extern int     ndmca_media_write_filemarks (struct ndm_session *sess);
+extern int     ndmca_media_read_label (struct ndm_session *sess,
+                       char labbuf[]);
+extern int     ndmca_media_write_label (struct ndm_session *sess,
+                       int type, char labbuf[]);
+extern int     ndmca_media_check_label (struct ndm_session *sess,
+                       int type, char labbuf[]);
+extern int     ndmca_media_verify (struct ndm_session *sess);
+extern int     ndmca_media_tattle (struct ndm_session *sess);
+extern unsigned long long
+               ndmca_media_capture_tape_offset (struct ndm_session *sess);
+extern int     ndmca_media_capture_mover_window (struct ndm_session *sess);
+extern int     ndmca_media_calculate_windows (struct ndm_session *sess);
+extern int     ndmca_media_calculate_offsets (struct ndm_session *sess);
+extern int     ndmca_media_set_window_current (struct ndm_session *sess);
+
+
+/* ndma_ctrl_robot.c */
+extern int     ndmca_robot_issue_scsi_req (struct smc_ctrl_block *smc);
+extern int     ndmca_robot_prep_target (struct ndm_session *sess);
+extern int     ndmca_robot_obtain_info (struct ndm_session *sess);
+extern int     ndmca_robot_init_elem_status (struct ndm_session *sess);
+extern int     ndmca_robot_startup (struct ndm_session *sess);
+extern int     ndmca_robot_move (struct ndm_session *sess,
+                       int src_addr, int dst_addr);
+extern int     ndmca_robot_load (struct ndm_session *sess, int slot_addr);
+extern int     ndmca_robot_unload (struct ndm_session *sess, int slot_addr);
+extern struct smc_element_descriptor *
+                       ndmca_robot_find_element (struct ndm_session *sess,
+                                                       int element_address);
+extern int     ndmca_robot_check_ready (struct ndm_session *sess);
+extern int     ndmca_robot_remedy_ready (struct ndm_session *sess);
+extern int     ndmca_robot_query (struct ndm_session *sess);
+extern int     ndmca_robot_verify_media (struct ndm_session *sess);
+extern int     ndmca_robot_synthesize_media (struct ndm_session *sess);
+
+
+/* ndma_ctrl_conn.c */
+extern int     ndmca_connect_xxx_agent (struct ndm_session *sess,
+                       struct ndmconn **connp, char *prefix,
+                       struct ndmagent *agent);
+extern int     ndmca_connect_data_agent (struct ndm_session *sess);
+extern int     ndmca_connect_tape_agent (struct ndm_session *sess);
+extern int     ndmca_connect_robot_agent (struct ndm_session *sess);
+extern int     ndmca_connect_control_agent (struct ndm_session *sess);
+
+
+
+/* ndma_ctst_tape.c */
+extern int     ndmca_op_test_tape (struct ndm_session *sess);
+
+/* ndma_ctst_mover.c */
+extern int     ndmca_op_test_mover (struct ndm_session *sess);
+
+/* ndma_ctst_data.c */
+extern int     ndmca_op_test_data (struct ndm_session *sess);
+
+/* ndma_ctst_subr.c */
+extern int     ndmca_test_query_conn_types (struct ndm_session *sess,
+                                            struct ndmconn *ref_conn);
+extern int     ndmca_test_load_tape (struct ndm_session *sess);
+extern int     ndmca_test_unload_tape (struct ndm_session *sess);
+extern int     ndmca_test_call (struct ndmconn *conn,
+                       struct ndmp_xa_buf *xa, ndmp9_error expect_err);
+extern int     ndmca_test_check_expect_errs (struct ndmconn *conn,
+                       int rc, ndmp9_error expect_errs[]);
+extern int     ndmca_test_check_expect (struct ndmconn *conn,
+                       int rc, ndmp9_error expect_err);
+extern int     ndmca_test_check_expect_no_err (struct ndmconn *conn,
+                       int rc);
+extern int     ndmca_test_check_expect_illegal_state (struct ndmconn *conn,
+                       int rc);
+extern int     ndmca_test_check_expect_illegal_args (struct ndmconn *conn,
+                       int rc);
+extern void    ndmca_test_phase (struct ndm_session *sess,
+                       char *test_phase, char *desc);
+extern void    ndmca_test_log_step (struct ndm_session *sess,
+                       int level, char *msg);
+extern void    ndmca_test_log_note (struct ndm_session *sess,
+                       int level, char *msg);
+extern void    ndmca_test_done_phase (struct ndm_session *sess);
+extern void    ndmca_test_done_series (struct ndm_session *sess,
+                       char *series_name);
+extern void    ndmca_test_open (struct ndm_session *sess,
+                                char *test_name,
+                                char *sub_test_name);
+extern void    ndmca_test_warn (struct ndm_session *sess, char *warn_msg);
+extern void    ndmca_test_fail (struct ndm_session *sess, char *fail_msg);
+extern void    ndmca_test_close (struct ndm_session *sess);
+
+
+extern void    ndmca_test_fill_data (char *buf, int bufsize,
+                       int recno, int fileno);
+
+#endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
+
+
+
+
+#ifndef NDMOS_OPTION_NO_DATA_AGENT
+/*
+ * DATA AGENT
+ ****************************************************************
+ *
+ * NDMP Elements of Data Agent (backup)
+ *
+ *  +-----------+stderr
+ *  | bu_type   |--------formatter_err---------NDMP_LOG-------> to CONTROL
+ *  | formatter |
+ *  | process   |========formatter_data=+=====================> to image stream
+ *  +-----------+stdout                 |
+ *                                  +-------+
+ *                                  | snoop |--NDMP_FH_ADD_x--> to CONTROL
+ *                                  +-------+
+ *
+ ****************************************************************
+ *
+ * NDMP Elements of Data Agent (recover)
+ *
+ *  +-----------+stderr
+ *  | bu_type   |--------formatter_err---------NDMP_LOG-------> to CONTROL
+ *  | formatter |                 +--------+
+ *  | process   |<=======fmt_data=| direct |==================< from image str
+ *  +-----------+stdin            |        |-NOTIFY_DATA_READ-> to CONTROL
+ *                                | snoop  |
+ *                                +--------+
+ *
+ ****************************************************************
+ *
+ * NDMP Elements of Data Agent (recover filehist)
+ *
+ *                                +--------+
+ *                                | direct |==================< from image str
+ *                                |        |-NOTIFY_DATA_READ-> to CONTROL
+ *                                | snoop  |--NDMP_FH_ADD_x---> to CONTROL
+ *                                +--------+
+ *
+ ****************************************************************
+ */
+
+
+
+#ifndef NDMDA_N_FMT_IMAGE_BUF
+#define NDMDA_N_FMT_IMAGE_BUF  (8*1024)
+#endif
+#ifndef NDMDA_N_FHH_BUF
+#define NDMDA_N_FHH_BUF                (8*1024)
+#endif
+#ifndef NDMDA_N_FMT_ERROR_BUF
+#define NDMDA_N_FMT_ERROR_BUF  (8*1024)
+#endif
+#ifndef NDMDA_N_FMT_WRAP_BUF
+#define NDMDA_N_FMT_WRAP_BUF   (4*1024)
+#endif
+#ifndef NDMDA_MAX_CMD
+#define NDMDA_MAX_CMD          (4*1024)
+#endif
+
+
+
+#ifndef NDMOS_OPTION_NO_GTAR_BUTYPE
+extern int     ndmda_butype_gtar_config_get_attrs (struct ndm_session *sess,
+                                       u_long *attrs_p, int protocol_version);
+
+extern int     ndmda_butype_gtar_config_get_default_env (
+                                       struct ndm_session *sess,
+                                       ndmp9_pval **env_p, int *n_env_p,
+                                       int protocol_version);
+extern int     ndmda_butype_gtar_attach (struct ndm_session *sess);
+#endif
+#ifndef NDMOS_OPTION_NO_DUMP_BUTYPE
+extern int     ndmda_butype_dump_config_get_attrs (struct ndm_session *sess,
+                                       u_long *attrs_p, int protocol_version);
+
+extern int     ndmda_butype_dump_config_get_default_env (
+                                       struct ndm_session *sess,
+                                       ndmp9_pval **env_p, int *n_env_p,
+                                       int protocol_version);
+extern int     ndmda_butype_dump_attach (struct ndm_session *sess);
+#endif
+
+
+
+
+struct ndm_data_recovery_interval {
+       ndmp9_u_quad    offset;
+       ndmp9_u_quad    length;
+};
+
+enum ndm_data_recovery_access_method {
+       NDMDA_RECO_ACCESS_SEQUENTIAL = 1,
+       NDMDA_RECO_ACCESS_DIRECT,
+       NDMDA_RECO_ACCESS_SEMI_DIRECT,
+       NDMDA_RECO_ACCESS_SEMI_DIRECT_PENDING,
+};
+
+enum ndm_data_recovery_state {
+       NDMDA_RECO_STATE_START = 1,
+       NDMDA_RECO_STATE_PASS_THRU,
+       NDMDA_RECO_STATE_CHOOSE_NLENT,
+       NDMDA_RECO_STATE_ACQUIRE,
+       NDMDA_RECO_STATE_DISPOSE,
+       NDMDA_RECO_STATE_FINISH_NLENT,
+       NDMDA_RECO_STATE_ALL_DONE,
+};
+
+enum ndm_data_recovery_acquire_mode {
+       NDMDA_RECO_ACQUIRE_EVERYTHING = 1,
+       NDMDA_RECO_ACQUIRE_SEARCHING,
+       NDMDA_RECO_ACQUIRE_MATCHING,
+};
+
+enum ndm_data_recovery_disposition {
+       NDMDA_RECO_DISPOSITION_PASS = 1,
+       NDMDA_RECO_DISPOSITION_DISCARD,
+};
+
+
+struct ndm_data_agent {
+       int                     protocol_version;
+
+       char                    bu_type[32];
+       struct ndm_env_table    env_tab;
+       struct ndm_nlist_table  nlist_tab;
+
+       NDM_FLAG_DECL(enable_hist)
+       unsigned long long      pass_resid;
+
+       ndmp9_data_get_state_reply data_state;
+       int                     data_notify_pending;
+
+       struct ndmchan          formatter_image;        /* stdin/out */
+       struct ndmchan          formatter_error;        /* stderr */
+       struct ndmchan          formatter_wrap;         /* fd=3 */
+       int                     formatter_pid;
+
+       char                    fmt_image_buf[NDMDA_N_FMT_IMAGE_BUF];
+       char                    fmt_error_buf[NDMDA_N_FMT_ERROR_BUF];
+       char                    fmt_wrap_buf[NDMDA_N_FMT_WRAP_BUF];
+
+       struct ndmfhheap        fhh;
+       unsigned long           fhh_buf[NDMDA_N_FHH_BUF];
+
+#ifdef NDMOS_MACRO_DATA_AGENT_ADDITIONS
+       NDMOS_MACRO_DATA_AGENT_ADDITIONS
+#endif /* NDMOS_MACRO_DATA_AGENT_ADDITIONS */
+};
+
+
+
+/* ndma_data.c */
+extern int             ndmda_initialize (struct ndm_session *sess);
+extern int             ndmda_commission (struct ndm_session *sess);
+extern int             ndmda_decommission (struct ndm_session *sess);
+extern int             ndmda_belay (struct ndm_session *sess);
+
+extern ndmp9_error     ndmda_data_start_backup (struct ndm_session *sess);
+extern ndmp9_error     ndmda_data_start_recover (struct ndm_session *sess);
+extern ndmp9_error     ndmda_data_start_recover_fh (struct ndm_session *sess);
+
+extern void            ndmda_sync_state (struct ndm_session *sess);
+extern ndmp9_error     ndmda_data_listen (struct ndm_session *sess);
+extern ndmp9_error     ndmda_data_connect (struct ndm_session *sess);
+extern void            ndmda_data_abort (struct ndm_session *sess);
+extern void            ndmda_sync_environment (struct ndm_session *sess);
+extern void            ndmda_data_halt (struct ndm_session *sess,
+                               ndmp9_data_halt_reason reason);
+extern void            ndmda_data_stop (struct ndm_session *sess);
+
+extern int             ndmda_quantum (struct ndm_session *sess);
+extern int             ndmda_quantum_image (struct ndm_session *sess);
+extern int             ndmda_quantum_stderr (struct ndm_session *sess);
+extern int             ndmda_quantum_wrap (struct ndm_session *sess);
+
+extern int             ndmda_wrap_in (struct ndm_session *sess,
+                               char *wrap_line);
+
+extern void            ndmda_send_logmsg (struct ndm_session *sess,
+                               char *fmt, ...);
+
+extern void            ndmda_send_notice (struct ndm_session *sess);
+extern void            ndmda_send_data_read (struct ndm_session *sess,
+                               unsigned long long offset,
+                               unsigned long long length);
+
+extern int             ndmda_copy_environment (struct ndm_session *sess,
+                               ndmp9_pval *env, unsigned n_env);
+extern struct ndmp9_pval *ndmda_find_env (struct ndm_session *sess,
+                               char *name);
+
+extern int             ndmda_interpret_boolean_value (char *value_str,
+                               int default_value);
+
+extern void            ndmda_purge_environment (struct ndm_session *sess);
+
+extern int             ndmda_copy_nlist (struct ndm_session *sess,
+                               ndmp9_name *nlist, unsigned n_nlist);
+extern void            ndmda_purge_nlist (struct ndm_session *sess);
+extern int             ndmda_count_invalid_fh_info (struct ndm_session *sess);
+extern int             ndmda_count_invalid_fh_info_pending
+                                               (struct ndm_session *sess);
+
+/* in ndma_data_recover.c */
+extern int     ndmda_quantum_recover_common (struct ndm_session *sess);
+extern int     ndmda_reco_state_start (struct ndm_session *sess);
+extern int     ndmda_reco_pass_thru (struct ndm_session *sess);
+extern int     ndmda_reco_state_pass_thru (struct ndm_session *sess);
+extern int     ndmda_reco_state_choose_nlent (struct ndm_session *sess);
+extern int     ndmda_reco_state_acquire (struct ndm_session *sess);
+extern int     ndmda_reco_state_dispose (struct ndm_session *sess);
+extern int     ndmda_reco_state_finish_nlent (struct ndm_session *sess);
+extern int     ndmda_reco_state_all_done (struct ndm_session *sess);
+extern int     ndmda_reco_assess_channels (struct ndm_session *sess);
+extern int     ndmda_reco_assess_intervals (struct ndm_session *sess);
+extern int     ndmda_reco_align_to_wanted (struct ndm_session *sess);
+extern int     ndmda_reco_obtain_wanted (struct ndm_session *sess);
+extern int     ndmda_reco_send_data_read (struct ndm_session *sess,
+                                               unsigned long long offset,
+                                               unsigned long long length);
+extern int     ndmda_reco_internal_error (struct ndm_session *sess,
+                                               char *why);
+
+/* ndma_data_fh.c */
+extern int             ndmda_fh_initialize (struct ndm_session *sess);
+extern int             ndmda_fh_commission (struct ndm_session *sess);
+extern int             ndmda_fh_decommission (struct ndm_session *sess);
+extern int             ndmda_fh_belay (struct ndm_session *sess);
+extern void            ndmda_fh_add_file (struct ndm_session *sess,
+                               ndmp9_file_stat *filestat, char *name);
+extern void            ndmda_fh_add_dir (struct ndm_session *sess,
+                               unsigned long long dir_fileno,
+                               char *name,
+                               unsigned long long fileno);
+extern void            ndmda_fh_add_node (struct ndm_session *sess,
+                               ndmp9_file_stat *filestat);
+
+extern int             ndmda_fh_prepare (struct ndm_session *sess,
+                                 int vers, int msg, int entry_size,
+                                 unsigned n_item,
+                                 unsigned total_size_of_items);
+extern void            ndmda_fh_flush (struct ndm_session *sess);
+
+
+/* ndma_data_gtar.c */
+extern ndmp9_error     ndmda_gtar_start_backup (struct ndm_session *sess);
+extern ndmp9_error     ndmda_gtar_start_recover (struct ndm_session *sess);
+extern ndmp9_error     ndmda_gtar_start_recover_fh (struct ndm_session *sess);
+extern int             ndmda_gtar_snoop (struct ndm_session *sess,
+                               struct ndmchan *ch);
+struct tar_digest_hdr;
+extern void            ndmda_gtar_fh_add (struct ndm_session *sess,
+                               struct tar_digest_hdr *tdh);
+
+
+/* ndma_data_pfe.c (pipe-fork-exec) */
+extern int             ndmda_pipe_fork_exec (struct ndm_session *sess,
+                               char *cmd, int is_backup);
+extern int             ndmda_add_to_cmd_with_escapes (char *cmd,
+                               char *word, char *special);
+extern int             ndmda_add_to_cmd (char *cmd, char *word);
+extern int             ndmda_add_to_cmd_allow_file_wildcards (char *cmd,
+                               char *word);
+
+#endif /* !NDMOS_OPTION_NO_DATA_AGENT */
+
+
+
+
+#ifndef NDMOS_OPTION_NO_TAPE_AGENT
+/*
+ * TAPE AGENT
+ ****************************************************************
+ */
+
+struct ndm_tape_agent {
+       int                     protocol_version;
+
+       /* TAPE */
+       ndmp9_tape_get_state_reply tape_state;
+
+       /* MOVER */
+       ndmp9_mover_get_state_reply mover_state;
+       u_long                  mover_window_first_blockno;
+       unsigned long long      mover_window_end;
+       unsigned long long      mover_want_pos;
+       int                     mover_notify_pending;
+
+       int                     pending_change_after_drain;
+       ndmp9_mover_state       pending_mover_state;
+       ndmp9_mover_halt_reason pending_mover_halt_reason;
+       ndmp9_mover_pause_reason pending_mover_pause_reason;
+
+       char                    tape_buffer[NDMOS_CONST_TAPE_REC_MAX];
+       unsigned long           tb_blockno;
+
+#ifdef NDMOS_MACRO_TAPE_AGENT_ADDITIONS
+       NDMOS_MACRO_TAPE_AGENT_ADDITIONS
+#endif /* NDMOS_MACRO_DATA_AGENT_ADDITIONS */
+};
+
+#define NDMTA_TAPE_IS_WRITABLE(TA) \
+       (   (TA)->tape_state.open_mode == NDMP9_TAPE_RDWR_MODE \
+        || (TA)->tape_state.open_mode == NDMP9_TAPE_RAW_MODE)
+
+extern int             ndmta_initialize (struct ndm_session *sess);
+extern int             ndmta_commission (struct ndm_session *sess);
+extern int             ndmta_decommission (struct ndm_session *sess);
+extern int             ndmta_init_mover_state (struct ndm_session *sess);
+
+extern void            ndmta_mover_sync_state (struct ndm_session *sess);
+ndmp9_error            ndmta_mover_listen (struct ndm_session *sess,
+                               ndmp9_mover_mode mover_mode);
+ndmp9_error            ndmta_mover_connect (struct ndm_session *sess,
+                               ndmp9_mover_mode mover_mode);
+extern void            ndmta_mover_halt (struct ndm_session *sess,
+                               ndmp9_mover_halt_reason reason);
+extern void            ndmta_mover_pause (struct ndm_session *sess,
+                               ndmp9_mover_pause_reason reason);
+extern void            ndmta_mover_active (struct ndm_session *sess);
+extern void            ndmta_mover_start_active (struct ndm_session *sess);
+extern void            ndmta_mover_stop (struct ndm_session *sess);
+extern void            ndmta_mover_abort (struct ndm_session *sess);
+extern void            ndmta_mover_continue (struct ndm_session *sess);
+extern void            ndmta_mover_close (struct ndm_session *sess);
+extern void            ndmta_mover_read (struct ndm_session *sess,
+                               unsigned long long offset,
+                               unsigned long long length);
+
+extern int             ndmta_quantum (struct ndm_session *sess);
+extern int             ndmta_read_quantum (struct ndm_session *sess);
+extern int             ndmta_write_quantum (struct ndm_session *sess);
+extern void            ndmta_mover_send_notice (struct ndm_session *sess);
+
+#endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
+
+
+
+
+#ifndef NDMOS_OPTION_NO_ROBOT_AGENT
+/*
+ * ROBOT AGENT
+ ****************************************************************
+ */
+
+struct ndm_robot_agent {
+       int                     protocol_version;
+
+       ndmp9_scsi_get_state_reply scsi_state;
+
+#ifdef NDMOS_MACRO_ROBOT_AGENT_ADDITIONS
+       NDMOS_MACRO_ROBOT_AGENT_ADDITIONS
+#endif /* NDMOS_MACRO_ROBOT_AGENT_ADDITIONS */
+};
+
+extern int             ndmra_initialize (struct ndm_session *sess);
+extern int             ndmra_commission (struct ndm_session *sess);
+extern int             ndmra_decommission (struct ndm_session *sess);
+
+/* all semantic operations are done directly to the ndmos_scsi layer */
+#endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
+
+
+
+
+/*
+ * IMAGE STREAM
+ ****************************************************************
+ */
+
+#ifndef NDM_N_IMAGE_STREAM_BUF
+#define NDM_N_IMAGE_STREAM_BUF (100*1024)
+#endif
+
+enum ndmis_connect_status {
+       NDMIS_CONN_IDLE = 0,
+       NDMIS_CONN_LISTEN,
+       NDMIS_CONN_ACCEPTED,
+       NDMIS_CONN_CONNECTED,
+       NDMIS_CONN_DISCONNECTED,
+       NDMIS_CONN_CLOSED,
+       NDMIS_CONN_BOTCHED,
+       NDMIS_CONN_REMOTE,
+       NDMIS_CONN_EXCLUDE,
+};
+typedef enum ndmis_connect_status      ndmis_connect_status;
+
+struct ndmis_end_point {
+       char *                  name;
+       ndmis_connect_status    connect_status;
+       int                     transfer_mode;
+       ndmp9_addr_type         addr_type;
+};
+
+struct ndmis_remote {
+       ndmis_connect_status    connect_status;
+       int                     transfer_mode;
+       ndmp9_addr              local_addr;
+       ndmp9_addr              peer_addr;
+       ndmp9_addr              listen_addr;
+       struct ndmchan          listen_chan;
+       struct ndmchan          sanity_chan;
+};
+
+struct ndm_image_stream {
+       struct ndmis_end_point  data_ep;
+       struct ndmis_end_point  tape_ep;
+
+       struct ndmis_remote     remote;
+
+       /* transfer stuff */
+       int                     transfer_mode;
+       struct ndmchan          chan;
+       char                    buf[NDM_N_IMAGE_STREAM_BUF];
+};
+
+extern int             ndmis_initialize (struct ndm_session *sess);
+extern int             ndmis_commission (struct ndm_session *sess);
+extern int             ndmis_decommission (struct ndm_session *sess);
+extern int             ndmis_belay (struct ndm_session *sess);
+
+extern int             ndmis_quantum (struct ndm_session *sess);
+
+extern ndmp9_error     ndmis_data_listen (struct ndm_session *sess,
+                         ndmp9_addr_type addr_type, ndmp9_addr *ret_addr,
+                         char *reason);
+extern ndmp9_error     ndmis_tape_listen (struct ndm_session *sess,
+                         ndmp9_addr_type addr_type, ndmp9_addr *ret_addr,
+                         char *reason);
+extern ndmp9_error     ndmis_data_connect (struct ndm_session *sess,
+                         ndmp9_addr *addr, char *reason);
+extern ndmp9_error     ndmis_tape_connect (struct ndm_session *sess,
+                         ndmp9_addr *addr, char *reason);
+extern int
+ndmis_data_start (struct ndm_session *sess, int chan_mode);
+extern int
+ndmis_tape_start (struct ndm_session *sess, int chan_mode);
+extern int
+ndmis_data_close (struct ndm_session *sess);
+extern int
+ndmis_tape_close (struct ndm_session *sess);
+
+
+extern ndmp9_error     ndmis_audit_data_listen (struct ndm_session *sess,
+                         ndmp9_addr_type addr_type, char *reason);
+extern ndmp9_error     ndmis_audit_tape_listen (struct ndm_session *sess,
+                         ndmp9_addr_type addr_type, char *reason);
+extern ndmp9_error     ndmis_audit_data_connect (struct ndm_session *sess,
+                         ndmp9_addr_type addr_type, char *reason);
+extern ndmp9_error     ndmis_audit_tape_connect (struct ndm_session *sess,
+                         ndmp9_addr_type addr_type, char *reason);
+
+extern ndmp9_error     ndmis_audit_ep_listen (
+                         struct ndm_session *sess,
+                         ndmp9_addr_type addr_type,
+                         char *reason,
+                         struct ndmis_end_point *mine_ep,
+                         struct ndmis_end_point *peer_ep);
+
+extern ndmp9_error     ndmis_audit_ep_connect (
+                         struct ndm_session *sess,
+                         ndmp9_addr_type addr_type,
+                         char *reason,
+                         struct ndmis_end_point *mine_ep,
+                         struct ndmis_end_point *peer_ep);
+
+extern ndmp9_error     ndmis_ep_listen (
+                         struct ndm_session *sess,
+                         ndmp9_addr_type addr_type,
+                         ndmp9_addr *ret_addr,
+                         char *reason,
+                         struct ndmis_end_point *mine_ep,
+                         struct ndmis_end_point *peer_ep);
+
+extern ndmp9_error     ndmis_ep_connect (
+                         struct ndm_session *sess,
+                         ndmp9_addr *addr,
+                         char *reason,
+                         struct ndmis_end_point *mine_ep,
+                         struct ndmis_end_point *peer_ep);
+
+extern int             ndmis_ep_close (
+                         struct ndm_session *sess,
+                         struct ndmis_end_point *mine_ep,
+                         struct ndmis_end_point *peer_ep);
+
+extern int             ndmis_tcp_listen (struct ndm_session *sess,
+                         struct ndmp9_addr *listen_addr);
+extern int             ndmis_tcp_accept (struct ndm_session *sess);
+extern int             ndmis_tcp_connect (struct ndm_session *sess,
+                         struct ndmp9_addr *connect_addr);
+extern int             ndmis_tcp_close (struct ndm_session *sess);
+
+extern int             ndmis_tcp_get_local_and_peer_addrs (
+                         struct ndm_session *sess);
+extern int             ndmis_tcp_green_light (struct ndm_session *sess,
+                         int sock, ndmis_connect_status new_status);
+
+
+
+/*
+ * PLUMBING
+ ****************************************************************
+ */
+
+struct ndm_plumbing {
+       struct ndmconn *        control;
+       struct ndmconn *        data;
+       struct ndmconn *        tape;
+       struct ndmconn *        robot;
+
+       struct ndm_image_stream image_stream;
+};
+
+
+
+
+/*
+ * SESSION
+ ****************************************************************
+ */
+
+struct ndm_session_param {
+       struct ndmlog           log;
+       char *                  log_tag;
+       int                     log_level;
+       char *                  config_file_name;
+};
+
+struct ndm_session {
+#ifndef NDMOS_OPTION_NO_CONTROL_AGENT
+       struct ndm_control_agent control_acb;
+#endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
+#ifndef NDMOS_OPTION_NO_DATA_AGENT
+       struct ndm_data_agent   data_acb;
+#endif /* !NDMOS_OPTION_NO_DATA_AGENT */
+#ifndef NDMOS_OPTION_NO_TAPE_AGENT
+       struct ndm_tape_agent   tape_acb;
+#endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
+#ifndef NDMOS_OPTION_NO_ROBOT_AGENT
+       struct ndm_robot_agent  robot_acb;
+#endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
+
+       struct ndm_plumbing     plumb;
+
+       struct ndm_session_param param;
+
+       /* scratch pad stuff */
+       ndmp9_config_info       config_info;
+       char                    md5_challenge[64]; /* CONNECT_AUTH MD5 */
+
+       NDM_FLAG_DECL(conn_open)
+       NDM_FLAG_DECL(conn_authorized)
+       NDM_FLAG_DECL(md5_challenge_valid)
+
+       int                     connect_status;
+
+#ifdef NDMOS_MACRO_SESSION_ADDITIONS
+       NDMOS_MACRO_SESSION_ADDITIONS
+#endif /* NDMOS_MACRO_SESSION_ADDITIONS */
+};
+
+
+/* ndma_session.c */
+extern int     ndma_client_session (struct ndm_session *sess);
+extern int     ndma_server_session (struct ndm_session *sess,
+                       int control_sock);
+extern int     ndma_daemon_session (struct ndm_session *sess, int port, int is_test_daemon);
+extern int     ndma_session_quantum (struct ndm_session *sess,
+                       int max_delay_secs);
+extern int     ndma_session_initialize (struct ndm_session *sess);
+extern int     ndma_session_commission (struct ndm_session *sess);
+extern int     ndma_session_decommission (struct ndm_session *sess);
+extern gpointer        exit_on_stdin_eof_thread(gpointer data G_GNUC_UNUSED);
+
+
+
+
+/* ndma_comm_subr.c */
+extern void    ndmalogf (struct ndm_session *sess, char *tag,
+                                       int level, char *fmt, ...);
+extern void    ndmalogfv (struct ndm_session *sess, char *tag,
+                                       int level, char *fmt, va_list ap);
+
+
+
+
+/*
+ * Dispatch Version/Reqeust Tables (DVT, DRT)
+ ****************************************************************
+ */
+
+struct ndm_dispatch_request_table {
+       unsigned short  message;
+       unsigned short  flags;
+       int             (*dispatch_request) (   /* "dr" for short */
+                               struct ndm_session *sess,
+                               struct ndmp_xa_buf *xa,
+                               struct ndmconn *ref_conn);
+};
+
+struct ndm_dispatch_version_table {
+       int                                     protocol_version;
+       struct ndm_dispatch_request_table *     dispatch_request_table;
+};
+
+#define NDM_DRT_FLAG_OK_NOT_CONNECTED          0x0001
+#define NDM_DRT_FLAG_OK_NOT_AUTHORIZED         0x0002
+
+
+/* ndma_comm_dispatch.c */
+extern int     ndma_dispatch_request (struct ndm_session *sess,
+                       struct ndmp_xa_buf *xa, struct ndmconn *ref_conn);
+extern int     ndma_dispatch_raise_error (struct ndm_session *sess,
+                       struct ndmp_xa_buf *xa, struct ndmconn *ref_conn,
+                       ndmp9_error error, char *errstr);
+extern int     ndma_dispatch_conn (struct ndm_session *sess,
+                       struct ndmconn *conn);
+extern void    ndma_dispatch_ctrl_unexpected (struct ndmconn *conn,
+                       struct ndmp_msg_buf *nmb);
+extern int     ndmta_local_mover_read (struct ndm_session *sess,
+                       unsigned long long offset,
+                       unsigned long long length);
+extern int     ndma_call_no_tattle (struct ndmconn *conn,
+                       struct ndmp_xa_buf *xa);
+extern int     ndma_call (struct ndmconn *conn, struct ndmp_xa_buf *xa);
+extern int     ndma_send_to_control (struct ndm_session *sess,
+                       struct ndmp_xa_buf *xa,
+                       struct ndmconn *from_conn);
+extern int     ndma_tattle (struct ndmconn *conn,
+                       struct ndmp_xa_buf *xa, int rc);
+extern struct ndm_dispatch_request_table *
+               ndma_drt_lookup (struct ndm_dispatch_version_table *dvt,
+                       unsigned protocol_version, unsigned message);
+
+#define NDMADR_RAISE(ERROR,ERRSTR) \
+          return ndma_dispatch_raise_error (sess, xa, ref_conn, ERROR, ERRSTR)
+
+#define NDMADR_RAISE_ILLEGAL_ARGS(ERRSTR) \
+                       NDMADR_RAISE(NDMP9_ILLEGAL_ARGS_ERR, ERRSTR)
+#define NDMADR_RAISE_ILLEGAL_STATE(ERRSTR) \
+                       NDMADR_RAISE(NDMP9_ILLEGAL_STATE_ERR, ERRSTR)
+
+
+
+
+#define NDMADR_UNIMPLEMENTED_MESSAGE   (-1)    /* aka "TODO" */
+#define NDMADR_UNSPECIFIED_MESSAGE     (-123)  /* no such per specs */
+#define NDMADR_UNIMPLEMENTED_VERSION   (-1234) /* implementation error */
+
+
+
+
+/*
+ * Operating System Specific
+ ****************************************************************
+ * Must be implemented in ndmos_xxx.c
+ */
+
+/* from ndma_dispatch_request() in ndma_dispatch.c */
+extern int             ndmos_dispatch_request (struct ndm_session *sess,
+                               struct ndmp_xa_buf *xa,
+                               struct ndmconn *ref_conn);
+
+/* from ndmadr_connect_client_auth() in ndma_dispatch.c */
+extern int             ndmos_ok_name_password (struct ndm_session *sess,
+                               char *name, char *pass);
+extern int             ndmos_get_md5_challenge (struct ndm_session *sess);
+extern int             ndmos_ok_name_md5_digest (struct ndm_session *sess,
+                               char *name, char digest[16]);
+
+/* from ndmadr_config_get_{host,server}_info() in ndma_dispatch.c */
+extern void            ndmos_sync_config_info (struct ndm_session *sess);
+
+/* from ndma_image_stream.c and ndma_ctrl_conn.c and others */
+extern void            ndmos_condition_pipe_fd (struct ndm_session *sess,
+                               int fd);
+extern void            ndmos_condition_listen_socket (
+                               struct ndm_session *sess, int sock);
+extern void            ndmos_condition_control_socket (
+                               struct ndm_session *sess, int sock);
+extern void            ndmos_condition_image_stream_socket (
+                               struct ndm_session *sess, int sock);
+
+#ifndef NDMOS_OPTION_NO_TAPE_AGENT
+extern int             ndmos_tape_initialize (struct ndm_session *sess);
+extern ndmp9_error     ndmos_tape_open (struct ndm_session *sess,
+                               char *drive_name, int will_write);
+extern ndmp9_error     ndmos_tape_close (struct ndm_session *sess);
+extern void            ndmos_tape_sync_state (struct ndm_session *sess);
+extern ndmp9_error     ndmos_tape_mtio (struct ndm_session *sess,
+                               ndmp9_tape_mtio_op op,
+                               u_long count, u_long *resid);
+extern ndmp9_error     ndmos_tape_write (struct ndm_session *sess,
+                               char *buf,
+                               u_long count, u_long *done_count);
+extern ndmp9_error     ndmos_tape_wfm (struct ndm_session *sess);
+extern ndmp9_error     ndmos_tape_read (struct ndm_session *sess,
+                               char *buf,
+                               u_long count, u_long *done_count);
+extern ndmp9_error     ndmos_tape_execute_cdb (struct ndm_session *sess,
+                               ndmp9_execute_cdb_request *request,
+                               ndmp9_execute_cdb_reply *reply);
+#endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
+
+#ifndef NDMOS_OPTION_NO_ROBOT_AGENT
+extern int             ndmos_scsi_initialize (struct ndm_session *sess);
+extern void            ndmos_scsi_sync_state (struct ndm_session *sess);
+extern void            ndmos_scsi_sync_config_info (struct ndm_session *sess);
+ndmp9_error            ndmos_scsi_open (struct ndm_session *sess, char *name);
+ndmp9_error            ndmos_scsi_close (struct ndm_session *sess);
+ndmp9_error            ndmos_scsi_set_target (struct ndm_session *sess);
+ndmp9_error            ndmos_scsi_reset_device (struct ndm_session *sess);
+ndmp9_error            ndmos_scsi_reset_bus (struct ndm_session *sess);
+ndmp9_error            ndmos_scsi_execute_cdb (struct ndm_session *sess,
+                               ndmp9_execute_cdb_request *request,
+                               ndmp9_execute_cdb_reply *reply);
+#endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
+
+
+/* ndma_noti_calls.c */
+#ifndef NDMOS_OPTION_NO_DATA_AGENT
+extern int     ndma_notify_data_halted (struct ndm_session *sess);
+extern int     ndma_notify_data_read (struct ndm_session *sess,
+                       unsigned long long offset,
+                       unsigned long long length);
+#endif /* !NDMOS_OPTION_NO_DATA_AGENT */
+#ifndef NDMOS_OPTION_NO_TAPE_AGENT
+extern int     ndma_notify_mover_halted (struct ndm_session *sess);
+extern int     ndma_notify_mover_paused (struct ndm_session *sess);
+#endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
+#ifndef NDMOS_EFFECT_NO_SERVER_AGENTS
+extern void    ndma_send_logmsg (struct ndm_session *sess,
+                       ndmp9_log_type ltype, struct ndmconn *from_conn,
+                       char *fmt, ...);
+#endif /* !NDMOS_EFFECT_NO_SERVER_AGENTS */