/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "restore.h"
#include <byteorder.h>
#include <stdlib.h>
#include <unistd.h>
#include <utime.h>
/*
* Symbol table of directories read from tape.
*/
struct inotab {
};
/*
* Information retained about directories.
*/
static struct modeinfo {
} node;
/*
* Global variables for this file.
*/
if (name[0] == '#') { \
tmpdir = "/tmp"; \
}
/*
* Format of old style directories.
*/
struct odirect {
};
#ifdef __STDC__
static void flushent(void);
static RST_DIR *rst_initdirfile(char *);
static void nodeflush(void);
#else
static void putdir();
static void putent();
static void skipmetadata();
static void flushent();
static void dcvt();
static RST_DIR *rst_initdirfile();
static offset_t rst_telldir();
static void rst_seekdir();
static struct inotab *allocinotab();
static void nodeflush();
static struct inotab *inotablookup();
#endif
/*
* Extract directory contents, building up a directory structure
* on disk for extraction by name.
* If genmode is requested, save mode, owner, and times for all
* directories on the tape.
*/
void
{
int ts;
int saverr;
INIT_DIRFILE();
gettext("%s: %s - cannot create directory temporary\n"),
perror("fopen");
done(1);
}
if (genmode != 0) {
gettext("%s: %s - cannot create modefile \n"),
perror("fopen");
done(1);
}
}
/* LINTED DIRSIZ will always fit into a ushort_t */
/* LINTED sign extension ok in assert */
for (;;) {
continue;
}
"%s: extractdirs: Failed internal consistency check, curfile.dip is NULL\n"),
progname);
done(1);
}
/* XXX Legitimate error, bad complaint string */
perror("initdirfile");
/* XXX Legitimate error, bad complaint string */
panic("%s: %s\n",
}
"Root directory is not on tape\n"));
done(1);
}
return;
}
nodeflush();
flushent();
}
}
/*
* skip over all the directories on the tape
*/
void
skipdirs()
{
skipfile();
}
}
/*
* Recursively find names and inumbers of all files in subtree
* pname and pass them off to be processed.
*/
void
{
/*
* Pname is name of a simple file or an unchanged directory.
*/
return;
}
/*
* Pname is a dumped directory name.
*/
return;
/*
* begin search through the directory
* skipping over "." and ".."
*/
else
gettext("Warning: `.' missing from directory %s\n"),
pname);
else
gettext("Warning: `..' missing from directory %s\n"),
pname);
/*
* a zero inode signals end of directory
*/
"%s%s: ignoring name that exceeds %d char\n"),
} else {
/* Always fits by if() condition */
/* put a double null on string for lookupname() */
}
}
}
/*
* Scan the directory table looking for extended attribute trees.
* Recursively find names and inumbers in each tree and pass them
* off to be processed. If the always parameter is not set, only
* process the attribute tree if the attribute tree parent is to
* be extracted.
*/
void
{
int len;
if (!always &&
continue;
MAXCOMPLEXLEN - 3);
inattrspace = 1;
}
inattrspace = 0;
} else {
gettext("Warning: orphaned attribute directory\n"));
}
} else {
gettext("Warning: `..' missing from attribute directory\n"));
}
}
}
/*
* Search the directory tree rooted at inode ROOTINO
* for the path pointed at by n. Note that n must be
* modifiable, although it is returned in the same
* condition it was given to us in.
*/
psearch(char *n)
{
char c;
if (*(cp = n) == '/')
cp++;
next:
cp1++;
c = *cp1;
*cp1 = 0;
if (ino == 0) {
*cp1 = c;
return (0);
}
*cp1 = c;
if (c == '/') {
goto next;
}
return (ino);
}
/*
* search the directory inode ino
* looking for entry cp
*/
static ino_t
{
return (0);
do {
return (0);
}
/*
* Put the directory entries in the directory file
*/
static void
{
if (cvtflag) {
/*LINTED [buf is char[] in getfile, size % fs_fsize == 0]*/
/*LINTED [buf is char[] in getfile]*/
}
} else {
loc = 0;
/*LINTED [buf is char[] in getfile, loc % 4 == 0]*/
loc += i;
continue;
}
}
}
}
}
/*
* These variables are "local" to the following two functions.
*/
/*
* add a new directory entry to a file.
*/
static void
{
/* LINTED DIRSIZ will always fit in a ushort_t */
/* LINTED sign extension ok in assert */
/*LINTED [prev += dp->d_reclen, prev % 4 == 0]*/
dirloc = 0;
}
}
/*
* flush out a directory that is finished.
*/
static void
#ifdef __STDC__
flushent(void)
#else
flushent()
#endif
{
/* LINTED prev += dp->d_reclen, prev % 4 == 0 */
dirloc = 0;
}
static void
{
/* Note that odp->d_name may not be null-terminated */
/* LINTED assertion always true */
/* LINTED: strlen will fit into d_namlen */
/* LINTED sign extension ok in assert */
/* LINTED DIRSIZ always fits in ushort_t */
}
/*
* Initialize the directory file
*/
static RST_DIR *
{
int fd;
return ((RST_DIR *)0);
return ((RST_DIR *)0);
}
return (dp);
}
/*
* Simulate the opening of a directory
*/
RST_DIR *
{
return (dirp);
}
return ((RST_DIR *)0);
}
/*
* Releases the hidden state created by rst_opendir().
* Specifically, the dirp it provided to the caller is malloc'd.
*/
void
{
}
/*
* return a pointer into a directory
*/
static offset_t
{
perror("Could not determine position in directory file");
done(1);
}
}
/*
* Seek to an entry in a directory.
* Only values returned by ``rst_telldir'' should be passed to rst_seekdir.
* This routine handles many directories in a single file.
* It takes the base of the directory in the file, plus
* the desired seek offset into it.
*/
static void
{
return;
if (loc < 0)
}
/*
* get next entry in a directory.
*/
struct direct *
{
for (;;) {
gettext("error reading directory\n"));
return ((struct direct *)0);
}
}
continue;
}
/*LINTED [rvalue will be aligned on int boundary]*/
gettext("corrupted directory: bad reclen %d\n"),
return ((struct direct *)0);
}
continue;
gettext("corrupted directory: bad inum %lu\n"),
continue;
}
return (dp);
}
}
/*
* Set the mode, owner, and times for all new or changed directories
*/
void
#ifdef __STDC__
setdirmodes(void)
#else
#endif
{
int saverr;
static int complained_chown = 0;
static int complained_chmod = 0;
int dfd;
/* XXX if modefile[0] == '#', shouldn't we just bail here? */
/* XXX why isn't it set already? */
perror("fopen");
gettext("directory mode, owner, and times not set\n"));
return;
}
for (;;) {
break;
continue;
}
if (override < 0) {
"Directories already exist, set modes anyway"))
== FAIL)
override = 0;
else
override = 1;
}
if (override == 0) {
/* LINTED: result fits into short */
continue;
}
}
continue;
}
}
continue;
}
gettext("Can not set attribute context: %s\n"),
continue;
}
}
gettext("Can not set directory permissions: %s\n"),
complained_chmod = 1;
}
gettext("Cannot malloc metadata\n"));
done(1);
}
}
/*
* BUG 4302943
* Since the ACLs must be set before fixing the ownership,
* chown should be called only after metaproc
*/
gettext("Can not set directory ownership: %s\n"),
complained_chown = 1;
}
/* LINTED: result fits into short */
}
}
}
void
{
/* XXX should we bail if this doesn't work? */
/* LINTED unsigned -> signed conversion ok here */
}
/*
* Generate a literal copy of a directory.
*/
int
{
off64_t i;
gettext("Cannot find directory inode %d named %s\n"),
return (FAIL);
}
return (FAIL);
}
if (dp < 0) {
return (FAIL);
}
/* LINTED cast is safe due to comparison */
/* XXX instead of done(), clean up and return FAIL? */
"read error extracting inode %d, name %s\n"),
perror("read");
done(1);
}
"write error extracting inode %d, name %s\n"),
perror("write");
done(1);
}
}
return (GOOD);
}
/*
* Determine the type of an inode
*/
int
{
return (LEAF);
return (NODE);
}
/*
* Allocate and initialize a directory inode entry.
* If requested, save its pertinent mode, owner, and time info.
*/
static struct inotab *
{
if (itp == 0) {
gettext("no memory for directory table\n"));
done(1);
}
}
return (itp);
return (itp);
}
void
{
char *metadata;
"Inconsistency detected: modefile pointer is NULL\n"));
done(1);
}
}
/*
* Look up an inode in the table of directories
*/
static struct inotab *
{
return (itp);
return ((struct inotab *)0);
}
/*
* Clean up and exit
*/
void
{
if (modefile[0] != '#')
if (dirfile[0] != '#')
}