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 */ 36 37 #define WRAP_INVALID_FHINFO (-1ull) 38 #define WRAP_MAX_PATH (1024 + 512) 39 #define WRAP_MAX_NAME 256 40 #define WRAP_MAX_ENV 100 41 #define WRAP_MAX_FILE 100 42 #define WRAP_MAX_COMMAND (20 * 1024) 43 #define WRAP_MAX_O_OPTION 100 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 /* forward */ 50 struct wrap_ccb; 51 52 /* 53 * MAIN helpers 54 **************************************************************** 55 */ 56 57 extern int wrap_main(int ac, char* av[], struct wrap_ccb* wccb); 58 extern int wrap_main_start_index_file(struct wrap_ccb* wccb); 59 extern int wrap_main_start_image_file(struct wrap_ccb* wccb); 60 61 extern void wrap_log(struct wrap_ccb* wccb, char* fmt, ...); 62 63 extern int wrap_set_error(struct wrap_ccb* wccb, int error); 64 65 66 /* 67 * Command Execution 68 **************************************************************** 69 * 70 * This wrapper will spawn (fork/exec) a subprocess to do 71 * the real work. These help form the sh(1) command line, 72 * create the pipe fittings, and spawn the subprocess. 73 * 74 * The fdmap[3] corresponds to the subprocess stdin, stdout, 75 * and stderr. A value >= 0 is assumed to be an inherited 76 * file descriptor. A value < 0 is one of the special codes 77 * WRAP_FDMAP_xxx. On return, the _PIPE special codes are 78 * replaced with the file descriptor for the parent process 79 * end of the pipe. 80 */ 81 82 #define WRAP_FDMAP_INPUT_PIPE -2 /* input to child, parent writes */ 83 #define WRAP_FDMAP_OUTPUT_PIPE -3 /* output from child, parent reads */ 84 #define WRAP_FDMAP_DEV_NULL -4 /* /dev/null */ 85 86 extern int wrap_cmd_add_with_escapes(char* cmd, char* word, char* special); 87 extern int wrap_cmd_add_with_sh_escapes(char* cmd, char* word); 88 extern int wrap_cmd_add_allow_file_wildcards(char* cmd, char* word); 89 extern int wrap_pipe_fork_exec(char* cmd, int fdmap[3]); 90 91 92 /* 93 * CCB -- Command Control Block 94 **************************************************************** 95 * 96 * A digested form of command line arguments 97 */ 98 99 enum wrap_ccb_op 100 { 101 WRAP_CCB_OP_NONE = 0, 102 WRAP_CCB_OP_BACKUP = 1, /* -c */ 103 WRAP_CCB_OP_RECOVER = 2, /* -x */ 104 WRAP_CCB_OP_RECOVER_FILEHIST = 3 /* -t */ 105 }; 106 107 struct wrap_env { 108 char* name; 109 char* value; 110 }; 111 112 struct wrap_file { 113 uint64_t fhinfo; 114 char* original_name; /* relative to backup root */ 115 char* save_to_name; /* relative to file system */ 116 }; 117 118 struct wrap_ccb { 119 int error; 120 int log_seq_num; 121 char errmsg[WRAP_MAX_NAME]; 122 123 /* Raw arguments */ 124 char* B_butype; /* -B TYPE */ 125 int d_debug; /* -d N */ 126 struct wrap_env env[WRAP_MAX_ENV]; /* -E NAME=VALUE */ 127 int n_env; 128 char* f_file_name; /* -f FILE */ 129 char* I_index_file_name; /* -I FILE */ 130 char* o_option[WRAP_MAX_O_OPTION]; /* -o OPTION */ 131 int n_o_option; 132 133 struct wrap_file file[WRAP_MAX_FILE]; /* recovery only */ 134 int n_file; 135 136 /* derived from arguments */ 137 char* progname; 138 enum wrap_ccb_op op; 139 FILE* index_fp; 140 int data_conn_fd; 141 142 /* Common interprettations of the env */ 143 int hist_enable; 144 int direct_enable; 145 char* backup_root; 146 147 /* 148 * Recovery variables. 149 * 150 * All offset/length pairs refer to a portion of the 151 * backup image. 152 * 153 * have The portion currently in the buffer. 154 * want The portion wanted by the formatter 155 * (e.g. tar, dump). 156 * reading The portion immediately after what we 157 * "have" (in the buffer) still coming due 158 * to the last NDMP_NOTIFY_DATA_READ. 159 * last_read The portion requested by the last 160 * NDMP_NOTIFY_DATA_READ. 161 * expect Composite of have and reading. 162 */ 163 char* iobuf; 164 uint32_t n_iobuf; 165 166 char* have; 167 uint64_t have_offset; 168 uint32_t have_length; /* never bigger than iobuf */ 169 uint64_t want_offset; 170 uint64_t want_length; 171 uint64_t reading_offset; 172 uint64_t reading_length; 173 uint64_t last_read_offset; 174 uint64_t last_read_length; 175 uint64_t expect_offset; 176 uint64_t expect_length; 177 int data_conn_mode; 178 }; 179 180 extern int wrap_process_args(int argc, char* argv[], struct wrap_ccb* wccb); 181 extern char* wrap_find_env(struct wrap_ccb* wccb, char* name); 182 183 184 extern int wrap_reco_seek(struct wrap_ccb* wccb, 185 uint64_t want_offset, 186 uint64_t want_length, 187 uint32_t must_have_length); 188 extern int wrap_reco_must_have(struct wrap_ccb* wccb, uint32_t length); 189 extern int wrap_reco_pass(struct wrap_ccb* wccb, 190 int write_fd, 191 uint64_t length, 192 unsigned write_bsize); 193 extern int wrap_reco_align_to_wanted(struct wrap_ccb* wccb); 194 extern int wrap_reco_receive(struct wrap_ccb* wccb); 195 extern int wrap_reco_consume(struct wrap_ccb* wccb, uint32_t length); 196 extern int wrap_reco_issue_read(struct wrap_ccb* wccb); 197 198 199 /* 200 * WRAP Messages 201 **************************************************************** 202 * 203 * A message is simply one text line following a format. 204 * These structures are used to buffer incoming messages. 205 */ 206 207 struct wrap_log_message { /* Lx */ 208 char message[WRAP_MAX_PATH]; 209 }; 210 211 enum wrap_ftype 212 { 213 WRAP_FTYPE_INVALID = 0, 214 WRAP_FTYPE_DIR = 1, /* d */ 215 WRAP_FTYPE_FIFO = 2, /* p */ 216 WRAP_FTYPE_CSPEC = 3, /* c */ 217 WRAP_FTYPE_BSPEC = 4, /* b */ 218 WRAP_FTYPE_REG = 5, /* - */ 219 WRAP_FTYPE_SLINK = 6, /* l */ 220 WRAP_FTYPE_SOCK = 7, /* s */ 221 WRAP_FTYPE_REGISTRY = 8, /* R */ 222 WRAP_FTYPE_OTHER = 9 /* o */ 223 }; 224 225 struct wrap_fstat { 226 uint32_t valid; 227 #define WRAP_FSTAT_VALID_FTYPE (1ul << 0u) 228 #define WRAP_FSTAT_VALID_MODE (1ul << 1u) 229 #define WRAP_FSTAT_VALID_LINKS (1ul << 2u) 230 #define WRAP_FSTAT_VALID_SIZE (1ul << 3u) 231 #define WRAP_FSTAT_VALID_UID (1ul << 4u) 232 #define WRAP_FSTAT_VALID_GID (1ul << 5u) 233 #define WRAP_FSTAT_VALID_ATIME (1ul << 6u) 234 #define WRAP_FSTAT_VALID_MTIME (1ul << 7u) 235 #define WRAP_FSTAT_VALID_CTIME (1ul << 8u) 236 #define WRAP_FSTAT_VALID_FILENO (1ul << 9u) 237 238 enum wrap_ftype ftype; /* f%s */ 239 uint16_t mode; /* m%04o */ 240 uint32_t links; /* l%lu */ 241 uint64_t size; /* s%llu */ 242 uint32_t uid; /* u%lu */ 243 uint32_t gid; /* g%lu */ 244 uint32_t atime; /* ta%lu */ 245 uint32_t mtime; /* tm%lu */ 246 uint32_t ctime; /* tc%lu */ 247 uint64_t fileno; /* i%llu */ 248 }; 249 250 /* 251 * HF path [@fhinfo] [stats] 252 * 253 * History File -- Corresponds to NDMPv?_FH_ADD_FILE 254 */ 255 struct wrap_add_file { 256 uint64_t fhinfo; /* @%llu */ 257 struct wrap_fstat fstat; 258 char path[WRAP_MAX_PATH]; 259 }; 260 261 /* 262 * HD dir_fileno name fileno [@fhinfo] 263 * 264 * History Directory entry -- Corresponds to NDMPv?_FH_ADD_DIR 265 */ 266 struct wrap_add_dirent { 267 uint64_t fhinfo; /* @%llu */ 268 uint64_t dir_fileno; /* %llu */ 269 uint64_t fileno; /* %llu */ 270 char name[WRAP_MAX_NAME]; 271 }; 272 273 /* 274 * HN [@fhinfo] [stats] -- iFILENO must be present 275 * 276 * History Node -- Corresponds to NDMPv?_FH_ADD_NODE 277 */ 278 struct wrap_add_node { /* HN */ 279 uint64_t fhinfo; /* @%llu */ 280 struct wrap_fstat fstat; 281 }; 282 283 /* 284 * DE name value 285 * 286 * Data Env -- Corresponds to NDMPv?_DATA_GET_ENV 287 * This is used for the post backup processing env[]. 288 */ 289 struct wrap_add_env { 290 char name[WRAP_MAX_NAME]; 291 char value[WRAP_MAX_PATH]; 292 }; 293 294 /* 295 * DR offset length 296 * 297 * Data Read -- Corresponds to NDMPv?_NOTIFY_DATA_READ 298 * This is used during recovery operations to retrieve 299 * portions of the backup image. 300 */ 301 struct wrap_data_read { /* DR */ 302 uint64_t offset; /* %llu */ 303 uint64_t length; /* %llu */ 304 }; 305 306 /* 307 * DS s{r|d|f} [wN] [etN] [ebN] 308 * 309 * Data Stats -- Supplemental info for NDMPv?_DATA_GET_STATE 310 * Sent periodically to update certain fields of the 311 * DATA_GET_STATE reply. 312 */ 313 314 enum wrap_data_status 315 { 316 WRAP_DS_INVALID = 0, 317 WRAP_DS_RUNNING = 1, /* sr */ 318 WRAP_DS_DONE_OK = 2, /* sd */ 319 WRAP_DS_DONE_FAILED = 3 /* sf */ 320 }; 321 322 struct wrap_data_stats { /* DS */ 323 uint32_t valid; 324 #define WRAP_DATASTATS_VALID_BYTES_WRITTEN (1ul << 0u) 325 #define WRAP_DATASTATS_VALID_EST_TIME_REMAINING (1ul << 1u) 326 #define WRAP_DATASTATS_VALID_EST_BYTES_REMAINING (1ul << 2u) 327 328 enum wrap_data_status status; /* s{r|d|f} */ 329 uint64_t bytes_written; /* w%llu */ 330 uint64_t est_time_remaining; /* et%llu */ 331 uint64_t est_bytes_remaining; /* eb%llu */ 332 }; 333 334 /* 335 * RR errno path 336 * 337 * Recovery Result -- Corresponds to NDMPv?_LOG_FILE 338 * Sent during recovery operations to report the 339 * success or failure of recovery. 340 */ 341 struct wrap_recovery_result { /* RR */ 342 int rr_errno; /* sys/errno.h */ 343 char path[WRAP_MAX_PATH]; 344 }; 345 346 enum wrap_msg_type 347 { 348 WRAP_MSGTYPE_LOG_MESSAGE = 1, 349 WRAP_MSGTYPE_ADD_FILE = 2, 350 WRAP_MSGTYPE_ADD_DIRENT = 3, 351 WRAP_MSGTYPE_ADD_NODE = 4, 352 WRAP_MSGTYPE_ADD_ENV = 5, 353 WRAP_MSGTYPE_DATA_READ = 6, 354 WRAP_MSGTYPE_DATA_STATS = 7, 355 WRAP_MSGTYPE_RECOVERY_RESULT = 8, 356 }; 357 358 struct wrap_msg_buf { 359 enum wrap_msg_type msg_type; 360 union { 361 struct wrap_log_message log_message; 362 struct wrap_add_file add_file; 363 struct wrap_add_dirent add_dirent; 364 struct wrap_add_node add_node; 365 struct wrap_add_env add_env; 366 struct wrap_data_read data_read; 367 struct wrap_data_stats data_stats; 368 struct wrap_recovery_result recovery_result; 369 } body; 370 }; 371 372 extern int wrap_parse_msg(char* buf, struct wrap_msg_buf* wmsg); 373 extern int wrap_parse_log_message_msg(char* buf, struct wrap_msg_buf* wmsg); 374 extern int wrap_send_log_message(FILE* fp, char* message); 375 extern int wrap_parse_add_file_msg(char* buf, struct wrap_msg_buf* wmsg); 376 extern int wrap_send_add_file(FILE* fp, 377 char* path, 378 uint64_t fhinfo, 379 struct wrap_fstat* fstat); 380 extern int wrap_parse_add_dirent_msg(char* buf, struct wrap_msg_buf* wmsg); 381 extern int wrap_send_add_dirent(FILE* fp, 382 char* name, 383 uint64_t fhinfo, 384 uint64_t dir_fileno, 385 uint64_t fileno); 386 extern int wrap_parse_add_node_msg(char* buf, struct wrap_msg_buf* wmsg); 387 extern int wrap_send_add_node(FILE* fp, 388 uint64_t fhinfo, 389 struct wrap_fstat* fstat); 390 extern int wrap_parse_fstat_subr(char** scanp, struct wrap_fstat* fstat); 391 extern int wrap_send_fstat_subr(FILE* fp, struct wrap_fstat* fstat); 392 extern int wrap_parse_add_env_msg(char* buf, struct wrap_msg_buf* wmsg); 393 extern int wrap_send_add_env(FILE* fp, char* name, char* value); 394 extern int wrap_parse_data_read_msg(char* buf, struct wrap_msg_buf* wmsg); 395 extern int wrap_send_data_read(FILE* fp, uint64_t offset, uint64_t length); 396 397 398 /* 399 * Canonical strings 400 **************************************************************** 401 * Convert strings to/from HTTP-like canonical strings (%xx). 402 * Example "a b%c" --> "a%20b%25c" 403 */ 404 405 #define NDMCSTR_WARN '%' 406 extern int wrap_cstr_from_str(char* src, char* dst, unsigned dst_max); 407 extern int wrap_cstr_to_str(char* src, char* dst, unsigned dst_max); 408 extern int wrap_cstr_from_hex(int c); 409 410 #ifdef __cplusplus 411 } 412 #endif 413