#define WRAP_INVALID_FHINFO (-1ull)
#define WRAP_MAX_PATH (1024+512)
#define WRAP_MAX_NAME 256
#define WRAP_MAX_ENV 100
#define WRAP_MAX_FILE 100
#define WRAP_MAX_COMMAND (20*1024)
#define WRAP_MAX_O_OPTION 100
/* forward */
struct wrap_ccb;
/*
* MAIN helpers
****************************************************************
*/
extern int wrap_main (int ac, char *av[], struct wrap_ccb *wccb);
extern int wrap_main_start_index_file (struct wrap_ccb *wccb);
extern int wrap_main_start_image_file (struct wrap_ccb *wccb);
extern void wrap_log (struct wrap_ccb *wccb, char *fmt, ...);
extern int wrap_set_error (struct wrap_ccb *wccb, int error);
/*
* Command Execution
****************************************************************
*
* This wrapper will spawn (fork/exec) a subprocess to do
* the real work. These help form the sh(1) command line,
* create the pipe fittings, and spawn the subprocess.
*
* The fdmap[3] corresponds to the subprocess stdin, stdout,
* and stderr. A value >= 0 is assumed to be an inherited
* file descriptor. A value < 0 is one of the special codes
* WRAP_FDMAP_xxx. On return, the _PIPE special codes are
* replaced with the file descriptor for the parent process
* end of the pipe.
*/
#define WRAP_FDMAP_INPUT_PIPE -2 /* input to child, parent writes */
#define WRAP_FDMAP_OUTPUT_PIPE -3 /* output from child, parent reads */
#define WRAP_FDMAP_DEV_NULL -4 /* /dev/null */
extern int wrap_cmd_add_with_escapes (char *cmd, char *word,
char *special);
extern int wrap_cmd_add_with_sh_escapes (char *cmd, char *word);
extern int wrap_cmd_add_allow_file_wildcards (char *cmd, char *word);
extern int wrap_pipe_fork_exec (char *cmd, int fdmap[3]);
/*
* CCB -- Command Control Block
****************************************************************
*
* A digested form of command line arguments
*/
enum wrap_ccb_op {
WRAP_CCB_OP_NONE = 0,
WRAP_CCB_OP_BACKUP = 1, /* -c */
WRAP_CCB_OP_RECOVER = 2, /* -x */
WRAP_CCB_OP_RECOVER_FILEHIST = 3 /* -t */
};
struct wrap_env {
char * name;
char * value;
};
struct wrap_file {
unsigned long long fhinfo;
char * original_name; /* relative to backup root */
char * save_to_name; /* relative to file system */
};
struct wrap_ccb {
int error;
int log_seq_num;
char errmsg[WRAP_MAX_NAME];
/* Raw arguments */
char * B_butype; /* -B TYPE */
int d_debug; /* -d N */
struct wrap_env env[WRAP_MAX_ENV]; /* -E NAME=VALUE */
int n_env;
char * f_file_name; /* -f FILE */
char * I_index_file_name; /* -I FILE */
char * o_option[WRAP_MAX_O_OPTION]; /* -o OPTION */
int n_o_option;
struct wrap_file file[WRAP_MAX_FILE]; /* recovery only */
int n_file;
/* derived from arguments */
char * progname;
enum wrap_ccb_op op;
FILE * index_fp;
int data_conn_fd;
/* Common interprettations of the env */
int hist_enable;
int direct_enable;
char * backup_root;
/*
* Recovery variables.
*
* All offset/length pairs refer to a portion of the
* backup image.
*
* have The portion currently in the buffer.
* want The portion wanted by the formatter
* (e.g. tar, dump).
* reading The portion immediately after what we
* "have" (in the buffer) still coming due
* to the last NDMP_NOTIFY_DATA_READ.
* last_read The portion requested by the last
* NDMP_NOTIFY_DATA_READ.
* expect Composite of have and reading.
*/
char * iobuf;
unsigned long n_iobuf;
char * have;
unsigned long long have_offset;
unsigned long have_length; /* never bigger than iobuf */
unsigned long long want_offset;
unsigned long long want_length;
unsigned long long reading_offset;
unsigned long long reading_length;
unsigned long long last_read_offset;
unsigned long long last_read_length;
unsigned long long expect_offset;
unsigned long long expect_length;
int data_conn_mode;
};
extern int wrap_process_args (int argc, char *argv[],
struct wrap_ccb *wccb);
extern char * wrap_find_env (struct wrap_ccb *wccb, char *name);
extern int wrap_reco_seek (struct wrap_ccb *wccb,
unsigned long long want_offset,
unsigned long long want_length,
unsigned long must_have_length);
extern int wrap_reco_must_have (struct wrap_ccb *wccb,
unsigned long length);
extern int wrap_reco_pass (struct wrap_ccb *wccb, int write_fd,
unsigned long long length, unsigned write_bsize);
extern int wrap_reco_align_to_wanted (struct wrap_ccb *wccb);
extern int wrap_reco_receive (struct wrap_ccb *wccb);
extern int wrap_reco_consume (struct wrap_ccb *wccb,
unsigned long length);
extern int wrap_reco_issue_read (struct wrap_ccb *wccb);
/*
* WRAP Messages
****************************************************************
*
* A message is simply one text line following a format.
* These structures are used to buffer incoming messages.
*/
struct wrap_log_message { /* Lx */
char message[WRAP_MAX_PATH];
};
enum wrap_ftype {
WRAP_FTYPE_INVALID = 0,
WRAP_FTYPE_DIR = 1, /* d */
WRAP_FTYPE_FIFO = 2, /* p */
WRAP_FTYPE_CSPEC = 3, /* c */
WRAP_FTYPE_BSPEC = 4, /* b */
WRAP_FTYPE_REG = 5, /* - */
WRAP_FTYPE_SLINK = 6, /* l */
WRAP_FTYPE_SOCK = 7, /* s */
WRAP_FTYPE_REGISTRY = 8, /* R */
WRAP_FTYPE_OTHER = 9 /* o */
};
struct wrap_fstat {
unsigned long valid;
#define WRAP_FSTAT_VALID_FTYPE (1ul<<0u)
#define WRAP_FSTAT_VALID_MODE (1ul<<1u)
#define WRAP_FSTAT_VALID_LINKS (1ul<<2u)
#define WRAP_FSTAT_VALID_SIZE (1ul<<3u)
#define WRAP_FSTAT_VALID_UID (1ul<<4u)
#define WRAP_FSTAT_VALID_GID (1ul<<5u)
#define WRAP_FSTAT_VALID_ATIME (1ul<<6u)
#define WRAP_FSTAT_VALID_MTIME (1ul<<7u)
#define WRAP_FSTAT_VALID_CTIME (1ul<<8u)
#define WRAP_FSTAT_VALID_FILENO (1ul<<9u)
enum wrap_ftype ftype; /* f%s */
unsigned short mode; /* m%04o */
unsigned long links; /* l%lu */
unsigned long long size; /* s%llu */
unsigned long uid; /* u%lu */
unsigned long gid; /* g%lu */
unsigned long atime; /* ta%lu */
unsigned long mtime; /* tm%lu */
unsigned long ctime; /* tc%lu */
unsigned long long fileno; /* i%llu */
};
/*
* HF path [@fhinfo] [stats]
*
* History File -- Corresponds to NDMPv?_FH_ADD_FILE
*/
struct wrap_add_file {
unsigned long long fhinfo; /* @%llu */
struct wrap_fstat fstat;
char path[WRAP_MAX_PATH];
};
/*
* HD dir_fileno name fileno [@fhinfo]
*
* History Directory entry -- Corresponds to NDMPv?_FH_ADD_DIR
*/
struct wrap_add_dirent {
unsigned long long fhinfo; /* @%llu */
unsigned long long dir_fileno; /* %llu */
unsigned long long fileno; /* %llu */
char name[WRAP_MAX_NAME];
};
/*
* HN [@fhinfo] [stats] -- iFILENO must be present
*
* History Node -- Corresponds to NDMPv?_FH_ADD_NODE
*/
struct wrap_add_node { /* HN */
unsigned long long fhinfo; /* @%llu */
struct wrap_fstat fstat;
};
/*
* DE name value
*
* Data Env -- Corresponds to NDMPv?_DATA_GET_ENV
* This is used for the post backup processing env[].
*/
struct wrap_add_env {
char name[WRAP_MAX_NAME];
char value[WRAP_MAX_PATH];
};
/*
* DR offset length
*
* Data Read -- Corresponds to NDMPv?_NOTIFY_DATA_READ
* This is used during recovery operations to retrieve
* portions of the backup image.
*/
struct wrap_data_read { /* DR */
unsigned long long offset; /* %llu */
unsigned long long length; /* %llu */
};
/*
* DS s{r|d|f} [wN] [etN] [ebN]
*
* Data Stats -- Supplemental info for NDMPv?_DATA_GET_STATE
* Sent periodically to update certain fields of the
* DATA_GET_STATE reply.
*/
enum wrap_data_status {
WRAP_DS_INVALID = 0,
WRAP_DS_RUNNING = 1, /* sr */
WRAP_DS_DONE_OK = 2, /* sd */
WRAP_DS_DONE_FAILED = 3 /* sf */
};
struct wrap_data_stats { /* DS */
unsigned long valid;
#define WRAP_DATASTATS_VALID_BYTES_WRITTEN (1ul<<0u)
#define WRAP_DATASTATS_VALID_EST_TIME_REMAINING (1ul<<1u)
#define WRAP_DATASTATS_VALID_EST_BYTES_REMAINING (1ul<<2u)
enum wrap_data_status status; /* s{r|d|f} */
unsigned long long bytes_written; /* w%llu */
unsigned long long est_time_remaining; /* et%llu */
unsigned long long est_bytes_remaining; /* eb%llu */
};
/*
* RR errno path
*
* Recovery Result -- Corresponds to NDMPv?_LOG_FILE
* Sent during recovery operations to report the
* success or failure of recovery.
*/
struct wrap_recovery_result { /* RR */
int rr_errno; /* sys/errno.h */
char path[WRAP_MAX_PATH];
};
enum wrap_msg_type {
WRAP_MSGTYPE_LOG_MESSAGE = 1,
WRAP_MSGTYPE_ADD_FILE = 2,
WRAP_MSGTYPE_ADD_DIRENT = 3,
WRAP_MSGTYPE_ADD_NODE = 4,
WRAP_MSGTYPE_ADD_ENV = 5,
WRAP_MSGTYPE_DATA_READ = 6,
WRAP_MSGTYPE_DATA_STATS = 7,
WRAP_MSGTYPE_RECOVERY_RESULT = 8,
};
struct wrap_msg_buf {
enum wrap_msg_type msg_type;
union {
struct wrap_log_message log_message;
struct wrap_add_file add_file;
struct wrap_add_dirent add_dirent;
struct wrap_add_node add_node;
struct wrap_add_env add_env;
struct wrap_data_read data_read;
struct wrap_data_stats data_stats;
struct wrap_recovery_result recovery_result;
} body;
};
extern int wrap_parse_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_parse_log_message_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_send_log_message (FILE *fp, char *message);
extern int wrap_parse_add_file_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_send_add_file (FILE *fp, char *path, unsigned long long fhinfo,
struct wrap_fstat *fstat);
extern int wrap_parse_add_dirent_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_send_add_dirent (FILE *fp, char *name,
unsigned long long fhinfo,
unsigned long long dir_fileno,
unsigned long long fileno);
extern int wrap_parse_add_node_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_send_add_node (FILE *fp, unsigned long long fhinfo,
struct wrap_fstat *fstat);
extern int wrap_parse_fstat_subr (char **scanp, struct wrap_fstat *fstat);
extern int wrap_send_fstat_subr (FILE *fp, struct wrap_fstat *fstat);
extern int wrap_parse_add_env_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_send_add_env (FILE *fp, char *name, char *value);
extern int wrap_parse_data_read_msg (char *buf, struct wrap_msg_buf *wmsg);
extern int wrap_send_data_read (FILE *fp, unsigned long long offset,
unsigned long long length);
/*
* Canonical strings
****************************************************************
* Convert strings to/from HTTP-like canonical strings (%xx).
* Example "a b%c" --> "a%20b%25c"
*/
#define NDMCSTR_WARN '%'
extern int wrap_cstr_from_str (char *src, char *dst, unsigned dst_max);
extern int wrap_cstr_to_str (char *src, char *dst, unsigned dst_max);
extern int wrap_cstr_from_hex (int c);