2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens * Copyright (c) 2015 by Delphix. 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
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/param.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <sys/types.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <ctype.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <errno.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <fcntl.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <limits.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdarg.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdio.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <stdlib.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <string.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <time.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <unistd.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include <libnvpair.h>
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd_log.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#include "ndmpd.h"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The dumpdates file on file system.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define NDMP_DUMPDATES "dumpdates"
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Offsets into the ctime string to various parts.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define E_MONTH 4
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define E_DAY 8
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define E_HOUR 11
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define E_MINUTE 14
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define E_SECOND 17
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar#define E_YEAR 20
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The contents of the file dumpdates is maintained on a linked list.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdartypedef struct dumpdates {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char dd_name[TLM_MAX_PATH_NAME];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char dd_level;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar time_t dd_ddate;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct dumpdates *dd_next;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar} dumpdates_t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Month names used in ctime string.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Binary lock for accessing the dumpdates file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmutex_t ndmp_dd_lock = DEFAULTMUTEX;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint ndmp_isdst = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarchar *zfs_dumpdate_props[] = {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level0",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level1",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level2",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level3",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level4",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level5",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level6",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level7",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level8",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "dumpdates:level9",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar};
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * lookup
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Look up the month (3-character) name and return its number.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns -1 if the months name is not valid.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarlookup(char *str)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar register char *cp, *cp2;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!str)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strncmp(cp, cp2, 3) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return ((cp-months) / 3);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * unctime
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Convert a ctime(3) format string into a system format date.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return the date thus calculated.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Return -1 if the string is not in ctime format.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarunctime(char *str, time_t *t)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar struct tm then;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char dbuf[26];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!str || !t)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset(&then, 0, sizeof (then));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(dbuf, str, sizeof (dbuf) - 1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbuf[sizeof (dbuf) - 1] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dbuf[E_MONTH+3] = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_mday = atoi(&dbuf[E_DAY]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_hour = atoi(&dbuf[E_HOUR]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_min = atoi(&dbuf[E_MINUTE]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_sec = atoi(&dbuf[E_SECOND]);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_year = atoi(&dbuf[E_YEAR]) - 1900;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_isdst = ndmp_isdst;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "yday %d wday %d %d/%d/%d %02d:%02d:%02d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_yday, then.tm_wday, then.tm_year, then.tm_mon,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar then.tm_mday, then.tm_hour, then.tm_min, then.tm_sec);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *t = mktime(&then);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ddates_pathname
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Create the dumpdates file full path name.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarddates_pathname(char *buf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (ndmpd_make_bk_dir_path(buf, NDMP_DUMPDATES));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
23a1ccea6aac035f084a7a4cdc968687d1b02dafRoger A. Faulkner * getaline
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get a line from the file and handle the continued lines.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
23a1ccea6aac035f084a7a4cdc968687d1b02dafRoger A. Faulknergetaline(FILE *fp, char *line, int llen)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *save;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp || !line)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *(save = line) = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fgets(line, llen, fp) != line)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* comment line? */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*line == '#')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar len = strlen(line);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* short line */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (len <= 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar line += len-1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*line != '\n')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* trim the trailing new line */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *line = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (--len <= 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*(line-1) != '\\')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *(line-1) = '\n';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar llen -= len;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (llen > 0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (save);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * get_ddname
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the path name from the buffer passed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the beginning of the path name. The buffer pointer is moved
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * forward to point to where the next field (the dump level) begins.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_ddname(char **bpp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *h, *t, *save;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bpp || !*bpp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp += strspn(*bpp, "\t ");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = h = t = *bpp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (*t) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*t == '\t' || *t == ' ') {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* consume the '\t' or space character */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar t++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*t == '\\')
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (*(t+1)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case '\t':
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ' ':
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar t++; /* skip the '\\' */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break; /* nothing */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *h++ = *t++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp = t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *h++ = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (save);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * get_ddlevel
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the dump level from the buffer passed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the dump level found. The buffer pointer is moved
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * forward to point to where the next field (the dump date) begins.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_ddlevel(char **bpp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *t, *save;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bpp || !*bpp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp += strspn(*bpp, "\t ");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = t = *bpp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * For 'F', 'A', 'I', and 'D' return the character itself.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_LBR_BKTYPE(*t)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Lbr bk type %c", *t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Skip the backup type character and null terminate the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * string.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *++t = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp = ++t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (toupper(*save));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (isdigit(*t))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar t++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *t++ = '\0';
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp = t;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (atoi(save));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * get_ddate
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the dump date from the buffer passed.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns the dump date string. The buffer pointer is moved
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * forward. It points to the end of the buffer now.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic char *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarget_ddate(char **bpp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *save;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!bpp || !*bpp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (NULL);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp += strspn(*bpp, "\t ");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = *bpp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *bpp += strlen(*bpp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (save);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * put_ddname
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Print the dump path name to the dumpdates file. It escapes the space,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * '\t' and new line characters in the path name. The same characters are
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * considered in the get_ddname().
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarput_ddname(FILE *fp, char *nm)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!nm)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (*nm)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar switch (*nm) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case ' ':
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case '\n':
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar case '\t':
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fputc('\\', fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* FALLTHROUGH */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar default:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fputc(*nm++, fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * put_ddlevel
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Print the dump level into the dumpdates file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarput_ddlevel(FILE *fp, int level)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fprintf(fp, IS_LBR_BKTYPE(level) ? "%c" : "%d", level);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * put_ddate
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Print the dump date into the dumpdates file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void put_ddate(FILE *fp,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar time_t t)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char tbuf[64];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%u]", t);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ctime_r(&t, tbuf, sizeof (tbuf));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* LINTED variable format specifier */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fprintf(fp, tbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dd_free
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Free the linked list of dumpdates entries.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardd_free(dumpdates_t *ddheadp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumpdates_t *save;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddheadp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddheadp = ddheadp->dd_next;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar while (ddheadp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = ddheadp->dd_next;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(ddheadp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddheadp = save;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * makedumpdate
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Make the dumpdate node based on the string buffer passed to it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarmakedumpdate(dumpdates_t *ddp, char *tbuf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char *nmp, *un_buf;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * While parsing each line, if a line contains one of the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * LBR-type levels, then checking the return value of
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * get_ddlevel() against negative values, it OK. Because
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * neither of the 'F', 'A', 'I' nor 'D' have negative
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * ASCII value.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddp || !tbuf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar else if (!(nmp = get_ddname(&tbuf))) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "get_ddname failed 0x%p", nmp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if ((ddp->dd_level = get_ddlevel(&tbuf)) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "dd_level < 0 %d", ddp->dd_level);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (!(un_buf = get_ddate(&tbuf))) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "get_ddate failed 0x%p", un_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else if (unctime(un_buf, &ddp->dd_ddate) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = -1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "unctime failed \"%s\"", un_buf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(ddp->dd_name, nmp, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * getrecord
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read a record of dumpdates file and parse it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * The records that span multiple lines are covered.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on success
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0 on error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdargetrecord(FILE *fp, dumpdates_t *ddatep, int *recno)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char tbuf[BUFSIZ];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp || !ddatep || !recno)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar do {
23a1ccea6aac035f084a7a4cdc968687d1b02dafRoger A. Faulkner if (getaline(fp, tbuf, sizeof (tbuf)) != tbuf)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } while (!*tbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (makedumpdate(ddatep, tbuf) < 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Unknown intermediate format in %s, line %d", tbuf, *recno);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (*recno)++;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_LBR_BKTYPE(ddatep->dd_level & 0xff)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddatep->dd_name, ddatep->dd_level, ddatep->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddatep->dd_name, ddatep->dd_level, ddatep->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * readdumptimes
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Read the dumpdates file and make a linked list of its entries.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on success
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0 on error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarreaddumptimes(FILE *fp, dumpdates_t *ddheadp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int recno;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar register struct dumpdates *ddwalk;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp || !ddheadp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar recno = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *)ddheadp, 0, sizeof (*ddheadp));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (; ; ) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddwalk = ndmp_malloc(sizeof (*ddwalk));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddwalk)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (getrecord(fp, ddwalk, &recno) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar free(ddwalk);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddwalk->dd_next = ddheadp->dd_next;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddheadp->dd_next = ddwalk;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddheadp = ddwalk;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * dumprecout
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Print a record into the dumpdates file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic void
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdardumprecout(FILE *fp, dumpdates_t *ddp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_LBR_BKTYPE(ddp->dd_level)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar put_ddname(fp, ddp->dd_name);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fputc('\t', fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar put_ddlevel(fp, ddp->dd_level);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fputc('\t', fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar put_ddate(fp, ddp->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * initdumptimes
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Open the dumpdates file and read it into memory.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on success
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0 on error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarinitdumptimes(dumpdates_t *ddheadp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char fname[PATH_MAX];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar FILE *fp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddheadp)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddates_pathname(fname))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fp = fopen(fname, "r");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (errno != ENOENT) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot read %s: %m.", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Dumpdates does not exist, make an empty one.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "No file `%s', making an empty one", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fp = fopen(fname, "w");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot create %s: %m.", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fp = fopen(fname, "r");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Cannot read %s after creating it. %m.", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = readdumptimes(fp, ddheadp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * putdumptime
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put the record specified by path, level and backup date to the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Update the record if such entry already exists; append if not.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on success
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0 on error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarputdumptime(char *path, int level, time_t ddate)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int found;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char fname[PATH_MAX], bakfname[PATH_MAX];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar FILE *rfp, *wfp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumpdates_t ddhead, tmpdd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar register dumpdates_t *ddp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!path)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_LBR_BKTYPE(level)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Lbr: [%s][%c][%u]", path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]", path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ddates_pathname(fname)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot get dumpdate file path name.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rfp = fopen(fname, "r");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!rfp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Creating %s.", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *)&ddhead, 0, sizeof (ddhead));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (initdumptimes(&ddhead) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Could not initialize %s.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_DUMPDATES);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dd_free(&ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = readdumptimes(rfp, &ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (rv < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Error reading dumpdates file.");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(rfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dd_free(&ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(rfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(bakfname, PATH_MAX, "%s.bak", fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar wfp = fopen(bakfname, "w");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!wfp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot open %s: %m.", bakfname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dd_free(&ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%s]", fname, bakfname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* try to locate the entry in the file */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (ddp = ddhead.dd_next; ddp; ddp = ddp->dd_next) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ddp->dd_level != level)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (strcmp(path, ddp->dd_name))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar continue;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "Found: [%s][%d][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* update the record for the entry */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar found = 1;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddp->dd_ddate = ddate;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Updated to: [%s][%d][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddp->dd_name, ddp->dd_level, ddp->dd_ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* dump all the read records */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (ddp = ddhead.dd_next; ddp; ddp = ddp->dd_next)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumprecout(wfp, ddp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dd_free(&ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* append a new record */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!found) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tmpdd.dd_name, path, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tmpdd.dd_level = level;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tmpdd.dd_ddate = ddate;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumprecout(wfp, &tmpdd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(wfp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) rename(bakfname, fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * append_dumptime
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Append the record specified by path, level and backup date to the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic int
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarappend_dumptime(char *fname, char *path, int level, time_t ddate)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char fpath[PATH_MAX], bakfpath[PATH_MAX];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar FILE *fp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumpdates_t tmpdd;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fname || !*fname || !path || !*path)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_LBR_BKTYPE(level & 0xff)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "Lbr: [%s][%s][%c][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fname, path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%s][%d][%u]",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fname, path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!ndmpd_make_bk_dir_path(fpath, fname)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot get dumpdate file path name %s.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fname);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) snprintf(bakfpath, PATH_MAX, "%s.bak", fpath);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If the file is there and can be opened then make a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * backup copy it.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fp = fopen(fpath, "r");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (fp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (filecopy(bakfpath, fpath) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot copy %s to %s: %m.",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fpath, bakfpath);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* open the new copy to append the record to it */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar fp = fopen(bakfpath, "a");
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!fp) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_ERR, "Cannot open %s: %m.", bakfpath);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%s]", fpath, bakfpath);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* append a new record */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) strlcpy(tmpdd.dd_name, path, TLM_MAX_PATH_NAME);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tmpdd.dd_level = level;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar tmpdd.dd_ddate = ddate;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumprecout(fp, &tmpdd);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) fclose(fp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) rename(bakfpath, fpath);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * find_date
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Find the specified date
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarstatic dumpdates_t *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarfind_date(dumpdates_t *ddp, char *path, int level, time_t t)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (; ddp; ddp = ddp->dd_next)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (ddp->dd_level == level && ddp->dd_ddate > t &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar strcmp(path, ddp->dd_name) == 0)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (ddp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Get the dumpdate of the last level backup done on the path.
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar * The last level normally is (level - 1) in case of NetBackup
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar * but some DMAs allow that previous level could be anything
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar * between 0 and the current level.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on success
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0 on error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_get_dumptime(char *path, int *level, time_t *ddate)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int i;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dumpdates_t ddhead, *ddp, *save;
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char vol[ZFS_MAX_DATASET_NAME_LEN];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar nvlist_t *userprops;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_handle_t *zhp;
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar nvlist_t *propval = NULL;
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar char *strval = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!path || !level || !ddate)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s] level %d",
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar path, *level);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (*level == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = (time_t)0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check if this is a ZFS dataset */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((zlibh != NULL) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar if ((userprops = zfs_get_user_props(zhp)) == NULL) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *level = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = (time_t)0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_close(zhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar for (i = *level - 1; i >= 0; i--) {
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar if (nvlist_lookup_nvlist(userprops,
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar zfs_dumpdate_props[i], &propval) == 0) {
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar *level = i;
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar break;
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar }
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar }
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar if (propval == NULL ||
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar nvlist_lookup_string(propval, ZPROP_VALUE,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar &strval) != 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *level = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = (time_t)0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_close(zhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
f3012b5938cc7fcdee754ac9bb2817f86ebd9e92Reza Sabdar if (unctime(strval, ddate) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_close(zhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_close(zhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) memset((void *)&ddhead, 0, sizeof (ddhead));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (initdumptimes(&ddhead) < 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dd_free(&ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (-1);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Empty dumpdates file means level 0 for all paths.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((ddp = ddhead.dd_next) == 0) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!IS_LBR_BKTYPE(*level & 0xff))
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *level = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * If it's not level backup, then find the exact record
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * type.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (IS_LBR_BKTYPE(*level & 0xff)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = find_date(ddp, path, *level, *ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar "LBR_BKTYPE save 0x%p", save);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = save ? save->dd_ddate : (time_t)0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar } else {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Go find the entry with the same name for a maximum of a
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * lower increment and older date.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = NULL;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar for (i = *level - 1; i >= 0; i--) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar save = find_date(ddp, path, i, *ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (save) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *level = save->dd_level;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = save->dd_ddate;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar break;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if (!save) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *level = 0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *ddate = (time_t)0;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar dd_free(&ddhead);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (0);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Put the date and the level of the back up for the
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * specified path in the dumpdates file. If there is a line
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * for the same path and the same level, the date is updated.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Otherwise, a line is appended to the file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar *
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Returns:
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * 0 on success
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * < 0 on error
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_put_dumptime(char *path, int level, time_t ddate)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char vol[ZFS_MAX_DATASET_NAME_LEN];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_handle_t *zhp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char tbuf[64];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%d][%u]", path, level,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check if this is a ZFS dataset */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((zlibh != NULL) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ctime_r(&ddate, tbuf, sizeof (tbuf));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = zfs_prop_set(zhp, zfs_dumpdate_props[level], tbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_close(zhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&ndmp_dd_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = putdumptime(path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&ndmp_dd_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar/*
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar * Append a backup date record to the specified file.
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarint
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdarndmpd_append_dumptime(char *fname, char *path, int level, time_t ddate)
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar{
9adfa60d484ce2435f5af77cc99dcd4e692b6660Matthew Ahrens char vol[ZFS_MAX_DATASET_NAME_LEN];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_handle_t *zhp;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar char tbuf[64];
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar int rv;
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar NDMP_LOG(LOG_DEBUG, "[%s][%s][%d][%u]", fname,
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar /* Check if this is a ZFS dataset */
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar if ((zlibh != NULL) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (get_zfsvolname(vol, sizeof (vol), path) == 0) &&
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar ((zhp = zfs_open(zlibh, vol, ZFS_TYPE_DATASET)) != NULL)) {
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) ctime_r(&ddate, tbuf, sizeof (tbuf));
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = zfs_prop_set(zhp, zfs_dumpdate_props[level], tbuf);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar zfs_close(zhp);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar }
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&zlib_mtx);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_lock(&ndmp_dd_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar rv = append_dumptime(fname, path, level, ddate);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar (void) mutex_unlock(&ndmp_dd_lock);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar return (rv);
2654012f83cec5dc15b61dfe3e4a4915f186e7a6Reza Sabdar}