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 <stdlib.h>
40 #include <ctype.h>
41 #include <stdio.h>
42 #include <limits.h>
43 #include <string.h>
44 #include <time.h>
45 #include <sys/types.h>
46 #include <sys/acl.h>
47 #include <utime.h>
48 #include <unistd.h>
49 #include <pthread.h>
50 #include <archives.h>
51 #include <priv.h>
52 #include <tlm.h>
53 #include <libzfs.h>
54 #include <ndmpd_prop.h>
55 #include "tlm_proto.h"
56 
57 
58 #define	PM_EXACT_OR_CHILD(m)	((m) == PM_EXACT || (m) == PM_CHILD)
59 
60 typedef boolean_t name_match_fp_t(char *s, char *t);
61 
62 static void set_acl(char *name,
63     tlm_acls_t *acls);
64 static long restore_file(int *fp,
65     char *real_name,
66     long size,
67     longlong_t huge_size,
68     tlm_acls_t *,
69     boolean_t want_this_file,
70     tlm_cmd_t *,
71     tlm_job_stats_t *);
72 static long restore_xattr_hdr(int *fp,
73     char *name,
74     char *fname,
75     long size,
76     tlm_acls_t *acls,
77     tlm_cmd_t *local_commands,
78     tlm_job_stats_t *job_stats);
79 static int get_long_name(int lib,
80     int drv,
81     long recsize,
82     char *name,
83     long *buf_spot,
84     tlm_cmd_t *local_commands);
85 static int get_humongus_file_header(int lib,
86     int	drv,
87     long recsize,
88     longlong_t *size,
89     char *name,
90     tlm_cmd_t *);
91 static int create_directory(char *dir,
92     tlm_job_stats_t *);
93 static int create_hard_link(char *name,
94     char *link,
95     tlm_acls_t *,
96     tlm_job_stats_t *);
97 static int create_sym_link(char *dst,
98     char *target,
99     tlm_acls_t *,
100     tlm_job_stats_t *);
101 static int create_fifo(char *name,
102     tlm_acls_t *);
103 static long load_acl_info(int lib,
104     int	drv,
105     long size,
106     tlm_acls_t *,
107     long *acl_spot,
108     tlm_cmd_t *);
109 static char *get_read_buffer(int want,
110     int	*error,
111     int	*actual_size,
112     tlm_cmd_t *);
113 static boolean_t wildcard_enabled(void);
114 static boolean_t is_file_wanted(char *name,
115     char **sels,
116     char **exls,
117     int	flags,
118     int	*mchtype,
119     int	*pos);
120 static char *catnames(struct rs_name_maker *rnp,
121     char *buf,
122     int	pos,
123     char *path);
124 
125 static char *rs_new_name(struct rs_name_maker *rnp,
126     char *real_name,
127     int pos,
128     char *path);
129 
130 typedef struct stack_ent {
131 	char *se_name;
132 	tlm_acls_t se_acls;
133 } stack_ent_t;
134 
135 
136 /*
137  * dtree_push
138  */
139 int
140 dtree_push(cstack_t *stp, char *nmp, tlm_acls_t *acls)
141 {
142 	int len;
143 	stack_ent_t *sp;
144 
145 	sp = ndmp_malloc(sizeof (stack_ent_t));
146 	if (!sp || !nmp || !acls) {
147 		free(sp);
148 		return (-1);
149 	}
150 
151 	len = strlen(nmp) + 1;
152 	sp->se_name = ndmp_malloc(len);
153 	if (!sp->se_name) {
154 		free(sp);
155 		return (-1);
156 	}
157 
158 	(void) strlcpy(sp->se_name, nmp, len);
159 	(void) memcpy(&sp->se_acls, acls, sizeof (*acls));
160 
161 	return (cstack_push(stp, (void *)sp, sizeof (*sp)));
162 }
163 
164 /*
165  * dtree_pop
166  */
167 int
168 dtree_pop(cstack_t *stp)
169 {
170 	int err;
171 	stack_ent_t *sp;
172 
173 	err = cstack_pop(stp, (void **)&sp, (void *)NULL);
174 	if (err)
175 		return (-1);
176 
177 	set_acl(sp->se_name, &sp->se_acls);
178 
179 	free(sp->se_name);
180 	free(sp);
181 	return (err);
182 }
183 
184 
185 /*
186  * dtree_peek
187  */
188 char *
189 dtree_peek(cstack_t *stp)
190 {
191 	int err;
192 	stack_ent_t *sp;
193 
194 	err = cstack_top(stp, (void **)&sp, (void *)NULL);
195 	if (err)
196 		return (NULL);
197 
198 	return (sp->se_name);
199 }
200 
201 /*
202  * NBU and EBS may not send us the correct file list containing hardlinks
203  * during a DAR restore, e.g. they appear always send the first name
204  * associated with an inode, even if other link names were
205  * selected for the restore.  As a workaround, we use the file name entry
206  * in sels[] (ignore the name in the tar header) as restore target.
207  */
208 static char *
209 rs_darhl_new_name(struct rs_name_maker *rnp, char *name, char **sels, int *pos,
210     char *longname)
211 {
212 	int x;
213 
214 	for (x = 0; sels[x] != NULL; x++) {
215 		if (strcmp(sels[x], " ")) {
216 			*pos = x;
217 			(void) strlcpy(longname, sels[x], TLM_MAX_PATH_NAME);
218 			NDMP_LOG(LOG_DEBUG,
219 			    "to replace hardlink name [%s], pos [%d]",
220 			    longname, *pos);
221 
222 			return (rs_new_name(rnp, name, *pos, longname));
223 		}
224 	}
225 
226 	return (NULL);
227 }
228 
229 
230 /*
231  * Main dir restore funciton for tar
232  */
233 int
234 tar_getdir(tlm_commands_t *commands,
235     tlm_cmd_t *local_commands,
236     tlm_job_stats_t *job_stats,
237     struct rs_name_maker *rnp,
238     int	lib,
239     int	drv,
240     char **sels, /* what to get off the tape */
241     char **exls, /* what to leave behind */
242     int	flags,
243     int	DAR, struct hardlink_q *hardlink_q)
244 {
245 	int	fp = 0;		/* file being restored ... */
246 				/*  ...need to preserve across volume changes */
247 	tlm_acls_t *acls;	/* file access info */
248 	char	*longname;
249 	boolean_t is_long_name = FALSE;
250 	char	*longlink;
251 	char	*hugename;
252 	longlong_t huge_size = 0;	/* size of a HUGE file */
253 	long	acl_spot;		/* any ACL info on the next volume */
254 	long	file_size;		/* size of file to restore */
255 	long	size_left = 0;		/* need this after volume change */
256 	int	last_action = 0;	/* what we are doing at EOT */
257 	boolean_t multi_volume = FALSE;	/* is this a multi-volume switch ? */
258 	int	chk_rv;			/* scratch area */
259 
260 	int	mchtype, pos;
261 					/*
262 					 * if an exact match is found for
263 					 * restore and its position in the
264 					 * selections list
265 					 */
266 	int	nzerohdr;		/* the number of empty tar headers */
267 	boolean_t break_flg;		/* exit the while loop */
268 	int	rv;
269 	long nm_end, lnk_end;
270 	char	*name, *nmp;
271 	cstack_t *stp;
272 	char 	*bkpath;
273 	char 	*parentlnk;
274 	/*
275 	 * The directory where temporary files may be created during a partial
276 	 * non-DAR restore of hardlinks.  It is intended to be initialized by
277 	 * an environment variable that can be set by user.
278 	 *
279 	 * It is not initialized for now.   We keep it here for future use.
280 	 */
281 	char *tmplink_dir = NULL;
282 
283 	/*
284 	 * startup
285 	 */
286 
287 	longname = ndmp_malloc(TLM_MAX_PATH_NAME);
288 	longlink = ndmp_malloc(TLM_MAX_PATH_NAME);
289 	hugename = ndmp_malloc(TLM_MAX_PATH_NAME);
290 	parentlnk = ndmp_malloc(TLM_MAX_PATH_NAME);
291 	name = ndmp_malloc(TLM_MAX_PATH_NAME);
292 	acls = ndmp_malloc(sizeof (tlm_acls_t));
293 	stp = cstack_new();
294 	if (longname == NULL || longlink == NULL || hugename == NULL ||
295 	    name == NULL || acls == NULL || stp == NULL || parentlnk == NULL) {
296 		cstack_delete(stp);
297 		free(longname);
298 		free(longlink);
299 		free(hugename);
300 		free(parentlnk);
301 		free(name);
302 		free(acls);
303 		return (-TLM_NO_SCRATCH_SPACE);
304 	}
305 
306 	acl_spot = 0;
307 	*hugename = '\0';
308 	*parentlnk = '\0';
309 	nm_end = 0;
310 	*longname = '\0';
311 	lnk_end = 0;
312 	*longlink = '\0';
313 	(void) memset(acls, 0, sizeof (tlm_acls_t));
314 	if (IS_SET(flags, RSFLG_OVR_ALWAYS)) {
315 		acls->acl_overwrite = TRUE;
316 		NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_ALWAYS");
317 	} else if (IS_SET(flags, RSFLG_OVR_UPDATE)) {
318 		acls->acl_update = TRUE;
319 		NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_UPDATE");
320 	}
321 
322 	/*
323 	 * work
324 	 */
325 	rv = 0;
326 	nzerohdr = 0;
327 	break_flg = FALSE;
328 	while (commands->tcs_writer != TLM_ABORT &&
329 	    local_commands->tc_writer != TLM_STOP) {
330 		tlm_tar_hdr_t fake_tar_hdr;
331 		char	*file_name;
332 		char	*link_name;
333 		int	erc;
334 		int	actual_size;
335 		boolean_t want_this_file;
336 		int	want = sizeof (tlm_tar_hdr_t);
337 		tlm_tar_hdr_t *tar_hdr;
338 
339 		/* The inode of an LF_LINK type. */
340 		unsigned long hardlink_inode = 0;
341 
342 		/*
343 		 * Indicate whether a file with the same inode has been
344 		 * restored.
345 		 */
346 		int hardlink_done = 0;
347 
348 		/* The path of the restored hardlink file */
349 		char *hardlink_target = NULL;
350 		int is_hardlink = 0;
351 
352 		/*
353 		 * Whether a temporary file should be created for restoring
354 		 * hardlink.
355 		 */
356 		int hardlink_tmp_file = 0;
357 		char *hardlink_tmp_name = ".tmphlrsnondar";
358 
359 		/* used to make up hardlink_tmp_name */
360 		static int hardlink_tmp_idx = 0;
361 
362 		if (break_flg) {
363 			NDMP_LOG(LOG_DEBUG,
364 			    "Exiting writer thread drive %d", drv);
365 			break;
366 		}
367 
368 		if (multi_volume) {
369 			NDMP_LOG(LOG_DEBUG, "multi_volume %c %d",
370 			    last_action, size_left);
371 
372 			/*
373 			 * the previous volume is out of data
374 			 * and is back in the rack, a new tape
375 			 * is loaded and ready to read.
376 			 *
377 			 * We need to pick up where we left off.
378 			 */
379 			(void) memset(&fake_tar_hdr, 0, sizeof (fake_tar_hdr));
380 			file_size = size_left;
381 			tar_hdr = &fake_tar_hdr;
382 			tar_hdr->th_linkflag = last_action;
383 
384 			multi_volume = FALSE;
385 			last_action = 0;
386 		} else {
387 			tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(want,
388 			    &erc, &actual_size, local_commands);
389 
390 			if (tar_hdr == NULL) {
391 				rv = -1;
392 				continue;
393 			}
394 
395 			/*
396 			 * we can ignore read errors here because
397 			 *   1) they are logged by Restore Reader
398 			 *   2) we are not doing anything important here
399 			 *	just looking for the next work record.
400 			 */
401 			if (actual_size < want) {
402 				/*
403 				 * EOF hits here
404 				 *
405 				 * wait for another buffer to come along
406 				 * or until the Reader thread tells us
407 				 * that no more tapes will be loaded ...
408 				 * time to stop.
409 				 */
410 				continue;
411 			}
412 
413 			/*
414 			 * check for "we are lost"
415 			 */
416 			chk_rv = tlm_vfy_tar_checksum(tar_hdr);
417 			if (chk_rv == 0) {
418 				/* one of the end of tar file marks */
419 				if (++nzerohdr >= 2) {
420 					NDMP_LOG(LOG_DEBUG,
421 					    "nzerohdr %d, breaking",
422 					    nzerohdr);
423 					/* end of tar file */
424 					break;
425 				}
426 				NDMP_LOG(LOG_DEBUG, "nzerohdr %d, continuing",
427 				    nzerohdr);
428 				continue;
429 			} else if (chk_rv < 0) {
430 				nzerohdr = 0;
431 				/* skip this record */
432 				continue;
433 			}
434 			nzerohdr = 0;
435 
436 			/*
437 			 * When files are spanned to the next tape, the
438 			 * information of the acls must not be over-written
439 			 * by the information of the LF_MULTIVOL and LF_VOLHDR
440 			 * header, whose information is irrelevant to the file.
441 			 * The information of the original header must be
442 			 * kept in the 'acl'.
443 			 */
444 			if (tar_hdr->th_linkflag != LF_MULTIVOL &&
445 			    tar_hdr->th_linkflag != LF_VOLHDR) {
446 				acls->acl_attr.st_mode =
447 				    oct_atoi(tar_hdr->th_mode);
448 				acls->acl_attr.st_size =
449 				    oct_atoi(tar_hdr->th_size);
450 				acls->acl_attr.st_uid =
451 				    oct_atoi(tar_hdr->th_uid);
452 				acls->acl_attr.st_gid =
453 				    oct_atoi(tar_hdr->th_gid);
454 				acls->acl_attr.st_mtime =
455 				    oct_atoi(tar_hdr->th_mtime);
456 				file_size = oct_atoi(tar_hdr->th_size);
457 				acl_spot = 0;
458 				last_action = tar_hdr->th_linkflag;
459 			}
460 		}
461 
462 		NDMP_LOG(LOG_DEBUG, "n [%s] f [%c] s %lld m %o u %d g %d t %d",
463 		    tar_hdr->th_name, tar_hdr->th_linkflag,
464 		    acls->acl_attr.st_size, acls->acl_attr.st_mode,
465 		    acls->acl_attr.st_uid, acls->acl_attr.st_gid,
466 		    acls->acl_attr.st_mtime);
467 
468 		switch (tar_hdr->th_linkflag) {
469 		case LF_MULTIVOL:
470 			multi_volume = TRUE;
471 			break;
472 		case LF_LINK:
473 			is_hardlink = 1;
474 			hardlink_inode =
475 			    oct_atoi(tar_hdr->th_shared.th_hlink_ino);
476 
477 			/*
478 			 * Check if we have restored a link with the same inode
479 			 * If the inode is 0, we have to restore it as a
480 			 * regular file.
481 			 */
482 			if (hardlink_inode) {
483 				hardlink_done = !hardlink_q_get(hardlink_q,
484 				    hardlink_inode, 0, &hardlink_target);
485 			}
486 
487 			if (hardlink_done) {
488 				NDMP_LOG(LOG_DEBUG,
489 				    "found hardlink, inode = %u, target = [%s]",
490 				    hardlink_inode,
491 				    hardlink_target? hardlink_target : "--");
492 
493 				/* create a hardlink to hardlink_target */
494 				file_name = (*longname == 0) ?
495 				    tar_hdr->th_name : longname;
496 				if (!is_file_wanted(file_name, sels, exls,
497 				    flags, &mchtype, &pos)) {
498 					nmp = NULL;
499 					/*
500 					 * This means that DMA did not send us
501 					 * the correct fh_info for the file
502 					 * in restore list.  We use the file
503 					 * name entry in sels[] (ignore the
504 					 * name in the tar header) as restore
505 					 * target.
506 					 */
507 					if (DAR) {
508 						nmp = rs_darhl_new_name(rnp,
509 						    name, sels, &pos,
510 						    file_name);
511 					}
512 				} else {
513 					nmp = rs_new_name(rnp, name, pos,
514 					    file_name);
515 					if (!nmp) {
516 						NDMP_LOG(LOG_DEBUG,
517 						    "can't make name for %s",
518 						    longname);
519 					}
520 				}
521 
522 				if (nmp) {
523 					if (hardlink_target) {
524 						erc = create_hard_link(
525 						    hardlink_target, nmp,
526 						    acls, job_stats);
527 						if (erc == 0) {
528 							(void)
529 							    tlm_entry_restored(
530 							    job_stats,
531 							    file_name, pos);
532 							NDMP_LOG(LOG_DEBUG,
533 							    "restored %s -> %s",
534 							    nmp,
535 							    hardlink_target);
536 						}
537 					} else {
538 						NDMP_LOG(LOG_DEBUG,
539 						    "no target for hardlink %s",
540 						    nmp);
541 					}
542 
543 					name[0] = 0;
544 					is_long_name = FALSE;
545 				}
546 
547 				nm_end = 0;
548 				longname[0] = 0;
549 				lnk_end = 0;
550 				longlink[0] = 0;
551 
552 				break;
553 			}
554 			/* otherwise fall through, restore like a normal file */
555 			/*FALLTHROUGH*/
556 		case LF_OLDNORMAL:
557 			/*
558 			 * check for TAR's end-of-tape method
559 			 * of zero filled records.
560 			 */
561 			if (tar_hdr->th_name[0] == 0) {
562 				break;
563 			}
564 			/*
565 			 * otherwise fall through,
566 			 * this is an old style normal file header
567 			 */
568 			/*FALLTHROUGH*/
569 		case LF_NORMAL:
570 		case LF_CONTIG:
571 			job_stats->js_files_so_far++;
572 			if (*hugename != 0) {
573 				(void) strlcpy(longname, hugename,
574 				    TLM_MAX_PATH_NAME);
575 			} else if (*longname == 0) {
576 				if (tar_hdr->th_name[0] != '/') {
577 					/*
578 					 * check for old tar format, it
579 					 * does not have a leading "/"
580 					 */
581 					longname[0] = '/';
582 					longname[1] = 0;
583 					(void) strlcat(longname,
584 					    tar_hdr->th_name,
585 					    TLM_MAX_PATH_NAME);
586 				} else {
587 					(void) strlcpy(longname,
588 					    tar_hdr->th_name,
589 					    TLM_MAX_PATH_NAME);
590 				}
591 			}
592 
593 			want_this_file = is_file_wanted(longname, sels, exls,
594 			    flags, &mchtype, &pos);
595 			if (!want_this_file) {
596 				nmp = NULL;
597 				/*
598 				 * This means that DMA did not send us valid
599 				 * fh_info for the file in restore list.  We
600 				 * use the file name entry in sels[] (ignore
601 				 * the name in the tar header) as restore
602 				 * target.
603 				 */
604 				if (DAR && (tar_hdr->th_linkflag == LF_LINK)) {
605 					nmp = rs_darhl_new_name(rnp, name,
606 					    sels, &pos, longname);
607 
608 					if (nmp) {
609 						want_this_file = TRUE;
610 						mchtype = PM_EXACT;
611 					} else {
612 						break_flg = TRUE;
613 						break;
614 					}
615 				}
616 			} else {
617 				nmp = rs_new_name(rnp, name, pos, longname);
618 				if (!nmp)
619 					want_this_file = FALSE;
620 			}
621 
622 			if (nmp)
623 				(void) strlcpy(parentlnk, nmp, strlen(nmp) + 1);
624 
625 			/*
626 			 * For a hardlink, even if it's not asked to be
627 			 * restored, we restore it to a temporary location,
628 			 * in case other links to the same file need to be
629 			 * restored later.
630 			 *
631 			 * The temp files are created in tmplink_dir, with
632 			 * names like ".tmphlrsnondar*".  They are cleaned up
633 			 * at the completion of a restore.  However, if a
634 			 * restore were interrupted, e.g. by a system reboot,
635 			 * they would have to be cleaned up manually in order
636 			 * for the disk space to be freed.
637 			 *
638 			 * If tmplink_dir is NULL, no temperorary files are
639 			 * created during a restore.  This may result in some
640 			 * hardlinks not being restored during a partial
641 			 * restore.
642 			 */
643 			if (is_hardlink && !DAR && !want_this_file && !nmp) {
644 				if (tmplink_dir) {
645 					(void) snprintf(name, TLM_MAX_PATH_NAME,
646 					    "%s/%s_%d", tmplink_dir,
647 					    hardlink_tmp_name,
648 					    hardlink_tmp_idx);
649 					nmp = name;
650 
651 					hardlink_tmp_idx++;
652 					hardlink_tmp_file = 1;
653 					want_this_file = TRUE;
654 					NDMP_LOG(LOG_DEBUG,
655 					    "To restore temp hardlink file %s.",
656 					    nmp);
657 				} else {
658 					NDMP_LOG(LOG_DEBUG,
659 					    "No tmplink_dir specified.");
660 				}
661 			}
662 
663 			size_left = restore_file(&fp, nmp, file_size,
664 			    huge_size, acls, want_this_file, local_commands,
665 			    job_stats);
666 
667 			/*
668 			 * In the case of non-DAR, we have to record the first
669 			 * link for an inode that has multiple links. That's
670 			 * the only link with data records actually backed up.
671 			 * In this way, when we run into the other links, they
672 			 * will be treated as links, and we won't go to look
673 			 * for the data records to restore.  This is not a
674 			 * problem for DAR, where DMA tells the tape where
675 			 * to locate the data records.
676 			 */
677 			if (is_hardlink && !DAR) {
678 				if (hardlink_q_add(hardlink_q, hardlink_inode,
679 				    0, nmp, hardlink_tmp_file))
680 					NDMP_LOG(LOG_DEBUG,
681 					    "failed to add (%u, %s) to HL q",
682 					    hardlink_inode, nmp);
683 			}
684 
685 			/* remove / reverse the temporary stuff */
686 			if (hardlink_tmp_file) {
687 				nmp = NULL;
688 				want_this_file = FALSE;
689 				hardlink_tmp_file = 0;
690 			}
691 
692 			/*
693 			 * Check if it is time to set the attribute
694 			 * of the restored directory
695 			 */
696 			while (nmp && ((bkpath = dtree_peek(stp)) != NULL)) {
697 				if (strstr(nmp, bkpath))
698 					break;
699 
700 				(void) dtree_pop(stp);
701 			}
702 
703 			NDMP_LOG(LOG_DEBUG, "sizeleft %s %d, %lld", longname,
704 			    size_left, huge_size);
705 
706 			if (size_left == -TLM_STOP) {
707 				break_flg = TRUE;
708 				rv = -1;
709 				commands->tcs_reader = TLM_ABORT;
710 				NDMP_LOG(LOG_DEBUG, "restoring [%s] failed",
711 				    longname);
712 				break;
713 			}
714 
715 			if (want_this_file) {
716 				job_stats->js_bytes_total += file_size;
717 				job_stats->js_files_total++;
718 			}
719 
720 			huge_size -= file_size;
721 			if (huge_size < 0) {
722 				huge_size = 0;
723 			}
724 			if (size_left == 0 && huge_size == 0) {
725 				if (PM_EXACT_OR_CHILD(mchtype)) {
726 					(void) tlm_entry_restored(job_stats,
727 					    longname, pos);
728 
729 					/*
730 					 * Add an entry to hardlink_q to record
731 					 * this hardlink.
732 					 */
733 					if (is_hardlink) {
734 						NDMP_LOG(LOG_DEBUG,
735 						    "Restored hardlink file %s",
736 						    nmp);
737 
738 						if (DAR) {
739 							(void) hardlink_q_add(
740 							    hardlink_q,
741 							    hardlink_inode, 0,
742 							    nmp, 0);
743 						}
744 					}
745 				}
746 
747 				nm_end = 0;
748 				longname[0] = 0;
749 				lnk_end = 0;
750 				longlink[0] = 0;
751 				hugename[0] = 0;
752 				name[0] = 0;
753 				is_long_name = FALSE;
754 			}
755 			break;
756 		case LF_XATTR:
757 			file_name = (*longname == 0) ? tar_hdr->th_name :
758 			    longname;
759 
760 			size_left = restore_xattr_hdr(&fp, parentlnk,
761 			    file_name, file_size, acls, local_commands,
762 			    job_stats);
763 
764 			break;
765 		case LF_SYMLINK:
766 			file_name = (*longname == 0) ? tar_hdr->th_name :
767 			    longname;
768 			link_name = (*longlink == 0) ?
769 			    tar_hdr->th_linkname : longlink;
770 			NDMP_LOG(LOG_DEBUG, "file_name[%s]", file_name);
771 			NDMP_LOG(LOG_DEBUG, "link_name[%s]", link_name);
772 			if (is_file_wanted(file_name, sels, exls, flags,
773 			    &mchtype, &pos)) {
774 				nmp = rs_new_name(rnp, name, pos, file_name);
775 				if (nmp) {
776 					erc = create_sym_link(nmp, link_name,
777 					    acls, job_stats);
778 					if (erc == 0 &&
779 					    PM_EXACT_OR_CHILD(mchtype))
780 						(void) tlm_entry_restored(
781 						    job_stats, file_name, pos);
782 					name[0] = 0;
783 				}
784 			}
785 			nm_end = 0;
786 			longname[0] = 0;
787 			lnk_end = 0;
788 			longlink[0] = 0;
789 			break;
790 		case LF_DIR:
791 			file_name = *longname == 0 ? tar_hdr->th_name :
792 			    longname;
793 			if (is_file_wanted(file_name, sels, exls, flags,
794 			    &mchtype, &pos)) {
795 				nmp = rs_new_name(rnp, name, pos, file_name);
796 				if (nmp && mchtype != PM_PARENT) {
797 					(void) strlcpy(parentlnk, nmp,
798 					    strlen(nmp));
799 					erc = create_directory(nmp, job_stats);
800 					if (erc == 0 &&
801 					    PM_EXACT_OR_CHILD(mchtype))
802 						(void) tlm_entry_restored(
803 						    job_stats, file_name, pos);
804 					/*
805 					 * Check if it is time to set
806 					 * the attribute of the restored
807 					 * directory
808 					 */
809 					while ((bkpath = dtree_peek(stp))
810 					    != NULL) {
811 						if (strstr(nmp, bkpath))
812 							break;
813 						(void) dtree_pop(stp);
814 					}
815 
816 					(void) dtree_push(stp, nmp, acls);
817 					name[0] = 0;
818 				}
819 			}
820 			nm_end = 0;
821 			longname[0] = 0;
822 			lnk_end = 0;
823 			longlink[0] = 0;
824 			break;
825 		case LF_FIFO:
826 			file_name = *longname == 0 ? tar_hdr->th_name :
827 			    longname;
828 			if (is_file_wanted(file_name, sels, exls, flags,
829 			    &mchtype, &pos)) {
830 				nmp = rs_new_name(rnp, name, pos, file_name);
831 				if (nmp) {
832 					erc = create_fifo(nmp, acls);
833 					if (erc == 0 &&
834 					    PM_EXACT_OR_CHILD(mchtype))
835 						(void) tlm_entry_restored(
836 						    job_stats, file_name, pos);
837 					name[0] = 0;
838 				}
839 			}
840 			nm_end = 0;
841 			longname[0] = 0;
842 			lnk_end = 0;
843 			longlink[0] = 0;
844 			break;
845 		case LF_LONGLINK:
846 			file_size = min(file_size, TLM_MAX_PATH_NAME - lnk_end);
847 			file_size = max(0, file_size);
848 			size_left = get_long_name(lib, drv, file_size, longlink,
849 			    &lnk_end, local_commands);
850 
851 			if (size_left != 0)
852 				NDMP_LOG(LOG_DEBUG,
853 				    "fsize %d sleft %d lnkend %d",
854 				    file_size, size_left, lnk_end);
855 			break;
856 		case LF_LONGNAME:
857 			file_size = min(file_size, TLM_MAX_PATH_NAME - nm_end);
858 			file_size = max(0, file_size);
859 			size_left = get_long_name(lib, drv, file_size, longname,
860 			    &nm_end, local_commands);
861 
862 			if (size_left != 0)
863 				NDMP_LOG(LOG_DEBUG,
864 				    "fsize %d sleft %d nmend %d",
865 				    file_size, size_left, nm_end);
866 			is_long_name = TRUE;
867 			break;
868 		case LF_ACL:
869 			size_left = load_acl_info(lib, drv, file_size, acls,
870 			    &acl_spot, local_commands);
871 			break;
872 		case LF_VOLHDR:
873 			break;
874 		case LF_HUMONGUS:
875 			(void) memset(hugename, 0, TLM_MAX_PATH_NAME);
876 			(void) get_humongus_file_header(lib, drv, file_size,
877 			    &huge_size, hugename, local_commands);
878 			break;
879 		default:
880 			break;
881 
882 		}
883 
884 		/*
885 		 * If the restore is running using DAR we should check for
886 		 * long file names and HUGE file sizes.
887 		 */
888 		if (DAR && tar_hdr->th_linkflag != LF_ACL &&
889 		    !huge_size && !is_long_name)
890 			break;
891 	}
892 
893 	/*
894 	 * tear down
895 	 */
896 	if (fp != 0) {
897 		(void) close(fp);
898 	}
899 	while (dtree_pop(stp) != -1)
900 		;
901 	cstack_delete(stp);
902 	free(acls);
903 	free(longname);
904 	free(parentlnk);
905 	free(longlink);
906 	free(hugename);
907 	free(name);
908 	return (rv);
909 }
910 
911 /*
912  * Main file restore function for tar (should run as a thread)
913  */
914 int
915 tar_getfile(tlm_backup_restore_arg_t *argp)
916 {
917 	tlm_job_stats_t	*job_stats;
918 	char	**sels;		/* list of files desired */
919 	char	**exls;		/* list of files not wanted */
920 	char	*dir;		/* where to restore the files */
921 	char	job[TLM_MAX_BACKUP_JOB_NAME+1];
922 				/* the restore job name */
923 	int	erc;		/* error return codes */
924 	int	flags;
925 	struct	rs_name_maker rn;
926 	tlm_commands_t *commands;
927 	tlm_cmd_t *local_commands;
928 	char *list = NULL;
929 
930 	commands = argp->ba_commands;
931 	local_commands = argp->ba_cmd;
932 
933 	flags = 0;
934 
935 	dir = ndmp_malloc(TLM_MAX_PATH_NAME);
936 	if (dir == NULL) {
937 		local_commands->tc_reader = TLM_STOP;
938 		(void) pthread_barrier_wait(&argp->ba_barrier);
939 		return (-1);
940 	}
941 
942 	(void) strlcpy(job, argp->ba_job, TLM_MAX_BACKUP_JOB_NAME+1);
943 	(void) strlcpy(dir, argp->ba_dir, TLM_MAX_PATH_NAME);
944 
945 	flags |= RSFLG_OVR_ALWAYS;
946 	flags |= RSFLG_IGNORE_CASE;
947 
948 	/*
949 	 * do not test for "dir" having no string, since that
950 	 * is a legal condition.  Restore to origional location
951 	 * will not have a restore directory.
952 	 */
953 	if (*job == '\0') {
954 		NDMP_LOG(LOG_DEBUG, "No job defined");
955 		local_commands->tc_reader = TLM_STOP;
956 		free(dir);
957 		(void) pthread_barrier_wait(&argp->ba_barrier);
958 		return (-1);
959 	}
960 
961 	sels = argp->ba_sels;
962 	if (sels == NULL) {
963 		local_commands->tc_reader = TLM_STOP;
964 		free(dir);
965 		(void) pthread_barrier_wait(&argp->ba_barrier);
966 		return (-1);
967 	}
968 	exls = &list;
969 
970 	tlm_log_list("selections", sels);
971 	tlm_log_list("exclusions", exls);
972 
973 	if (wildcard_enabled())
974 		flags |= RSFLG_MATCH_WCARD;
975 
976 	local_commands->tc_ref++;
977 	commands->tcs_writer_count++;
978 
979 	/*
980 	 * let the launcher continue
981 	 */
982 	(void) pthread_barrier_wait(&argp->ba_barrier);
983 
984 	job_stats = tlm_ref_job_stats(job);
985 
986 	rn.rn_fp = catnames;
987 	rn.rn_nlp = dir;
988 
989 	/*
990 	 * work
991 	 */
992 	NDMP_LOG(LOG_DEBUG, "start restore job %s", job);
993 	erc = tar_getdir(commands, local_commands, job_stats, &rn, 1, 1,
994 	    sels, exls, flags, 0, NULL);
995 
996 	/*
997 	 * teardown
998 	 */
999 	NDMP_LOG(LOG_DEBUG, "end restore job %s", job);
1000 	tlm_un_ref_job_stats(job);
1001 	tlm_release_list(sels);
1002 	tlm_release_list(exls);
1003 
1004 	commands->tcs_writer_count--;
1005 	local_commands->tc_reader = TLM_STOP;
1006 	tlm_release_reader_writer_ipc(local_commands);
1007 	free(dir);
1008 	return (erc);
1009 }
1010 
1011 /*
1012  * Creates the directories all the way down to the
1013  * end if they dont exist
1014  */
1015 int
1016 make_dirs(char *dir)
1017 {
1018 	char c;
1019 	char *cp, *end;
1020 	struct stat64 st;
1021 
1022 	cp = dir;
1023 	cp += strspn(cp, "/");
1024 	end = dir + strlen(dir);
1025 	do {
1026 		if (*cp == '\0' || *cp == '/') {
1027 			c = *cp;
1028 			*cp = '\0';
1029 			if (lstat64(dir, &st) < 0)
1030 				if (mkdir(dir, 0777) < 0) {
1031 					NDMP_LOG(LOG_DEBUG, "Error %d"
1032 					    " creating directory %s",
1033 					    errno, dir);
1034 					*cp = c;
1035 					return (-1);
1036 				}
1037 
1038 			*cp = c;
1039 		}
1040 	} while (++cp <= end);
1041 
1042 	return (0);
1043 }
1044 
1045 /*
1046  * Creates the directories leading to the given path
1047  */
1048 int
1049 mkbasedir(char *path)
1050 {
1051 	int rv;
1052 	char *cp;
1053 	struct stat64 st;
1054 
1055 	if (!path || !*path) {
1056 		NDMP_LOG(LOG_DEBUG, "Invalid argument");
1057 		return (-1);
1058 	}
1059 
1060 	cp = strrchr(path, '/');
1061 	if (cp)
1062 		*cp = '\0';
1063 	rv = lstat64(path, &st);
1064 	if (rv < 0)	/* need new directories */
1065 		rv = make_dirs(path);
1066 	if (cp)
1067 		*cp = '/';
1068 
1069 	return (rv);
1070 }
1071 
1072 
1073 /*
1074  * read the file off the tape back onto disk
1075  */
1076 static long
1077 restore_file(int *fp,
1078     char *real_name,
1079     long size,
1080     longlong_t huge_size,
1081     tlm_acls_t *acls,
1082     boolean_t want_this_file,
1083     tlm_cmd_t *local_commands,
1084     tlm_job_stats_t *job_stats)
1085 {
1086 	struct stat64	attr;
1087 
1088 	if (!real_name) {
1089 		if (want_this_file) {
1090 			NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
1091 			want_this_file = FALSE;
1092 		}
1093 	} else
1094 		NDMP_LOG(LOG_DEBUG, "new file[%s]", real_name);
1095 
1096 	/*
1097 	 * OK, some FM is creeping in here ...
1098 	 * int *fp is used to keep the
1099 	 * backup file channel open through
1100 	 * the interruption of EOT and
1101 	 * processing the headers of the
1102 	 * next tape.  So, if *fp is zero
1103 	 * then no file is open yet and all
1104 	 * is normal.  If *fp has a number
1105 	 * then we are returning after an
1106 	 * EOT break.
1107 	 *
1108 	 * *fp is now also open for HUGE files
1109 	 * that are put back in sections.
1110 	 */
1111 
1112 	if (*fp == 0 && want_this_file) {
1113 		int	erc_stat;
1114 
1115 		if (mkbasedir(real_name) < 0)
1116 			job_stats->js_errors++;
1117 
1118 		erc_stat = stat64(real_name, (struct stat64 *)&attr);
1119 		if (erc_stat < 0) {
1120 			/*EMPTY*/
1121 			/* new file */
1122 		} else if (acls->acl_overwrite) {
1123 			/*EMPTY*/
1124 			/* take this file no matter what */
1125 		} else if (acls->acl_update) {
1126 			if (attr.st_mtime < acls->acl_attr.st_mtime) {
1127 				/*EMPTY*/
1128 				/* tape is newer */
1129 			} else {
1130 				/* disk file is newer */
1131 				want_this_file = FALSE;
1132 			}
1133 		} else {
1134 			/*
1135 			 * no overwrite, no update,
1136 			 * do not ever replace old files.
1137 			 */
1138 			want_this_file = TRUE;
1139 		}
1140 		if (want_this_file) {
1141 
1142 			*fp = open(real_name, O_CREAT | O_WRONLY,
1143 			    S_IRUSR | S_IWUSR);
1144 			if (*fp == -1) {
1145 				NDMP_LOG(LOG_ERR,
1146 				    "Could not open %s for restore.",
1147 				    real_name);
1148 				NDMP_LOG(LOG_DEBUG,
1149 				    "fp=%d err=%d ", *fp, errno);
1150 				job_stats->js_errors++;
1151 				want_this_file = FALSE;
1152 				/*
1153 				 * we cannot return here,
1154 				 * the file is still on
1155 				 * the tape and must be
1156 				 * skipped over.
1157 				 */
1158 			}
1159 		}
1160 		(void) strlcpy(local_commands->tc_file_name, real_name,
1161 		    TLM_MAX_PATH_NAME);
1162 	}
1163 
1164 	/*
1165 	 * this is the size left in the next segment
1166 	 */
1167 	huge_size -= size;
1168 
1169 	/*
1170 	 * work
1171 	 */
1172 	while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
1173 		int	actual_size;
1174 		int	error;
1175 		char	*rec;
1176 		int	write_size;
1177 
1178 		/*
1179 		 * Use bytes_in_file field to tell reader the amount
1180 		 * of data still need to be read for this file.
1181 		 */
1182 		job_stats->js_bytes_in_file = size;
1183 
1184 		error = 0;
1185 		rec = get_read_buffer(size, &error, &actual_size,
1186 		    local_commands);
1187 		if (actual_size <= 0) {
1188 			NDMP_LOG(LOG_DEBUG,
1189 			    "RESTORE WRITER> error %d, actual_size %d",
1190 			    error, actual_size);
1191 
1192 			/* no more data for this file for now */
1193 			job_stats->js_bytes_in_file = 0;
1194 
1195 			return (size);
1196 		} else if (error) {
1197 			NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
1198 			    error, local_commands->tc_file_name);
1199 			break;
1200 		} else {
1201 			write_size = min(size, actual_size);
1202 			if (want_this_file) {
1203 				write_size = write(*fp, rec, write_size);
1204 			}
1205 			NS_ADD(wdisk, write_size);
1206 			NS_INC(wfile);
1207 			size -= write_size;
1208 		}
1209 	}
1210 
1211 	/* no more data for this file for now */
1212 	job_stats->js_bytes_in_file = 0;
1213 
1214 	/*
1215 	 * teardown
1216 	 */
1217 	if (*fp != 0 && huge_size <= 0) {
1218 		(void) close(*fp);
1219 		*fp = 0;
1220 		set_acl(real_name, acls);
1221 	}
1222 	return (0);
1223 }
1224 
1225 /*
1226  * Set the extended attributes file attribute
1227  */
1228 static void
1229 set_xattr(int fd, struct stat64 st)
1230 {
1231 	struct timeval times[2];
1232 
1233 	times[0].tv_sec = st.st_atime;
1234 	times[1].tv_sec = st.st_mtime;
1235 
1236 	(void) fchmod(fd, st.st_mode);
1237 	(void) fchown(fd, st.st_uid, st.st_gid);
1238 	(void) futimesat(fd, ".", times);
1239 }
1240 
1241 /*
1242  * read the extended attribute header and write
1243  * it to the file
1244  */
1245 static long
1246 restore_xattr_hdr(int *fp,
1247     char *name,
1248     char *fname,
1249     long size,
1250     tlm_acls_t *acls,
1251     tlm_cmd_t *local_commands,
1252     tlm_job_stats_t *job_stats)
1253 {
1254 	tlm_tar_hdr_t *tar_hdr;
1255 	struct xattr_hdr *xhdr;
1256 	struct xattr_buf *xbuf;
1257 	int namelen;
1258 	char *xattrname;
1259 	int actual_size;
1260 	int error;
1261 
1262 	if (!fname) {
1263 		NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
1264 	} else {
1265 		NDMP_LOG(LOG_DEBUG, "new xattr[%s]", fname);
1266 	}
1267 
1268 	error = 0;
1269 	xhdr = (struct xattr_hdr *)get_read_buffer(size, &error,
1270 	    &actual_size, local_commands);
1271 	if (error) {
1272 		NDMP_LOG(LOG_DEBUG,
1273 		    "Could not read xattr [%s:%s] for restore. ",
1274 		    name, fname);
1275 		job_stats->js_errors++;
1276 		return (0);
1277 	}
1278 
1279 	/* Check extended attribute header */
1280 	if (strcmp(xhdr->h_version, XATTR_ARCH_VERS) != 0) {
1281 		NDMP_LOG(LOG_DEBUG,
1282 		    "Unrecognized header format [%s]", xhdr->h_version);
1283 		return (0);
1284 	}
1285 	xbuf = (struct xattr_buf *)(((char *)xhdr) + sizeof (struct xattr_hdr));
1286 
1287 	(void) sscanf(xbuf->h_namesz, "%7d", &namelen);
1288 	xattrname = xbuf->h_names + strlen(xbuf->h_names) + 1;
1289 
1290 	if (*fp == 0) {
1291 		int fd;
1292 
1293 		fd = attropen(name, xattrname, O_CREAT | O_RDWR, 0755);
1294 		if (fd == -1) {
1295 			NDMP_LOG(LOG_DEBUG,
1296 			    "Could not open xattr [%s:%s] for restore.",
1297 			    name, xattrname);
1298 			NDMP_LOG(LOG_DEBUG, "err=%d ", errno);
1299 			job_stats->js_errors++;
1300 		}
1301 		(void) strlcpy(local_commands->tc_file_name, xattrname,
1302 		    TLM_MAX_PATH_NAME);
1303 		*fp = fd;
1304 	}
1305 
1306 	/* Get the actual extended attribute file */
1307 	tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(sizeof (*tar_hdr),
1308 	    &error, &actual_size, local_commands);
1309 	if (error) {
1310 		NDMP_LOG(LOG_DEBUG,
1311 		    "Could not read xattr data [%s:%s] for restore. ",
1312 		    fname, xattrname);
1313 		job_stats->js_errors++;
1314 		return (0);
1315 	}
1316 	acls->acl_attr.st_mode = oct_atoi(tar_hdr->th_mode);
1317 	acls->acl_attr.st_size = oct_atoi(tar_hdr->th_size);
1318 	acls->acl_attr.st_uid = oct_atoi(tar_hdr->th_uid);
1319 	acls->acl_attr.st_gid = oct_atoi(tar_hdr->th_gid);
1320 	acls->acl_attr.st_mtime = oct_atoi(tar_hdr->th_mtime);
1321 
1322 	size = acls->acl_attr.st_size;
1323 	while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
1324 		char	*rec;
1325 		int	write_size;
1326 
1327 		error = 0;
1328 		rec = get_read_buffer(size, &error, &actual_size,
1329 		    local_commands);
1330 		if (actual_size <= 0) {
1331 			NDMP_LOG(LOG_DEBUG,
1332 			    "RESTORE WRITER> error %d, actual_size %d",
1333 			    error, actual_size);
1334 
1335 			return (size);
1336 		} else if (error) {
1337 			NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
1338 			    error, local_commands->tc_file_name);
1339 			break;
1340 		} else {
1341 			write_size = min(size, actual_size);
1342 			write_size = write(*fp, rec, write_size);
1343 			NS_ADD(wdisk, write_size);
1344 			NS_INC(wfile);
1345 			size -= write_size;
1346 		}
1347 	}
1348 
1349 	if (*fp != 0) {
1350 		set_xattr(*fp, acls->acl_attr);
1351 		(void) close(*fp);
1352 		*fp = 0;
1353 	}
1354 	return (0);
1355 }
1356 
1357 /*
1358  * Match the name with the list
1359  */
1360 static int
1361 exact_find(char *name, char **list)
1362 {
1363 	boolean_t found;
1364 	int i;
1365 	char *cp;
1366 
1367 	found = FALSE;
1368 	for (i = 0; *list != NULL; list++, i++) {
1369 		cp = *list + strspn(*list, "/");
1370 		if (match(cp, name)) {
1371 			found = TRUE;
1372 			NDMP_LOG(LOG_DEBUG, "exact_find> found[%s]", cp);
1373 			break;
1374 		}
1375 	}
1376 
1377 	return (found);
1378 }
1379 
1380 /*
1381  * On error, return FALSE and prevent restoring(probably) unwanted data.
1382  */
1383 static int
1384 is_parent(char *parent, char *child, int flags)
1385 {
1386 	char tmp[TLM_MAX_PATH_NAME];
1387 	boolean_t rv;
1388 
1389 	if (IS_SET(flags, RSFLG_MATCH_WCARD)) {
1390 		if (!tlm_cat_path(tmp, parent, "*")) {
1391 			NDMP_LOG(LOG_DEBUG,
1392 			    "is_parent> path too long [%s]", parent);
1393 			rv = FALSE;
1394 		} else
1395 			rv = (match(tmp, child) != 0) ? TRUE : FALSE;
1396 	} else {
1397 		if (!tlm_cat_path(tmp, parent, "/")) {
1398 			NDMP_LOG(LOG_DEBUG,
1399 			    "is_parent> path too long [%s]", parent);
1400 			rv = FALSE;
1401 		} else
1402 			rv = (strncmp(tmp, child, strlen(tmp)) == 0) ?
1403 			    TRUE : FALSE;
1404 	}
1405 
1406 	return (rv);
1407 }
1408 
1409 /*
1410  * Used to match the filename inside the list
1411  */
1412 static boolean_t
1413 strexactcmp(char *s, char *t)
1414 {
1415 	return ((strcmp(s, t) == 0) ? TRUE : FALSE);
1416 }
1417 
1418 /*
1419  * Check if the file is needed to be restored
1420  */
1421 static boolean_t
1422 is_file_wanted(char *name,
1423     char **sels,
1424     char **exls,
1425     int flags,
1426     int *mchtype,
1427     int *pos)
1428 {
1429 	char *p_sel;
1430 	char *uc_name, *retry, *namep;
1431 	boolean_t found;
1432 	int i;
1433 	name_match_fp_t *cmp_fp;
1434 
1435 	if (name == NULL || sels == NULL || exls == NULL)
1436 		return (FALSE);
1437 
1438 	found = FALSE;
1439 	if (mchtype != NULL)
1440 		*mchtype = PM_NONE;
1441 	if (pos != NULL)
1442 		*pos = 0;
1443 
1444 	/*
1445 	 * For empty selection, restore everything
1446 	 */
1447 	if (*sels == NULL || **sels == '\0') {
1448 		NDMP_LOG(LOG_DEBUG, "is_file_wanted: Restore all");
1449 		return (TRUE);
1450 	}
1451 
1452 	uc_name = ndmp_malloc(TLM_MAX_PATH_NAME);
1453 	retry = ndmp_malloc(TLM_MAX_PATH_NAME);
1454 	if (uc_name == NULL || retry == NULL) {
1455 		free(uc_name);
1456 		free(retry);
1457 		return (FALSE);
1458 	}
1459 
1460 	if (IS_SET(flags, RSFLG_MATCH_WCARD))
1461 		cmp_fp = match;
1462 	else
1463 		cmp_fp = strexactcmp;
1464 
1465 	namep = name + strspn(name, "/");
1466 	if (IS_SET(flags, RSFLG_IGNORE_CASE)) {
1467 		(void) strlcpy(uc_name, namep, TLM_MAX_PATH_NAME);
1468 		(void) strupr(uc_name);
1469 		namep = uc_name;
1470 	}
1471 	NDMP_LOG(LOG_DEBUG, "is_file_wanted> flg: 0x%x name: [%s]",
1472 	    flags, name);
1473 
1474 	for (i = 0; *sels != NULL; sels++, i++) {
1475 		p_sel = *sels + strspn(*sels, "/");
1476 
1477 		/*
1478 		 * Try exact match.
1479 		 */
1480 		if ((*cmp_fp)(p_sel, namep)) {
1481 			NDMP_LOG(LOG_DEBUG, "match1> pos: %d [%s][%s]",
1482 			    i, p_sel, name);
1483 			found = TRUE;
1484 			if (mchtype != NULL)
1485 				*mchtype = PM_EXACT;
1486 			break;
1487 		}
1488 		/*
1489 		 * Try "entry/" and the current selection.  The
1490 		 * current selection may be something like "<something>/".
1491 		 */
1492 		(void) tlm_cat_path(retry, namep, "/");
1493 		if ((*cmp_fp)(p_sel, retry)) {
1494 			NDMP_LOG(LOG_DEBUG, "match2> pos %d [%s][%s]",
1495 			    i, p_sel, name);
1496 			found = TRUE;
1497 			if (mchtype != NULL)
1498 				*mchtype = PM_EXACT;
1499 			break;
1500 		}
1501 		/*
1502 		 * If the following check returns true it means that the
1503 		 * 'name' is an entry below the 'p_sel' hierarchy.
1504 		 */
1505 		if (is_parent(p_sel, namep, flags)) {
1506 			NDMP_LOG(LOG_DEBUG, "parent1> pos %d [%s][%s]",
1507 			    i, p_sel, name);
1508 			found = TRUE;
1509 			if (mchtype != NULL)
1510 				*mchtype = PM_CHILD;
1511 			break;
1512 		}
1513 
1514 		/*
1515 		 * There is a special case for parent directories of a
1516 		 * selection.  If 'p_sel' is something like "*d1", the
1517 		 * middle directories of the final entry can't be determined
1518 		 * until the final entry matches with 'p_sel'.  At that
1519 		 * time the middle directories of the entry have been passed
1520 		 * and they can't be restored.
1521 		 */
1522 		if (is_parent(namep, p_sel, flags)) {
1523 			NDMP_LOG(LOG_DEBUG, "parent2> pos %d [%s][%s]",
1524 			    i, p_sel, name);
1525 			found = TRUE;
1526 			if (mchtype != NULL)
1527 				*mchtype = PM_PARENT;
1528 			break;
1529 		}
1530 	}
1531 
1532 	/* Check for exclusions.  */
1533 	if (found && exact_find(namep, exls)) {
1534 		if (mchtype != NULL)
1535 			*mchtype = PM_NONE;
1536 		found = FALSE;
1537 	}
1538 	if (found && pos != NULL)
1539 		*pos = i;
1540 
1541 	free(uc_name);
1542 	free(retry);
1543 	return (found);
1544 }
1545 
1546 /*
1547  * Read the specified amount data into the buffer.  Detects EOT or EOF
1548  * during read.
1549  *
1550  * Returns the number of bytes actually read.  On error returns -1.
1551  */
1552 static int
1553 input_mem(int l,
1554     int d,
1555     tlm_cmd_t *lcmds,
1556     char *mem,
1557     int len)
1558 {
1559 	int err;
1560 	int toread, actual_size, rec_size;
1561 	char *rec;
1562 
1563 	if (l <= 0 || d <= 0 || !lcmds || !mem) {
1564 		NDMP_LOG(LOG_DEBUG, "Invalid argument");
1565 		return (-1);
1566 	}
1567 
1568 	toread = len;
1569 	while (toread > 0) {
1570 		rec = get_read_buffer(toread, &err, &actual_size, lcmds);
1571 		if (actual_size <= 0) {
1572 			NDMP_LOG(LOG_DEBUG, "err %d act_size %d detected",
1573 			    err, actual_size);
1574 			break;
1575 		} else if (err) {
1576 			NDMP_LOG(LOG_DEBUG, "error %d reading data", err);
1577 			return (-1);
1578 		}
1579 		rec_size = min(actual_size, toread);
1580 		(void) memcpy(mem, rec, rec_size);
1581 		mem += rec_size;
1582 		toread -= rec_size;
1583 	}
1584 
1585 	return (len - toread);
1586 }
1587 
1588 /*
1589  * pick up the name and size of a HUGE file
1590  */
1591 static	int
1592 get_humongus_file_header(int lib,
1593     int	drv,
1594     long recsize,
1595     longlong_t *size,
1596     char *name,
1597     tlm_cmd_t *local_commands)
1598 {
1599 	char *p_record, *value;
1600 	int rv;
1601 
1602 	NDMP_LOG(LOG_DEBUG, "HUGE Record found: %d", recsize);
1603 
1604 	rv = 0;
1605 	if (recsize == 0) {
1606 		/*
1607 		 * The humongus_file_header was written in a
1608 		 * RECORDSIZE block and the header.size field of this
1609 		 * record was 0 before this fix.  For backward compatiblity
1610 		 * read only one RECORDSIZE-size block if the header.size
1611 		 * field is 0.  Otherwise the header.size field should show
1612 		 * the length of the data of this header.
1613 		 */
1614 		NDMP_LOG(LOG_DEBUG, "Old HUGE record found");
1615 		recsize = RECORDSIZE;
1616 	}
1617 
1618 	if (input_mem(lib, drv, local_commands, name, recsize) != recsize) {
1619 		rv = -1;
1620 		*size = 0;
1621 		*name = '\0';
1622 		NDMP_LOG(LOG_DEBUG, "Error reading a HUGE file name");
1623 	} else {
1624 		NDMP_LOG(LOG_DEBUG, "HUGE [%s]", name);
1625 
1626 		p_record = name;
1627 		value = parse(&p_record, " ");
1628 		*size = atoll(value);
1629 		/*
1630 		 * Note: Since the backed up names are not longer than
1631 		 * NAME_MAX and the buffer passed to us is
1632 		 * TLM_MAX_PATH_NAME, it should be safe to use strlcpy
1633 		 * without check on the buffer size.
1634 		 */
1635 		(void) strlcpy(name, p_record, TLM_MAX_PATH_NAME);
1636 	}
1637 
1638 	NDMP_LOG(LOG_DEBUG, "HUGE Record %lld [%s]", *size, name);
1639 
1640 	return (rv);
1641 }
1642 
1643 /*
1644  * pick up the long name from the special tape file
1645  */
1646 static int
1647 get_long_name(int lib,
1648     int drv,
1649     long recsize,
1650     char *name,
1651     long *buf_spot,
1652     tlm_cmd_t *local_commands)
1653 {
1654 	int nread;
1655 
1656 	NDMP_LOG(LOG_DEBUG, "LONGNAME Record found rs %d bs %d", recsize,
1657 	    *buf_spot);
1658 
1659 	if (*buf_spot < 0)
1660 		*buf_spot = 0;
1661 
1662 	nread = input_mem(lib, drv, local_commands, name + *buf_spot,
1663 	    recsize);
1664 	if (nread < 0) {
1665 		nread = recsize; /* return 0 as size left */
1666 		name[*buf_spot] = '\0';
1667 		NDMP_LOG(LOG_ERR, "Error %d reading a long file name %s.",
1668 		    nread, name);
1669 	} else {
1670 		*buf_spot += nread;
1671 		name[*buf_spot] = '\0';
1672 		NDMP_LOG(LOG_DEBUG, "LONGNAME [%s]", name);
1673 	}
1674 
1675 	return (recsize - nread);
1676 }
1677 
1678 /*
1679  * create a new directory
1680  */
1681 static	int
1682 create_directory(char *dir, tlm_job_stats_t *job_stats)
1683 {
1684 	struct stat64 attr;
1685 	char	*p;
1686 	char	temp;
1687 	int	erc;
1688 
1689 	/*
1690 	 * Make sure all directories in this path exist, create them if
1691 	 * needed.
1692 	 */
1693 	NDMP_LOG(LOG_DEBUG, "new dir[%s]", dir);
1694 
1695 	erc = 0;
1696 	p = &dir[1];
1697 	do {
1698 		temp = *p;
1699 		if (temp == '/' || temp == 0) {
1700 			*p = 0;
1701 			if (stat64(dir, &attr) < 0) {
1702 				erc = mkdir(dir, 0777);
1703 				if (erc < 0) {
1704 					job_stats->js_errors++;
1705 					NDMP_LOG(LOG_DEBUG,
1706 					    "Could not create directory %s",
1707 					    dir);
1708 					break;
1709 				}
1710 			}
1711 			*p = temp;
1712 		}
1713 		p++;
1714 	} while (temp != 0);
1715 
1716 	return (erc);
1717 }
1718 
1719 /*
1720  * create a new hardlink
1721  */
1722 static int
1723 create_hard_link(char *name_old, char *name_new,
1724     tlm_acls_t *acls, tlm_job_stats_t *job_stats)
1725 {
1726 	int erc;
1727 
1728 	if (mkbasedir(name_new)) {
1729 		NDMP_LOG(LOG_DEBUG, "faile to make base dir for [%s]",
1730 		    name_new);
1731 
1732 		return (-1);
1733 	}
1734 
1735 	erc = link(name_old, name_new);
1736 	if (erc) {
1737 		job_stats->js_errors++;
1738 		NDMP_LOG(LOG_DEBUG, "error %d (errno %d) hardlink [%s] to [%s]",
1739 		    erc, errno, name_new, name_old);
1740 	} else {
1741 		set_acl(name_new, acls);
1742 	}
1743 	return (erc);
1744 }
1745 
1746 /*
1747  * create a new symlink
1748  */
1749 /*ARGSUSED*/
1750 static int
1751 create_sym_link(char *dst, char *target, tlm_acls_t *acls,
1752     tlm_job_stats_t *job_satats)
1753 {
1754 	int erc;
1755 
1756 	if (mkbasedir(dst) < 0)
1757 		return (-1);
1758 
1759 	erc = symlink(target, dst);
1760 	if (erc) {
1761 		job_satats->js_errors++;
1762 		NDMP_LOG(LOG_DEBUG, "error %d (errno %d) softlink [%s] to [%s]",
1763 		    erc, errno, dst, target);
1764 	}
1765 
1766 	return (erc);
1767 }
1768 
1769 /*
1770  * create a new FIFO
1771  */
1772 static int
1773 create_fifo(char *name, tlm_acls_t *acls)
1774 {
1775 	(void) mknod(name, 0777 + S_IFIFO, 0);
1776 	set_acl(name, acls);
1777 	return (0);
1778 }
1779 
1780 /*
1781  * read in the ACLs for the next file
1782  */
1783 static long
1784 load_acl_info(int lib,
1785     int drv,
1786     long file_size,
1787     tlm_acls_t *acls,
1788     long *acl_spot,
1789     tlm_cmd_t *local_commands)
1790 {
1791 	char *bp;
1792 	int nread;
1793 
1794 	/*
1795 	 * If the ACL is spanned on tapes, then the acl_spot should NOT be
1796 	 * 0 on next calls to this function to read the rest of the ACL
1797 	 * on next tapes.
1798 	 */
1799 	if (*acl_spot == 0) {
1800 		(void) memset(acls, 0, sizeof (tlm_acls_t));
1801 	}
1802 
1803 	bp = ((char *)&acls->acl_info) + *acl_spot;
1804 	nread = input_mem(lib, drv, local_commands, (void *)bp, file_size);
1805 	if (nread < 0) {
1806 		*acl_spot = 0;
1807 		(void) memset(acls, 0, sizeof (tlm_acls_t));
1808 		NDMP_LOG(LOG_DEBUG, "Error reading ACL data");
1809 		return (0);
1810 	}
1811 	*acl_spot += nread;
1812 	acls->acl_non_trivial = TRUE;
1813 
1814 	return (file_size - nread);
1815 }
1816 
1817 static int
1818 ndmp_set_eprivs_least(void)
1819 {
1820 	priv_set_t *priv_set;
1821 
1822 	if ((priv_set = priv_allocset()) == NULL) {
1823 		NDMP_LOG(LOG_ERR, "Out of memory.");
1824 		return (-1);
1825 	}
1826 	priv_emptyset(priv_set);
1827 	(void) priv_addset(priv_set, "basic");
1828 	(void) priv_addset(priv_set, "proc_audit");
1829 	(void) priv_addset(priv_set, "proc_setid");
1830 	(void) priv_addset(priv_set, "proc_owner");
1831 	(void) priv_addset(priv_set, "file_chown");
1832 	(void) priv_addset(priv_set, "file_chown_self");
1833 	(void) priv_addset(priv_set, "file_dac_read");
1834 	(void) priv_addset(priv_set, "file_dac_search");
1835 	(void) priv_addset(priv_set, "file_dac_write");
1836 	(void) priv_addset(priv_set, "file_owner");
1837 	(void) priv_addset(priv_set, "file_setid");
1838 	(void) priv_addset(priv_set, "sys_linkdir");
1839 	(void) priv_addset(priv_set, "sys_devices");
1840 	(void) priv_addset(priv_set, "sys_mount");
1841 	(void) priv_addset(priv_set, "sys_config");
1842 
1843 	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) == -1) {
1844 		NDMP_LOG(LOG_ERR, "Additional privileges required.");
1845 		priv_freeset(priv_set);
1846 		return (-1);
1847 	}
1848 	priv_freeset(priv_set);
1849 	return (0);
1850 }
1851 
1852 static int
1853 ndmp_set_eprivs_all(void)
1854 {
1855 	priv_set_t *priv_set;
1856 
1857 	if ((priv_set = priv_str_to_set("all", ",", NULL)) == NULL) {
1858 		NDMP_LOG(LOG_ERR, "Could not set privileges to 'all'.");
1859 		return (-1);
1860 	}
1861 	if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) != 0) {
1862 		NDMP_LOG(LOG_ERR, "Additional privileges required.");
1863 		return (-1);
1864 	}
1865 	priv_freeset(priv_set);
1866 	return (0);
1867 }
1868 
1869 /*
1870  * Set the standard attributes of the file
1871  */
1872 static void
1873 set_attr(char *name, struct stat64 *st)
1874 {
1875 	struct utimbuf tbuf;
1876 	boolean_t priv_all = FALSE;
1877 
1878 	if (!name || !st)
1879 		return;
1880 
1881 	NDMP_LOG(LOG_DEBUG, "set_attr: %s uid %d gid %d mode %o", name,
1882 	    st->st_uid, st->st_gid, st->st_mode);
1883 
1884 	if (chown(name, st->st_uid, st->st_gid))
1885 		NDMP_LOG(LOG_ERR,
1886 		    "Could not set uid or/and gid for file %s.", name);
1887 
1888 	if ((st->st_mode & (S_ISUID | S_ISGID)) != 0) {
1889 		/*
1890 		 * Change effective privileges to 'all' which is required to
1891 		 * change setuid bit for 'root' owned files. If fails, just
1892 		 * send error to log file and proceed.
1893 		 */
1894 		if (ndmp_set_eprivs_all()) {
1895 			NDMP_LOG(LOG_ERR,
1896 			    "Could not set effective privileges to 'all'.");
1897 		} else {
1898 			priv_all = TRUE;
1899 		}
1900 	}
1901 
1902 	if (chmod(name, st->st_mode))
1903 		NDMP_LOG(LOG_ERR,
1904 		    "Could not set correct file permission for file %s.", name);
1905 
1906 	if (priv_all == TRUE) {
1907 		/*
1908 		 * Give up the 'all' privileges for effective sets and go back
1909 		 * to least required privileges. If fails, just send error to
1910 		 * log file and proceed.
1911 		 */
1912 		if (ndmp_set_eprivs_least())
1913 			NDMP_LOG(LOG_ERR,
1914 			    "Could not set least required privileges.");
1915 	}
1916 
1917 	tbuf.modtime = st->st_mtime;
1918 	tbuf.actime = st->st_atime;
1919 	(void) utime(name, &tbuf);
1920 }
1921 
1922 /*
1923  * Set the ACL info for the file
1924  */
1925 static void
1926 set_acl(char *name, tlm_acls_t *acls)
1927 {
1928 	int erc;
1929 	acl_t *aclp = NULL;
1930 
1931 	if (name)
1932 		NDMP_LOG(LOG_DEBUG, "set_acl: %s", name);
1933 	if (acls != 0) {
1934 		/* Need a place to save real modification time */
1935 
1936 		set_attr(name, &acls->acl_attr);
1937 
1938 		if (!acls->acl_non_trivial) {
1939 			(void) memset(acls, 0, sizeof (tlm_acls_t));
1940 			NDMP_LOG(LOG_DEBUG, "set_acl: skipping trivial");
1941 			return;
1942 		}
1943 
1944 		erc = acl_fromtext(acls->acl_info.attr_info, &aclp);
1945 		if (erc != 0) {
1946 			NDMP_LOG(LOG_DEBUG,
1947 			    "TAPE RESTORE> acl_fromtext errno %d", erc);
1948 		}
1949 		if (aclp) {
1950 			erc = acl_set(name, aclp);
1951 			if (erc < 0) {
1952 				NDMP_LOG(LOG_DEBUG,
1953 				    "TAPE RESTORE> acl_set errno %d", errno);
1954 			}
1955 			acl_free(aclp);
1956 		}
1957 		(void) memset(acls, 0, sizeof (tlm_acls_t));
1958 	}
1959 }
1960 
1961 /*
1962  * a wrapper to tlm_get_read_buffer so that
1963  * we can cleanly detect ABORT commands
1964  * without involving the TLM library with
1965  * our problems.
1966  */
1967 static char *
1968 get_read_buffer(int want,
1969     int	*error,
1970     int	*actual_size,
1971     tlm_cmd_t *local_commands)
1972 {
1973 	while (local_commands->tc_writer == TLM_RESTORE_RUN) {
1974 		char	*rec;
1975 		rec = tlm_get_read_buffer(want, error,
1976 		    local_commands->tc_buffers, actual_size);
1977 		if (rec != 0) {
1978 			return (rec);
1979 		}
1980 	}
1981 
1982 	/*
1983 	 * the job is ending, give Writer a buffer that will never be read ...
1984 	 * it does not matter anyhow, we are aborting.
1985 	 */
1986 	*actual_size = RECORDSIZE;
1987 	return (NULL);
1988 }
1989 
1990 /*
1991  * Enable wildcard for restore options
1992  */
1993 static boolean_t
1994 wildcard_enabled(void)
1995 {
1996 	char *cp;
1997 
1998 	cp = ndmpd_get_prop_default(NDMP_RESTORE_WILDCARD_ENABLE, "n");
1999 	return ((toupper(*cp) == 'Y') ? TRUE : FALSE);
2000 }
2001 
2002 
2003 /*
2004  * Concatenate two names
2005  */
2006 /*ARGSUSED*/
2007 static char *
2008 catnames(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2009 {
2010 	char *rv;
2011 
2012 	rv = NULL;
2013 	if (!buf) {
2014 		NDMP_LOG(LOG_DEBUG, "buf is NULL");
2015 	} else if (!path) {
2016 		NDMP_LOG(LOG_DEBUG, "path is NULL");
2017 	} else if (!rnp->rn_nlp) {
2018 		NDMP_LOG(LOG_DEBUG, "rn_nlp is NULL [%s]", path);
2019 	} else if (!tlm_cat_path(buf, rnp->rn_nlp, path)) {
2020 		NDMP_LOG(LOG_DEBUG, "Path too long [%s][%s]",
2021 		    rnp->rn_nlp, path);
2022 	} else
2023 		rv = buf;
2024 
2025 	return (rv);
2026 }
2027 
2028 
2029 /*
2030  * Create a new name path for restore
2031  */
2032 static char *
2033 rs_new_name(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2034 {
2035 	if (!rnp || !rnp->rn_fp)
2036 		return (NULL);
2037 
2038 	return (*rnp->rn_fp)(rnp, buf, pos, path);
2039 }
2040 
2041 /*
2042  * Iterate over ZFS metadata stored in the backup stream and use the callback
2043  * to restore it.
2044  */
2045 int
2046 ndmp_iter_zfs(ndmp_context_t *nctx, int (*np_restore_property)(nvlist_t *,
2047     void *), void *ptr)
2048 {
2049 	tlm_commands_t *cmds;
2050 	ndmp_metadata_header_t *mhp;
2051 	ndmp_metadata_property_t *mpp;
2052 	tlm_cmd_t *lcmd;
2053 	int actual_size;
2054 	nvlist_t *nvl;
2055 	nvlist_t *nvl_head;
2056 	nvlist_t *valp;
2057 	nvpair_t *nvp = NULL;
2058 	nvpair_t *nvph = NULL;
2059 	char plname[100];
2060 	char *mhbuf, *pp, *tp;
2061 	int rv, i;
2062 	int size, lsize, sz;
2063 	int align = RECORDSIZE - 1;
2064 
2065 	if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2066 		return (-1);
2067 
2068 	nctx->nc_plname = plname;
2069 	if ((lcmd = cmds->tcs_command) == NULL ||
2070 	    lcmd->tc_buffers == NULL)
2071 		return (-1);
2072 
2073 	size = sizeof (ndmp_metadata_header_t) +
2074 	    ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t);
2075 	size += align;
2076 	size &= ~align;
2077 
2078 	/* For nvlist cleanup */
2079 	if (nvlist_alloc(&nvl_head, NV_UNIQUE_NAME, 0) != 0)
2080 		return (-1);
2081 
2082 	if ((mhbuf = malloc(size)) == NULL)
2083 		return (-1);
2084 
2085 	/* LINTED improper alignment */
2086 	while ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2087 	    &actual_size, lcmd)) != NULL) {
2088 		pp = mhbuf;
2089 
2090 		if (strncmp(mhp->nh_magic, ZFS_META_MAGIC,
2091 		    sizeof (mhp->nh_magic)) != 0) {
2092 			/* No more metadata */
2093 			tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2094 			nvlist_free(nvl_head);
2095 			return (0);
2096 		}
2097 
2098 		(void) memcpy(pp, (char *)mhp, (actual_size < size) ?
2099 		    actual_size : size);
2100 		pp += (actual_size < size) ? actual_size : size;
2101 
2102 		sz = actual_size;
2103 		while (sz < size &&
2104 		    ((tp = get_read_buffer(size - sz, &rv, &lsize,
2105 		    lcmd))) != NULL) {
2106 			(void) memcpy(pp, tp, size - sz);
2107 			sz += lsize;
2108 			pp += lsize;
2109 		}
2110 		if (sz > size) {
2111 			tlm_unget_read_buffer(lcmd->tc_buffers, sz - size);
2112 		}
2113 		/* LINTED improper alignment */
2114 		mhp = (ndmp_metadata_header_t *)mhbuf;
2115 
2116 		nctx->nc_plversion = mhp->nh_plversion;
2117 		(void) strlcpy(plname, mhp->nh_plname, sizeof (plname));
2118 
2119 		if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
2120 			goto nvlist_err;
2121 
2122 		mpp = &mhp->nh_property[0];
2123 		for (i = 0; i < mhp->nh_count && mpp; i++) {
2124 			if (nvlist_alloc(&valp, NV_UNIQUE_NAME, 0) != 0 ||
2125 			    nvlist_add_string(valp, "value",
2126 			    mpp->mp_value) != 0 ||
2127 			    nvlist_add_string(valp, "source",
2128 			    mpp->mp_source) != 0 ||
2129 			    nvlist_add_nvlist(nvl, mpp->mp_name, valp) != 0)
2130 				goto nvlist_err;
2131 			mpp++;
2132 		}
2133 
2134 		if (np_restore_property(nvl, ptr) != 0)
2135 			goto nvlist_err;
2136 
2137 		(void) nvlist_add_nvlist(nvl_head, "_", nvl);
2138 	}
2139 	free(mhbuf);
2140 
2141 	nvlist_free(nvl_head);
2142 	return (0);
2143 
2144 nvlist_err:
2145 	free(mhbuf);
2146 	while ((nvph = nvlist_next_nvpair(nvl_head, nvph)) != NULL &&
2147 	    nvpair_value_nvlist(nvph, &nvl) == 0) {
2148 		while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
2149 		    nvpair_value_nvlist(nvp, &valp) == 0) {
2150 			nvlist_free(valp);
2151 		}
2152 		nvlist_free(nvl);
2153 	}
2154 	nvlist_free(nvl_head);
2155 	return (-1);
2156 }
2157 
2158 /*
2159  * Returns the version number of the plugin which created the metadata
2160  */
2161 uint_t
2162 ndmp_context_get_version(ndmp_context_t *nctx)
2163 {
2164 	tlm_commands_t *cmds;
2165 	ndmp_metadata_header_t *mhp;
2166 	tlm_cmd_t *lcmd;
2167 	int actual_size;
2168 	int rv;
2169 	int size;
2170 	int align = RECORDSIZE - 1;
2171 
2172 	if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2173 		return (0);
2174 
2175 	if ((lcmd = cmds->tcs_command) == NULL ||
2176 	    lcmd->tc_buffers == NULL)
2177 		return (0);
2178 
2179 	size = sizeof (ndmp_metadata_header_t);
2180 	size += align;
2181 	size &= ~align;
2182 
2183 	/* LINTED improper alignment */
2184 	if ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2185 	    &actual_size, lcmd)) != NULL) {
2186 		if (strncmp(mhp->nh_magic, ZFS_META_MAGIC,
2187 		    sizeof (mhp->nh_magic)) != 0) {
2188 			/* No more metadata */
2189 			tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2190 			return (0);
2191 		}
2192 
2193 		nctx->nc_plversion = mhp->nh_plversion;
2194 		tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2195 	}
2196 
2197 	return (nctx->nc_plversion);
2198 }
2199