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