1 /* 2 * Copyright (c) 1998,1999,2000,2002 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 38 #ifndef _NDMLIB_H_ 39 #define _NDMLIB_H_ 40 41 #include "ndmos.h" 42 43 #include "ndmprotocol.h" 44 #include "ndmp_msg_buf.h" 45 #include "ndmp_translate.h" 46 47 /* Probably unnecessary, yet prudent. Compilers/debuggers sometimes goof. */ 48 #ifndef NDM_FLAG_DECL 49 #define NDM_FLAG_DECL(XXX) unsigned XXX : 1; 50 #endif /* !NDM_FLAG_DECL */ 51 52 #ifdef __cplusplus 53 extern "C" { 54 #endif 55 56 /* boring forward reference stuff */ 57 struct ndmagent; 58 59 60 61 62 /* 63 * NDMLOG 64 **************************************************************** 65 * 66 * ndmlog is a simple abstraction for log messages. 67 * Each log entry has: 68 * - a tag, which is a short string indicating origin or purpose 69 * - a level between 0-9, the higher the value the greater the detail 70 * - a message 71 * The application will typically direct log messages to a file. 72 * Yet, logging directly to a FILE tends to be restrictive. Hence 73 * this abstraction. 74 * 75 * The time stamp is relative to the start time, and has millisecond 76 * granularity. 77 */ 78 79 struct ndmlog { 80 void (*deliver)(struct ndmlog *log, char *tag, int lev, char *msg); 81 void * ctx; 82 struct ndm_fhdb_callbacks *nfc; 83 }; 84 extern char * ndmlog_time_stamp (void); 85 extern void ndmlogf (struct ndmlog *log, char *tag, 86 int level, char *fmt, ...); 87 extern void ndmlogfv (struct ndmlog *log, char *tag, 88 int level, char *fmt, va_list ap); 89 90 91 92 93 /* 94 * NDMNMB -- NDMP Message Buffer 95 **************************************************************** 96 * 97 * The ndmnmb routines are trivial aids for handling 98 * NMB (NDMP Messsage Buffer). ndmp_msg_buf is defined in 99 * ndmp_msg_buf.h, and pretty much amounts to a huge 100 * union of all NDMP request and reply types. 101 */ 102 103 extern xdrproc_t ndmnmb_find_xdrproc (struct ndmp_msg_buf *nmb); 104 extern void ndmnmb_free (struct ndmp_msg_buf *nmb); 105 extern void ndmnmb_snoop (struct ndmlog *log, char *tag, int level, 106 struct ndmp_msg_buf *nmb, char *whence); 107 extern unsigned ndmnmb_get_reply_error_raw (struct ndmp_msg_buf *nmb); 108 extern ndmp9_error ndmnmb_get_reply_error (struct ndmp_msg_buf *nmb); 109 extern int ndmnmb_set_reply_error_raw (struct ndmp_msg_buf *nmb, 110 unsigned raw_error); 111 extern int ndmnmb_set_reply_error (struct ndmp_msg_buf *nmb, 112 ndmp9_error error); 113 114 115 116 117 118 119 120 /* 121 * NDMCHAN -- Async I/O channel 122 **************************************************************** 123 * 124 * ndmchan is a wrapper around I/O channels, and is used 125 * to juggle (manage) multiple I/O activities at one time. 126 * The data buffer is used linearly. beg_ix and end_ix 127 * bracket the valid data. When the end of the buffer is reached, 128 * the remaining valid data is moved to the begining. 129 */ 130 struct ndmchan { 131 char * name; /* short name, helps debugging */ 132 133 char mode; /* NDMCHAN_MODE_... (see below) */ 134 135 NDM_FLAG_DECL(check) /* Want select()/poll() to check */ 136 NDM_FLAG_DECL(ready) /* select()/poll() indicates ready */ 137 NDM_FLAG_DECL(eof) /* eof pending upon n_ready()==0 */ 138 NDM_FLAG_DECL(error) /* error (channel shutdown) */ 139 140 int fd; /* der eff dee */ 141 int saved_errno; /* errno captured if ->error occurs */ 142 143 unsigned beg_ix; /* relative to ->data */ 144 unsigned end_ix; /* relative to ->data */ 145 char * data; /* data buffer (READ/WRITE/RESIDENT) */ 146 unsigned data_size; /* size of data buffer */ 147 }; 148 #define NDMCHAN_MODE_IDLE 0 /* not doing anything */ 149 #define NDMCHAN_MODE_RESIDENT 1 /* resident, within this process */ 150 #define NDMCHAN_MODE_READ 2 /* read from ->fd into ->data */ 151 #define NDMCHAN_MODE_WRITE 3 /* write to ->fd from ->data */ 152 #define NDMCHAN_MODE_READCHK 4 /* check ->fd readable, no ->data */ 153 #define NDMCHAN_MODE_LISTEN 5 /* ->fd listen()ing */ 154 #define NDMCHAN_MODE_PENDING 6 /* ->fd and ->data ready */ 155 #define NDMCHAN_MODE_CLOSED 7 /* ->fd closed */ 156 157 enum ndmchan_read_interpretation { 158 NDMCHAN_RI_EMPTY = 10, /* no data, might be more coming */ 159 NDMCHAN_RI_READY, /* data ready */ 160 NDMCHAN_RI_READY_FULL, /* data ready, no more until consumed */ 161 NDMCHAN_RI_DRAIN_EOF, /* data ready, DONE_EOF after consumed */ 162 NDMCHAN_RI_DRAIN_ERROR, /* data ready, DONE_ERROR after consumed */ 163 NDMCHAN_RI_DONE_EOF, /* no data, no more coming, normal EOF */ 164 NDMCHAN_RI_DONE_ERROR, /* no data, no more coming, something wrong */ 165 NDMCHAN_RI_FAULT /* crazy request */ 166 }; 167 168 enum ndmchan_write_interpretation { 169 NDMCHAN_WI_FULL = 30, /* no buffer, no more until some sent */ 170 NDMCHAN_WI_AVAIL, /* buffer ready, sending in progress */ 171 NDMCHAN_WI_AVAIL_EMPTY, /* buffer ready, done sending */ 172 NDMCHAN_WI_DRAIN_EOF, /* no more buffer, DONE_EOF after sent */ 173 NDMCHAN_WI_DRAIN_ERROR, /* no more buffer, DONE_ERROR after sent */ 174 NDMCHAN_WI_DONE_EOF, /* no more buffer, done sending, normal EOF */ 175 NDMCHAN_WI_DONE_ERROR, /* no more buffer, done sending, went wrong */ 176 NDMCHAN_WI_FAULT /* crazy request */ 177 }; 178 179 extern void ndmchan_initialize (struct ndmchan *ch, char *name); 180 extern int ndmchan_setbuf (struct ndmchan *ch, char *data, 181 unsigned data_size); 182 extern int ndmchan_start_mode (struct ndmchan *ch, int fd, int chan_mode); 183 extern int ndmchan_start_read (struct ndmchan *ch, int fd); 184 extern int ndmchan_start_write (struct ndmchan *ch, int fd); 185 extern int ndmchan_start_readchk (struct ndmchan *ch, int fd); 186 extern int ndmchan_start_listen (struct ndmchan *ch, int fd); 187 extern int ndmchan_start_resident (struct ndmchan *ch); 188 extern int ndmchan_start_pending (struct ndmchan *ch, int fd); 189 extern int ndmchan_pending_to_mode (struct ndmchan *ch, int chan_mode); 190 extern int ndmchan_pending_to_read (struct ndmchan *ch); 191 extern int ndmchan_pending_to_write (struct ndmchan *ch); 192 extern void ndmchan_set_eof (struct ndmchan *ch); 193 extern void ndmchan_close_set_errno (struct ndmchan *ch, int err_no); 194 extern void ndmchan_close (struct ndmchan *ch); 195 extern void ndmchan_abort (struct ndmchan *ch); 196 extern void ndmchan_close_as_is (struct ndmchan *ch); 197 extern void ndmchan_cleanup (struct ndmchan *ch); 198 extern int ndmchan_quantum (struct ndmchan *chtab[], 199 unsigned n_chtab, int milli_timo); 200 extern int ndmchan_pre_poll (struct ndmchan *chtab[], unsigned n_chtab); 201 extern int ndmchan_post_poll (struct ndmchan *chtab[], unsigned n_chtab); 202 extern void ndmchan_compress (struct ndmchan *ch); 203 extern int ndmchan_n_avail (struct ndmchan *ch); 204 extern int ndmchan_n_avail_record (struct ndmchan *ch, uint32_t size); 205 extern int ndmchan_n_avail_total (struct ndmchan *ch); 206 extern int ndmchan_n_ready (struct ndmchan *ch); 207 extern enum ndmchan_read_interpretation 208 ndmchan_read_interpret (struct ndmchan *ch, char **data_p, 209 unsigned *n_ready_p); 210 extern enum ndmchan_write_interpretation 211 ndmchan_write_interpret (struct ndmchan *ch, char **data_p, 212 unsigned *n_avail_p); 213 214 extern void ndmchan_pp (struct ndmchan *ch, char *buf); 215 216 extern int ndmos_chan_poll (struct ndmchan *chtab[], 217 unsigned n_chtab, int milli_timo); 218 219 220 221 222 /* 223 * NDMCONN -- Bidirectional control connections 224 **************************************************************** 225 */ 226 227 #define NDMCONN_TYPE_NONE 0 228 #define NDMCONN_TYPE_RESIDENT 1 229 #define NDMCONN_TYPE_REMOTE 2 230 231 232 #define NDMCONN_CALL_STATUS_HDR_ERROR (-2) 233 #define NDMCONN_CALL_STATUS_BOTCH (-1) 234 #define NDMCONN_CALL_STATUS_OK 0 235 #define NDMCONN_CALL_STATUS_REPLY_ERROR 1 236 #define NDMCONN_CALL_STATUS_REPLY_LATE 2 237 238 239 struct ndmconn { 240 struct sockaddr sa; 241 242 struct ndmchan chan; 243 244 char conn_type; 245 char protocol_version; 246 char was_allocated; 247 248 void * context; 249 250 XDR xdrs; 251 unsigned char frag_hdr_buf[4]; /* see ndmconn_readit() */ 252 unsigned fhb_off; 253 uint32_t frag_resid; 254 255 uint32_t next_sequence; 256 257 void (*unexpected)(struct ndmconn *conn, 258 struct ndmp_msg_buf *nmb); 259 260 int snoop_level; 261 struct ndmlog * snoop_log; 262 263 char * last_err_msg; 264 265 int (*call) (struct ndmconn *conn, struct ndmp_xa_buf *xa); 266 267 struct ndmp_xa_buf call_xa_buf; 268 269 int last_message; 270 int last_call_status; 271 ndmp9_error last_header_error; 272 ndmp9_error last_reply_error; 273 274 long sent_time; 275 long received_time; 276 long time_limit; 277 }; 278 279 extern struct ndmconn * ndmconn_initialize (struct ndmconn *aconn, char *name); 280 extern void ndmconn_destruct (struct ndmconn *conn); 281 extern int ndmconn_connect_agent (struct ndmconn *conn, 282 struct ndmagent *agent); 283 extern int ndmconn_connect_host_port (struct ndmconn *conn, 284 char * hostname, int port, 285 unsigned want_protocol_version); 286 extern int ndmconn_connect_sockaddr_in (struct ndmconn *conn, 287 struct sockaddr_in *sin, 288 unsigned want_protocol_version); 289 extern int ndmconn_try_open (struct ndmconn *conn, 290 unsigned protocol_version); 291 extern int ndmconn_accept (struct ndmconn *conn, int sock); 292 extern int ndmconn_abort (struct ndmconn *conn); 293 extern int ndmconn_close (struct ndmconn *conn); 294 extern int ndmconn_fileno (struct ndmconn *conn); 295 extern int ndmconn_auth_agent (struct ndmconn *conn, 296 struct ndmagent *agent); 297 extern int ndmconn_auth_none (struct ndmconn *conn); 298 extern int ndmconn_auth_text (struct ndmconn *conn, 299 char *id, char *pw); 300 extern int ndmconn_auth_md5 (struct ndmconn *conn, 301 char *id, char *pw); 302 extern int ndmconn_call (struct ndmconn *conn, 303 struct ndmp_xa_buf *xa); 304 extern int ndmconn_exchange_nmb (struct ndmconn *conn, 305 struct ndmp_msg_buf *request_nmb, 306 struct ndmp_msg_buf *reply_nmb); 307 extern int ndmconn_send_nmb (struct ndmconn *conn, 308 struct ndmp_msg_buf *nmb); 309 extern int ndmconn_recv_nmb (struct ndmconn *conn, 310 struct ndmp_msg_buf *nmb); 311 extern void ndmconn_free_nmb (struct ndmconn *conn, 312 struct ndmp_msg_buf *nmb); 313 extern int ndmconn_xdr_nmb (struct ndmconn *conn, 314 struct ndmp_msg_buf *nmb, 315 enum xdr_op x_op); 316 extern int ndmconn_readit (void *a_conn, char *buf, int len); 317 extern int ndmconn_writeit (void *a_conn, char *buf, int len); 318 extern int ndmconn_sys_read (struct ndmconn *conn, 319 char *buf, unsigned len); 320 extern int ndmconn_sys_write (struct ndmconn *conn, 321 char *buf, unsigned len); 322 extern void ndmconn_unexpected (struct ndmconn *conn, 323 struct ndmp_msg_buf *nmb); 324 extern int ndmconn_set_snoop (struct ndmconn *conn, 325 struct ndmlog *log, int level); 326 extern void ndmconn_clear_snoop (struct ndmconn *conn); 327 extern void ndmconn_snoop_nmb (struct ndmconn *conn, 328 struct ndmp_msg_buf *nmb, 329 char *whence); 330 extern void ndmconn_snoop (struct ndmconn *conn, 331 int level, char *fmt, ...); 332 extern void ndmconn_hex_dump (struct ndmconn *conn, 333 char *buf, unsigned len); 334 extern int ndmconn_set_err_msg (struct ndmconn *conn, 335 char *err_msg); 336 extern char * ndmconn_get_err_msg (struct ndmconn *conn); 337 338 339 340 341 /* 342 * NDMC_WITH() AND FRIENDS 343 **************************************************************** 344 * 345 * Macro NDMC_WITH() and friends. These are patterned after 346 * the Pascal "with" construct. These macros take care of 347 * the tedious, error prone, mind-numbing, and distracting 348 * code required to perform NDMP RPCs. These greatly 349 * facilitate the clarity of the main body of code. 350 * Code sequences look something like: 351 * 352 * NDMC_WITH(ndmp_config_get_butype_attr) 353 * request->xxx = yyy; 354 * ... 355 * rc = NDMC_CALL(ndmconn); 356 * if (rc == 0) { 357 * reply->xxx ... 358 * .... 359 * } 360 * NDMC_FREE_REPLY() 361 * NDMC_ENDWITH 362 * 363 * The NDMC macros are for client-side (caller) sequences. 364 * The NDMS macros are for server-side (callee) sequences. 365 * 366 * These macros are very dependent on ndmp_msg_buf.h and ndmp_ammend.h 367 * 368 * Implementation note: initialization of *request and *reply 369 * are separate from their declarations. They used to be 370 * initialized declarators. The separation made gcc -Wall happy. 371 */ 372 373 #define NDMC_WITH(TYPE,VERS) \ 374 { \ 375 struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ 376 TYPE##_request * request; \ 377 TYPE##_reply * reply; \ 378 request = &xa->request.body.TYPE##_request_body; \ 379 reply = &xa->reply.body.TYPE##_reply_body; \ 380 NDMOS_MACRO_ZEROFILL (xa); \ 381 xa->request.protocol_version = VERS; \ 382 xa->request.header.message = (ndmp0_message) MT_##TYPE; \ 383 { 384 385 386 #define NDMC_WITH_VOID_REQUEST(TYPE,VERS) \ 387 { \ 388 struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ 389 TYPE##_reply * reply; \ 390 reply = &xa->reply.body.TYPE##_reply_body; \ 391 NDMOS_MACRO_ZEROFILL (xa); \ 392 xa->request.protocol_version = VERS; \ 393 xa->request.header.message = (ndmp0_message) MT_##TYPE; \ 394 { 395 396 #define NDMC_WITH_NO_REPLY(TYPE,VERS) \ 397 { \ 398 struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ 399 TYPE##_request * request; \ 400 request = &xa->request.body.TYPE##_request_body; \ 401 NDMOS_MACRO_ZEROFILL (xa); \ 402 xa->request.protocol_version = VERS; \ 403 xa->request.header.message = (ndmp0_message) MT_##TYPE; \ 404 { 405 406 #ifndef NDMOS_OPTION_NO_NDMP4 407 #define NDMC_WITH_POST(TYPE,VERS) \ 408 { \ 409 struct ndmp_xa_buf * xa = &conn->call_xa_buf; \ 410 TYPE##_post * request; \ 411 request = &xa->request.body.TYPE##_post_body; \ 412 NDMOS_MACRO_ZEROFILL (xa); \ 413 xa->request.protocol_version = VERS; \ 414 xa->request.header.message = (ndmp0_message) MT_##TYPE; \ 415 { 416 #endif /* !NDMOS_OPTION_NO_NDMP4 */ 417 418 419 #define NDMC_ENDWITH \ 420 } } 421 422 #define NDMC_CALL(CONN) (*(CONN)->call)(CONN, xa); 423 #define NDMC_SEND(CONN) (*(CONN)->call)(CONN, xa); 424 #define NDMC_FREE_REPLY() ndmconn_free_nmb ((void*)0, &xa->reply) 425 426 427 428 #define NDMS_WITH(TYPE) \ 429 { \ 430 TYPE##_request * request; \ 431 TYPE##_reply * reply; \ 432 request = &xa->request.body.TYPE##_request_body; \ 433 reply = &xa->reply.body.TYPE##_reply_body; \ 434 { 435 436 #define NDMS_WITH_VOID_REQUEST(TYPE) \ 437 { \ 438 TYPE##_reply * reply; \ 439 reply = &xa->reply.body.TYPE##_reply_body; \ 440 { 441 442 #define NDMS_WITH_NO_REPLY(TYPE) \ 443 { \ 444 TYPE##_request * request; \ 445 request = &xa->request.body.TYPE##_request_body; \ 446 { 447 448 #ifndef NDMOS_OPTION_NO_NDMP4 449 #define NDMS_WITH_POST(TYPE) \ 450 { \ 451 TYPE##_post * request; \ 452 request = &xa->request.body.TYPE##_post_body; \ 453 { 454 #endif /* !NDMOS_OPTION_NO_NDMP4 */ 455 456 #define NDMS_ENDWITH \ 457 } } 458 459 460 461 462 463 464 /* 465 * NDMAGENT -- "Address" of agent 466 **************************************************************** 467 * 468 * A struct ndmagent contains the information necessary 469 * to establish a connection with an NDMP agent (server). 470 * An agent can be remote (NDMCONN_TYPE_REMOTE) or resident 471 * (...._RESIDENT). 472 * TODO: MD5 473 */ 474 #define NDMAGENT_HOST_MAX 63 475 #define NDMAGENT_ACCOUNT_MAX 15 476 #define NDMAGENT_PASSWORD_MAX 32 477 478 struct ndmagent { 479 char conn_type; /* NDMCONN_TYPE_... (see above) */ 480 char protocol_version; /* 0->best, 2->v2 3->v3 */ 481 char host[NDMAGENT_HOST_MAX+1]; /* name */ 482 int port; /* 0->default (NDMPPORT) */ 483 char account[NDMAGENT_ACCOUNT_MAX+1]; /* clear text */ 484 char password[NDMAGENT_PASSWORD_MAX+1]; /* clear text */ 485 #if 0 486 ndmp_auth_type auth_type; 487 #else 488 int auth_type; 489 #endif 490 }; 491 extern int ndmagent_from_str (struct ndmagent *agent, char *str); 492 extern int ndmhost_lookup (char *hostname, struct sockaddr_in *sin); 493 extern int ndmagent_to_sockaddr_in (struct ndmagent *agent, 494 struct sockaddr_in *sin); 495 496 497 498 499 /* 500 * NDMSCSI -- "Address" of SCSI device 501 **************************************************************** 502 */ 503 504 struct ndmscsi_target { 505 char dev_name[NDMOS_CONST_PATH_MAX]; 506 int controller; 507 int sid; 508 int lun; 509 }; 510 511 #define NDMSCSI_MAX_SENSE_DATA 127 512 struct ndmscsi_request { 513 unsigned char completion_status; 514 unsigned char status_byte; 515 unsigned char data_dir; 516 unsigned char n_cmd; 517 518 unsigned char cmd[12]; 519 520 unsigned char * data; 521 unsigned n_data_avail; 522 unsigned n_data_done; 523 uint32_t _pad; 524 525 unsigned char n_sense_data; 526 unsigned char sense_data[NDMSCSI_MAX_SENSE_DATA]; 527 }; 528 529 #define NDMSCSI_CS_GOOD 0 530 #define NDMSCSI_CS_FAIL 1 531 /* more? */ 532 533 #define NDMSCSI_DD_NONE 0 534 #define NDMSCSI_DD_IN 1 /* adapter->app */ 535 #define NDMSCSI_DD_OUT 2 /* app->adapter */ 536 537 538 extern int ndmscsi_target_from_str (struct ndmscsi_target *targ, 539 char *str); 540 extern int ndmscsi_open (struct ndmconn *conn, char *dev_name); 541 extern int ndmscsi_close (struct ndmconn *conn); 542 extern int ndmscsi_get_state (struct ndmconn *conn, 543 struct ndmscsi_target *targ); 544 extern int ndmscsi_set_target (struct ndmconn *conn, 545 struct ndmscsi_target *targ); 546 extern int ndmscsi_use (struct ndmconn *conn, 547 struct ndmscsi_target *targ); 548 extern int ndmscsi_execute (struct ndmconn *conn, 549 struct ndmscsi_request *req, 550 struct ndmscsi_target *targ); 551 552 553 554 555 /* 556 * NDMMEDIA -- media (tape) labels, position, and status 557 **************************************************************** 558 */ 559 560 #define NDMMEDIA_LABEL_MAX 31 561 562 struct ndmmedia { 563 NDM_FLAG_DECL(valid_label) /* ->label[] valid */ 564 NDM_FLAG_DECL(valid_filemark) /* ->file_mark_skip valid */ 565 NDM_FLAG_DECL(valid_n_bytes) /* ->n_bytes valid */ 566 NDM_FLAG_DECL(valid_slot) /* ->slot_addr valid */ 567 568 /* results flags */ 569 NDM_FLAG_DECL(media_used) /* was used (loaded) */ 570 NDM_FLAG_DECL(media_written) /* media was written */ 571 NDM_FLAG_DECL(media_eof) /* reached EOF of tape file */ 572 NDM_FLAG_DECL(media_eom) /* reached EOM (tape full) */ 573 NDM_FLAG_DECL(media_open_error) /* open-time error (write-protect?) */ 574 NDM_FLAG_DECL(media_io_error) /* media error */ 575 576 NDM_FLAG_DECL(label_read) /* ->label[] read fm media */ 577 NDM_FLAG_DECL(label_written) /* ->label[] written to media */ 578 NDM_FLAG_DECL(label_io_error) /* error label read/write */ 579 NDM_FLAG_DECL(label_mismatch) /* label wasn't as expected */ 580 581 NDM_FLAG_DECL(fmark_error) /* error skipping file marks */ 582 583 NDM_FLAG_DECL(nb_determined) /* true ->n_bytes determined */ 584 NDM_FLAG_DECL(nb_aligned) /* ->n_bytes aligned per rec_size */ 585 586 NDM_FLAG_DECL(slot_empty) /* slot empty per robot */ 587 NDM_FLAG_DECL(slot_bad) /* ->slot_addr invalid */ 588 NDM_FLAG_DECL(slot_missing) /* !->valid_slot */ 589 590 /* all fields are specified/actual depending on context */ 591 char label[NDMMEDIA_LABEL_MAX+1]; 592 unsigned file_mark_offset; 593 uint64_t n_bytes; 594 unsigned slot_addr; 595 596 /* scratch pad */ 597 uint64_t begin_offset, end_offset; 598 599 int index; 600 struct ndmmedia *next; 601 }; 602 603 extern int ndmmedia_from_str (struct ndmmedia *me, char *str); 604 extern int ndmmedia_to_str (struct ndmmedia *me, char *str); 605 extern int ndmmedia_pp (struct ndmmedia *me, int lineno, char *buf); 606 extern int64_t ndmmedia_strtoll (char *str, char **tailp, int defbase); 607 608 609 610 611 /* 612 * NDMFHH -- file history (FH) heap 613 **************************************************************** 614 * 615 * As DATA accumulates individual File History (FH) entries they 616 * are saved into a heap buffer. When the heap is full it is flushed 617 * from DATA to CONTROL using NDMP?_FH_ADD_.... requests/posts. 618 */ 619 620 struct ndmfhheap { 621 int fhtype; 622 int entry_size; 623 624 void * table; 625 void * allo_entry; 626 627 void * allo_item; 628 629 void * heap_base; 630 void * heap_end; 631 unsigned heap_size; 632 633 void * heap_top; 634 void * heap_bot; 635 }; 636 637 struct ndmfhh_generic_table { 638 u_int table_len; 639 void * table_val; 640 }; 641 642 #define NDMFHH_RET_OK (0) 643 #define NDMFHH_RET_OVERFLOW (-1) 644 #define NDMFHH_RET_TYPE_CHANGE (-2) 645 #define NDMFHH_RET_NO_HEAP (-3) 646 #define NDMFHH_RET_ENTRY_SIZE_MISMATCH (-4) 647 648 649 extern int ndmfhh_initialize (struct ndmfhheap *fhh); 650 extern int ndmfhh_commission (struct ndmfhheap *fhh, 651 void *heap, unsigned size); 652 extern int ndmfhh_prepare (struct ndmfhheap *fhh, 653 int fhtype, int entry_size, 654 unsigned n_item, 655 unsigned total_size_of_items); 656 extern void * ndmfhh_add_entry (struct ndmfhheap *fhh); 657 extern void * ndmfhh_add_item (struct ndmfhheap *fhh, unsigned size); 658 extern void * ndmfhh_save_item (struct ndmfhheap *fhh, 659 void *item, unsigned size); 660 extern int ndmfhh_reset (struct ndmfhheap *fhh); 661 extern int ndmfhh_get_table (struct ndmfhheap *fhh, 662 int *fhtype_p, void **table_p, 663 unsigned *n_entry_p); 664 665 666 667 668 /* 669 * NDMCSTR -- canonical strings 670 **************************************************************** 671 * Convert strings to/from HTTP-like canonical strings (%xx). 672 * Example "a b%c" --> "a%20b%25c" 673 */ 674 675 #define NDMCSTR_WARN '%' 676 extern int ndmcstr_from_str (char *src, char *dst, unsigned dst_max); 677 extern int ndmcstr_to_str (char *src, char *dst, unsigned dst_max); 678 extern int ndmcstr_from_hex (int c); 679 680 681 682 683 /* 684 * NDMMD5 -- MD5 helpers 685 **************************************************************** 686 * This is a wrapper around the MD5 functions. ndml_md5.c 687 * is the only thing that needs to #include md5.h. 688 * The NDMP rules for converting a clear-text password 689 * into an MD5 digest are implemented here. 690 */ 691 692 #define NDMP_MD5_CHALLENGE_LENGTH 64 693 #define NDMP_MD5_DIGEST_LENGTH 16 694 #define NDMP_MD5_MESSAGE_LENGTH 128 695 #define NDMP_MD5_MAX_PASSWORD_LENGTH 32 696 697 698 extern int ndmmd5_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH], 699 char *clear_text_password, 700 char digest[NDMP_MD5_DIGEST_LENGTH]); 701 extern int ndmmd5_generate_challenge ( 702 char challenge[NDMP_MD5_CHALLENGE_LENGTH]); 703 704 extern int ndmmd5_ok_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH], 705 char *clear_text_password, 706 char digest[NDMP_MD5_DIGEST_LENGTH]); 707 708 709 710 711 /* 712 * NDMBSTF -- Binary Search Text File 713 **************************************************************** 714 * Use conventional binary search method on a sorted text 715 * file. The file MUST be sorted in ascending, lexicographic 716 * order. This is the default order of sort(1). 717 */ 718 719 extern int ndmbstf_first (FILE *fp, char *key, char *buf, unsigned max_buf); 720 extern int ndmbstf_next (FILE *fp, char *key, char *buf, unsigned max_buf); 721 extern int ndmbstf_first_with_bounds (FILE *fp, char *key, 722 char *buf, unsigned max_buf, off_t lower_bound, off_t upper_bound); 723 extern int ndmbstf_getline (FILE *fp, char *buf, unsigned max_buf); 724 extern int ndmbstf_seek_and_align (FILE *fp, off_t *off); 725 extern int ndmbstf_match (char *key, char *buf); 726 extern int ndmbstf_compare (char *key, char *buf); 727 728 729 730 731 /* 732 * NDMSTZF -- Stanza File 733 **************************************************************** 734 * 735 * Stanza files look about like this: 736 * [stanza name line] 737 * stanza body lines 738 * 739 * These are used for config files. 740 */ 741 extern int ndmstz_getline (FILE *fp, char *buf, int n_buf); 742 extern int ndmstz_getstanza (FILE *fp, char *buf, int n_buf); 743 extern int ndmstz_parse (char *buf, char *argv[], int max_argv); 744 745 746 747 748 /* 749 * NDMCFG -- Config File 750 **************************************************************** 751 * 752 * Config files are stanza files (see above) which describe 753 * backup types, tape and scsi devices, etc. 754 * See ndml_config.c for details and stanza formats. 755 */ 756 extern int ndmcfg_load (char *filename, ndmp9_config_info *config_info); 757 extern int ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info); 758 759 760 761 762 /* 763 * NDMFHDB -- File History Database 764 * 765 * The File History is generated by the DATA and sent to the CONTROL 766 * using NDMP?_FH_ADD_... requests/posts. During backup the CONTROL 767 * writes the File History info to a text file as it arrives. Upon 768 * completion of the backup the text file should be sorted (UNIX 769 * sort(1) command). For recovery the file history index is searched 770 * using binary search (see NDMBSTF above). The fh_info, a 64-bit 771 * cookie used by DATA to identify the region of the backup image 772 * containing the corresponding object, is retreived from the index. 773 */ 774 775 struct ndmfhdb { 776 FILE * fp; 777 int use_dir_node; 778 uint64_t root_node; 779 }; 780 781 struct ndm_fhdb_callbacks { 782 int (*add_file) (struct ndmlog *ixlog, int tagc, 783 char *raw_name, ndmp9_file_stat *fstat); 784 int (*add_dir) (struct ndmlog *ixlog, int tagc, 785 char *raw_name, ndmp9_u_quad dir_node, ndmp9_u_quad node); 786 int (*add_node) (struct ndmlog *ixlog, int tagc, 787 ndmp9_u_quad node, ndmp9_file_stat *fstat); 788 int (*add_dirnode_root) (struct ndmlog *ixlog, int tagc, 789 ndmp9_u_quad root_node); 790 }; 791 792 extern void ndmfhdb_register_callbacks (struct ndmlog *ixlog, 793 struct ndm_fhdb_callbacks *callbacks); 794 extern void ndmfhdb_unregister_callbacks (struct ndmlog *ixlog); 795 extern int ndmfhdb_add_file (struct ndmlog *ixlog, int tagc, 796 char *raw_name, ndmp9_file_stat *fstat); 797 extern int ndmfhdb_add_dir (struct ndmlog *ixlog, int tagc, 798 char *raw_name, ndmp9_u_quad dir_node, 799 ndmp9_u_quad node); 800 extern int ndmfhdb_add_node (struct ndmlog *ixlog, int tagc, 801 ndmp9_u_quad node, ndmp9_file_stat *fstat); 802 extern int ndmfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc, 803 ndmp9_u_quad root_node); 804 805 extern int ndmfhdb_add_fh_info_to_nlist (FILE *fp, 806 ndmp9_name *nlist, int n_nlist); 807 extern int ndmfhdb_open (FILE *fp, struct ndmfhdb *fhcb); 808 extern int ndmfhdb_lookup (struct ndmfhdb *fhcb, char *path, 809 ndmp9_file_stat *fstat); 810 extern int ndmfhdb_dirnode_root (struct ndmfhdb *fhcb); 811 extern int ndmfhdb_dirnode_lookup (struct ndmfhdb *fhcb, char *path, 812 ndmp9_file_stat *fstat); 813 extern int ndmfhdb_dir_lookup (struct ndmfhdb *fhcb, 814 uint64_t dir_node, char *name, uint64_t *node_p); 815 extern int ndmfhdb_node_lookup (struct ndmfhdb *fhcb, 816 uint64_t node, ndmp9_file_stat *fstat); 817 extern int ndmfhdb_file_root (struct ndmfhdb *fhcb); 818 extern int ndmfhdb_file_lookup (struct ndmfhdb *fhcb, char *path, 819 ndmp9_file_stat *fstat); 820 extern char * ndm_fstat_to_str (ndmp9_file_stat *fstat, char *buf); 821 extern int ndm_fstat_from_str (ndmp9_file_stat *fstat, char *buf); 822 823 #ifdef __cplusplus 824 } 825 #endif 826 827 #endif /* _NDMLIB_H_ */ 828