1 /*
2  * Copyright (c) 1998,1999,2000
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 #include "ndmos.h" /* rpc/rpc.h */
39 #include "ndmprotocol.h"
40 
41 
42 #ifndef NDMOS_OPTION_NO_NDMP3
43 
44 
ndmp3_pp_header(void * data,char * buf)45 int ndmp3_pp_header(void* data, char* buf)
46 {
47   ndmp3_header* mh = (ndmp3_header*)data;
48 
49   if (mh->message_type == NDMP3_MESSAGE_REQUEST) {
50     sprintf(buf, "C %s %lu", ndmp3_message_to_str(mh->message), mh->sequence);
51   } else if (mh->message_type == NDMP3_MESSAGE_REPLY) {
52     sprintf(buf, "R %s %lu (%lu)", ndmp3_message_to_str(mh->message),
53             mh->reply_sequence, mh->sequence);
54     if (mh->error != NDMP3_NO_ERR) {
55       sprintf(NDMOS_API_STREND(buf), " %s", ndmp3_error_to_str(mh->error));
56       return 0; /* no body */
57     }
58   } else {
59     strcpy(buf, "??? INVALID MESSAGE TYPE");
60     return -1; /* no body */
61   }
62   return 1; /* body */
63 }
64 
ndmp3_pp_addr(char * buf,ndmp3_addr * ma)65 int ndmp3_pp_addr(char* buf, ndmp3_addr* ma)
66 {
67   sprintf(buf, "%s", ndmp3_addr_type_to_str(ma->addr_type));
68   if (ma->addr_type == NDMP3_ADDR_TCP) {
69     sprintf(NDMOS_API_STREND(buf), "(%lx,%d)",
70             ma->ndmp3_addr_u.tcp_addr.ip_addr, ma->ndmp3_addr_u.tcp_addr.port);
71   }
72   return 0;
73 }
74 
75 
ndmp3_pp_request(ndmp3_message msg,void * data,int lineno,char * buf)76 int ndmp3_pp_request(ndmp3_message msg, void* data, int lineno, char* buf)
77 {
78   int i;
79   unsigned int j;
80 
81   switch (msg) {
82     default:
83       strcpy(buf, "<<INVALID MSG>>");
84       return -1;
85 
86     case NDMP3_CONNECT_OPEN:
87       NDMP_PP_WITH(ndmp3_connect_open_request)
88       sprintf(buf, "version=%d", p->protocol_version);
89       NDMP_PP_ENDWITH
90       break;
91 
92     case NDMP3_CONNECT_CLIENT_AUTH:
93       NDMP_PP_WITH(ndmp3_connect_client_auth_request)
94       sprintf(buf, "auth_type=%s",
95               ndmp3_auth_type_to_str(p->auth_data.auth_type));
96       sprintf(buf, "auth_type=%s",
97               ndmp3_auth_type_to_str(p->auth_data.auth_type));
98       switch (p->auth_data.auth_type) {
99         case NDMP3_AUTH_NONE:
100           break;
101 
102         case NDMP3_AUTH_TEXT:
103           sprintf(NDMOS_API_STREND(buf), " auth_id=%s",
104                   p->auth_data.ndmp3_auth_data_u.auth_text.auth_id);
105           break;
106 
107         case NDMP3_AUTH_MD5:
108           sprintf(NDMOS_API_STREND(buf), " auth_id=%s",
109                   p->auth_data.ndmp3_auth_data_u.auth_md5.auth_id);
110           break;
111 
112         default:
113           sprintf(NDMOS_API_STREND(buf), " ????");
114           break;
115       }
116       NDMP_PP_ENDWITH
117       break;
118 
119     case NDMP3_CONNECT_CLOSE:
120     case NDMP3_CONFIG_GET_HOST_INFO:
121     case NDMP3_CONFIG_GET_CONNECTION_TYPE:
122     case NDMP3_CONFIG_GET_SERVER_INFO:
123     case NDMP3_CONFIG_GET_BUTYPE_INFO:
124     case NDMP3_CONFIG_GET_FS_INFO:
125     case NDMP3_CONFIG_GET_TAPE_INFO:
126     case NDMP3_CONFIG_GET_SCSI_INFO:
127     case NDMP3_SCSI_CLOSE:
128     case NDMP3_SCSI_GET_STATE:
129     case NDMP3_SCSI_RESET_DEVICE:
130     case NDMP3_SCSI_RESET_BUS:
131     case NDMP3_TAPE_GET_STATE:
132     case NDMP3_TAPE_CLOSE:
133     case NDMP3_MOVER_GET_STATE:
134     case NDMP3_MOVER_CONTINUE:
135     case NDMP3_MOVER_ABORT:
136     case NDMP3_MOVER_STOP:
137     case NDMP3_MOVER_CLOSE:
138     case NDMP3_DATA_GET_STATE:
139     case NDMP3_DATA_ABORT:
140     case NDMP3_DATA_STOP:
141     case NDMP3_DATA_GET_ENV:
142       *buf = 0; /* no body */
143       return 0;
144 
145     case NDMP3_CONNECT_SERVER_AUTH:
146       strcpy(buf, "<<unimplemented pp>>");
147       break;
148 
149     case NDMP3_CONFIG_GET_AUTH_ATTR:
150       NDMP_PP_WITH(ndmp3_config_get_auth_attr_request)
151       sprintf(buf, "auth_type=%s", ndmp3_auth_type_to_str(p->auth_type));
152       NDMP_PP_ENDWITH
153       break;
154 
155     case NDMP3_SCSI_OPEN:
156       NDMP_PP_WITH(ndmp3_scsi_open_request)
157       sprintf(buf, "device='%s'", p->device);
158       NDMP_PP_ENDWITH
159       break;
160 
161     case NDMP3_SCSI_SET_TARGET:
162       NDMP_PP_WITH(ndmp3_scsi_set_target_request)
163       sprintf(buf, "device='%s' cont=%d sid=%d lun=%d", p->device,
164               p->target_controller, p->target_id, p->target_lun);
165       NDMP_PP_ENDWITH
166       break;
167 
168     case NDMP3_SCSI_EXECUTE_CDB:
169     case NDMP3_TAPE_EXECUTE_CDB:
170       NDMP_PP_WITH(ndmp3_execute_cdb_request)
171       switch (lineno) {
172         case 0:
173           sprintf(buf, "flags=0x%lx timeout=%ld datain_len=%ld", p->flags,
174                   p->timeout, p->datain_len);
175           break;
176         case 1:
177           sprintf(buf, "cmd[%d]={", p->cdb.cdb_len);
178           for (j = 0; j < p->cdb.cdb_len; j++) {
179             sprintf(NDMOS_API_STREND(buf), " %02x", p->cdb.cdb_val[j] & 0xFF);
180           }
181           strcat(buf, " }");
182           break;
183       }
184       return 2;
185       NDMP_PP_ENDWITH
186       break;
187 
188     case NDMP3_TAPE_OPEN:
189       NDMP_PP_WITH(ndmp3_tape_open_request)
190       sprintf(buf, "device='%s' mode=%s", p->device,
191               ndmp3_tape_open_mode_to_str(p->mode));
192       NDMP_PP_ENDWITH
193       break;
194 
195     case NDMP3_TAPE_MTIO:
196       NDMP_PP_WITH(ndmp3_tape_mtio_request)
197       sprintf(buf, "op=%s count=%ld", ndmp3_tape_mtio_op_to_str(p->tape_op),
198               p->count);
199       NDMP_PP_ENDWITH
200       break;
201 
202     case NDMP3_TAPE_WRITE:
203       NDMP_PP_WITH(ndmp3_tape_write_request)
204       sprintf(buf, "data_out_len=%d", p->data_out.data_out_len);
205       NDMP_PP_ENDWITH
206       break;
207 
208     case NDMP3_TAPE_READ:
209       NDMP_PP_WITH(ndmp3_tape_read_request)
210       sprintf(buf, "count=%ld", p->count);
211       NDMP_PP_ENDWITH
212       break;
213 
214     case NDMP3_DATA_START_BACKUP:
215       NDMP_PP_WITH(ndmp3_data_start_backup_request)
216       if (lineno == 0) {
217         sprintf(buf, "bu_type='%s' n_env=%d", p->bu_type, p->env.env_len);
218       } else {
219         i = lineno - 1;
220         if (0 <= i && (unsigned)i < p->env.env_len) {
221           sprintf(buf, "env[%d] name='%s' value='%s'", i,
222                   p->env.env_val[i].name, p->env.env_val[i].value);
223         } else {
224           strcpy(buf, "--INVALID--");
225         }
226       }
227       return 1 + p->env.env_len;
228       NDMP_PP_ENDWITH
229       break;
230 
231     case NDMP3_DATA_START_RECOVER:
232     case NDMP3_DATA_START_RECOVER_FILEHIST:
233       NDMP_PP_WITH(ndmp3_data_start_recover_request)
234       if (lineno == 0) {
235         sprintf(buf, "bu_type='%s' n_env=%d n_nlist=%d", p->bu_type,
236                 p->env.env_len, p->nlist.nlist_len);
237       } else {
238         i = lineno - 1;
239         if (0 <= i && (unsigned)i < p->env.env_len) {
240           sprintf(buf, "env[%d] name='%s' value='%s'", i,
241                   p->env.env_val[i].name, p->env.env_val[i].value);
242         } else {
243           i -= p->env.env_len;
244           if (0 <= i && (unsigned)i < p->nlist.nlist_len * 4) {
245             ndmp3_name* nm = &p->nlist.nlist_val[i / 4];
246 
247             switch (i % 4) {
248               case 0:
249                 sprintf(buf, "nl[%d] original_path='%s'", i / 4,
250                         nm->original_path);
251                 break;
252               case 1:
253                 sprintf(buf, "..... destination_dir='%s'", nm->destination_dir);
254                 break;
255               case 2:
256                 sprintf(buf, "..... new_name='%s' other='%s'", nm->new_name,
257                         nm->other_name);
258                 break;
259               case 3:
260                 sprintf(buf, "..... node=%lld fh_info=%lld", nm->node,
261                         nm->fh_info);
262                 break;
263             }
264           } else {
265             strcpy(buf, "--INVALID--");
266           }
267         }
268       }
269       return 1 + p->env.env_len + p->nlist.nlist_len * 4;
270       NDMP_PP_ENDWITH
271       break;
272 
273     case NDMP3_DATA_LISTEN:
274       NDMP_PP_WITH(ndmp3_data_listen_request)
275       sprintf(buf, "addr_type=%s", ndmp3_addr_type_to_str(p->addr_type));
276       NDMP_PP_ENDWITH
277       break;
278 
279     case NDMP3_DATA_CONNECT:
280       NDMP_PP_WITH(ndmp3_data_connect_request)
281       sprintf(buf, "addr=");
282       ndmp3_pp_addr(NDMOS_API_STREND(buf), &p->addr);
283       NDMP_PP_ENDWITH
284       break;
285 
286     case NDMP3_NOTIFY_DATA_HALTED:
287       NDMP_PP_WITH(ndmp3_notify_data_halted_request)
288       sprintf(buf, "reason=%s text_reason='%s'",
289               ndmp3_data_halt_reason_to_str(p->reason), p->text_reason);
290       NDMP_PP_ENDWITH
291       break;
292 
293     case NDMP3_NOTIFY_CONNECTED:
294       NDMP_PP_WITH(ndmp3_notify_connected_request)
295       sprintf(buf, "reason=%s protocol_version=%d text_reason='%s'",
296               ndmp3_connect_reason_to_str(p->reason), p->protocol_version,
297               p->text_reason);
298       NDMP_PP_ENDWITH
299       break;
300 
301     case NDMP3_NOTIFY_MOVER_HALTED:
302       NDMP_PP_WITH(ndmp3_notify_mover_halted_request)
303       sprintf(buf, "reason=%s text_reason='%s'",
304               ndmp3_mover_halt_reason_to_str(p->reason), p->text_reason);
305       NDMP_PP_ENDWITH
306       break;
307 
308     case NDMP3_NOTIFY_MOVER_PAUSED:
309       NDMP_PP_WITH(ndmp3_notify_mover_paused_request)
310       sprintf(buf, "reason=%s seek_position=%lld",
311               ndmp3_mover_pause_reason_to_str(p->reason), p->seek_position);
312       NDMP_PP_ENDWITH
313       break;
314 
315     case NDMP3_NOTIFY_DATA_READ:
316       NDMP_PP_WITH(ndmp3_notify_data_read_request)
317       sprintf(buf, "offset=%lld length=%lld", p->offset, p->length);
318       NDMP_PP_ENDWITH
319       break;
320 
321     case NDMP3_LOG_FILE:
322       NDMP_PP_WITH(ndmp3_log_file_request)
323       sprintf(buf, "file=%s error=%s", p->name, ndmp3_error_to_str(p->error));
324       NDMP_PP_ENDWITH
325       break;
326 
327     case NDMP3_LOG_MESSAGE:
328       NDMP_PP_WITH(ndmp3_log_message_request)
329       sprintf(buf, "log_type=%s id=%lu message='%s'",
330               ndmp3_log_type_to_str(p->log_type), p->message_id, p->entry);
331       NDMP_PP_ENDWITH
332       break;
333 
334     case NDMP3_FH_ADD_FILE:
335       NDMP_PP_WITH(ndmp3_fh_add_file_request)
336       int n_line = 0, n_names = 0, n_stats = 0;
337       unsigned int n_normal = 0;
338 
339       n_line++;
340       for (j = 0; j < p->files.files_len; j++) {
341         int nn, ns;
342 
343         nn = p->files.files_val[j].names.names_len;
344         ns = p->files.files_val[j].stats.stats_len;
345 
346         n_line += 1 + nn + ns;
347         if (nn == 1 && ns == 1) n_normal++;
348         n_names += nn;
349         n_stats += ns;
350       }
351 
352       if (n_normal == p->files.files_len) {
353         /* could do something more efficient here */
354       }
355 
356       if (lineno == 0) {
357         sprintf(buf, "n_files=%d  total n_names=%d n_stats=%d",
358                 p->files.files_len, n_names, n_stats);
359         return n_line;
360       }
361       lineno--;
362       for (j = 0; j < p->files.files_len; j++) {
363         ndmp3_file* file = &p->files.files_val[j];
364         unsigned int k;
365 
366         if (lineno == 0) {
367           sprintf(buf, "[%d] n_names=%d n_stats=%d node=%lld fhinfo=%lld", j,
368                   file->names.names_len, file->stats.stats_len, file->node,
369                   file->fh_info);
370           return n_line;
371         }
372 
373         lineno--;
374 
375         for (k = 0; k < file->names.names_len; k++, lineno--) {
376           ndmp3_file_name* filename;
377 
378           if (lineno != 0) continue;
379 
380           filename = &file->names.names_val[k];
381 
382           sprintf(buf, "  name[%d] fs_type=%s", k,
383                   ndmp3_fs_type_to_str(filename->fs_type));
384 
385           switch (filename->fs_type) {
386             default:
387               sprintf(NDMOS_API_STREND(buf), " other=%s",
388                       filename->ndmp3_file_name_u.other_name);
389               break;
390 
391             case NDMP3_FS_UNIX:
392               sprintf(NDMOS_API_STREND(buf), " unix=%s",
393                       filename->ndmp3_file_name_u.unix_name);
394               break;
395 
396             case NDMP3_FS_NT:
397               sprintf(NDMOS_API_STREND(buf), " nt=%s dos=%s",
398                       filename->ndmp3_file_name_u.nt_name.nt_path,
399                       filename->ndmp3_file_name_u.nt_name.dos_path);
400               break;
401           }
402           return n_line;
403         }
404 
405         for (k = 0; k < file->stats.stats_len; k++, lineno--) {
406           ndmp3_file_stat* filestat;
407 
408           if (lineno != 0) continue;
409 
410           filestat = &file->stats.stats_val[k];
411 
412           sprintf(buf, "  stat[%ud] fs_type=%s ftype=%s size=%lld", k,
413                   ndmp3_fs_type_to_str(filestat->fs_type),
414                   ndmp3_file_type_to_str(filestat->ftype), filestat->size);
415 
416           return n_line;
417         }
418       }
419       sprintf(buf, "  YIKES n_line=%d lineno=%d", n_line, lineno);
420       return -1;
421       NDMP_PP_ENDWITH
422       break;
423 
424     case NDMP3_FH_ADD_DIR:
425       NDMP_PP_WITH(ndmp3_fh_add_dir_request)
426       int n_line = 0, n_names = 0;
427       unsigned int n_normal = 0;
428 
429       n_line++;
430       for (j = 0; j < p->dirs.dirs_len; j++) {
431         int nn;
432 
433         nn = p->dirs.dirs_val[j].names.names_len;
434 
435         n_line += 1 + nn;
436         if (nn == 1) n_normal++;
437         n_names += nn;
438       }
439 
440       if (n_normal == p->dirs.dirs_len) {
441         /* could do something more efficient here */
442       }
443 
444       if (lineno == 0) {
445         sprintf(buf, "n_dirs=%d  total n_names=%d", p->dirs.dirs_len, n_names);
446         return n_line;
447       }
448       lineno--;
449       for (j = 0; j < p->dirs.dirs_len; j++) {
450         ndmp3_dir* dir = &p->dirs.dirs_val[j];
451         unsigned int k;
452 
453         if (lineno == 0) {
454           sprintf(buf, "[%ud] n_names=%d node=%lld parent=%lld", j,
455                   dir->names.names_len, dir->node, dir->parent);
456           return n_line;
457         }
458 
459         lineno--;
460 
461         for (k = 0; k < dir->names.names_len; k++, lineno--) {
462           ndmp3_file_name* filename;
463 
464           if (lineno != 0) continue;
465 
466           filename = &dir->names.names_val[k];
467 
468           sprintf(buf, "  name[%ud] fs_type=%s", k,
469                   ndmp3_fs_type_to_str(filename->fs_type));
470 
471           switch (filename->fs_type) {
472             default:
473               sprintf(NDMOS_API_STREND(buf), " other=%s",
474                       filename->ndmp3_file_name_u.other_name);
475               break;
476 
477             case NDMP3_FS_UNIX:
478               sprintf(NDMOS_API_STREND(buf), " unix=%s",
479                       filename->ndmp3_file_name_u.unix_name);
480               break;
481 
482             case NDMP3_FS_NT:
483               sprintf(NDMOS_API_STREND(buf), " nt=%s dos=%s",
484                       filename->ndmp3_file_name_u.nt_name.nt_path,
485                       filename->ndmp3_file_name_u.nt_name.dos_path);
486               break;
487           }
488           return n_line;
489         }
490       }
491       sprintf(buf, "  YIKES n_line=%d lineno=%d", n_line, lineno);
492       return -1;
493       NDMP_PP_ENDWITH
494       break;
495 
496     case NDMP3_FH_ADD_NODE:
497       NDMP_PP_WITH(ndmp3_fh_add_node_request)
498       int n_line = 0, n_stats = 0;
499       unsigned int n_normal = 0;
500 
501       n_line++;
502       for (j = 0; j < p->nodes.nodes_len; j++) {
503         int ns;
504 
505         ns = p->nodes.nodes_val[j].stats.stats_len;
506 
507         n_line += 1 + ns;
508         if (ns == 1) n_normal++;
509         n_stats += ns;
510       }
511 
512       if (n_normal == p->nodes.nodes_len) {
513         /* could do something more efficient here */
514       }
515 
516       if (lineno == 0) {
517         sprintf(buf, "n_nodes=%d  total n_stats=%d", p->nodes.nodes_len,
518                 n_stats);
519         return n_line;
520       }
521       lineno--;
522       for (j = 0; j < p->nodes.nodes_len; j++) {
523         ndmp3_node* node = &p->nodes.nodes_val[j];
524         unsigned int k;
525 
526         if (lineno == 0) {
527           sprintf(buf, "[%ud] n_stats=%d node=%lld fhinfo=%lld", j,
528                   node->stats.stats_len, node->node, node->fh_info);
529           return n_line;
530         }
531 
532         lineno--;
533 
534         for (k = 0; k < node->stats.stats_len; k++, lineno--) {
535           ndmp3_file_stat* filestat;
536 
537           if (lineno != 0) continue;
538 
539           filestat = &node->stats.stats_val[k];
540 
541           sprintf(buf, "  stat[%ud] fs_type=%s ftype=%s size=%lld", k,
542                   ndmp3_fs_type_to_str(filestat->fs_type),
543                   ndmp3_file_type_to_str(filestat->ftype), filestat->size);
544 
545           return n_line;
546         }
547       }
548       sprintf(buf, "  YIKES n_line=%d lineno=%d", n_line, lineno);
549       return -1;
550       NDMP_PP_ENDWITH
551       break;
552 
553     case NDMP3_MOVER_LISTEN:
554       NDMP_PP_WITH(ndmp3_mover_listen_request)
555       sprintf(buf, "mode=%s addr_type=%s", ndmp3_mover_mode_to_str(p->mode),
556               ndmp3_addr_type_to_str(p->addr_type));
557       NDMP_PP_ENDWITH
558       break;
559 
560     case NDMP3_MOVER_SET_WINDOW:
561       NDMP_PP_WITH(ndmp3_mover_set_window_request)
562       sprintf(buf, "offset=%lld length=%lld", p->offset, p->length);
563       NDMP_PP_ENDWITH
564       break;
565 
566     case NDMP3_MOVER_READ:
567       NDMP_PP_WITH(ndmp3_mover_read_request)
568       sprintf(buf, "offset=%lld length=%lld", p->offset, p->length);
569       NDMP_PP_ENDWITH
570       break;
571 
572     case NDMP3_MOVER_SET_RECORD_SIZE:
573       NDMP_PP_WITH(ndmp3_mover_set_record_size_request)
574       sprintf(buf, "len=%lu", p->len);
575       NDMP_PP_ENDWITH
576       break;
577 
578     case NDMP3_MOVER_CONNECT:
579       NDMP_PP_WITH(ndmp3_mover_connect_request)
580       sprintf(buf, "mode=%s addr=", ndmp3_mover_mode_to_str(p->mode));
581       ndmp3_pp_addr(NDMOS_API_STREND(buf), &p->addr);
582       NDMP_PP_ENDWITH
583       break;
584   }
585   return 1; /* one line in buf */
586 }
587 
588 
ndmp3_pp_reply(ndmp3_message msg,void * data,int lineno,char * buf)589 int ndmp3_pp_reply(ndmp3_message msg, void* data, int lineno, char* buf)
590 {
591   int i;
592   unsigned int j;
593 
594   switch (msg) {
595     default:
596       strcpy(buf, "<<INVALID MSG>>");
597       return -1;
598 
599     case NDMP3_CONNECT_OPEN:
600     case NDMP3_CONNECT_CLIENT_AUTH:
601     case NDMP3_SCSI_OPEN:
602     case NDMP3_SCSI_CLOSE:
603     case NDMP3_SCSI_SET_TARGET:
604     case NDMP3_SCSI_RESET_DEVICE:
605     case NDMP3_SCSI_RESET_BUS:
606     case NDMP3_TAPE_OPEN:
607     case NDMP3_TAPE_CLOSE:
608     case NDMP3_MOVER_CONTINUE:
609     case NDMP3_MOVER_ABORT:
610     case NDMP3_MOVER_STOP:
611     case NDMP3_MOVER_READ:
612     case NDMP3_MOVER_SET_WINDOW:
613     case NDMP3_MOVER_CLOSE:
614     case NDMP3_MOVER_SET_RECORD_SIZE:
615     case NDMP3_MOVER_CONNECT:
616     case NDMP3_DATA_START_BACKUP:
617     case NDMP3_DATA_START_RECOVER:
618     case NDMP3_DATA_START_RECOVER_FILEHIST:
619     case NDMP3_DATA_ABORT:
620     case NDMP3_DATA_STOP:
621     case NDMP3_DATA_CONNECT:
622       NDMP_PP_WITH(ndmp3_error)
623       sprintf(buf, "error=%s", ndmp3_error_to_str(*p));
624       NDMP_PP_ENDWITH
625       break;
626 
627     case NDMP3_CONFIG_GET_CONNECTION_TYPE:
628       NDMP_PP_WITH(ndmp3_config_get_connection_type_reply)
629       sprintf(buf, "error=%s addr_types[%d]={", ndmp3_error_to_str(p->error),
630               p->addr_types.addr_types_len);
631       for (j = 0; j < p->addr_types.addr_types_len; j++) {
632         sprintf(NDMOS_API_STREND(buf), " %s",
633                 ndmp3_addr_type_to_str(p->addr_types.addr_types_val[j]));
634       }
635       strcat(buf, " }");
636       NDMP_PP_ENDWITH
637       break;
638 
639     case NDMP3_CONFIG_GET_SERVER_INFO:
640     case NDMP3_CONFIG_GET_BUTYPE_INFO:
641     case NDMP3_CONFIG_GET_FS_INFO:
642     case NDMP3_CONFIG_GET_TAPE_INFO:
643     case NDMP3_CONFIG_GET_SCSI_INFO:
644       strcpy(buf, "<<unimplemented pp>>");
645       break;
646 
647     case NDMP3_CONNECT_CLOSE:
648       *buf = 0;
649       return 0;
650 
651     case NDMP3_CONNECT_SERVER_AUTH:
652       strcpy(buf, "<<unimplemented pp>>");
653       break;
654 
655     case NDMP3_CONFIG_GET_HOST_INFO:
656       NDMP_PP_WITH(ndmp3_config_get_host_info_reply)
657       switch (lineno) {
658         case 0:
659           sprintf(buf, "error=%s hostname=%s", ndmp3_error_to_str(p->error),
660                   p->hostname);
661           break;
662         case 1:
663           sprintf(buf, "os_type=%s os_vers=%s hostid=%s", p->os_type,
664                   p->os_vers, p->hostid);
665           break;
666         default:
667           strcpy(buf, "--INVALID--");
668           break;
669       }
670       return 2;
671       NDMP_PP_ENDWITH
672       break;
673 
674     case NDMP3_CONFIG_GET_AUTH_ATTR:
675       strcpy(buf, "<<unimplemented pp>>");
676       break;
677 
678     case NDMP3_SCSI_GET_STATE:
679       NDMP_PP_WITH(ndmp3_scsi_get_state_reply)
680       sprintf(buf, "error=%s cont=%d sid=%d lun=%d",
681               ndmp3_error_to_str(p->error), p->target_controller, p->target_id,
682               p->target_lun);
683       NDMP_PP_ENDWITH
684       break;
685 
686     case NDMP3_SCSI_EXECUTE_CDB:
687     case NDMP3_TAPE_EXECUTE_CDB:
688       NDMP_PP_WITH(ndmp3_execute_cdb_reply)
689       switch (lineno) {
690         case 0:
691           sprintf(buf, "error=%s status=%02x dataout_len=%ld datain_len=%d",
692                   ndmp3_error_to_str(p->error), p->status, p->dataout_len,
693                   p->datain.datain_len);
694           break;
695         case 1:
696           sprintf(buf, "sense[%d]={", p->ext_sense.ext_sense_len);
697           for (j = 0; j < p->ext_sense.ext_sense_len; j++) {
698             sprintf(NDMOS_API_STREND(buf), " %02x",
699                     p->ext_sense.ext_sense_val[j] & 0xFF);
700           }
701           strcat(buf, " }");
702           break;
703       }
704       return 2;
705       NDMP_PP_ENDWITH
706       break;
707 
708     case NDMP3_TAPE_GET_STATE:
709       NDMP_PP_WITH(ndmp3_tape_get_state_reply)
710       switch (lineno) {
711         case 0:
712           sprintf(buf, "invalid=%lx error=%s flags=0x%lx file_num=%ld",
713                   p->invalid, ndmp3_error_to_str(p->error), p->flags,
714                   p->file_num);
715           break;
716         case 1:
717           sprintf(buf, "soft_errors=%lu block_size=%lu blockno=%lu",
718                   p->soft_errors, p->block_size, p->blockno);
719           break;
720         case 2:
721           sprintf(buf, "total_space=%lld space_remain=%lld partition=%lu",
722                   p->total_space, p->space_remain, p->partition);
723           break;
724         default:
725           strcpy(buf, "--INVALID--");
726           break;
727       }
728       return 3;
729       NDMP_PP_ENDWITH
730       break;
731 
732     case NDMP3_TAPE_MTIO:
733       NDMP_PP_WITH(ndmp3_tape_mtio_reply)
734       sprintf(buf, "error=%s resid_count=%ld", ndmp3_error_to_str(p->error),
735               p->resid_count);
736       NDMP_PP_ENDWITH
737       break;
738 
739     case NDMP3_TAPE_WRITE:
740       NDMP_PP_WITH(ndmp3_tape_write_reply)
741       sprintf(buf, "error=%s count=%ld", ndmp3_error_to_str(p->error),
742               p->count);
743       NDMP_PP_ENDWITH
744       break;
745 
746     case NDMP3_TAPE_READ:
747       NDMP_PP_WITH(ndmp3_tape_read_reply)
748       sprintf(buf, "error=%s data_in_len=%d", ndmp3_error_to_str(p->error),
749               p->data_in.data_in_len);
750       NDMP_PP_ENDWITH
751       break;
752 
753     case NDMP3_DATA_GET_STATE:
754       NDMP_PP_WITH(ndmp3_data_get_state_reply)
755       switch (lineno) {
756         case 0:
757           sprintf(buf, "invalid=%lx error=%s op=%s", p->invalid,
758                   ndmp3_error_to_str(p->error),
759                   ndmp3_data_operation_to_str(p->operation));
760           break;
761         case 1:
762           sprintf(buf, "state=%s", ndmp3_data_state_to_str(p->state));
763           break;
764         case 2:
765           sprintf(buf, "halt_reason=%s",
766                   ndmp3_data_halt_reason_to_str(p->halt_reason));
767           break;
768         case 3:
769           sprintf(buf, "bytes_processed=%lld est_bytes_remain=%lld",
770                   p->bytes_processed, p->est_bytes_remain);
771           break;
772         case 4:
773           sprintf(buf,
774                   "est_time_remain=%ld data_conn_addr=", p->est_time_remain);
775           ndmp3_pp_addr(NDMOS_API_STREND(buf), &p->data_connection_addr);
776           break;
777         case 5:
778           sprintf(buf, "read_offset=%lld read_length=%lld", p->read_offset,
779                   p->read_length);
780           break;
781         default:
782           strcpy(buf, "--INVALID--");
783           break;
784       }
785       return 6;
786       NDMP_PP_ENDWITH
787       break;
788 
789     case NDMP3_DATA_GET_ENV:
790       NDMP_PP_WITH(ndmp3_data_get_env_reply)
791       if (lineno == 0) {
792         sprintf(buf, "error=%s n_env=%d", ndmp3_error_to_str(p->error),
793                 p->env.env_len);
794       } else {
795         i = lineno - 1;
796         if (0 <= i && (unsigned)i < p->env.env_len) {
797           sprintf(buf, "[%d] name='%s' value='%s'", i, p->env.env_val[i].name,
798                   p->env.env_val[i].value);
799         } else {
800           strcpy(buf, "--INVALID--");
801         }
802       }
803       return p->env.env_len + 1;
804       NDMP_PP_ENDWITH
805       break;
806 
807     case NDMP3_NOTIFY_DATA_HALTED:
808     case NDMP3_NOTIFY_CONNECTED:
809     case NDMP3_NOTIFY_MOVER_HALTED:
810     case NDMP3_NOTIFY_MOVER_PAUSED:
811     case NDMP3_NOTIFY_DATA_READ:
812     case NDMP3_LOG_FILE:
813     case NDMP3_LOG_MESSAGE:
814     case NDMP3_FH_ADD_FILE:
815     case NDMP3_FH_ADD_DIR:
816     case NDMP3_FH_ADD_NODE:
817       strcpy(buf, "<<ILLEGAL REPLY>>");
818       break;
819 
820     case NDMP3_MOVER_GET_STATE:
821       NDMP_PP_WITH(ndmp3_mover_get_state_reply)
822       switch (lineno) {
823         case 0:
824           sprintf(buf, "error=%s state=%s", ndmp3_error_to_str(p->error),
825                   ndmp3_mover_state_to_str(p->state));
826           break;
827         case 1:
828           sprintf(buf, "pause_reason=%s",
829                   ndmp3_mover_pause_reason_to_str(p->pause_reason));
830           break;
831         case 2:
832           sprintf(buf, "halt_reason=%s",
833                   ndmp3_mover_halt_reason_to_str(p->halt_reason));
834           break;
835         case 3:
836           sprintf(buf, "record_size=%lu record_num=%lu data_written=%lld",
837                   p->record_size, p->record_num, p->data_written);
838           break;
839         case 4:
840           sprintf(buf, "seek=%lld to_read=%lld win_off=%lld win_len=%lld",
841                   p->seek_position, p->bytes_left_to_read, p->window_offset,
842                   p->window_length);
843           break;
844         case 5:
845           sprintf(buf, "data_conn_addr=");
846           ndmp3_pp_addr(NDMOS_API_STREND(buf), &p->data_connection_addr);
847           break;
848         default:
849           strcpy(buf, "--INVALID--");
850           break;
851       }
852       return 6;
853       NDMP_PP_ENDWITH
854       break;
855 
856     case NDMP3_DATA_LISTEN:
857       NDMP_PP_WITH(ndmp3_data_listen_reply)
858       sprintf(buf, "error=%s mover_conn_addr=", ndmp3_error_to_str(p->error));
859       ndmp3_pp_addr(NDMOS_API_STREND(buf), &p->data_connection_addr);
860       NDMP_PP_ENDWITH
861       break;
862 
863     case NDMP3_MOVER_LISTEN:
864       NDMP_PP_WITH(ndmp3_mover_listen_reply)
865       sprintf(buf, "error=%s data_conn_addr=", ndmp3_error_to_str(p->error));
866       ndmp3_pp_addr(NDMOS_API_STREND(buf), &p->data_connection_addr);
867       NDMP_PP_ENDWITH
868       break;
869   }
870 
871   return 1; /* one line in buf */
872 }
873 
874 #endif /* !NDMOS_OPTION_NO_NDMP3 */
875