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