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