2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * BSD 3 Clause License
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Copyright (c) 2007, The Storage Networking Industry Association.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Redistribution and use in source and binary forms, with or without
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * modification, are permitted provided that the following conditions
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * are met:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions of source code must retain the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Redistributions in binary form must reproduce the above copyright
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * notice, this list of conditions and the following disclaimer in
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the documentation and/or other materials provided with the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * distribution.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * - Neither the name of The Storage Networking Industry Association (SNIA)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * nor the names of its contributors may be used to endorse or promote
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * products derived from this software without specific prior written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * permission.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * POSSIBILITY OF SUCH DAMAGE.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdlib.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <ctype.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <limits.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <string.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <time.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/types.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/acl.h>
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar#include <sys/mkdev.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <utime.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <pthread.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <archives.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <priv.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <tlm.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <libzfs.h>
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar#include <pwd.h>
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar#include <grp.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <ndmpd_prop.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "tlm_proto.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define PM_EXACT_OR_CHILD(m) ((m) == PM_EXACT || (m) == PM_CHILD)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl#define ERROR_IS_FATAL(err) ((err) == ENOSPC || (err) == EDQUOT)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef boolean_t name_match_fp_t(char *s, char *t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Krylstatic int set_acl(char *name, tlm_acls_t *acls);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Krylstatic int restore_file(int *fp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *real_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t huge_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t want_this_file,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl tlm_job_stats_t *,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl long *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic long restore_xattr_hdr(int *fp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *fname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *job_stats);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int get_long_name(int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long recsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long *buf_spot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int get_humongus_file_header(int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long recsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t *size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int create_directory(char *dir,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int create_hard_link(char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *link,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int create_sym_link(char *dst,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *target,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdarstatic int create_special(char,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar char *name,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tlm_acls_t *,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar int,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar int,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tlm_job_stats_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic long load_acl_info(int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long *acl_spot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *get_read_buffer(int want,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *error,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t wildcard_enabled(void);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t is_file_wanted(char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **sels,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **exls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *mchtype,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *catnames(struct rs_name_maker *rnp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *buf,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int pos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *rs_new_name(struct rs_name_maker *rnp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *real_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int pos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdarstatic void rs_create_new_bkpath(char *bk_path,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar char *path,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar char *pbuf);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct stack_ent {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *se_name;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t se_acls;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} stack_ent_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dtree_push
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardtree_push(cstack_t *stp, char *nmp, tlm_acls_t *acls)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar stack_ent_t *sp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sp = ndmp_malloc(sizeof (stack_ent_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!sp || !nmp || !acls) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(sp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar len = strlen(nmp) + 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sp->se_name = ndmp_malloc(len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!sp->se_name) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(sp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(sp->se_name, nmp, len);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(&sp->se_acls, acls, sizeof (*acls));
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar (void) memset(acls, 0, sizeof (tlm_acls_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (cstack_push(stp, (void *)sp, sizeof (*sp)));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dtree_pop
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardtree_pop(cstack_t *stp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar stack_ent_t *sp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = cstack_pop(stp, (void **)&sp, (void *)NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl err = set_acl(sp->se_name, &sp->se_acls);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(sp->se_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(sp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dtree_peek
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarchar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardtree_peek(cstack_t *stp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar stack_ent_t *sp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err = cstack_top(stp, (void **)&sp, (void *)NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (err)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (sp->se_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NBU and EBS may not send us the correct file list containing hardlinks
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * during a DAR restore, e.g. they appear always send the first name
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * associated with an inode, even if other link names were
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * selected for the restore. As a workaround, we use the file name entry
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in sels[] (ignore the name in the tar header) as restore target.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarrs_darhl_new_name(struct rs_name_maker *rnp, char *name, char **sels, int *pos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *longname)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int x;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (x = 0; sels[x] != NULL; x++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strcmp(sels[x], " ")) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *pos = x;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(longname, sels[x], TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "to replace hardlink name [%s], pos [%d]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname, *pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rs_new_name(rnp, name, *pos, longname));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar * Main dir restore function for tar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl *
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * If this function returns non-zero return value it means that fatal error
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * was encountered.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartar_getdir(tlm_commands_t *commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *job_stats,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct rs_name_maker *rnp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **sels, /* what to get off the tape */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **exls, /* what to leave behind */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int flags,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar int DAR,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar char *bk_path,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar struct hardlink_q *hardlink_q)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fp = 0; /* file being restored ... */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* ...need to preserve across volume changes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *acls; /* file access info */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *longname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t is_long_name = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *longlink;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *hugename;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t huge_size = 0; /* size of a HUGE file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long acl_spot; /* any ACL info on the next volume */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long file_size; /* size of file to restore */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size_left = 0; /* need this after volume change */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int last_action = 0; /* what we are doing at EOT */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t multi_volume = FALSE; /* is this a multi-volume switch ? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int chk_rv; /* scratch area */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int mchtype, pos;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * if an exact match is found for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restore and its position in the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * selections list
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int nzerohdr; /* the number of empty tar headers */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long nm_end, lnk_end;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name, *nmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cstack_t *stp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *bkpath;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *parentlnk;
c9fd6b31f4fa1345ad799549dc0f1101b9cef127Reza Sabdar int dir_dar = 0;
c9fd6b31f4fa1345ad799549dc0f1101b9cef127Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The directory where temporary files may be created during a partial
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * non-DAR restore of hardlinks. It is intended to be initialized by
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * an environment variable that can be set by user.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * It is not initialized for now. We keep it here for future use.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *tmplink_dir = NULL;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int dar_recovered = 0;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar char *thname_buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * startup
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlink = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hugename = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar parentlnk = ndmp_malloc(TLM_MAX_PATH_NAME);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar thname_buf = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls = ndmp_malloc(sizeof (tlm_acls_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar stp = cstack_new();
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (longname == NULL || longlink == NULL || hugename == NULL ||
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar name == NULL || acls == NULL || stp == NULL || parentlnk == NULL ||
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar thname_buf == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cstack_delete(stp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(longname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(longlink);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(hugename);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(parentlnk);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(acls);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar free(thname_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-TLM_NO_SCRATCH_SPACE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acl_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *hugename = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *parentlnk = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nm_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *longname = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnk_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *longlink = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(acls, 0, sizeof (tlm_acls_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_SET(flags, RSFLG_OVR_ALWAYS)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_overwrite = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_ALWAYS");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (IS_SET(flags, RSFLG_OVR_UPDATE)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_update = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "RSFLG_OVR_UPDATE");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * work
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nzerohdr = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (commands->tcs_writer != TLM_ABORT &&
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl local_commands->tc_writer != TLM_STOP && rv == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t fake_tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *file_name;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *link_name;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int erc;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t want_this_file;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int want = sizeof (tlm_tar_hdr_t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t *tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* The inode of an LF_LINK type. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar unsigned long hardlink_inode = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Indicate whether a file with the same inode has been
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restored.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int hardlink_done = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* The path of the restored hardlink file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *hardlink_target = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int is_hardlink = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Whether a temporary file should be created for restoring
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * hardlink.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int hardlink_tmp_file = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *hardlink_tmp_name = ".tmphlrsnondar";
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* used to make up hardlink_tmp_name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar static int hardlink_tmp_idx = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (multi_volume) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "multi_volume %c %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar last_action, size_left);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the previous volume is out of data
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and is back in the rack, a new tape
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is loaded and ready to read.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * We need to pick up where we left off.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(&fake_tar_hdr, 0, sizeof (fake_tar_hdr));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size = size_left;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = &fake_tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag = last_action;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar multi_volume = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar last_action = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(want,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &erc, &actual_size, local_commands);
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar if (tar_hdr == NULL) {
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar rv = -1;
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar continue;
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar }
7bc22e45a20f905cdd06bb98c98a5c8be7fd25c0Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we can ignore read errors here because
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 1) they are logged by Restore Reader
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 2) we are not doing anything important here
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * just looking for the next work record.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size < want) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * EOF hits here
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * wait for another buffer to come along
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * or until the Reader thread tells us
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * that no more tapes will be loaded ...
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * time to stop.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for "we are lost"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar chk_rv = tlm_vfy_tar_checksum(tar_hdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (chk_rv == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* one of the end of tar file marks */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (++nzerohdr >= 2) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "nzerohdr %d, breaking",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nzerohdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* end of tar file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "nzerohdr %d, continuing",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nzerohdr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (chk_rv < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nzerohdr = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* skip this record */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nzerohdr = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * When files are spanned to the next tape, the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * information of the acls must not be over-written
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * by the information of the LF_MULTIVOL and LF_VOLHDR
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * header, whose information is irrelevant to the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The information of the original header must be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * kept in the 'acl'.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tar_hdr->th_linkflag != LF_MULTIVOL &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkflag != LF_VOLHDR) {
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar if (tar_hdr->th_linkflag != LF_HUMONGUS) {
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar acls->acl_attr.st_mode =
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar oct_atoi(tar_hdr->th_mode);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar acls->acl_attr.st_size =
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar oct_atoi(tar_hdr->th_size);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar acls->acl_attr.st_uid =
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar oct_atoi(tar_hdr->th_uid);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar acls->acl_attr.st_gid =
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar oct_atoi(tar_hdr->th_gid);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar acls->acl_attr.st_mtime =
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar oct_atoi(tar_hdr->th_mtime);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar (void) strlcpy(acls->uname,
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar tar_hdr->th_uname,
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sizeof (acls->uname));
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar (void) strlcpy(acls->gname,
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar tar_hdr->th_gname,
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar sizeof (acls->gname));
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size = oct_atoi(tar_hdr->th_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acl_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar last_action = tar_hdr->th_linkflag;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "n [%s] f [%c] s %lld m %o u %d g %d t %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_name, tar_hdr->th_linkflag,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_size, acls->acl_attr.st_mode,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_uid, acls->acl_attr.st_gid,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_mtime);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar /*
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * If the restore is running using DAR we should check for
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar * extended attribute entries
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar */
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (dar_recovered &&
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar tar_hdr->th_linkflag != LF_XATTR)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar break;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar rs_create_new_bkpath(bk_path, tar_hdr->th_name, thname_buf);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (tar_hdr->th_linkflag) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_MULTIVOL:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar multi_volume = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_LINK:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar is_hardlink = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_inode =
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar oct_atoi(tar_hdr->th_shared.th_hlink_ino);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if we have restored a link with the same inode
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the inode is 0, we have to restore it as a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * regular file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_inode) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_done = !hardlink_q_get(hardlink_q,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_inode, 0, &hardlink_target);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_done) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "found hardlink, inode = %u, target = [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_inode,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_target? hardlink_target : "--");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* create a hardlink to hardlink_target */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_name = (*longname == 0) ?
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar thname_buf : longname;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!is_file_wanted(file_name, sels, exls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags, &mchtype, &pos)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This means that DMA did not send us
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the correct fh_info for the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in restore list. We use the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * name entry in sels[] (ignore the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * name in the tar header) as restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * target.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (DAR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_darhl_new_name(rnp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name, sels, &pos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_new_name(rnp, name, pos,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!nmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "can't make name for %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_target) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc = create_hard_link(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_target, nmp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls, job_stats);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(erc)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = erc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (erc == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_entry_restored(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_name, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "restored %s -> %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_target);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "no target for hardlink %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar is_long_name = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nm_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnk_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlink[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* otherwise fall through, restore like a normal file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*FALLTHROUGH*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_OLDNORMAL:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for TAR's end-of-tape method
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of zero filled records.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tar_hdr->th_name[0] == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * otherwise fall through,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this is an old style normal file header
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*FALLTHROUGH*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_NORMAL:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_CONTIG:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_files_so_far++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*hugename != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(longname, hugename,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (*longname == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tar_hdr->th_name[0] != '/') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * check for old tar format, it
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * does not have a leading "/"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[0] = '/';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[1] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcat(longname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(longname,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar thname_buf,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = is_file_wanted(longname, sels, exls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags, &mchtype, &pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!want_this_file) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * This means that DMA did not send us valid
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * fh_info for the file in restore list. We
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * use the file name entry in sels[] (ignore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the name in the tar header) as restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * target.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (DAR && (tar_hdr->th_linkflag == LF_LINK)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_darhl_new_name(rnp, name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sels, &pos, longname);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (nmp == NULL) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = ENOMEM;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl want_this_file = TRUE;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl mchtype = PM_EXACT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_new_name(rnp, name, pos, longname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!nmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nmp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(parentlnk, nmp, strlen(nmp) + 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For a hardlink, even if it's not asked to be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restored, we restore it to a temporary location,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * in case other links to the same file need to be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restored later.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The temp files are created in tmplink_dir, with
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * names like ".tmphlrsnondar*". They are cleaned up
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * at the completion of a restore. However, if a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restore were interrupted, e.g. by a system reboot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * they would have to be cleaned up manually in order
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * for the disk space to be freed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If tmplink_dir is NULL, no temperorary files are
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * created during a restore. This may result in some
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * hardlinks not being restored during a partial
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * restore.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_hardlink && !DAR && !want_this_file && !nmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (tmplink_dir) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(name, TLM_MAX_PATH_NAME,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "%s/%s_%d", tmplink_dir,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_tmp_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_tmp_idx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = name;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_tmp_idx++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_tmp_file = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "To restore temp hardlink file %s.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "No tmplink_dir specified.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = restore_file(&fp, nmp, file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar huge_size, acls, want_this_file, local_commands,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl job_stats, &size_left);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (rv != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In the case of non-DAR, we have to record the first
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * link for an inode that has multiple links. That's
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the only link with data records actually backed up.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * In this way, when we run into the other links, they
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will be treated as links, and we won't go to look
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * for the data records to restore. This is not a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * problem for DAR, where DMA tells the tape where
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to locate the data records.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_hardlink && !DAR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_q_add(hardlink_q, hardlink_inode,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar 0, nmp, hardlink_tmp_file))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "failed to add (%u, %s) to HL q",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_inode, nmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* remove / reverse the temporary stuff */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (hardlink_tmp_file) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_tmp_file = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if it is time to set the attribute
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of the restored directory
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (nmp && ((bkpath = dtree_peek(stp)) != NULL)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl int erc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strstr(nmp, bkpath))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = dtree_pop(stp);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(erc)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = erc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl break;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (rv != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "sizeleft %s %d, %lld", longname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left, huge_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (want_this_file) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_bytes_total += file_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_files_total++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar huge_size -= file_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (huge_size < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar huge_size = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (size_left == 0 && huge_size == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (PM_EXACT_OR_CHILD(mchtype)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_entry_restored(job_stats,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Add an entry to hardlink_q to record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this hardlink.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_hardlink) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Restored hardlink file %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (DAR) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) hardlink_q_add(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_q,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hardlink_inode, 0,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp, 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nm_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnk_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlink[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar hugename[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar is_long_name = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_XATTR:
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar file_name = (*longname == 0) ? thname_buf :
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = restore_xattr_hdr(&fp, parentlnk,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_name, file_size, acls, local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_SYMLINK:
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar file_name = (*longname == 0) ? thname_buf :
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar link_name = (*longlink == 0) ?
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr->th_linkname : longlink;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "file_name[%s]", file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "link_name[%s]", link_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_file_wanted(file_name, sels, exls, flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &mchtype, &pos)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_new_name(rnp, name, pos, file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nmp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc = create_sym_link(nmp, link_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls, job_stats);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(erc)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = erc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (erc == 0 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar PM_EXACT_OR_CHILD(mchtype))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_entry_restored(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats, file_name, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nm_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnk_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlink[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_DIR:
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar file_name = *longname == 0 ? thname_buf :
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_file_wanted(file_name, sels, exls, flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &mchtype, &pos)) {
c9fd6b31f4fa1345ad799549dc0f1101b9cef127Reza Sabdar dir_dar = DAR;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_new_name(rnp, name, pos, file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nmp && mchtype != PM_PARENT) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(parentlnk, nmp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar strlen(nmp));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc = create_directory(nmp, job_stats);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(erc)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = erc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (erc == 0 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar PM_EXACT_OR_CHILD(mchtype))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_entry_restored(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats, file_name, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if it is time to set
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the attribute of the restored
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * directory
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((bkpath = dtree_peek(stp))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar != NULL) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl int rc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strstr(nmp, bkpath))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rc = dtree_pop(stp);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(rc)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = rc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl break;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (rv != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) dtree_push(stp, nmp, acls);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
c9fd6b31f4fa1345ad799549dc0f1101b9cef127Reza Sabdar } else {
c9fd6b31f4fa1345ad799549dc0f1101b9cef127Reza Sabdar dir_dar = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nm_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnk_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlink[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_FIFO:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case LF_BLK:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case LF_CHR:
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar file_name = *longname == 0 ? thname_buf :
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_file_wanted(file_name, sels, exls, flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &mchtype, &pos)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nmp = rs_new_name(rnp, name, pos, file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nmp) {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar erc = create_special(
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tar_hdr->th_linkflag, nmp, acls,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar oct_atoi(tar_hdr->th_shared.
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar th_dev.th_devmajor),
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar oct_atoi(tar_hdr->th_shared.
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar th_dev.th_devminor), job_stats);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(erc)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = erc;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl continue;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (erc == 0 &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar PM_EXACT_OR_CHILD(mchtype))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_entry_restored(
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats, file_name, pos);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nm_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longname[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lnk_end = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlink[0] = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_LONGLINK:
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar file_size = min(file_size,
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar TLM_MAX_PATH_NAME - lnk_end - 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size = max(0, file_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = get_long_name(lib, drv, file_size, longlink,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &lnk_end, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (size_left != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "fsize %d sleft %d lnkend %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size, size_left, lnk_end);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_LONGNAME:
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar file_size = min(file_size,
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar TLM_MAX_PATH_NAME - nm_end - 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size = max(0, file_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = get_long_name(lib, drv, file_size, longname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &nm_end, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (size_left != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "fsize %d sleft %d nmend %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar file_size, size_left, nm_end);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar is_long_name = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_ACL:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size_left = load_acl_info(lib, drv, file_size, acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &acl_spot, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_VOLHDR:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case LF_HUMONGUS:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(hugename, 0, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) get_humongus_file_header(lib, drv, file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &huge_size, hugename, local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the restore is running using DAR we should check for
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * long file names and HUGE file sizes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (DAR && tar_hdr->th_linkflag != LF_ACL &&
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar tar_hdr->th_linkflag != LF_XATTR &&
c9fd6b31f4fa1345ad799549dc0f1101b9cef127Reza Sabdar !huge_size && !is_long_name && !dir_dar)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar dar_recovered = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * tear down
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (rv != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl commands->tcs_reader = TLM_ABORT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fp != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (dtree_pop(stp) != -1)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cstack_delete(stp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(acls);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(longname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(parentlnk);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(longlink);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(hugename);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(name);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar free(thname_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Main file restore function for tar (should run as a thread)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartar_getfile(tlm_backup_restore_arg_t *argp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *job_stats;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **sels; /* list of files desired */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **exls; /* list of files not wanted */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *dir; /* where to restore the files */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char job[TLM_MAX_BACKUP_JOB_NAME+1];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* the restore job name */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int erc; /* error return codes */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int flags;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct rs_name_maker rn;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_commands_t *commands;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *list = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar commands = argp->ba_commands;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands = argp->ba_cmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dir = ndmp_malloc(TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (dir == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_reader = TLM_STOP;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) pthread_barrier_wait(&argp->ba_barrier);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(job, argp->ba_job, TLM_MAX_BACKUP_JOB_NAME+1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(dir, argp->ba_dir, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags |= RSFLG_OVR_ALWAYS;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags |= RSFLG_IGNORE_CASE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * do not test for "dir" having no string, since that
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is a legal condition. Restore to origional location
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * will not have a restore directory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*job == '\0') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "No job defined");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_reader = TLM_STOP;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(dir);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) pthread_barrier_wait(&argp->ba_barrier);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sels = argp->ba_sels;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (sels == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_reader = TLM_STOP;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(dir);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) pthread_barrier_wait(&argp->ba_barrier);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar exls = &list;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_log_list("selections", sels);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_log_list("exclusions", exls);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (wildcard_enabled())
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags |= RSFLG_MATCH_WCARD;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_ref++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar commands->tcs_writer_count++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * let the launcher continue
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) pthread_barrier_wait(&argp->ba_barrier);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats = tlm_ref_job_stats(job);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rn.rn_fp = catnames;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rn.rn_nlp = dir;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * work
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "start restore job %s", job);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc = tar_getdir(commands, local_commands, job_stats, &rn, 1, 1,
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar sels, exls, flags, 0, NULL, NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * teardown
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "end restore job %s", job);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_un_ref_job_stats(job);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_release_list(sels);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_release_list(exls);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar commands->tcs_writer_count--;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_reader = TLM_STOP;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_release_reader_writer_ipc(local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(dir);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Creates the directories all the way down to the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * end if they dont exist
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmake_dirs(char *dir)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char c;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *cp, *end;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct stat64 st;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = dir;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp += strspn(cp, "/");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar end = dir + strlen(dir);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*cp == '\0' || *cp == '/') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar c = *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *cp = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (lstat64(dir, &st) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mkdir(dir, 0777) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar " creating directory %s",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar errno, dir);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *cp = c;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *cp = c;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (++cp <= end);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Creates the directories leading to the given path
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmkbasedir(char *path)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct stat64 st;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!path || !*path) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = strrchr(path, '/');
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *cp = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = lstat64(path, &st);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv < 0) /* need new directories */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = make_dirs(path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (cp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *cp = '/';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read the file off the tape back onto disk
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl *
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * If the function returns a non-zero return code, it means that fatal error
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * was encountered and restore should terminate immediately.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Krylstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarrestore_file(int *fp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *real_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t huge_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t want_this_file,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl tlm_job_stats_t *job_stats,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl long *size_left)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct stat64 attr;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl int ret, rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl *size_left = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!real_name) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (want_this_file) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "new file[%s]", real_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * OK, some FM is creeping in here ...
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * int *fp is used to keep the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * backup file channel open through
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the interruption of EOT and
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * processing the headers of the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * next tape. So, if *fp is zero
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * then no file is open yet and all
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * is normal. If *fp has a number
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * then we are returning after an
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * EOT break.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * *fp is now also open for HUGE files
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * that are put back in sections.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp == 0 && want_this_file) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl ret = mkbasedir(real_name);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ret != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(ret))
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (ret);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl ret = stat64(real_name, (struct stat64 *)&attr);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ret < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*EMPTY*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* new file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (acls->acl_overwrite) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*EMPTY*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* take this file no matter what */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (acls->acl_update) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (attr.st_mtime < acls->acl_attr.st_mtime) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*EMPTY*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* tape is newer */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* disk file is newer */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * no overwrite, no update,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * do not ever replace old files.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (want_this_file) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
c211fc479225fa54805cf480633bf6689ca9a2dbReza Sabdar *fp = open(real_name, O_CREAT | O_TRUNC | O_WRONLY,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar S_IRUSR | S_IWUSR);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Could not open %s for restore: %d",
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl real_name, errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar want_this_file = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * In case of non-fatal error we cannot return
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * here, because the file is still on the tape
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl * and must be skipped over.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(errno))
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(local_commands->tc_file_name, real_name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * this is the size left in the next segment
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar huge_size -= size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * work
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int error;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int write_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Use bytes_in_file field to tell reader the amount
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * of data still need to be read for this file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_bytes_in_file = size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_read_buffer(size, &error, &actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size <= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "RESTORE WRITER> error %d, actual_size %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* no more data for this file for now */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_bytes_in_file = 0;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl *size_left = size;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (error) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error, local_commands->tc_file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl write_size = min(size, actual_size);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (want_this_file) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl ret = write(*fp, rec, write_size);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ret < 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_ERR,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Write error %d for file [%s]", errno,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl local_commands->tc_file_name);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl job_stats->js_errors++;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(errno)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl rv = errno;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl break;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl } else {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NS_ADD(wdisk, ret);
588541fbf64fffe619698198cef04af1900f1f86Reza Sabdar NS_INC(wfile);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ret < write_size) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_ERR,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Partial write for file [%s]",
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl local_commands->tc_file_name);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl size -= write_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* no more data for this file for now */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_bytes_in_file = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * teardown
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp != 0 && huge_size <= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(*fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *fp = 0;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (rv == 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl ret = set_acl(real_name, acls);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(ret))
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (ret);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set the extended attributes file attribute
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarset_xattr(int fd, struct stat64 st)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct timeval times[2];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar times[0].tv_sec = st.st_atime;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar times[1].tv_sec = st.st_mtime;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fchmod(fd, st.st_mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fchown(fd, st.st_uid, st.st_gid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) futimesat(fd, ".", times);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar/*
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * Read the system attribute file in a single buffer to write
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * it as a single write. A partial write to system attribute would
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar * cause an EINVAL on write.
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar */
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdarstatic char *
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdarget_read_one_buf(char *rec, int actual_size, int size, int *error,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar tlm_cmd_t *lc)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar{
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar char *buf, *p;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int read_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (actual_size > size)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (rec);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar buf = ndmp_malloc(size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (buf == NULL) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar *error = ENOMEM;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (NULL);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) memcpy(buf, rec, actual_size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar rec = buf;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar buf += actual_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar while (actual_size < size) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar p = get_read_buffer(size - actual_size, error, &read_size, lc);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar len = min(size - actual_size, read_size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar (void) memcpy(buf, p, len);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar actual_size += len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar buf += len;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (rec);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar}
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read the extended attribute header and write
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it to the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic long
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarrestore_xattr_hdr(int *fp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *fname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_tar_hdr_t *tar_hdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct xattr_hdr *xhdr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct xattr_buf *xbuf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int namelen;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *xattrname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int error;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fname) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "No file name but wanted!");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "new xattr[%s]", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xhdr = (struct xattr_hdr *)get_read_buffer(size, &error,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, local_commands);
7a088f03b431bdffa96c3b2175964d4d38420caaReza Sabdar if (xhdr == NULL || error != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not read xattr [%s:%s] for restore. ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name, fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check extended attribute header */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strcmp(xhdr->h_version, XATTR_ARCH_VERS) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Unrecognized header format [%s]", xhdr->h_version);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xbuf = (struct xattr_buf *)(((char *)xhdr) + sizeof (struct xattr_hdr));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) sscanf(xbuf->h_namesz, "%7d", &namelen);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar xattrname = xbuf->h_names + strlen(xbuf->h_names) + 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fd = attropen(name, xattrname, O_CREAT | O_RDWR, 0755);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fd == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "Could not open xattr [%s:%s] for restore err=%d.",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar name, xattrname, errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(local_commands->tc_file_name, xattrname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *fp = fd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Get the actual extended attribute file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tar_hdr = (tlm_tar_hdr_t *)get_read_buffer(sizeof (*tar_hdr),
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &error, &actual_size, local_commands);
7a088f03b431bdffa96c3b2175964d4d38420caaReza Sabdar if (tar_hdr == NULL || error != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not read xattr data [%s:%s] for restore. ",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fname, xattrname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_mode = oct_atoi(tar_hdr->th_mode);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_size = oct_atoi(tar_hdr->th_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_uid = oct_atoi(tar_hdr->th_uid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_gid = oct_atoi(tar_hdr->th_gid);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_attr.st_mtime = oct_atoi(tar_hdr->th_mtime);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "xattr_hdr: %s size %d mode %06o uid %d gid %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar xattrname, acls->acl_attr.st_size, acls->acl_attr.st_mode,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar acls->acl_attr.st_uid, acls->acl_attr.st_gid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size = acls->acl_attr.st_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (size > 0 && local_commands->tc_writer == TLM_RESTORE_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int write_size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar int sysattr_write = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_read_buffer(size, &error, &actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((actual_size < size) && sysattr_rw(xattrname)) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar rec = get_read_one_buf(rec, actual_size, size, &error,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar local_commands);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (rec == NULL) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar error, xattrname);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar return (size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar actual_size = size;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar sysattr_write = 1;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size <= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "RESTORE WRITER> error %d, actual_size %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (error) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error %d in file [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar error, local_commands->tc_file_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar write_size = min(size, actual_size);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((write_size = write(*fp, rec, write_size)) < 0) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (sysattr_write)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar free(rec);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar break;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_ADD(wdisk, write_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NS_INC(wfile);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size -= write_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (sysattr_write)
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar free(rec);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*fp != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar set_xattr(*fp, acls->acl_attr);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) close(*fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *fp = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Match the name with the list
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarexact_find(char *name, char **list)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t found;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; *list != NULL; list++, i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = *list + strspn(*list, "/");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (match(cp, name)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "exact_find> found[%s]", cp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (found);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * On error, return FALSE and prevent restoring(probably) unwanted data.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaris_parent(char *parent, char *child, int flags)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char tmp[TLM_MAX_PATH_NAME];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_SET(flags, RSFLG_MATCH_WCARD)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tlm_cat_path(tmp, parent, "*")) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "is_parent> path too long [%s]", parent);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = (match(tmp, child) != 0) ? TRUE : FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!tlm_cat_path(tmp, parent, "/")) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "is_parent> path too long [%s]", parent);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = (strncmp(tmp, child, strlen(tmp)) == 0) ?
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar TRUE : FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Used to match the filename inside the list
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstrexactcmp(char *s, char *t)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ((strcmp(s, t) == 0) ? TRUE : FALSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Check if the file is needed to be restored
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaris_file_wanted(char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **sels,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char **exls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int flags,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *mchtype,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *pos)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *p_sel;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *uc_name, *retry, *namep;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t found;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name_match_fp_t *cmp_fp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (name == NULL || sels == NULL || exls == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (FALSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mchtype != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *mchtype = PM_NONE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (pos != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *pos = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For empty selection, restore everything
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*sels == NULL || **sels == '\0') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "is_file_wanted: Restore all");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (TRUE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar retry = ndmp_malloc(TLM_MAX_PATH_NAME);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar if (retry == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (FALSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_SET(flags, RSFLG_MATCH_WCARD))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cmp_fp = match;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cmp_fp = strexactcmp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar namep = name + strspn(name, "/");
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_SET(flags, RSFLG_IGNORE_CASE)) {
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar uc_name = ndmp_malloc(TLM_MAX_PATH_NAME);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar if (uc_name == NULL) {
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar free(retry);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar return (FALSE);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(uc_name, namep, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strupr(uc_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar namep = uc_name;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "is_file_wanted> flg: 0x%x name: [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar flags, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = 0; *sels != NULL; sels++, i++) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar p_sel = *sels + strspn(*sels, "/");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Try exact match.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((*cmp_fp)(p_sel, namep)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "match1> pos: %d [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i, p_sel, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mchtype != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *mchtype = PM_EXACT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Try "entry/" and the current selection. The
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * current selection may be something like "<something>/".
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) tlm_cat_path(retry, namep, "/");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((*cmp_fp)(p_sel, retry)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "match2> pos %d [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i, p_sel, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mchtype != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *mchtype = PM_EXACT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the following check returns true it means that the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 'name' is an entry below the 'p_sel' hierarchy.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_parent(p_sel, namep, flags)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "parent1> pos %d [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i, p_sel, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mchtype != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *mchtype = PM_CHILD;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * There is a special case for parent directories of a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * selection. If 'p_sel' is something like "*d1", the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * middle directories of the final entry can't be determined
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * until the final entry matches with 'p_sel'. At that
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * time the middle directories of the entry have been passed
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * and they can't be restored.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (is_parent(namep, p_sel, flags)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "parent2> pos %d [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar i, p_sel, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mchtype != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *mchtype = PM_PARENT;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check for exclusions. */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (found && exact_find(namep, exls)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (mchtype != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *mchtype = PM_NONE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = FALSE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (found && pos != NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *pos = i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar if (IS_SET(flags, RSFLG_IGNORE_CASE))
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar free(uc_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(retry);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (found);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read the specified amount data into the buffer. Detects EOT or EOF
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * during read.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the number of bytes actually read. On error returns -1.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarinput_mem(int l,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int d,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *lcmds,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *mem,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int toread, actual_size, rec_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (l <= 0 || d <= 0 || !lcmds || !mem) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Invalid argument");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar toread = len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (toread > 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = get_read_buffer(toread, &err, &actual_size, lcmds);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (actual_size <= 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "err %d act_size %d detected",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar err, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (err) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "error %d reading data", err);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec_size = min(actual_size, toread);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(mem, rec, rec_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mem += rec_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar toread -= rec_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (len - toread);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pick up the name and size of a HUGE file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_humongus_file_header(int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long recsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar longlong_t *size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *p_record, *value;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "HUGE Record found: %d", recsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (recsize == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The humongus_file_header was written in a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * RECORDSIZE block and the header.size field of this
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * record was 0 before this fix. For backward compatiblity
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read only one RECORDSIZE-size block if the header.size
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * field is 0. Otherwise the header.size field should show
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the length of the data of this header.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Old HUGE record found");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar recsize = RECORDSIZE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (input_mem(lib, drv, local_commands, name, recsize) != recsize) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *size = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *name = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error reading a HUGE file name");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "HUGE [%s]", name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar p_record = name;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar value = parse(&p_record, " ");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *size = atoll(value);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Note: Since the backed up names are not longer than
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * NAME_MAX and the buffer passed to us is
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * TLM_MAX_PATH_NAME, it should be safe to use strlcpy
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * without check on the buffer size.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(name, p_record, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "HUGE Record %lld [%s]", *size, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * pick up the long name from the special tape file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_long_name(int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long recsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *name,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long *buf_spot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int nread;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "LONGNAME Record found rs %d bs %d", recsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *buf_spot);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*buf_spot < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *buf_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nread = input_mem(lib, drv, local_commands, name + *buf_spot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar recsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nread < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nread = recsize; /* return 0 as size left */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[*buf_spot] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Error %d reading a long file name %s.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nread, name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *buf_spot += nread;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar name[*buf_spot] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "LONGNAME [%s]", name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (recsize - nread);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * create a new directory
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Krylstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcreate_directory(char *dir, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct stat64 attr;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *p;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char temp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int erc;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Make sure all directories in this path exist, create them if
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * needed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "new dir[%s]", dir);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar p = &dir[1];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar temp = *p;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (temp == '/' || temp == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *p = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (stat64(dir, &attr) < 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (mkdir(dir, 0777) != 0 && errno != EEXIST) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = errno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "Could not create directory %s: %d",
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl dir, errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *p = temp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar p++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (temp != 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * create a new hardlink
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcreate_hard_link(char *name_old, char *name_new,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *acls, tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int erc;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = mkbasedir(name_new);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (link(name_old, name_new) != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = errno;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (erc) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl /* Nothing to do if the destination already exists */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc == EEXIST)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar job_stats->js_errors++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "error %d (errno %d) hardlink [%s] to [%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar erc, errno, name_new, name_old);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (set_acl(name_new, acls));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * create a new symlink
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcreate_sym_link(char *dst, char *target, tlm_acls_t *acls,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int erc;
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar struct stat64 *st;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = mkbasedir(dst);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar st = &acls->acl_attr;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (symlink(target, dst) != 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = errno;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar job_stats->js_errors++;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_DEBUG, "error %d softlink [%s] to [%s]",
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl errno, dst, target);
86c48bbfeb72d5a6ee171e713059939bab658b77Reza Sabdar } else {
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar st->st_mode |= S_IFLNK;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = set_acl(dst, acls);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar * create a new FIFO, char/block device special files
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdarcreate_special(char flag, char *name, tlm_acls_t *acls, int major, int minor,
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar tlm_job_stats_t *job_stats)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar dev_t dev;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar mode_t mode;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar switch (flag) {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case LF_CHR:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar mode = S_IFCHR;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar dev = makedev(major, minor);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar break;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case LF_BLK:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar mode = S_IFBLK;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar dev = makedev(major, minor);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar break;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar case LF_FIFO:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar mode = S_IFIFO;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar dev = 0;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar break;
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar default:
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar NDMP_LOG(LOG_ERR, "unsupported flag %d", flag);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar return (-1);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar }
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar /* Remove the old entry first */
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar if (rmdir(name) < 0) {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar if (errno == ENOTDIR)
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar (void) unlink(name);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (mknod(name, 0777 | mode, dev) != 0) {
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar job_stats->js_errors++;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_DEBUG, "error %d mknod [%s] major"
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl " %d minor %d", errno, name, major, minor);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (errno);
5181c2afafac4c39b4d5d9d8dd14e6ba0d227db2Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (set_acl(name, acls));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * read in the ACLs for the next file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic long
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarload_acl_info(int lib,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int drv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long file_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_acls_t *acls,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar long *acl_spot,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *bp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int nread;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the ACL is spanned on tapes, then the acl_spot should NOT be
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on next calls to this function to read the rest of the ACL
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * on next tapes.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*acl_spot == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(acls, 0, sizeof (tlm_acls_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar bp = ((char *)&acls->acl_info) + *acl_spot;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nread = input_mem(lib, drv, local_commands, (void *)bp, file_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nread < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *acl_spot = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(acls, 0, sizeof (tlm_acls_t));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Error reading ACL data");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *acl_spot += nread;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acls->acl_non_trivial = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (file_size - nread);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_set_eprivs_least(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priv_set_t *priv_set;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((priv_set = priv_allocset()) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Out of memory.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik priv_basicset(priv_set);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_PROC_AUDIT);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_PROC_SETID);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_PROC_OWNER);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_CHOWN);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_CHOWN_SELF);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_DAC_READ);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_DAC_SEARCH);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_DAC_WRITE);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_OWNER);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_FILE_SETID);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_LINKDIR);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_DEVICES);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_MOUNT);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik (void) priv_addset(priv_set, PRIV_SYS_CONFIG);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) == -1) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Additional privileges required.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priv_freeset(priv_set);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priv_freeset(priv_set);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_set_eprivs_all(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priv_set_t *priv_set;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik if ((priv_set = priv_allocset()) == NULL) {
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik NDMP_LOG(LOG_ERR, "Out of memory.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik priv_fillset(priv_set);
634e26ec75c89095090605284938356a3145f2b8Casper H.S. Dik
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (setppriv(PRIV_SET, PRIV_EFFECTIVE, priv_set) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Additional privileges required.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priv_freeset(priv_set);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set the standard attributes of the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Krylstatic int
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdarset_attr(char *name, tlm_acls_t *acls)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct utimbuf tbuf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar boolean_t priv_all = FALSE;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar struct stat64 *st;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uid_t uid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gid_t gid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar struct passwd *pwd;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar struct group *grp;
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl int erc = 0;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if (!name || !acls)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar st = &acls->acl_attr;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_attr: %s uid %d gid %d uname %s gname %s "
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar "mode %o", name, st->st_uid, st->st_gid, acls->uname, acls->gname,
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar st->st_mode);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uid = st->st_uid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((pwd = getpwnam(acls->uname)) != NULL) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_attr: new uid %d old %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar pwd->pw_uid, uid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar uid = pwd->pw_uid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gid = st->st_gid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar if ((grp = getgrnam(acls->gname)) != NULL) {
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_attr: new gid %d old %d",
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar grp->gr_gid, gid);
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar gid = grp->gr_gid;
b6b15642ffbc95b31765357dc6cc036b590c3a97Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = lchown(name, uid, gid);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = errno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not set uid or/and gid for file %s.", name);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((st->st_mode & (S_ISUID | S_ISGID)) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Change effective privileges to 'all' which is required to
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * change setuid bit for 'root' owned files. If fails, just
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * send error to log file and proceed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_set_eprivs_all()) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not set effective privileges to 'all'.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar priv_all = TRUE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar if (!S_ISLNK(st->st_mode)) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = chmod(name, st->st_mode);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = errno;
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar NDMP_LOG(LOG_ERR, "Could not set correct file"
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl " permission for file %s: %d", name, errno);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar tbuf.modtime = st->st_mtime;
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar tbuf.actime = st->st_atime;
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar (void) utime(name, &tbuf);
859b77458b5f7417d1e612e13d69159c0d6a894eReza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (priv_all == TRUE) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Give up the 'all' privileges for effective sets and go back
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to least required privileges. If fails, just send error to
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * log file and proceed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ndmp_set_eprivs_least())
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Could not set least required privileges.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Set the ACL info for the file
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Krylstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarset_acl(char *name, tlm_acls_t *acls)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int erc;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar acl_t *aclp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (name)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "set_acl: %s", name);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (acls == NULL)
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl /* Need a place to save real modification time */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = set_attr(name, acls);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (ERROR_IS_FATAL(erc))
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (!acls->acl_non_trivial) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl (void) memset(acls, 0, sizeof (tlm_acls_t));
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_DEBUG, "set_acl: skipping trivial");
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = acl_fromtext(acls->acl_info.attr_info, &aclp);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc != 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl NDMP_LOG(LOG_DEBUG,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "TAPE RESTORE> acl_fromtext errno %d", erc);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (aclp) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = acl_set(name, aclp);
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl if (erc < 0) {
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl erc = errno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl "TAPE RESTORE> acl_set errno %d", errno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl acl_free(aclp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl (void) memset(acls, 0, sizeof (tlm_acls_t));
2efb3bf9c7f4cf34038896f1431531c93d3f57c2Jan Kryl return (erc);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * a wrapper to tlm_get_read_buffer so that
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * we can cleanly detect ABORT commands
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * without involving the TLM library with
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * our problems.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_read_buffer(int want,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *error,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int *actual_size,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *local_commands)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (local_commands->tc_writer == TLM_RESTORE_RUN) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rec;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rec = tlm_get_read_buffer(want, error,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar local_commands->tc_buffers, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rec != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rec);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * the job is ending, give Writer a buffer that will never be read ...
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * it does not matter anyhow, we are aborting.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *actual_size = RECORDSIZE;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Enable wildcard for restore options
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic boolean_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarwildcard_enabled(void)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *cp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar cp = ndmpd_get_prop_default(NDMP_RESTORE_WILDCARD_ENABLE, "n");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ((toupper(*cp) == 'Y') ? TRUE : FALSE);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Concatenate two names
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*ARGSUSED*/
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarcatnames(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!buf) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "buf is NULL");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!path) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "path is NULL");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!rnp->rn_nlp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "rn_nlp is NULL [%s]", path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!tlm_cat_path(buf, rnp->rn_nlp, path)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Path too long [%s][%s]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rnp->rn_nlp, path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create a new name path for restore
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarrs_new_name(struct rs_name_maker *rnp, char *buf, int pos, char *path)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!rnp || !rnp->rn_fp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (*rnp->rn_fp)(rnp, buf, pos, path);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar/*
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar * Clear the extra "/" in the tar header if exists
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar */
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdarstatic void
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdarrs_create_new_bkpath(char *bk_path, char *path, char *pbuf)
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar{
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar char *p, *slashp;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar if ((p = strstr(path, bk_path)) == NULL) {
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar (void) strlcpy(pbuf, path, TLM_MAX_PATH_NAME);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar return;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar }
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar if (*(p += strlen(bk_path)) == '/')
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar p++;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar slashp = bk_path + strlen(bk_path) - 1;
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar if (*slashp == '/')
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar (void) snprintf(pbuf, TLM_MAX_PATH_NAME, "%s%s", bk_path, p);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar else
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar (void) snprintf(pbuf, TLM_MAX_PATH_NAME, "%s/%s", bk_path, p);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar NDMP_LOG(LOG_DEBUG, "old path [%s] new path [%s]", path, pbuf);
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar}
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
fb4eb4e8c8161158740a5a4057e45ec942165dc2Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Iterate over ZFS metadata stored in the backup stream and use the callback
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * to restore it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_iter_zfs(ndmp_context_t *nctx, int (*np_restore_property)(nvlist_t *,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar void *), void *ptr)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_commands_t *cmds;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_metadata_header_t *mhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_header_ext_t *mhpx;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_metadata_property_t *mpp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar ndmp_metadata_property_ext_t *mppx;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *lcmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_t *nvl;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_t *valp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvpair_t *nvp = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char plname[100];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *mhbuf, *pp, *tp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv, i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int size, lsize, sz;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int align = RECORDSIZE - 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nctx->nc_plname = plname;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((lcmd = cmds->tcs_command) == NULL ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lcmd->tc_buffers == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* Default minimum bytes needed */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size = sizeof (ndmp_metadata_header_t) +
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ZFS_MAX_PROPS * sizeof (ndmp_metadata_property_t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size += align;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size &= ~align;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((mhbuf = malloc(size)) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, lcmd)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp = mhbuf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strncmp(mhp->nh_magic, ZFS_META_MAGIC,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (mhp->nh_magic)) != 0 &&
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (mhp->nh_magic)) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* No more metadata */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar free(mhbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (mhp->nh_magic)) == 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhpx = (ndmp_metadata_header_ext_t *)mhp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhpx->nh_total_bytes > size) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if ((pp = realloc(mhbuf, mhpx->nh_total_bytes))
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar == NULL) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar free(mhbuf);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhbuf = pp;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar size = mhpx->nh_total_bytes;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memcpy(pp, (char *)mhp, (actual_size < size) ?
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar actual_size : size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp += (actual_size < size) ? actual_size : size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sz = actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (sz < size &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((tp = get_read_buffer(size - sz, &rv, &lsize,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lcmd))) != NULL) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) memcpy(pp, tp, lsize);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sz += lsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar pp += lsize;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (sz > size) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, sz - size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar mhp = (ndmp_metadata_header_t *)mhbuf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvl = NULL;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (strncmp(mhp->nh_magic, ZFS_META_MAGIC_EXT,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (mhp->nh_magic)) == 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* New metadata format */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* LINTED improper alignment */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhpx = (ndmp_metadata_header_ext_t *)mhbuf;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhpx->nh_major > META_HDR_MAJOR_VERSION) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* Major header mismatch */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar NDMP_LOG(LOG_ERR, "metadata header mismatch",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar "M%d != M%d", mhpx->nh_major,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar META_HDR_MAJOR_VERSION);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar free(mhbuf);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar return (-1);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (mhpx->nh_major == META_HDR_MAJOR_VERSION &&
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhpx->nh_minor > META_HDR_MINOR_VERSION) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar /* Minor header mismatch */
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar NDMP_LOG(LOG_ERR, "Warning:"
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar "metadata header mismatch m%d != m%d",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mhpx->nh_minor,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar META_HDR_MINOR_VERSION);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar continue;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nctx->nc_plversion = mhpx->nh_plversion;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(plname, mhpx->nh_plname,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (plname));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto nvlist_err;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mppx = &mhpx->nh_property[0];
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar for (i = 0; i < mhpx->nh_count && mppx; i++, mppx++) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (!*mppx->mp_name)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar continue;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar valp = NULL;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (nvlist_alloc(&valp,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar NV_UNIQUE_NAME, 0) != 0 ||
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_add_string(valp, "value",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mppx->mp_value) != 0 ||
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_add_string(valp, "source",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mppx->mp_source) != 0 ||
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_add_nvlist(nvl, mppx->mp_name,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar valp) != 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(valp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar goto nvlist_err;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(valp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar } else {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nctx->nc_plversion = mhp->nh_plversion;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar (void) strlcpy(plname, mhp->nh_plname,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar sizeof (plname));
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar goto nvlist_err;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mpp = &mhp->nh_property[0];
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar for (i = 0; i < mhp->nh_count && mpp; i++, mpp++) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (!*mpp->mp_name)
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar continue;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar valp = NULL;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar if (nvlist_alloc(&valp,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar NV_UNIQUE_NAME, 0) != 0 ||
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_add_string(valp, "value",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mpp->mp_value) != 0 ||
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_add_string(valp, "source",
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar mpp->mp_source) != 0 ||
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_add_nvlist(nvl, mpp->mp_name,
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar valp) != 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(valp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar goto nvlist_err;
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(valp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (np_restore_property(nvl, ptr) != 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar goto nvlist_err;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvpair_value_nvlist(nvp, &valp) == 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(valp);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(nvl);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar free(mhbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarnvlist_err:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(mhbuf);
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL &&
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvpair_value_nvlist(nvp, &valp) == 0) {
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(valp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
42ed7838f131b8f58d6c95db1c7e3a6a3e6ea7e4Reza Sabdar nvlist_free(nvl);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the version number of the plugin which created the metadata
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdaruint_t
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmp_context_get_version(ndmp_context_t *nctx)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_commands_t *cmds;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ndmp_metadata_header_t *mhp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_cmd_t *lcmd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int actual_size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int size;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int align = RECORDSIZE - 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (nctx == NULL || (cmds = (tlm_commands_t *)nctx->nc_cmds) == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((lcmd = cmds->tcs_command) == NULL ||
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar lcmd->tc_buffers == NULL)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size = sizeof (ndmp_metadata_header_t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size += align;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar size &= ~align;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED improper alignment */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((mhp = (ndmp_metadata_header_t *)get_read_buffer(size, &rv,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &actual_size, lcmd)) != NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strncmp(mhp->nh_magic, ZFS_META_MAGIC,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar sizeof (mhp->nh_magic)) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* No more metadata */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nctx->nc_plversion = mhp->nh_plversion;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tlm_unget_read_buffer(lcmd->tc_buffers, actual_size);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (nctx->nc_plversion);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}