2 * Copyright (c) 1998,1999,2000,2002
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
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.
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
43 #include "ndmprotocol.h"
44 #include "ndmp_msg_buf.h"
45 #include "ndmp_translate.h"
47 /* Probably unnecessary, yet prudent. Compilers/debuggers sometimes goof. */
49 #define NDM_FLAG_DECL(XXX) unsigned XXX : 1;
50 #endif /* !NDM_FLAG_DECL */
52 /* boring forward reference stuff */
60 ****************************************************************
62 * ndmlog is a simple abstraction for log messages.
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
67 * The application will typically direct log messages to a file.
68 * Yet, logging directly to a FILE tends to be restrictive. Hence
71 * The time stamp is relative to the start time, and has millisecond
76 void (*deliver)(struct ndmlog *log, char *tag, int lev, char *msg);
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);
89 * NDMNMB -- NDMP Message Buffer
90 ****************************************************************
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.
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,
106 extern int ndmnmb_set_reply_error (struct ndmp_msg_buf *nmb,
116 * NDMCHAN -- Async I/O channel
117 ****************************************************************
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.
126 char * name; /* short name, helps debugging */
128 char mode; /* NDMCHAN_MODE_... (see below) */
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) */
135 int fd; /* der eff dee */
136 int saved_errno; /* errno captured if ->error occurs */
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 */
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 */
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 */
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 */
174 extern void ndmchan_initialize (struct ndmchan *ch, char *name);
175 extern int ndmchan_setbuf (struct ndmchan *ch, char *data,
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);
209 extern void ndmchan_pp (struct ndmchan *ch, char *buf);
211 extern int ndmos_chan_poll (struct ndmchan *chtab[],
212 unsigned n_chtab, int milli_timo);
218 * NDMCONN -- Bidirectional control connections
219 ****************************************************************
222 #define NDMCONN_TYPE_NONE 0
223 #define NDMCONN_TYPE_RESIDENT 1
224 #define NDMCONN_TYPE_REMOTE 2
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
240 char protocol_version;
246 unsigned char frag_hdr_buf[4]; /* see ndmconn_readit() */
248 unsigned long frag_resid;
250 unsigned long next_sequence;
252 void (*unexpected)(struct ndmconn *conn,
253 struct ndmp_msg_buf *nmb);
256 struct ndmlog * snoop_log;
260 int (*call) (struct ndmconn *conn, struct ndmp_xa_buf *xa);
262 struct ndmp_xa_buf call_xa_buf;
265 int last_call_status;
266 ndmp9_error last_header_error;
267 ndmp9_error last_reply_error;
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,
295 extern int ndmconn_auth_md5 (struct ndmconn *conn,
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,
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,
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,
331 extern char * ndmconn_get_err_msg (struct ndmconn *conn);
337 * NDMC_WITH() AND FRIENDS
338 ****************************************************************
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:
347 * NDMC_WITH(ndmp_config_get_butype_attr)
348 * request->xxx = yyy;
350 * rc = NDMC_CALL(ndmconn);
358 * The NDMC macros are for client-side (caller) sequences.
359 * The NDMS macros are for server-side (callee) sequences.
361 * These macros are very dependent on ndmp_msg_buf.h and ndmp_ammend.h
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.
368 #define NDMC_WITH(TYPE,VERS) \
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; \
381 #define NDMC_WITH_VOID_REQUEST(TYPE,VERS) \
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; \
391 #define NDMC_WITH_NO_REPLY(TYPE,VERS) \
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; \
401 #ifndef NDMOS_OPTION_NO_NDMP4
402 #define NDMC_WITH_POST(TYPE,VERS) \
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; \
411 #endif /* !NDMOS_OPTION_NO_NDMP4 */
414 #define NDMC_ENDWITH \
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)
423 #define NDMS_WITH(TYPE) \
425 TYPE##_request * request; \
426 TYPE##_reply * reply; \
427 request = &xa->request.body.TYPE##_request_body; \
428 reply = &xa->reply.body.TYPE##_reply_body; \
431 #define NDMS_WITH_VOID_REQUEST(TYPE) \
433 TYPE##_reply * reply; \
434 reply = &xa->reply.body.TYPE##_reply_body; \
437 #define NDMS_WITH_NO_REPLY(TYPE) \
439 TYPE##_request * request; \
440 request = &xa->request.body.TYPE##_request_body; \
443 #ifndef NDMOS_OPTION_NO_NDMP4
444 #define NDMS_WITH_POST(TYPE) \
446 TYPE##_post * request; \
447 request = &xa->request.body.TYPE##_post_body; \
449 #endif /* !NDMOS_OPTION_NO_NDMP4 */
451 #define NDMS_ENDWITH \
460 * NDMAGENT -- "Address" of agent
461 ****************************************************************
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
469 #define NDMAGENT_HOST_MAX 63
470 #define NDMAGENT_ACCOUNT_MAX 15
471 #define NDMAGENT_PASSWORD_MAX 32
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 */
481 ndmp_auth_type auth_type;
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);
495 * NDMSCSI -- "Address" of SCSI device
496 ****************************************************************
499 struct ndmscsi_target {
500 char dev_name[PATH_MAX];
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;
513 unsigned char cmd[12];
515 unsigned char * data;
516 unsigned n_data_avail;
517 unsigned n_data_done;
520 unsigned char n_sense_data;
521 unsigned char sense_data[NDMSCSI_MAX_SENSE_DATA];
524 #define NDMSCSI_CS_GOOD 0
525 #define NDMSCSI_CS_FAIL 1
528 #define NDMSCSI_DD_NONE 0
529 #define NDMSCSI_DD_IN 1 /* adapter->app */
530 #define NDMSCSI_DD_OUT 2 /* app->adapter */
533 extern int ndmscsi_target_from_str (struct ndmscsi_target *targ,
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);
551 * NDMMEDIA -- media (tape) labels, position, and status
552 ****************************************************************
555 #define NDMMEDIA_LABEL_MAX 31
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 */
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 */
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 */
576 NDM_FLAG_DECL(fmark_error) /* error skipping file marks */
578 NDM_FLAG_DECL(nb_determined) /* true ->n_bytes determined */
579 NDM_FLAG_DECL(nb_aligned) /* ->n_bytes aligned per rec_size */
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 */
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;
592 unsigned long long begin_offset, end_offset;
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);
604 * NDMFHH -- file history (FH) heap
605 ****************************************************************
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.
629 struct ndmfhh_generic_table {
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)
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,
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);
661 * NDMCSTR -- canonical strings
662 ****************************************************************
663 * Convert strings to/from HTTP-like canonical strings (%xx).
664 * Example "a b%c" --> "a%20b%25c"
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);
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.
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
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]);
696 extern int ndmmd5_ok_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH],
697 char *clear_text_password,
698 char digest[NDMP_MD5_DIGEST_LENGTH]);
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).
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);
724 * NDMSTZF -- Stanza File
725 ****************************************************************
727 * Stanza files look about like this:
731 * These are used for config files.
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);
741 * NDMCFG -- Config File
742 ****************************************************************
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.
748 extern int ndmcfg_load (char *filename, ndmp9_config_info *config_info);
749 extern int ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info);
755 * NDMFHDB -- File History Database
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.
770 unsigned long long root_node;
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,
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);
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);
804 #endif /* _NDMLIB_H_ */