Files
Arquivotheca.SunOS-4.1.4/etc/dump/partial.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

179 lines
2.8 KiB
C

#if !defined(lint) && !defined(NOID)
static char sccsid[] = "@(#)partial.c 1.1 94/10/31 SMI";
#endif
/*
* Copyright 1989, Sun Microsystems, Inc.
*/
#include "dump.h"
#include <ftw.h>
static dev_t blockdev;
static int partial;
static char realdisk[32];
extern int errno;
extern char *estrdup();
extern char *strcpy(), *strcat(), *rindex();
static int ftw_check();
static int ftw_mark();
static char *strerror();
partial_check()
{
struct stat st;
if (stat(disk, &st) < 0 ||
(st.st_mode & S_IFMT) == S_IFCHR ||
(st.st_mode & S_IFMT) == S_IFBLK)
return;
blockdev = st.st_dev;
if (lftw("/dev", ftw_check, 0) <= 0) {
msg("Cannot find block device %d, %d\n",
major(blockdev), minor(blockdev));
dumpabort();
}
disk = strcpy(realdisk, rawname(realdisk));
partial = 1;
incno = '0';
uflag = 0;
}
static
ftw_check(name, st, flag)
char *name;
struct stat *st;
int flag;
{
if (flag == FTW_F &&
(st->st_mode & S_IFMT) == S_IFBLK &
st->st_rdev == blockdev) {
(void) strcpy(realdisk, name);
return 1;
}
return 0;
}
partial_mark(argc, argv)
int argc;
char *argv[];
{
char *path;
struct stat st;
if (partial == 0)
return 1;
while (--argc >= 0) {
path = *argv++;
if (stat(path, &st) < 0 ||
st.st_dev != blockdev) {
msg("%s is not on device %s\n",
path, disk);
dumpabort();
}
if (mark_root(blockdev, path)) {
msg("Cannot find filesystem mount point for %s\n",
path);
dumpabort();
}
if (lftw(path, ftw_mark, getdtablesize() / 2) < 0) {
msg("Error in ftw (%s)\n", strerror(errno));
dumpabort();
}
}
return 0;
}
/* mark directories between target and root */
static
mark_root(dev, path)
dev_t dev;
char *path;
{
struct stat st;
char dotdot[MAXPATHLEN + 16];
char *slash;
strcpy(dotdot, path);
if (stat(dotdot, &st) < 0)
return 1;
/* if target is a regular file, find directory */
if ((st.st_mode & S_IFMT) != S_IFDIR)
if (slash = rindex(dotdot, '/'))
/* "/file" -> "/" */
if (slash == dotdot)
slash[1] = 0;
/* "dir/file" -> "dir" */
else
slash[0] = 0;
else
/* "file" -> "." */
strcpy(dotdot, ".");
/* keep marking parent until we hit mount point */
do {
if (stat(dotdot, &st) < 0 ||
(st.st_mode & S_IFMT) != S_IFDIR ||
st.st_dev != dev)
return 1;
markino(st.st_ino);
strcat(dotdot, "/..");
} while (st.st_ino != 2);
return 0;
}
/*ARGSUSED*/
static
ftw_mark(name, st, flag)
char *name;
struct stat *st;
int flag;
{
if (flag != FTW_NS)
markino(st->st_ino);
return 0;
}
static
markino(i)
ino_t i;
{
struct dinode *dp;
dp = getino(ino = i);
mark(dp);
}
static char *
strerror(err)
int err;
{
extern int sys_nerr;
extern char *sys_errlist[];
static char errmsg[32];
if (err >= 0 && err < sys_nerr)
return sys_errlist[sys_nerr];
(void) sprintf(errmsg, "Error %d", err);
return errmsg;
}