a7f768f37d3198ee772b39d099f0438db6a20588
[debian/amanda] / ndmp-src / ndmlib.h
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_total (struct ndmchan *ch);
200 extern int      ndmchan_n_ready (struct ndmchan *ch);
201 extern enum ndmchan_read_interpretation
202                 ndmchan_read_interpret (struct ndmchan *ch, char **data_p,
203                         unsigned *n_ready_p);
204 extern enum ndmchan_write_interpretation
205                 ndmchan_write_interpret (struct ndmchan *ch, char **data_p,
206                         unsigned *n_avail_p);
207
208 extern void     ndmchan_pp (struct ndmchan *ch, char *buf);
209
210 extern int      ndmos_chan_poll (struct ndmchan *chtab[],
211                         unsigned n_chtab, int milli_timo);
212
213
214
215
216 /*
217  * NDMCONN -- Bidirectional control connections
218  ****************************************************************
219  */
220
221 #define NDMCONN_TYPE_NONE               0
222 #define NDMCONN_TYPE_RESIDENT           1
223 #define NDMCONN_TYPE_REMOTE             2
224
225
226 #define NDMCONN_CALL_STATUS_HDR_ERROR   (-2)
227 #define NDMCONN_CALL_STATUS_BOTCH       (-1)
228 #define NDMCONN_CALL_STATUS_OK          0
229 #define NDMCONN_CALL_STATUS_REPLY_ERROR 1
230 #define NDMCONN_CALL_STATUS_REPLY_LATE  2
231
232
233 struct ndmconn {
234         struct sockaddr sa;
235
236         struct ndmchan  chan;
237
238         char            conn_type;
239         char            protocol_version;
240         char            was_allocated;
241
242         void *          context;
243
244         XDR             xdrs;
245         unsigned char   frag_hdr_buf[4];        /* see ndmconn_readit() */
246         unsigned        fhb_off;
247         unsigned long   frag_resid;
248
249         unsigned long   next_sequence;
250
251         void            (*unexpected)(struct ndmconn *conn,
252                                         struct ndmp_msg_buf *nmb);
253
254         int             snoop_level;
255         struct ndmlog * snoop_log;
256
257         char *          last_err_msg;
258
259         int             (*call) (struct ndmconn *conn, struct ndmp_xa_buf *xa);
260
261         struct ndmp_xa_buf call_xa_buf;
262
263         int             last_message;
264         int             last_call_status;
265         ndmp9_error     last_header_error;
266         ndmp9_error     last_reply_error;
267
268         long            sent_time;
269         long            received_time;
270         long            time_limit;
271 };
272
273 extern struct ndmconn * ndmconn_initialize (struct ndmconn *aconn, char *name);
274 extern void             ndmconn_destruct (struct ndmconn *conn);
275 extern int              ndmconn_connect_agent (struct ndmconn *conn,
276                                 struct ndmagent *agent);
277 extern int              ndmconn_connect_host_port (struct ndmconn *conn,
278                                 char * hostname, int port,
279                                 unsigned want_protocol_version);
280 extern int              ndmconn_connect_sockaddr_in (struct ndmconn *conn,
281                                 struct sockaddr_in *sin,
282                                 unsigned want_protocol_version);
283 extern int              ndmconn_try_open (struct ndmconn *conn,
284                                 unsigned protocol_version);
285 extern int              ndmconn_accept (struct ndmconn *conn, int sock);
286 extern int              ndmconn_abort (struct ndmconn *conn);
287 extern int              ndmconn_close (struct ndmconn *conn);
288 extern int              ndmconn_fileno (struct ndmconn *conn);
289 extern int              ndmconn_auth_agent (struct ndmconn *conn,
290                                 struct ndmagent *agent);
291 extern int              ndmconn_auth_none (struct ndmconn *conn);
292 extern int              ndmconn_auth_text (struct ndmconn *conn,
293                                 char *id, char *pw);
294 extern int              ndmconn_auth_md5 (struct ndmconn *conn,
295                                 char *id, char *pw);
296 extern int              ndmconn_call (struct ndmconn *conn,
297                                 struct ndmp_xa_buf *xa);
298 extern int              ndmconn_exchange_nmb (struct ndmconn *conn,
299                                 struct ndmp_msg_buf *request_nmb,
300                                 struct ndmp_msg_buf *reply_nmb);
301 extern int              ndmconn_send_nmb (struct ndmconn *conn,
302                                 struct ndmp_msg_buf *nmb);
303 extern int              ndmconn_recv_nmb (struct ndmconn *conn,
304                                 struct ndmp_msg_buf *nmb);
305 extern void             ndmconn_free_nmb (struct ndmconn *conn,
306                                 struct ndmp_msg_buf *nmb);
307 extern int              ndmconn_xdr_nmb (struct ndmconn *conn,
308                                 struct ndmp_msg_buf *nmb,
309                                 enum xdr_op x_op);
310 extern int              ndmconn_readit (void *a_conn, char *buf, int len);
311 extern int              ndmconn_writeit (void *a_conn, char *buf, int len);
312 extern int              ndmconn_sys_read (struct ndmconn *conn,
313                                 char *buf, unsigned len);
314 extern int              ndmconn_sys_write (struct ndmconn *conn,
315                                 char *buf, unsigned len);
316 extern void             ndmconn_unexpected (struct ndmconn *conn,
317                                 struct ndmp_msg_buf *nmb);
318 extern int              ndmconn_set_snoop (struct ndmconn *conn,
319                                 struct ndmlog *log, int level);
320 extern void             ndmconn_clear_snoop (struct ndmconn *conn);
321 extern void             ndmconn_snoop_nmb (struct ndmconn *conn,
322                                 struct ndmp_msg_buf *nmb,
323                                 char *whence);
324 extern void             ndmconn_snoop (struct ndmconn *conn,
325                                 int level, char *fmt, ...);
326 extern void             ndmconn_hex_dump (struct ndmconn *conn,
327                                 char *buf, unsigned len);
328 extern int              ndmconn_set_err_msg (struct ndmconn *conn,
329                                 char *err_msg);
330 extern char *           ndmconn_get_err_msg (struct ndmconn *conn);
331
332
333
334
335 /*
336  * NDMC_WITH() AND FRIENDS
337  ****************************************************************
338  *
339  * Macro NDMC_WITH() and friends. These are patterned after
340  * the Pascal "with" construct. These macros take care of
341  * the tedious, error prone, mind-numbing, and distracting
342  * code required to perform NDMP RPCs. These greatly
343  * facilitate the clarity of the main body of code.
344  * Code sequences look something like:
345  *
346  *      NDMC_WITH(ndmp_config_get_butype_attr)
347  *              request->xxx = yyy;
348  *              ...
349  *              rc = NDMC_CALL(ndmconn);
350  *              if (rc == 0) {
351  *                      reply->xxx ...
352  *                      ....
353  *              }
354  *              NDMC_FREE_REPLY()
355  *      NDMC_ENDWITH
356  *
357  * The NDMC macros are for client-side (caller) sequences.
358  * The NDMS macros are for server-side (callee) sequences.
359  *
360  * These macros are very dependent on ndmp_msg_buf.h and ndmp_ammend.h
361  *
362  * Implementation note: initialization of *request and *reply
363  * are separate from their declarations. They used to be
364  * initialized declarators. The separation made gcc -Wall happy.
365  */
366
367 #define NDMC_WITH(TYPE,VERS) \
368   { \
369         struct ndmp_xa_buf *    xa = &conn->call_xa_buf; \
370         TYPE##_request * request; \
371         TYPE##_reply   * reply; \
372         request = &xa->request.body.TYPE##_request_body; \
373         reply = &xa->reply.body.TYPE##_reply_body; \
374         NDMOS_MACRO_ZEROFILL (xa); \
375         xa->request.protocol_version = VERS; \
376         xa->request.header.message = (ndmp0_message) MT_##TYPE; \
377      {
378
379
380 #define NDMC_WITH_VOID_REQUEST(TYPE,VERS) \
381   { \
382         struct ndmp_xa_buf *    xa = &conn->call_xa_buf; \
383         TYPE##_reply   * reply; \
384         reply = &xa->reply.body.TYPE##_reply_body; \
385         NDMOS_MACRO_ZEROFILL (xa); \
386         xa->request.protocol_version = VERS; \
387         xa->request.header.message = (ndmp0_message) MT_##TYPE; \
388      {
389
390 #define NDMC_WITH_NO_REPLY(TYPE,VERS) \
391   { \
392         struct ndmp_xa_buf *    xa = &conn->call_xa_buf; \
393         TYPE##_request * request; \
394         request = &xa->request.body.TYPE##_request_body; \
395         NDMOS_MACRO_ZEROFILL (xa); \
396         xa->request.protocol_version = VERS; \
397         xa->request.header.message = (ndmp0_message) MT_##TYPE; \
398      {
399
400 #ifndef NDMOS_OPTION_NO_NDMP4
401 #define NDMC_WITH_POST(TYPE,VERS) \
402   { \
403         struct ndmp_xa_buf *    xa = &conn->call_xa_buf; \
404         TYPE##_post * request; \
405         request = &xa->request.body.TYPE##_post_body; \
406         NDMOS_MACRO_ZEROFILL (xa); \
407         xa->request.protocol_version = VERS; \
408         xa->request.header.message = (ndmp0_message) MT_##TYPE; \
409      {
410 #endif /* !NDMOS_OPTION_NO_NDMP4 */
411
412
413 #define NDMC_ENDWITH \
414   } }
415
416 #define NDMC_CALL(CONN) (*(CONN)->call)(CONN, xa);
417 #define NDMC_SEND(CONN) (*(CONN)->call)(CONN, xa);
418 #define NDMC_FREE_REPLY() ndmconn_free_nmb ((void*)0, &xa->reply)
419
420
421
422 #define NDMS_WITH(TYPE) \
423   { \
424         TYPE##_request * request; \
425         TYPE##_reply   * reply; \
426         request = &xa->request.body.TYPE##_request_body; \
427         reply = &xa->reply.body.TYPE##_reply_body; \
428      {
429
430 #define NDMS_WITH_VOID_REQUEST(TYPE) \
431   { \
432         TYPE##_reply   * reply; \
433         reply = &xa->reply.body.TYPE##_reply_body; \
434      {
435
436 #define NDMS_WITH_NO_REPLY(TYPE) \
437   { \
438         TYPE##_request * request; \
439         request = &xa->request.body.TYPE##_request_body; \
440      {
441
442 #ifndef NDMOS_OPTION_NO_NDMP4
443 #define NDMS_WITH_POST(TYPE) \
444   { \
445         TYPE##_post * request; \
446         request = &xa->request.body.TYPE##_post_body; \
447      {
448 #endif /* !NDMOS_OPTION_NO_NDMP4 */
449
450 #define NDMS_ENDWITH \
451   } }
452
453
454
455
456
457
458 /*
459  * NDMAGENT -- "Address" of agent
460  ****************************************************************
461  *
462  * A struct ndmagent contains the information necessary
463  * to establish a connection with an NDMP agent (server).
464  * An agent can be remote (NDMCONN_TYPE_REMOTE) or resident
465  * (...._RESIDENT).
466  * TODO: MD5
467  */
468 #define NDMAGENT_HOST_MAX       63
469 #define NDMAGENT_ACCOUNT_MAX    15
470 #define NDMAGENT_PASSWORD_MAX   32
471
472 struct ndmagent {
473         char            conn_type;      /* NDMCONN_TYPE_... (see above) */
474         char            protocol_version; /* 0->best, 2->v2 3->v3 */
475         char            host[NDMAGENT_HOST_MAX+1];      /* name */
476         int             port;           /* 0->default (NDMPPORT) */
477         char            account[NDMAGENT_ACCOUNT_MAX+1]; /* clear text */
478         char            password[NDMAGENT_PASSWORD_MAX+1]; /* clear text */
479 #if 0
480         ndmp_auth_type  auth_type;
481 #else
482         int             auth_type;
483 #endif
484 };
485 extern int      ndmagent_from_str (struct ndmagent *agent, char *str);
486 extern int      ndmhost_lookup (char *hostname, struct sockaddr_in *sin);
487 extern int      ndmagent_to_sockaddr_in (struct ndmagent *agent,
488                         struct sockaddr_in *sin);
489
490
491
492
493 /*
494  * NDMSCSI -- "Address" of SCSI device
495  ****************************************************************
496  */
497
498 struct ndmscsi_target {
499         char            dev_name[PATH_MAX];
500         int             controller;
501         int             sid;
502         int             lun;
503 };
504
505 #define NDMSCSI_MAX_SENSE_DATA  127
506 struct ndmscsi_request {
507         unsigned char   completion_status;
508         unsigned char   status_byte;
509         unsigned char   data_dir;
510         unsigned char   n_cmd;
511
512         unsigned char   cmd[12];
513
514         unsigned char * data;
515         unsigned        n_data_avail;
516         unsigned        n_data_done;
517         unsigned long   _pad;
518
519         unsigned char   n_sense_data;
520         unsigned char   sense_data[NDMSCSI_MAX_SENSE_DATA];
521 };
522
523 #define NDMSCSI_CS_GOOD 0
524 #define NDMSCSI_CS_FAIL 1
525 /* more? */
526
527 #define NDMSCSI_DD_NONE 0
528 #define NDMSCSI_DD_IN   1       /* adapter->app */
529 #define NDMSCSI_DD_OUT  2       /* app->adapter */
530
531
532 extern int              ndmscsi_target_from_str (struct ndmscsi_target *targ,
533                                 char *str);
534 extern int              ndmscsi_open (struct ndmconn *conn, char *dev_name);
535 extern int              ndmscsi_close (struct ndmconn *conn);
536 extern int              ndmscsi_get_state (struct ndmconn *conn,
537                                 struct ndmscsi_target *targ);
538 extern int              ndmscsi_set_target (struct ndmconn *conn,
539                                 struct ndmscsi_target *targ);
540 extern int              ndmscsi_use (struct ndmconn *conn,
541                                 struct ndmscsi_target *targ);
542 extern int              ndmscsi_execute (struct ndmconn *conn,
543                                 struct ndmscsi_request *req,
544                                 struct ndmscsi_target *targ);
545
546
547
548
549 /*
550  * NDMMEDIA -- media (tape) labels, position, and status
551  ****************************************************************
552  */
553
554 #define NDMMEDIA_LABEL_MAX      31
555
556 struct ndmmedia {
557         NDM_FLAG_DECL(valid_label)      /* ->label[] valid */
558         NDM_FLAG_DECL(valid_filemark)   /* ->file_mark_skip valid */
559         NDM_FLAG_DECL(valid_n_bytes)    /* ->n_bytes valid */
560         NDM_FLAG_DECL(valid_slot)       /* ->slot_addr valid */
561
562         /* results flags */
563         NDM_FLAG_DECL(media_used)       /* was used (loaded) */
564         NDM_FLAG_DECL(media_written)    /* media was written */
565         NDM_FLAG_DECL(media_eof)        /* reached EOF of tape file */
566         NDM_FLAG_DECL(media_eom)        /* reached EOM (tape full) */
567         NDM_FLAG_DECL(media_open_error) /* open-time error (write-protect?) */
568         NDM_FLAG_DECL(media_io_error)   /* media error */
569
570         NDM_FLAG_DECL(label_read)       /* ->label[] read fm media */
571         NDM_FLAG_DECL(label_written)    /* ->label[] writn to media */
572         NDM_FLAG_DECL(label_io_error)   /* error label read/write */
573         NDM_FLAG_DECL(label_mismatch)   /* label wasn't as expected */
574
575         NDM_FLAG_DECL(fmark_error)      /* error skipping file marks */
576
577         NDM_FLAG_DECL(nb_determined)    /* true ->n_bytes determined */
578         NDM_FLAG_DECL(nb_aligned)       /* ->n_bytes aligned per rec_size */
579
580         NDM_FLAG_DECL(slot_empty)       /* slot empty per robot */
581         NDM_FLAG_DECL(slot_bad)         /* ->slot_addr invalid */
582         NDM_FLAG_DECL(slot_missing)     /* !->valid_slot */
583
584         /* all fields are specified/actual depending on context */
585         char            label[NDMMEDIA_LABEL_MAX+1];
586         unsigned        file_mark_offset;
587         unsigned long long n_bytes;
588         unsigned        slot_addr;
589
590         /* scratch pad */
591         unsigned long long begin_offset, end_offset;
592 };
593
594 extern int      ndmmedia_from_str (struct ndmmedia *me, char *str);
595 extern int      ndmmedia_to_str (struct ndmmedia *me, char *str);
596 extern int      ndmmedia_pp (struct ndmmedia *me, int lineno, char *buf);
597 extern long long ndmmedia_strtoll (char *str, char **tailp, int defbase);
598
599
600
601
602 /*
603  * NDMFHH -- file history (FH) heap
604  ****************************************************************
605  *
606  * As DATA accumulates individual File History (FH) entries they
607  * are saved into a heap buffer. When the heap is full it is flushed
608  * from DATA to CONTROL using NDMP?_FH_ADD_.... requests/posts.
609  */
610
611 struct ndmfhheap {
612         int             fhtype;
613         int             entry_size;
614
615         void *          table;
616         void *          allo_entry;
617
618         void *          allo_item;
619
620         void *          heap_base;
621         void *          heap_end;
622         unsigned        heap_size;
623
624         void *          heap_top;
625         void *          heap_bot;
626 };
627
628 struct ndmfhh_generic_table {
629         u_int   table_len;
630         void *  table_val;
631 };
632
633 #define NDMFHH_RET_OK           (0)
634 #define NDMFHH_RET_OVERFLOW     (-1)
635 #define NDMFHH_RET_TYPE_CHANGE  (-2)
636 #define NDMFHH_RET_NO_HEAP      (-3)
637 #define NDMFHH_RET_ENTRY_SIZE_MISMATCH (-4)
638
639
640 extern int      ndmfhh_initialize (struct ndmfhheap *fhh);
641 extern int      ndmfhh_commission (struct ndmfhheap *fhh,
642                                         void *heap, unsigned size);
643 extern int      ndmfhh_prepare (struct ndmfhheap *fhh,
644                                         int fhtype, int entry_size,
645                                         unsigned n_item,
646                                         unsigned total_size_of_items);
647 extern void *   ndmfhh_add_entry (struct ndmfhheap *fhh);
648 extern void *   ndmfhh_add_item (struct ndmfhheap *fhh, unsigned size);
649 extern void *   ndmfhh_save_item (struct ndmfhheap *fhh,
650                                         void *item, unsigned size);
651 extern int      ndmfhh_reset (struct ndmfhheap *fhh);
652 extern int      ndmfhh_get_table (struct ndmfhheap *fhh,
653                                         int *fhtype_p, void **table_p,
654                                         unsigned *n_entry_p);
655
656
657
658
659 /*
660  * NDMCSTR -- canonical strings
661  ****************************************************************
662  * Convert strings to/from HTTP-like canonical strings (%xx).
663  * Example "a b%c" --> "a%20b%25c"
664  */
665
666 #define NDMCSTR_WARN    '%'
667 extern int      ndmcstr_from_str (char *src, char *dst, unsigned dst_max);
668 extern int      ndmcstr_to_str (char *src, char *dst, unsigned dst_max);
669 extern int      ndmcstr_from_hex (int c);
670
671
672
673
674 /*
675  * NDMMD5 -- MD5 helpers
676  ****************************************************************
677  * This is a wrapper around the MD5 functions. ndml_md5.c
678  * is the only thing that needs to #include md5.h.
679  * The NDMP rules for converting a clear-text password
680  * into an MD5 digest are implemented here.
681  */
682
683 #define NDMP_MD5_CHALLENGE_LENGTH       64
684 #define NDMP_MD5_DIGEST_LENGTH          16
685 #define NDMP_MD5_MESSAGE_LENGTH         128
686 #define NDMP_MD5_MAX_PASSWORD_LENGTH    32
687
688
689 extern int      ndmmd5_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH],
690                                 char *clear_text_password,
691                                 char digest[NDMP_MD5_DIGEST_LENGTH]);
692 extern int      ndmmd5_generate_challenge (
693                                 char challenge[NDMP_MD5_CHALLENGE_LENGTH]);
694
695 extern int      ndmmd5_ok_digest (char challenge[NDMP_MD5_CHALLENGE_LENGTH],
696                                 char *clear_text_password,
697                                 char digest[NDMP_MD5_DIGEST_LENGTH]);
698
699
700
701
702 /*
703  * NDMBSTF -- Binary Search Text File
704  ****************************************************************
705  * Use conventional binary search method on a sorted text
706  * file. The file MUST be sorted in ascending, lexicographic
707  * order. This is the default order of sort(1).
708  */
709
710 extern int ndmbstf_first (FILE *fp, char *key, char *buf, unsigned max_buf);
711 extern int ndmbstf_next (FILE *fp, char *key, char *buf, unsigned max_buf);
712 extern int ndmbstf_first_with_bounds (FILE *fp, char *key,
713             char *buf, unsigned max_buf, off_t lower_bound, off_t upper_bound);
714 extern int ndmbstf_getline (FILE *fp, char *buf, unsigned max_buf);
715 extern int ndmbstf_seek_and_align (FILE *fp, off_t *off);
716 extern int ndmbstf_match (char *key, char *buf);
717 extern int ndmbstf_compare (char *key, char *buf);
718
719
720
721
722 /*
723  * NDMSTZF -- Stanza File
724  ****************************************************************
725  *
726  * Stanza files look about like this:
727  *      [stanza name line]
728  *      stanza body lines
729  *
730  * These are used for config files.
731  */
732 extern int ndmstz_getline (FILE *fp, char *buf, int n_buf);
733 extern int ndmstz_getstanza (FILE *fp, char *buf, int n_buf);
734 extern int ndmstz_parse (char *buf, char *argv[], int max_argv);
735
736
737
738
739 /*
740  * NDMCFG -- Config File
741  ****************************************************************
742  *
743  * Config files are stanza files (see above) which describe
744  * backup types, tape and scsi devices, etc.
745  * See ndml_config.c for details and stanza formats.
746  */
747 extern int      ndmcfg_load (char *filename, ndmp9_config_info *config_info);
748 extern int      ndmcfg_loadfp (FILE *fp, ndmp9_config_info *config_info);
749
750
751
752
753 /*
754  * NDMFHDB -- File History Database
755  *
756  * The File History is generated by the DATA and sent to the CONTROL
757  * using NDMP?_FH_ADD_... requests/posts. During backup the CONTROL
758  * writes the File History info to a text file as it arrives. Upon
759  * completion of the backup the text file should be sorted (UNIX
760  * sort(1) command). For recovery the file history index is searched
761  * using binary search (see NDMBSTF above). The fh_info, a 64-bit
762  * cookie used by DATA to identify the region of the backup image
763  * containing the corresponding object, is retreived from the index.
764  */
765
766 struct ndmfhdb {
767         FILE *                  fp;
768         int                     use_dir_node;
769         unsigned long long      root_node;
770 };
771
772 extern int      ndmfhdb_add_file (struct ndmlog *ixlog, int tagc,
773                         char *raw_name, ndmp9_file_stat *fstat);
774 extern int      ndmfhdb_add_dir (struct ndmlog *ixlog, int tagc,
775                         char *raw_name, ndmp9_u_quad dir_node,
776                         ndmp9_u_quad node);
777 extern int      ndmfhdb_add_node (struct ndmlog *ixlog, int tagc,
778                         ndmp9_u_quad node, ndmp9_file_stat *fstat);
779 extern int      ndmfhdb_add_dirnode_root (struct ndmlog *ixlog, int tagc,
780                         ndmp9_u_quad root_node);
781
782 extern int      ndmfhdb_add_fh_info_to_nlist (FILE *fp,
783                         ndmp9_name *nlist, int n_nlist);
784 extern int      ndmfhdb_open (FILE *fp, struct ndmfhdb *fhcb);
785 extern int      ndmfhdb_lookup (struct ndmfhdb *fhcb, char *path,
786                         ndmp9_file_stat *fstat);
787 extern int      ndmfhdb_dirnode_root (struct ndmfhdb *fhcb);
788 extern int      ndmfhdb_dirnode_lookup (struct ndmfhdb *fhcb, char *path,
789                         ndmp9_file_stat *fstat);
790 extern int      ndmfhdb_dir_lookup (struct ndmfhdb *fhcb,
791                         unsigned long long dir_node,
792                         char *name, unsigned long long *node_p);
793 extern int      ndmfhdb_node_lookup (struct ndmfhdb *fhcb,
794                         unsigned long long node,
795                         ndmp9_file_stat *fstat);
796 extern int      ndmfhdb_file_root (struct ndmfhdb *fhcb);
797 extern int      ndmfhdb_file_lookup (struct ndmfhdb *fhcb, char *path,
798                         ndmp9_file_stat *fstat);
799 extern char *   ndm_fstat_to_str (ndmp9_file_stat *fstat, char *buf);
800 extern int      ndm_fstat_from_str (ndmp9_file_stat *fstat, char *buf);
801
802
803 #endif /* _NDMLIB_H_ */