xref: /illumos-gate/usr/src/cmd/backup/dump/dumpitime.c (revision e0dfa398)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * Copyright 1996-1998, 2002-2003 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
157c478bd9Sstevel@tonic-gate #include "dump.h"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #ifndef LOCK_EX
18*e0dfa398SToomas Soome static	struct flock fl;
197c478bd9Sstevel@tonic-gate #define	flock(fd, flag) (fl.l_type = (flag), fcntl(fd, F_SETLKW, &fl))
207c478bd9Sstevel@tonic-gate #define	LOCK_EX F_WRLCK
217c478bd9Sstevel@tonic-gate #define	LOCK_SH F_RDLCK
227c478bd9Sstevel@tonic-gate #define	LOCK_UN F_UNLCK
237c478bd9Sstevel@tonic-gate #endif
247c478bd9Sstevel@tonic-gate 
25*e0dfa398SToomas Soome char		*disk;
26*e0dfa398SToomas Soome char		*dname;
27*e0dfa398SToomas Soome char		*increm;
28*e0dfa398SToomas Soome 
29*e0dfa398SToomas Soome char		incno;
30*e0dfa398SToomas Soome char		lastincno;
31*e0dfa398SToomas Soome int		uflag;
32*e0dfa398SToomas Soome uint_t		msiz;
33*e0dfa398SToomas Soome u_offset_t	o_esize;
34*e0dfa398SToomas Soome u_offset_t	f_esize;
35*e0dfa398SToomas Soome 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * Print a date.  A date of 0 is the beginning of time (the "epoch").
387c478bd9Sstevel@tonic-gate  * If the 2nd argument is non-zero, it is ok to format the date in
397c478bd9Sstevel@tonic-gate  * locale-specific form, otherwise we use ctime.  We must use ctime
407c478bd9Sstevel@tonic-gate  * for dates such as those in the dumpdates file, which must be
417c478bd9Sstevel@tonic-gate  * locale-independent.
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate char *
prdate(time_t d)44*e0dfa398SToomas Soome prdate(time_t d)
457c478bd9Sstevel@tonic-gate {
467c478bd9Sstevel@tonic-gate 	static char buf[256];
477c478bd9Sstevel@tonic-gate 	struct tm *tm;
487c478bd9Sstevel@tonic-gate 	char *p;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	if (d == 0)
517c478bd9Sstevel@tonic-gate 		return (gettext("the epoch"));
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate 	tm = localtime(&d);
547c478bd9Sstevel@tonic-gate 	if (strftime(buf, sizeof (buf), "%c", tm) != 0) {
557c478bd9Sstevel@tonic-gate 		p = buf;
567c478bd9Sstevel@tonic-gate 	} else {
577c478bd9Sstevel@tonic-gate 		/* Wouldn't fit in buf, fall back */
587c478bd9Sstevel@tonic-gate 		p = ctime(&d);
597c478bd9Sstevel@tonic-gate 		p[24] = '\0';	/* lose trailing newline */
607c478bd9Sstevel@tonic-gate 	}
617c478bd9Sstevel@tonic-gate 	return (p);
627c478bd9Sstevel@tonic-gate }
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate struct	idates	**idatev = 0;
657c478bd9Sstevel@tonic-gate size_t	nidates = 0;
667c478bd9Sstevel@tonic-gate static	int	idates_in = 0;		/* we have read the increment file */
677c478bd9Sstevel@tonic-gate static	int	recno;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate #ifdef __STDC__
707c478bd9Sstevel@tonic-gate static void readitimes(FILE *);
717c478bd9Sstevel@tonic-gate static void recout(FILE	*, struct idates *);
727c478bd9Sstevel@tonic-gate static int getrecord(FILE *, struct idates *);
737c478bd9Sstevel@tonic-gate static int makeidate(struct idates *, char *);
747c478bd9Sstevel@tonic-gate #else
757c478bd9Sstevel@tonic-gate static void readitimes();
767c478bd9Sstevel@tonic-gate static void recout();
777c478bd9Sstevel@tonic-gate static int getrecord();
787c478bd9Sstevel@tonic-gate static int makeidate();
797c478bd9Sstevel@tonic-gate #endif
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate void
inititimes(void)827c478bd9Sstevel@tonic-gate inititimes(void)
837c478bd9Sstevel@tonic-gate {
847c478bd9Sstevel@tonic-gate 	FILE *df;
857c478bd9Sstevel@tonic-gate 	int saverr;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	if (idates_in)
887c478bd9Sstevel@tonic-gate 		return;
897c478bd9Sstevel@tonic-gate 	if (increm == NULL || *increm == '\0') {
907c478bd9Sstevel@tonic-gate 		msg(gettext("inititimes: No dump record file name defined\n"));
917c478bd9Sstevel@tonic-gate 		dumpabort();
927c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
937c478bd9Sstevel@tonic-gate 	}
947c478bd9Sstevel@tonic-gate 	/*
957c478bd9Sstevel@tonic-gate 	 * No need to secure this, as increm is hard-coded to NINCREM,
967c478bd9Sstevel@tonic-gate 	 * and that file is in /etc.  If random people have write-permission
977c478bd9Sstevel@tonic-gate 	 * there, then there are more problems than any degree of paranoia
987c478bd9Sstevel@tonic-gate 	 * on our part can fix.
997c478bd9Sstevel@tonic-gate 	 */
1007c478bd9Sstevel@tonic-gate 	if ((df = fopen(increm, "r")) == NULL) {
1017c478bd9Sstevel@tonic-gate 		saverr = errno;
1027c478bd9Sstevel@tonic-gate 		if (errno == ENOENT)
1037c478bd9Sstevel@tonic-gate 			msg(gettext(
1047c478bd9Sstevel@tonic-gate 			    "Warning - dump record file `%s' does not exist\n"),
105*e0dfa398SToomas Soome 			    increm);
1067c478bd9Sstevel@tonic-gate 		else {
1077c478bd9Sstevel@tonic-gate 			msg(gettext("Cannot open dump record file `%s': %s\n"),
108*e0dfa398SToomas Soome 			    increm, strerror(saverr));
1097c478bd9Sstevel@tonic-gate 			dumpabort();
1107c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
1117c478bd9Sstevel@tonic-gate 		}
1127c478bd9Sstevel@tonic-gate 		return;
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 	if (uflag && access(increm, W_OK) < 0) {
1157c478bd9Sstevel@tonic-gate 		msg(gettext("Cannot access dump record file `%s' for update\n"),
1167c478bd9Sstevel@tonic-gate 		    increm);
1177c478bd9Sstevel@tonic-gate 		dumpabort();
1187c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 	(void) flock(fileno(df), LOCK_SH);
1217c478bd9Sstevel@tonic-gate 	readitimes(df);
1227c478bd9Sstevel@tonic-gate 	(void) fclose(df);
1237c478bd9Sstevel@tonic-gate }
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate static void
readitimes(FILE * df)126*e0dfa398SToomas Soome readitimes(FILE *df)
1277c478bd9Sstevel@tonic-gate {
1287c478bd9Sstevel@tonic-gate 	struct idates *idp;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	recno = 0;
1317c478bd9Sstevel@tonic-gate 	for (;;) {
1327c478bd9Sstevel@tonic-gate 		idp = (struct idates *)xcalloc(1, sizeof (*idp));
1337c478bd9Sstevel@tonic-gate 		if (getrecord(df, idp) < 0) {
1347c478bd9Sstevel@tonic-gate 			free((char *)idp);
1357c478bd9Sstevel@tonic-gate 			break;
1367c478bd9Sstevel@tonic-gate 		}
1377c478bd9Sstevel@tonic-gate 		nidates++;
1387c478bd9Sstevel@tonic-gate 		idatev = (struct idates **)xrealloc((void *)idatev,
1397c478bd9Sstevel@tonic-gate 		    nidates * (size_t)sizeof (*idatev));
1407c478bd9Sstevel@tonic-gate 		idatev[nidates - 1] = idp;
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 	/* LINTED: assigned value is used in inititimes */
1437c478bd9Sstevel@tonic-gate 	idates_in = 1;
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate void
getitime(void)1477c478bd9Sstevel@tonic-gate getitime(void)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate 	struct	idates	*ip;
1507c478bd9Sstevel@tonic-gate 	int	i;
1517c478bd9Sstevel@tonic-gate 	char	*fname;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	/*
1547c478bd9Sstevel@tonic-gate 	 * if an alternate name was specified via the N flag, use it instead
1557c478bd9Sstevel@tonic-gate 	 * of the disk name.
1567c478bd9Sstevel@tonic-gate 	 */
1577c478bd9Sstevel@tonic-gate 	if (dname != NULL)
1587c478bd9Sstevel@tonic-gate 		fname = dname;
1597c478bd9Sstevel@tonic-gate 	else
1607c478bd9Sstevel@tonic-gate 		fname = disk;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate #ifdef FDEBUG
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	/* XGETTEXT:  #ifdef FDEBUG only */
1657c478bd9Sstevel@tonic-gate 	msg(gettext("Looking for name %s in increm = %s for delta = %c\n"),
166*e0dfa398SToomas Soome 	    fname, increm, (uchar_t)incno);
1677c478bd9Sstevel@tonic-gate #endif
1687c478bd9Sstevel@tonic-gate 	spcl.c_ddate = 0;
1697c478bd9Sstevel@tonic-gate 	lastincno = '0';
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	inititimes();
1727c478bd9Sstevel@tonic-gate 	if (idatev == 0)
1737c478bd9Sstevel@tonic-gate 		return;
1747c478bd9Sstevel@tonic-gate 	/*
1757c478bd9Sstevel@tonic-gate 	 *	Go find the entry with the same name for a lower increment
1767c478bd9Sstevel@tonic-gate 	 *	and older date
1777c478bd9Sstevel@tonic-gate 	 */
1787c478bd9Sstevel@tonic-gate 	ITITERATE(i, ip) {
1797c478bd9Sstevel@tonic-gate 		if (strncmp(fname, ip->id_name, sizeof (ip->id_name)) != 0)
1807c478bd9Sstevel@tonic-gate 			continue;
1817c478bd9Sstevel@tonic-gate 		if (ip->id_incno >= incno)
1827c478bd9Sstevel@tonic-gate 			continue;
1837c478bd9Sstevel@tonic-gate 		if (ip->id_ddate <= spcl.c_ddate)
1847c478bd9Sstevel@tonic-gate 			continue;
1857c478bd9Sstevel@tonic-gate 		spcl.c_ddate = ip->id_ddate;
1867c478bd9Sstevel@tonic-gate 		lastincno = ip->id_incno;
1877c478bd9Sstevel@tonic-gate 	}
1887c478bd9Sstevel@tonic-gate }
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate void
putitime(void)1917c478bd9Sstevel@tonic-gate putitime(void)
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate 	FILE		*df;
1947c478bd9Sstevel@tonic-gate 	struct	idates	*itwalk;
1957c478bd9Sstevel@tonic-gate 	int		i;
1967c478bd9Sstevel@tonic-gate 	int		fd, saverr;
1977c478bd9Sstevel@tonic-gate 	char		*fname;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	if (uflag == 0)
2007c478bd9Sstevel@tonic-gate 		return;
2017c478bd9Sstevel@tonic-gate 	if ((df = safe_fopen(increm, "r+", 0664)) == (FILE *)NULL) {
2027c478bd9Sstevel@tonic-gate 		msg("%s: %s\n", increm, strerror(errno));
2037c478bd9Sstevel@tonic-gate 		(void) unlink(increm);
2047c478bd9Sstevel@tonic-gate 		dumpabort();
2057c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
2067c478bd9Sstevel@tonic-gate 	}
2077c478bd9Sstevel@tonic-gate 	fd = fileno(df);
2087c478bd9Sstevel@tonic-gate 	(void) flock(fd, LOCK_EX);
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate 	/*
2117c478bd9Sstevel@tonic-gate 	 * if an alternate name was specified via the N flag, use it instead
2127c478bd9Sstevel@tonic-gate 	 * of the disk name.
2137c478bd9Sstevel@tonic-gate 	 */
2147c478bd9Sstevel@tonic-gate 	if (dname != NULL)
2157c478bd9Sstevel@tonic-gate 		fname = dname;
2167c478bd9Sstevel@tonic-gate 	else
2177c478bd9Sstevel@tonic-gate 		fname = disk;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	if (idatev != 0) {
2207c478bd9Sstevel@tonic-gate 		for (i = 0; i < nidates && idatev[i] != 0; i++)
2217c478bd9Sstevel@tonic-gate 			free((char *)idatev[i]);
2227c478bd9Sstevel@tonic-gate 		free((char *)idatev);
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 	idatev = 0;
2257c478bd9Sstevel@tonic-gate 	nidates = 0;
2267c478bd9Sstevel@tonic-gate 	readitimes(df);
2277c478bd9Sstevel@tonic-gate 	if (fseek(df, 0L, 0) < 0) {   /* rewind() was redefined in dumptape.c */
2287c478bd9Sstevel@tonic-gate 		saverr = errno;
2297c478bd9Sstevel@tonic-gate 		msg(gettext("%s: %s error:\n"),
230*e0dfa398SToomas Soome 		    increm, "fseek", strerror(saverr));
2317c478bd9Sstevel@tonic-gate 		dumpabort();
2327c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 	spcl.c_ddate = 0;
2357c478bd9Sstevel@tonic-gate 	/* LINTED: won't dereference idatev if it is NULL (see readitimes) */
2367c478bd9Sstevel@tonic-gate 	ITITERATE(i, itwalk) {
2377c478bd9Sstevel@tonic-gate 		if (strncmp(fname, itwalk->id_name,
238*e0dfa398SToomas Soome 		    sizeof (itwalk->id_name)) != 0)
2397c478bd9Sstevel@tonic-gate 			continue;
2407c478bd9Sstevel@tonic-gate 		if (itwalk->id_incno != incno)
2417c478bd9Sstevel@tonic-gate 			continue;
2427c478bd9Sstevel@tonic-gate 		goto found;
2437c478bd9Sstevel@tonic-gate 	}
2447c478bd9Sstevel@tonic-gate 	/*
2457c478bd9Sstevel@tonic-gate 	 *	Add one more entry to idatev
2467c478bd9Sstevel@tonic-gate 	 */
2477c478bd9Sstevel@tonic-gate 	nidates++;
2487c478bd9Sstevel@tonic-gate 	idatev = (struct idates **)xrealloc((void *)idatev,
249*e0dfa398SToomas Soome 	    nidates * (size_t)sizeof (struct idates *));
2507c478bd9Sstevel@tonic-gate 	itwalk = idatev[nidates - 1] =
2517c478bd9Sstevel@tonic-gate 	    (struct idates *)xcalloc(1, sizeof (*itwalk));
2527c478bd9Sstevel@tonic-gate found:
2537c478bd9Sstevel@tonic-gate 	(void) strncpy(itwalk->id_name, fname, sizeof (itwalk->id_name));
2547c478bd9Sstevel@tonic-gate 	itwalk->id_name[sizeof (itwalk->id_name) - 1] = '\0';
2557c478bd9Sstevel@tonic-gate 	itwalk->id_incno = incno;
2567c478bd9Sstevel@tonic-gate 	itwalk->id_ddate = spcl.c_date;
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	ITITERATE(i, itwalk) {
2597c478bd9Sstevel@tonic-gate 		recout(df, itwalk);
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate 	if (ftruncate64(fd, ftello64(df))) {
2627c478bd9Sstevel@tonic-gate 		saverr = errno;
2637c478bd9Sstevel@tonic-gate 		msg(gettext("%s: %s error:\n"),
2647c478bd9Sstevel@tonic-gate 		    increm, "ftruncate64", strerror(saverr));
2657c478bd9Sstevel@tonic-gate 		dumpabort();
2667c478bd9Sstevel@tonic-gate 		/*NOTREACHED*/
2677c478bd9Sstevel@tonic-gate 	}
2687c478bd9Sstevel@tonic-gate 	(void) fclose(df);
2697c478bd9Sstevel@tonic-gate 	msg(gettext("Level %c dump on %s\n"),
2707c478bd9Sstevel@tonic-gate 	    (uchar_t)incno, prdate(spcl.c_date));
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate static void
recout(FILE * file,struct idates * what)274*e0dfa398SToomas Soome recout(FILE *file, struct idates *what)
2757c478bd9Sstevel@tonic-gate {
2767c478bd9Sstevel@tonic-gate 	time_t ddate = what->id_ddate;
2777c478bd9Sstevel@tonic-gate 	/* must use ctime, so we can later use unctime() */
278*e0dfa398SToomas Soome 	(void) fprintf(file, DUMPOUTFMT, what->id_name,
279*e0dfa398SToomas Soome 	    (uchar_t)what->id_incno, ctime(&ddate));
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate static int
getrecord(FILE * df,struct idates * idatep)283*e0dfa398SToomas Soome getrecord(FILE *df, struct idates *idatep)
2847c478bd9Sstevel@tonic-gate {
2857c478bd9Sstevel@tonic-gate 	char		buf[BUFSIZ];
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if ((fgets(buf, BUFSIZ, df)) != buf)
2887c478bd9Sstevel@tonic-gate 		return (-1);
2897c478bd9Sstevel@tonic-gate 	recno++;
2907c478bd9Sstevel@tonic-gate 	if (makeidate(idatep, buf) < 0) {
2917c478bd9Sstevel@tonic-gate 		msg(gettext(
2927c478bd9Sstevel@tonic-gate 		    "Malformed entry in dump record file `%s', line %d\n"),
293*e0dfa398SToomas Soome 		    increm, recno);
2947c478bd9Sstevel@tonic-gate 		if (strcmp(increm, NINCREM)) {
2957c478bd9Sstevel@tonic-gate 			msg(gettext("`%s' not a dump record file\n"), increm);
2967c478bd9Sstevel@tonic-gate 			dumpabort();
2977c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
2987c478bd9Sstevel@tonic-gate 		}
2997c478bd9Sstevel@tonic-gate 		return (-1);
3007c478bd9Sstevel@tonic-gate 	}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate #ifdef FDEBUG
3037c478bd9Sstevel@tonic-gate 	msg("getrecord: %s %c %s\n",
304*e0dfa398SToomas Soome 	    idatep->id_name,
305*e0dfa398SToomas Soome 	    (uchar_t)idatep->id_incno,
306*e0dfa398SToomas Soome 	    prdate(idatep->id_ddate));
3077c478bd9Sstevel@tonic-gate #endif
3087c478bd9Sstevel@tonic-gate 	return (0);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate static int
makeidate(struct idates * ip,char * buf)312*e0dfa398SToomas Soome makeidate(struct idates	*ip, char *buf)
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate 	char	un_buf[128];	/* size must be >= second one in DUMPINFMT */
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	/*
3177c478bd9Sstevel@tonic-gate 	 * MAXNAMLEN has different values in dirent.h and ufs_fsdir.h,
3187c478bd9Sstevel@tonic-gate 	 * and we need to ensure that the length in DUMPINFMT matches
3197c478bd9Sstevel@tonic-gate 	 * what we allow for.  Can't just use MAXNAMLEN in the test,
3207c478bd9Sstevel@tonic-gate 	 * because there's no convenient way to substitute it into
3217c478bd9Sstevel@tonic-gate 	 * DUMPINFMT.
3227c478bd9Sstevel@tonic-gate 	 * XXX There's got to be a better way.
3237c478bd9Sstevel@tonic-gate 	 */
3247c478bd9Sstevel@tonic-gate 	/*LINTED [assertion always true]*/
3257c478bd9Sstevel@tonic-gate 	assert(sizeof (ip->id_name) == (255 + 3));
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate 	if (sscanf(buf, DUMPINFMT, ip->id_name, &ip->id_incno, un_buf) != 3)
3287c478bd9Sstevel@tonic-gate 		return (-1);
3297c478bd9Sstevel@tonic-gate 	/* LINTED casting from 64-bit to 32-bit time */
3307c478bd9Sstevel@tonic-gate 	ip->id_ddate = (time32_t)unctime(un_buf);
3317c478bd9Sstevel@tonic-gate 	if (ip->id_ddate < 0)
3327c478bd9Sstevel@tonic-gate 		return (-1);
3337c478bd9Sstevel@tonic-gate 	return (0);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate /*
3377c478bd9Sstevel@tonic-gate  * This is an estimation of the number of tp_bsize blocks in the file.
3387c478bd9Sstevel@tonic-gate  * It estimates the number of blocks in files with holes by assuming
3397c478bd9Sstevel@tonic-gate  * that all of the blocks accounted for by di_blocks are data blocks
3407c478bd9Sstevel@tonic-gate  * (when some of the blocks are usually used for indirect pointers);
3417c478bd9Sstevel@tonic-gate  * hence the estimate may be high.
3427c478bd9Sstevel@tonic-gate  */
3437c478bd9Sstevel@tonic-gate void
est(struct dinode * ip)344*e0dfa398SToomas Soome est(struct dinode *ip)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate 	u_offset_t s, t;
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	/*
3497c478bd9Sstevel@tonic-gate 	 * ip->di_size is the size of the file in bytes.
3507c478bd9Sstevel@tonic-gate 	 * ip->di_blocks stores the number of sectors actually in the file.
3517c478bd9Sstevel@tonic-gate 	 * If there are more sectors than the size would indicate, this just
3527c478bd9Sstevel@tonic-gate 	 *	means that there are indirect blocks in the file or unused
3537c478bd9Sstevel@tonic-gate 	 *	sectors in the last file block; we can safely ignore these
3547c478bd9Sstevel@tonic-gate 	 *	(s = t below).
3557c478bd9Sstevel@tonic-gate 	 * If the file is bigger than the number of sectors would indicate,
3567c478bd9Sstevel@tonic-gate 	 *	then the file has holes in it.	In this case we must use the
3577c478bd9Sstevel@tonic-gate 	 *	block count to estimate the number of data blocks used, but
3587c478bd9Sstevel@tonic-gate 	 *	we use the actual size for estimating the number of indirect
3597c478bd9Sstevel@tonic-gate 	 *	dump blocks (t vs. s in the indirect block calculation).
3607c478bd9Sstevel@tonic-gate 	 */
3617c478bd9Sstevel@tonic-gate 	o_esize++;
3627c478bd9Sstevel@tonic-gate 	s = (unsigned)(ip->di_blocks) / (unsigned)(tp_bsize / DEV_BSIZE);
3637c478bd9Sstevel@tonic-gate 	/* LINTED: spurious complaint about sign-extending 32 to 64 bits */
3647c478bd9Sstevel@tonic-gate 	t = d_howmany(ip->di_size, (unsigned)tp_bsize);
3657c478bd9Sstevel@tonic-gate 	if (s > t)
3667c478bd9Sstevel@tonic-gate 		s = t;
3677c478bd9Sstevel@tonic-gate 	if (ip->di_size > (u_offset_t)((unsigned)(sblock->fs_bsize) * NDADDR)) {
3687c478bd9Sstevel@tonic-gate 		/* calculate the number of indirect blocks on the dump tape */
3697c478bd9Sstevel@tonic-gate 		/* LINTED: spurious complaint sign-extending 32 to 64 bits */
3707c478bd9Sstevel@tonic-gate 		s += d_howmany(t -
371*e0dfa398SToomas Soome 		    (unsigned)(NDADDR * sblock->fs_bsize / tp_bsize),
372*e0dfa398SToomas Soome 		    (unsigned)TP_NINDIR);
3737c478bd9Sstevel@tonic-gate 	}
3747c478bd9Sstevel@tonic-gate 	f_esize += s;
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate 
3777c478bd9Sstevel@tonic-gate /*ARGSUSED*/
3787c478bd9Sstevel@tonic-gate void
bmapest(uchar_t * map)379*e0dfa398SToomas Soome bmapest(uchar_t *map)
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate 	o_esize++;
3827c478bd9Sstevel@tonic-gate 	/* LINTED: spurious complaint sign-extending 32 to 64 bits */
3837c478bd9Sstevel@tonic-gate 	f_esize += d_howmany(msiz * sizeof (map[0]), (unsigned)tp_bsize);
3847c478bd9Sstevel@tonic-gate }
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate /*
3887c478bd9Sstevel@tonic-gate  * Check to see if what we are trying to dump is a fs snapshot
3897c478bd9Sstevel@tonic-gate  * If so, we can use the snapshot's create time to populate
3907c478bd9Sstevel@tonic-gate  * the dumpdates file, instead of the time of the dump.
3917c478bd9Sstevel@tonic-gate  */
3927c478bd9Sstevel@tonic-gate time32_t
is_fssnap_dump(char * disk)3937c478bd9Sstevel@tonic-gate is_fssnap_dump(char *disk)
3947c478bd9Sstevel@tonic-gate {
3957c478bd9Sstevel@tonic-gate 	struct stat st;
3967c478bd9Sstevel@tonic-gate 	char *last;
3977c478bd9Sstevel@tonic-gate 	int snapnum;
3987c478bd9Sstevel@tonic-gate 	kstat_ctl_t *kslib;
3997c478bd9Sstevel@tonic-gate 	kstat_t *ksnum;
4007c478bd9Sstevel@tonic-gate 	kstat_named_t *numval;
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 	last = basename(disk);
4037c478bd9Sstevel@tonic-gate 	if ((strstr(disk, SNAP_NAME) == NULL) || (stat(disk, &st) == -1) ||
4047c478bd9Sstevel@tonic-gate 	    (isdigit(last[0]) == 0))
4057c478bd9Sstevel@tonic-gate 		return (0);
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	snapnum = atoi(last);
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 	if ((kslib = kstat_open()) == NULL)
4107c478bd9Sstevel@tonic-gate 		return (0);
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	ksnum = kstat_lookup(kslib, SNAP_NAME, snapnum, FSSNAP_KSTAT_NUM);
4137c478bd9Sstevel@tonic-gate 	if (ksnum == NULL) {
4147c478bd9Sstevel@tonic-gate 		(void) kstat_close(kslib);
4157c478bd9Sstevel@tonic-gate 		return (0);
4167c478bd9Sstevel@tonic-gate 	}
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	if (kstat_read(kslib, ksnum, NULL) == -1) {
4197c478bd9Sstevel@tonic-gate 		(void) kstat_close(kslib);
4207c478bd9Sstevel@tonic-gate 		return (0);
4217c478bd9Sstevel@tonic-gate 	}
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 	numval = kstat_data_lookup(ksnum, FSSNAP_KSTAT_NUM_CREATETIME);
4247c478bd9Sstevel@tonic-gate 	if (numval == NULL) {
4257c478bd9Sstevel@tonic-gate 		(void) kstat_close(kslib);
4267c478bd9Sstevel@tonic-gate 		return (0);
4277c478bd9Sstevel@tonic-gate 	}
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate 	(void) kstat_close(kslib);
4307c478bd9Sstevel@tonic-gate 	/* LINTED casting from long to 32-bit time */
4317c478bd9Sstevel@tonic-gate 	return (time32_t)(numval->value.l & INT_MAX);
4327c478bd9Sstevel@tonic-gate }
433