xref: /illumos-gate/usr/src/cmd/ndmpadm/ndmpadm_print.c (revision 1fa2a66491e7d8ae0be84e7da4da8e812480c710)
1 /*
2  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 /*
6  * BSD 3 Clause License
7  *
8  * Copyright (c) 2007, The Storage Networking Industry Association.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *	- Redistributions of source code must retain the above copyright
14  *	  notice, this list of conditions and the following disclaimer.
15  *
16  *	- Redistributions in binary form must reproduce the above copyright
17  *	  notice, this list of conditions and the following disclaimer in
18  *	  the documentation and/or other materials provided with the
19  *	  distribution.
20  *
21  *	- Neither the name of The Storage Networking Industry Association (SNIA)
22  *	  nor the names of its contributors may be used to endorse or promote
23  *	  products derived from this software without specific prior written
24  *	  permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 #include <stdio.h>
39 #include <unistd.h>
40 #include <errno.h>
41 #include <locale.h>
42 #include <libndmp.h>
43 #include "ndmpadm.h"
44 
45 /* static functions prototype */
46 static void ndmp_tprint_addr(char *, ndmp_ad_type_t, char *);
47 static void ndmp_print_env(ndmp_session_info_t *);
48 static void ndmp_connect_print_conn(ndmp_session_info_t *);
49 static void ndmp_connect_print_scsi_v2(ndmp_session_info_t *);
50 static void ndmp_connect_print_tape_v2(ndmp_session_info_t *);
51 static void ndmp_connect_print_mover_v2(ndmp_session_info_t *);
52 static void ndmp_connect_print_data_v2(ndmp_session_info_t *);
53 static void ndmp_connect_print_v2(int, ndmp_session_info_t *);
54 static void ndmp_connect_print_mover_v3(ndmp_session_info_t *);
55 static void ndmp_connect_print_data_v3(ndmp_session_info_t *);
56 static void ndmp_connect_print_v3(int, ndmp_session_info_t *);
57 static void ndmp_connection_print(int, ndmp_session_info_t *);
58 
59 /* Boolean to string.  */
60 #define	B2S(b)	((b) ? "Yes" : "No")
61 
62 /*
63  * Print the address type and IP address if the address type is tcp
64  */
65 static void
66 ndmp_tprint_addr(char *label, ndmp_ad_type_t addr_type, char *tcp_addr)
67 {
68 	if ((label == NULL) || (tcp_addr == NULL))
69 		return;
70 
71 	switch (addr_type) {
72 	case NDMP_AD_LOCAL:
73 		(void) fprintf(stdout, gettext("\t%s type:\tLocal\n"), label);
74 		break;
75 	case NDMP_AD_TCP:
76 		(void) fprintf(stdout, gettext("\t%s type:\tTCP\n"), label);
77 		(void) fprintf(stdout, gettext("\t%s address:\t%s\n"),
78 		    label, tcp_addr);
79 		break;
80 	case NDMP_AD_FC:
81 		(void) fprintf(stdout, gettext("\t%s type:\tFC\n"), label);
82 		break;
83 	case NDMP_AD_IPC:
84 		(void) fprintf(stdout, gettext("\t%s type:\tIPC\n"), label);
85 		break;
86 	default:
87 		(void) fprintf(stdout,
88 		    gettext("\t%s addr type unknown (0x%x)\n"),
89 		    label, addr_type);
90 	}
91 }
92 
93 /*
94  * Print all the data environment variables for the active session
95  */
96 static void
97 ndmp_print_env(ndmp_session_info_t *si)
98 {
99 	int i, n;
100 	ndmp_dt_pval_t *ep;
101 
102 	n = si->nsi_data.nd_env_len;
103 	ep = si->nsi_data.nd_env;
104 	for (i = 0; ep && i < n; i++, ep++) {
105 		(void) fprintf(stdout, gettext("\tdata.env[%d]:\t%s: "),
106 		    i, ep->np_name);
107 		if ((ep->np_value != NULL) && (*ep->np_value != '\0'))
108 			(void) fprintf(stdout, "\"%s\"\n", ep->np_value);
109 	}
110 }
111 
112 /*
113  * Print common fields of the active connection.
114  */
115 static void
116 ndmp_connect_print_conn(ndmp_session_info_t *si)
117 {
118 	(void) fprintf(stdout, gettext("\tSession Id:\t%d\n"), si->nsi_sid);
119 	(void) fprintf(stdout, gettext("\tProtocol version:\t%d\n"),
120 	    si->nsi_pver);
121 	(void) fprintf(stdout, gettext("\tAuthenticated:\t\t%s\n"),
122 	    B2S(si->nsi_auth));
123 	(void) fprintf(stdout, gettext("\tEOF:\t\t\t%s\n"), B2S(si->nsi_eof));
124 	if (si->nsi_cl_addr != NULL)
125 		(void) fprintf(stdout,
126 		    gettext("\tClient address:\t\t%s\n"), si->nsi_cl_addr);
127 }
128 
129 /*
130  * Print the connection SCSI info.
131  */
132 static void
133 ndmp_connect_print_scsi_v2(ndmp_session_info_t *si)
134 {
135 	(void) fprintf(stdout, gettext("\tscsi.open:\t\t%s\n"),
136 	    B2S(si->nsi_scsi.ns_scsi_open != -1));
137 	if (si->nsi_scsi.ns_adapter_name)
138 		(void) fprintf(stdout, gettext("\tscsi.adapter:\t\t\"%s\"\n"),
139 		    si->nsi_scsi.ns_adapter_name);
140 	(void) fprintf(stdout, gettext("\tscsi.valid target:\t%s\n"),
141 	    B2S(si->nsi_scsi.ns_valid_target_set));
142 	if (si->nsi_scsi.ns_valid_target_set) {
143 		(void) fprintf(stdout,
144 		    gettext("\tscsi.SID:\t\t%d\n"), si->nsi_scsi.ns_scsi_id);
145 		(void) fprintf(stdout,
146 		    gettext("\tscsi.LUN:\t\t%d\n"), si->nsi_scsi.ns_lun);
147 	}
148 }
149 
150 /*
151  * Print the connection tape info.
152  */
153 static void
154 ndmp_connect_print_tape_v2(ndmp_session_info_t *si)
155 {
156 	if (si->nsi_tape.nt_fd != -1) {
157 		(void) fprintf(stdout, gettext("\ttape.fd:\t\t%d\n"),
158 		    si->nsi_tape.nt_fd);
159 		(void) fprintf(stdout, gettext("\ttape.record count:\t%d\n"),
160 		    (int)si->nsi_tape.nt_rec_count);
161 
162 		switch (si->nsi_tape.nt_mode) {
163 		case NDMP_TP_READ_MODE:
164 			(void) fprintf(stdout,
165 			    gettext("\ttape.mode:\t\tRead-only\n"));
166 			break;
167 		case NDMP_TP_WRITE_MODE:
168 			(void) fprintf(stdout,
169 			    gettext("\ttape.mode:\t\tRead/Write\n"));
170 			break;
171 		case NDMP_TP_RAW1_MODE:
172 			(void) fprintf(stdout,
173 			    gettext("\ttape.mode:\t\tRaw\n"));
174 			break;
175 		default:
176 			(void) fprintf(stdout,
177 			    gettext("\ttape.mode:\t\tUnknown (0x%x)\n"),
178 			    si->nsi_tape.nt_mode);
179 		}
180 
181 		if (si->nsi_tape.nt_dev_name)
182 			(void) fprintf(stdout,
183 			    gettext("\ttape.device name:\t%s\n"),
184 			    si->nsi_tape.nt_dev_name);
185 		if (si->nsi_tape.nt_adapter_name)
186 			(void) fprintf(stdout,
187 			    gettext("\ttape.adapter name:\t\"%s\"\n"),
188 			    si->nsi_tape.nt_adapter_name);
189 		(void) fprintf(stdout,
190 		    gettext("\ttape.SID:\t\t%d\n"), si->nsi_tape.nt_sid);
191 		(void) fprintf(stdout,
192 		    gettext("\ttape.LUN:\t\t%d\n"), si->nsi_tape.nt_lun);
193 	} else
194 		(void) fprintf(stdout, gettext("\ttape.device:\t\tNot open\n"));
195 }
196 
197 /*
198  * Print the connection mover info.
199  */
200 static void
201 ndmp_connect_print_mover_v2(ndmp_session_info_t *si)
202 {
203 	switch (si->nsi_mover.nm_state) {
204 	case NDMP_MV_STATE_IDLE:
205 		(void) fprintf(stdout, gettext("\tmover.state:\t\tIdle\n"));
206 		break;
207 	case NDMP_MV_STATE_LISTEN:
208 		(void) fprintf(stdout, gettext("\tmover.state:\t\tListen\n"));
209 		break;
210 	case NDMP_MV_STATE_ACTIVE:
211 		(void) fprintf(stdout, gettext("\tmover.state:\t\tActive\n"));
212 		break;
213 	case NDMP_MV_STATE_PAUSED:
214 		(void) fprintf(stdout, gettext("\tmover.state:\t\tPaused\n"));
215 		break;
216 	case NDMP_MV_STATE_HALTED:
217 		(void) fprintf(stdout, gettext("\tmover.state:\t\tHalted\n"));
218 		break;
219 	default:
220 		(void) fprintf(stdout,
221 		    gettext("\tmover.state:\t\tUnknown (0x%x)\n"),
222 		    si->nsi_mover.nm_state);
223 	}
224 
225 	switch (si->nsi_mover.nm_mode) {
226 	case NDMP_MV_MODE_READ:
227 		(void) fprintf(stdout, gettext("\tmover.mode:\t\tRead\n"));
228 		break;
229 	case NDMP_MV_MODE_WRITE:
230 		(void) fprintf(stdout, gettext("\tmover.mode:\t\tWrite\n"));
231 		break;
232 	default:
233 		(void) fprintf(stdout,
234 		    gettext("\tmover.mode:\t\tUnknown (0x%x)\n"),
235 		    si->nsi_mover.nm_mode);
236 	}
237 
238 	switch (si->nsi_mover.nm_pause_reason) {
239 	case NDMP_MV_PAUSE_NA:
240 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tN/A\n"));
241 		break;
242 	case NDMP_MV_PAUSE_EOM:
243 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tEOM\n"));
244 		break;
245 	case NDMP_MV_PAUSE_EOF:
246 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tEOF\n"));
247 		break;
248 	case NDMP_MV_PAUSE_SEEK:
249 		(void) fprintf(stdout,
250 		    gettext("\tmover.pause reason:\tSeek\n"));
251 		break;
252 	case NDMP_MV_PAUSE_MEDIA_ERROR:
253 		(void) fprintf(stdout,
254 		    gettext("\tmover.pause reason:\tMedia Error\n"));
255 		break;
256 	default:
257 		(void) fprintf(stdout,
258 		    gettext("\tmover.pause reason:\tUnknown (0x%x)\n"),
259 		    si->nsi_mover.nm_pause_reason);
260 	}
261 
262 	switch (si->nsi_mover.nm_halt_reason) {
263 	case NDMP_MV_HALT_NA:
264 		(void) fprintf(stdout, gettext("\tmover.halt reason:\tN/A\n"));
265 		break;
266 	case NDMP_MV_HALT_CONNECT_CLOSED:
267 		(void) fprintf(stdout,
268 		    gettext("\tmover.halt reason:\tConnection closed\n"));
269 		break;
270 	case NDMP_MV_HALT_ABORTED:
271 		(void) fprintf(stdout,
272 		    gettext("\tmover.halt reason:\tAborted\n"));
273 		break;
274 	case NDMP_MV_HALT_INTERNAL_ERROR:
275 		(void) fprintf(stdout,
276 		    gettext("\tmover.halt reason:\tInternal error\n"));
277 		break;
278 	case NDMP_MV_HALT_CONNECT_ERROR:
279 		(void) fprintf(stdout,
280 		    gettext("\tmover.halt reason:\tConnection error\n"));
281 		break;
282 	default:
283 		(void) fprintf(stdout,
284 		    gettext("\tmover.halt reason:\tUnknown (0x%x)\n"),
285 		    si->nsi_mover.nm_halt_reason);
286 	}
287 
288 	(void) fprintf(stdout, gettext("\tmover.record size:\t%d\n"),
289 	    (int)si->nsi_mover.nm_rec_size);
290 	(void) fprintf(stdout, gettext("\tmover.record number:\t%d\n"),
291 	    (int)si->nsi_mover.nm_rec_num);
292 	(void) fprintf(stdout, gettext("\tmover.pos:\t\t%lld\n"),
293 	    si->nsi_mover.nm_mov_pos);
294 	(void) fprintf(stdout, gettext("\tmover.win off:\t\t%lld\n"),
295 	    si->nsi_mover.nm_window_offset);
296 	(void) fprintf(stdout, gettext("\tmover.win len:\t\t%lld\n"),
297 	    si->nsi_mover.nm_window_length);
298 	(void) fprintf(stdout, gettext("\tmover.data socket:\t%d\n"),
299 	    si->nsi_mover.nm_sock);
300 }
301 
302 /*
303  * Print the connection data info.
304  */
305 static void
306 ndmp_connect_print_data_v2(ndmp_session_info_t *si)
307 {
308 	int i;
309 	ndmp_dt_name_t *np;
310 
311 	switch (si->nsi_data.nd_oper) {
312 	case NDMP_DT_OP_NOACTION:
313 		(void) fprintf(stdout, gettext("\tdata.operation:\t\tNone\n"));
314 		break;
315 	case NDMP_DT_OP_BACKUP:
316 		(void) fprintf(stdout,
317 		    gettext("\tdata.operation:\t\tBackup\n"));
318 		break;
319 	case NDMP_DT_OP_RECOVER:
320 		(void) fprintf(stdout,
321 		    gettext("\tdata.operation:\t\tRestore\n"));
322 		break;
323 	default:
324 		(void) fprintf(stdout,
325 		    gettext("\tdata.operation:\t\tUnknown (0x%x)\n"),
326 		    si->nsi_data.nd_oper);
327 	}
328 
329 	switch (si->nsi_data.nd_state) {
330 	case NDMP_DT_STATE_IDLE:
331 		(void) fprintf(stdout, gettext("\tdata.state:\t\tIdle\n"));
332 		break;
333 	case NDMP_DT_STATE_ACTIVE:
334 		(void) fprintf(stdout, gettext("\tdata.state:\t\tActive\n"));
335 		break;
336 	case NDMP_DT_STATE_HALTED:
337 		(void) fprintf(stdout, gettext("\tdata.state:\t\tHalted\n"));
338 		break;
339 	default:
340 		(void) fprintf(stdout,
341 		    gettext("\tdata.state:\t\tUnknown (0x%x)\n"),
342 		    si->nsi_data.nd_state);
343 	}
344 
345 	switch (si->nsi_data.nd_halt_reason) {
346 	case NDMP_DT_HALT_NA:
347 		(void) fprintf(stdout, gettext("\tdata.halt reason:\tN/A\n"));
348 		break;
349 	case NDMP_DT_HALT_SUCCESSFUL:
350 		(void) fprintf(stdout,
351 		    gettext("\tdata.halt reason:\tSuccessful\n"));
352 		break;
353 	case NDMP_DT_HALT_ABORTED:
354 		(void) fprintf(stdout,
355 		    gettext("\tdata.halt reason:\tAborted\n"));
356 		break;
357 	case NDMP_DT_HALT_INTERNAL_ERROR:
358 		(void) fprintf(stdout,
359 		    gettext("\tdata.halt reason:\tInternal error\n"));
360 		break;
361 	case NDMP_DT_HALT_CONNECT_ERROR:
362 		(void) fprintf(stdout,
363 		    gettext("\tdata.halt reason:\tConnection error\n"));
364 		break;
365 	default:
366 		(void) fprintf(stdout,
367 		    gettext("\tdata.halt reason:\tUnknown (0x%x)\n"),
368 		    si->nsi_data.nd_halt_reason);
369 	}
370 
371 	switch (si->nsi_data.nd_addr_type) {
372 	case NDMP_AD_LOCAL:
373 		(void) fprintf(stdout, gettext("\tdata.mover type:\tLocal\n"));
374 		break;
375 	case NDMP_AD_TCP:
376 		(void) fprintf(stdout, gettext("\tdata.mover type:\tTCP\n"));
377 		if (si->nsi_data.nd_tcp_addr)
378 			(void) fprintf(stdout,
379 			    gettext("\tdata.mover address:\t%s\n"),
380 			    si->nsi_data.nd_tcp_addr);
381 		(void) fprintf(stdout, gettext("\tdata.sock:\t%d\n"),
382 		    si->nsi_data.nd_sock);
383 		break;
384 	default:
385 		(void) fprintf(stdout,
386 		    gettext("\tdata.mover type:\tUnknown (0x%x)\n"),
387 		    si->nsi_data.nd_addr_type);
388 	}
389 
390 	(void) fprintf(stdout, gettext("\tdata.aborted:\t\t%s\n"),
391 	    B2S(si->nsi_data.nd_abort));
392 	(void) fprintf(stdout, gettext("\tdata.read offset:\t%llu\n"),
393 	    si->nsi_data.nd_read_offset);
394 	(void) fprintf(stdout, gettext("\tdata.read length:\t%llu\n"),
395 	    si->nsi_data.nd_read_length);
396 	(void) fprintf(stdout, gettext("\tdata.total size:\t%llu\n"),
397 	    si->nsi_data.nd_total_size);
398 
399 	ndmp_print_env(si);
400 
401 	np = si->nsi_data.nd_nlist.nld_nlist;
402 	for (i = 0; np && i < (int)si->nsi_data.nld_nlist_len; i++, np++) {
403 		if ((np->nn_name) && (np->nn_dest)) {
404 			(void) fprintf(stdout,
405 			    gettext("\tdata.nlist[%d]:\tname: "
406 			    "\"%s\"\n\t\tdest:\"%s\"\n"),
407 			    i, np->nn_name, np->nn_dest);
408 		}
409 	}
410 }
411 
412 /*
413  * Print V2 connection info for the given category.
414  */
415 static void
416 ndmp_connect_print_v2(int cat, ndmp_session_info_t *si)
417 {
418 		if (cat & NDMP_CAT_SCSI)
419 			ndmp_connect_print_scsi_v2(si);
420 		if (cat & NDMP_CAT_TAPE)
421 			ndmp_connect_print_tape_v2(si);
422 		if (cat & NDMP_CAT_MOVER)
423 			ndmp_connect_print_mover_v2(si);
424 		if (cat & NDMP_CAT_DATA)
425 			ndmp_connect_print_data_v2(si);
426 }
427 
428 /*
429  * Print the V3 connection mover info.
430  */
431 static void
432 ndmp_connect_print_mover_v3(ndmp_session_info_t *si)
433 {
434 	switch (si->nsi_mover.nm_state) {
435 	case NDMP_MV_STATE_IDLE:
436 		(void) fprintf(stdout, gettext("\tmover.state:\t\tIdle\n"));
437 		break;
438 	case NDMP_MV_STATE_LISTEN:
439 		(void) fprintf(stdout, gettext("\tmover.state:\t\tListen\n"));
440 		break;
441 	case NDMP_MV_STATE_ACTIVE:
442 		(void) fprintf(stdout, gettext("\tmover.state:\t\tActive\n"));
443 		break;
444 	case NDMP_MV_STATE_PAUSED:
445 		(void) fprintf(stdout, gettext("\tmover.state:\t\tPaused\n"));
446 		break;
447 	case NDMP_MV_STATE_HALTED:
448 		(void) fprintf(stdout, gettext("\tmover.state:\t\tHalted\n"));
449 		break;
450 	default:
451 		(void) fprintf(stdout,
452 		    gettext("\tmover.state:\t\tUnknown (0x%x)\n"),
453 		    si->nsi_mover.nm_state);
454 	}
455 
456 	switch (si->nsi_mover.nm_mode) {
457 	case NDMP_MV_MODE_READ:
458 		(void) fprintf(stdout, gettext("\tmover.mode:\t\tRead\n"));
459 		break;
460 	case NDMP_MV_MODE_WRITE:
461 		(void) fprintf(stdout, gettext("\tmover.mode:\t\tWrite\n"));
462 		break;
463 	default:
464 		(void) fprintf(stdout,
465 		    gettext("\tmover.mode:\t\tUnknown (0x%x)\n"),
466 		    si->nsi_mover.nm_mode);
467 	}
468 
469 	switch (si->nsi_mover.nm_pause_reason) {
470 	case NDMP_MV_PAUSE_NA:
471 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tN/A\n"));
472 		break;
473 	case NDMP_MV_PAUSE_EOM:
474 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tEOM\n"));
475 		break;
476 	case NDMP_MV_PAUSE_EOF:
477 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tEOF\n"));
478 		break;
479 	case NDMP_MV_PAUSE_SEEK:
480 		(void) fprintf(stdout,
481 		    gettext("\tmover.pause reason:\tSeek\n"));
482 		break;
483 	case NDMP_MV_PAUSE_MEDIA_ERROR:
484 		(void) fprintf(stdout,
485 		    gettext("\tmover.pause reason:\tMedia Error\n"));
486 		break;
487 	case NDMP_MV_PAUSE_EOW:
488 		(void) fprintf(stdout, gettext("\tmover.pause reason:\tEOW\n"));
489 		break;
490 	default:
491 		(void) fprintf(stdout,
492 		    gettext("\tmover.pause reason:\tUnknown (0x%x)\n"),
493 		    si->nsi_mover.nm_pause_reason);
494 	}
495 
496 	switch (si->nsi_mover.nm_halt_reason) {
497 	case NDMP_MV_HALT_NA:
498 		(void) fprintf(stdout, gettext("\tmover.halt reason:\tN/A\n"));
499 		break;
500 	case NDMP_MV_HALT_CONNECT_CLOSED:
501 		(void) fprintf(stdout,
502 		    gettext("\tmover.halt reason:\tConnection closed\n"));
503 		break;
504 	case NDMP_MV_HALT_ABORTED:
505 		(void) fprintf(stdout,
506 		    gettext("\tmover.halt reason:\tAborted\n"));
507 		break;
508 	case NDMP_MV_HALT_INTERNAL_ERROR:
509 		(void) fprintf(stdout,
510 		    gettext("\tmover.halt reason:\tInternal error\n"));
511 		break;
512 	case NDMP_MV_HALT_CONNECT_ERROR:
513 		(void) fprintf(stdout,
514 		    gettext("\tmover.halt reason:\tConnection error\n"));
515 		break;
516 	default:
517 		(void) fprintf(stdout,
518 		    gettext("\tmover.halt reason:\tUnknown (0x%x)\n"),
519 		    si->nsi_mover.nm_halt_reason);
520 	}
521 
522 	(void) fprintf(stdout, gettext("\tmover.record size:\t%d\n"),
523 	    (int)si->nsi_mover.nm_rec_size);
524 	(void) fprintf(stdout, gettext("\tmover.record number:\t%d\n"),
525 	    (int)si->nsi_mover.nm_rec_num);
526 	(void) fprintf(stdout, gettext("\tmover.pos:\t\t%lld\n"),
527 	    si->nsi_mover.nm_mov_pos, si->nsi_mover.nm_mov_pos);
528 
529 	(void) fprintf(stdout, gettext("\tmover.win len:\t\t%lld\n"),
530 	    si->nsi_mover.nm_window_length, si->nsi_mover.nm_window_length);
531 
532 	(void) fprintf(stdout, gettext("\tmover.win off:\t\t%lld\n"),
533 	    si->nsi_mover.nm_window_offset);
534 	switch (si->nsi_mover.nm_state) {
535 	case NDMP_MV_STATE_IDLE:
536 		if (si->nsi_mover.nm_listen_sock != -1)
537 			(void) fprintf(stdout,
538 			    gettext("\tmover.listenSock:\t%d\n"),
539 			    si->nsi_mover.nm_listen_sock);
540 		if (si->nsi_mover.nm_sock != -1)
541 			(void) fprintf(stdout, gettext("\tmover.sock:\t%d\n"),
542 			    si->nsi_mover.nm_sock);
543 		break;
544 	case NDMP_MV_STATE_LISTEN:
545 		(void) fprintf(stdout, gettext("\tmover.listen socket:\t%d\n"),
546 		    si->nsi_mover.nm_listen_sock);
547 		ndmp_tprint_addr(gettext("mover.listen"),
548 		    si->nsi_mover.nm_addr_type, si->nsi_mover.nm_tcp_addr);
549 		break;
550 	case NDMP_MV_STATE_ACTIVE:
551 	case NDMP_MV_STATE_PAUSED:
552 	case NDMP_MV_STATE_HALTED:
553 		(void) fprintf(stdout, gettext("\tmover.data socket:\t%d\n"),
554 		    si->nsi_mover.nm_sock);
555 		ndmp_tprint_addr(gettext("mover.data connection"),
556 		    si->nsi_mover.nm_addr_type, si->nsi_mover.nm_tcp_addr);
557 		break;
558 	}
559 }
560 
561 /*
562  * Print the connection data info.
563  */
564 static void
565 ndmp_connect_print_data_v3(ndmp_session_info_t *si)
566 {
567 	int i;
568 	ndmp_dt_name_v3_t *np;
569 
570 	switch (si->nsi_data.nd_oper) {
571 	case NDMP_DT_OP_NOACTION:
572 		(void) fprintf(stdout, gettext("\tdata.operation:\t\tNone\n"));
573 		break;
574 	case NDMP_DT_OP_BACKUP:
575 		(void) fprintf(stdout,
576 		    gettext("\tdata.operation:\t\tBackup\n"));
577 		break;
578 	case NDMP_DT_OP_RECOVER:
579 		(void) fprintf(stdout,
580 		    gettext("\tdata.operation:\t\tRestore\n"));
581 		break;
582 	default:
583 		(void) fprintf(stdout,
584 		    gettext("\tdata.operation:\t\tUnknown (0x%x)\n"),
585 		    si->nsi_data.nd_oper);
586 	}
587 
588 	switch (si->nsi_data.nd_state) {
589 	case NDMP_DT_STATE_IDLE:
590 		(void) fprintf(stdout, gettext("\tdata.state:\t\tIdle\n"));
591 		break;
592 	case NDMP_DT_STATE_ACTIVE:
593 		(void) fprintf(stdout, gettext("\tdata.state:\t\tActive\n"));
594 		break;
595 	case NDMP_DT_STATE_HALTED:
596 		(void) fprintf(stdout, gettext("\tdata.state:\t\tHalted\n"));
597 		break;
598 	case NDMP_DT_STATE_LISTEN:
599 		(void) fprintf(stdout, gettext("\tdata.state:\t\tListen\n"));
600 		break;
601 	case NDMP_DT_STATE_CONNECTED:
602 		(void) fprintf(stdout, gettext("\tdata.state:\t\tConnected\n"));
603 		break;
604 	default:
605 		(void) fprintf(stdout,
606 		    gettext("\tdata.state:\t\tUnknown (0x%x)\n"),
607 		    si->nsi_data.nd_state);
608 	}
609 
610 	switch (si->nsi_data.nd_halt_reason) {
611 	case NDMP_DT_HALT_NA:
612 		(void) fprintf(stdout,
613 		    gettext("\tdata.halt reason:\tN/A\n"));
614 		break;
615 	case NDMP_DT_HALT_SUCCESSFUL:
616 		(void) fprintf(stdout,
617 		    gettext("\tdata.halt reason:\tSuccessful\n"));
618 		break;
619 	case NDMP_DT_HALT_ABORTED:
620 		(void) fprintf(stdout,
621 		    gettext("\tdata.halt reason:\tAborted\n"));
622 		break;
623 	case NDMP_DT_HALT_INTERNAL_ERROR:
624 		(void) fprintf(stdout,
625 		    gettext("\tdata.halt reason:\tInternal error\n"));
626 		break;
627 	case NDMP_DT_HALT_CONNECT_ERROR:
628 		(void) fprintf(stdout,
629 		    gettext("\tdata.halt reason:\tConnection error\n"));
630 		break;
631 	default:
632 		(void) fprintf(stdout,
633 		    gettext("\tdata.halt reason:\tUnknown (0x%x)\n"),
634 		    si->nsi_data.nd_halt_reason);
635 	}
636 
637 	switch (si->nsi_data.nd_state) {
638 	case NDMP_DT_STATE_IDLE:
639 		if (si->nsi_data.nd_sock != -1)
640 			(void) fprintf(stdout,
641 			    gettext("\tdata.data socket:\t%d\n"),
642 			    si->nsi_data.nd_sock);
643 		if (si->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock != -1)
644 			(void) fprintf(stdout,
645 			    gettext("\tdata.data socket:\t%d\n"),
646 			    si->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock);
647 		break;
648 	case NDMP_DT_STATE_LISTEN:
649 		(void) fprintf(stdout, gettext("\tdata.listen socket:\t%d\n"),
650 		    si->nsi_data.nd_nlist.nld_dt_v3.dv3_listen_sock);
651 		ndmp_tprint_addr(gettext("data.listen"),
652 		    si->nsi_data.nd_addr_type, si->nsi_data.nd_tcp_addr);
653 		break;
654 	case NDMP_DT_STATE_ACTIVE:
655 	case NDMP_DT_STATE_HALTED:
656 	case NDMP_DT_STATE_CONNECTED:
657 		(void) fprintf(stdout, gettext("\tdata.data socket:\t%d\n"),
658 		    si->nsi_data.nd_sock);
659 		ndmp_tprint_addr(gettext("data.data"),
660 		    si->nsi_data.nd_addr_type, si->nsi_data.nd_tcp_addr);
661 		break;
662 	}
663 
664 	(void) fprintf(stdout, gettext("\tdata.aborted:\t\t%s\n"),
665 	    B2S(si->nsi_data.nd_abort));
666 	(void) fprintf(stdout, gettext("\tdata.read offset:\t%llu\n"),
667 	    si->nsi_data.nd_read_offset);
668 	(void) fprintf(stdout, gettext("\tdata.read length:\t%llu\n"),
669 	    si->nsi_data.nd_read_length);
670 	(void) fprintf(stdout, gettext("\tdata.total size:\t%llu\n"),
671 	    si->nsi_data.nd_total_size);
672 	(void) fprintf(stdout,
673 	    gettext("\tdata.bytes processed:\t%lld\n"),
674 	    si->nsi_data.nd_nlist.nld_dt_v3.dv3_bytes_processed);
675 
676 	ndmp_print_env(si);
677 
678 	np = si->nsi_data.nd_nlist.nld_dt_v3.dv3_nlist;
679 	for (i = 0; np && i < si->nsi_data.nld_nlist_len; i++, np++) {
680 		(void) fprintf(stdout, gettext("\tdata.nlist[%d]:\tname:\n"),
681 		    i);
682 		if (np->nn3_opath)
683 			(void) fprintf(stdout,
684 			    gettext("\t\torig: \"%s\"\n"), np->nn3_opath);
685 		if (np->nn3_dpath)
686 			(void) fprintf(stdout,
687 			    gettext("\t\tdest: \"%s\"\n"), np->nn3_dpath);
688 		else
689 			(void) fprintf(stdout, gettext("\t\tdest:\n"));
690 		(void) fprintf(stdout,
691 		    gettext("\t\tnode: %lld\n"), np->nn3_node);
692 		(void) fprintf(stdout, gettext("\t\tfh_info: %lld\n"),
693 		    np->nn3_fh_info);
694 	}
695 }
696 
697 /*
698  * Print V3 connection info for given category.
699  */
700 static void
701 ndmp_connect_print_v3(int cat, ndmp_session_info_t *si)
702 {
703 	if (cat & NDMP_CAT_SCSI)
704 		ndmp_connect_print_scsi_v2(si);
705 	if (cat & NDMP_CAT_TAPE)
706 		ndmp_connect_print_tape_v2(si);
707 	if (cat & NDMP_CAT_MOVER)
708 		ndmp_connect_print_mover_v3(si);
709 	if (cat & NDMP_CAT_DATA)
710 		ndmp_connect_print_data_v3(si);
711 }
712 
713 /*
714  * Print the list of all active sessions to the clients.  For each version,
715  * call the appropriate print function.
716  */
717 static void
718 ndmp_connection_print(int cat, ndmp_session_info_t *si)
719 {
720 	switch (si->nsi_pver) {
721 	case NDMP_V2:
722 		ndmp_connect_print_conn(si);
723 		ndmp_connect_print_v2(cat, si);
724 		break;
725 	case NDMP_V3:
726 	case NDMP_V4:
727 		ndmp_connect_print_conn(si);
728 		ndmp_connect_print_v3(cat, si);
729 		break;
730 	default:
731 		(void) fprintf(stdout,
732 		    gettext("Invalid version %d"), si->nsi_pver);
733 	}
734 }
735 
736 /*
737  * Print the list of all active sessions to the clients.
738  */
739 void
740 ndmp_session_all_print(int cat, ndmp_session_info_t *si, size_t num)
741 {
742 	int i;
743 	ndmp_session_info_t *sp;
744 
745 	sp = si;
746 	for (i = 0; i < num; i++, sp++) {
747 		ndmp_connection_print(cat, sp);
748 		(void) fprintf(stdout, "\n");
749 	}
750 
751 	if (num == 0) {
752 		(void) fprintf(stdout, gettext("No active session.\n"));
753 	} else {
754 		(void) fprintf(stdout, gettext("%d active sessions.\n"), num);
755 	}
756 }
757 
758 /*
759  * Print the connection information for the given category.
760  */
761 void
762 ndmp_session_print(int cat,  ndmp_session_info_t *si)
763 {
764 	ndmp_connection_print(cat, si);
765 }
766 
767 void
768 ndmp_devinfo_print(ndmp_devinfo_t *dip, size_t size)
769 {
770 	int i;
771 
772 	if (dip == NULL) {
773 		(void) fprintf(stdout, gettext("No device attached.\n"));
774 		return;
775 	}
776 
777 	for (i = 0; i < size; i++, dip++) {
778 		/*
779 		 * Don't print dead links.
780 		 */
781 		if ((access(dip->nd_name, F_OK) == -1) && (errno == ENOENT))
782 			continue;
783 		switch (dip->nd_dev_type) {
784 		case NDMP_SINQ_TAPE_ROBOT:
785 			(void) fprintf(stdout, gettext("Robot (Changer):\n"));
786 			break;
787 		case NDMP_SINQ_SEQ_ACCESS_DEVICE:
788 			(void) fprintf(stdout, gettext("Tape drive(s):\n"));
789 			break;
790 		}
791 		if (dip->nd_name)
792 			(void) fprintf(stdout,
793 			    gettext("\tName      : %s\n"), dip->nd_name);
794 		(void) fprintf(stdout,
795 		    gettext("\tLUN #     : %d\n"), dip->nd_lun);
796 		(void) fprintf(stdout,
797 		    gettext("\tSCSI ID # : %d\n"), dip->nd_sid);
798 		if (dip->nd_vendor)
799 			(void) fprintf(stdout,
800 			    gettext("\tVendor    : %s\n"), dip->nd_vendor);
801 		if (dip->nd_product)
802 			(void) fprintf(stdout,
803 			    gettext("\tProduct   : %s\n"), dip->nd_product);
804 		if (dip->nd_revision)
805 			(void) fprintf(stdout,
806 			    gettext("\tRevision  : %s\n"), dip->nd_revision);
807 		if (dip->nd_serial)
808 			(void) fprintf(stdout,
809 			    gettext("\tSerial    : %s\n"), dip->nd_serial);
810 		if (dip->nd_wwn)
811 			(void) fprintf(stdout,
812 			    gettext("\tWWN       : %s\n"), dip->nd_wwn);
813 		(void) fprintf(stdout, "\n");
814 	}
815 }
816