X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Futilities.c;h=f17bd9ce458a7214ab50050f787c794d79a033a1;hp=7c3bcd8b1dcbeb183fee5af349557a719ebd4aa6;hb=f32a70b091d3ee6524e760ec2cb21080f67fe2ee;hpb=ddd2ef55b78a62c4bc3daad18bef8a90e85a2052 diff --git a/restore/utilities.c b/restore/utilities.c index 7c3bcd8..f17bd9c 100644 --- a/restore/utilities.c +++ b/restore/utilities.c @@ -2,8 +2,8 @@ * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 - * Stelian Pop , 1999 - * + * Stelian Pop , 1999-2000 + * Stelian Pop - AlcĂ´ve , 2000-2002 */ /* @@ -18,11 +18,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -40,35 +36,46 @@ */ #ifndef lint -#if 0 -static char sccsid[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95"; -#endif static const char rcsid[] = - "$Id: utilities.c,v 1.3 1999/10/11 12:59:21 stelian Exp $"; + "$Id: utilities.c,v 1.28 2005/03/30 13:21:45 stelian Exp $"; #endif /* not lint */ +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #ifdef __linux__ #include +#include +#include +#ifdef HAVE_EXT2FS_EXT2_FS_H +#include +#else #include +#endif +#include #include #else /* __linux__ */ +#ifdef sunos +#include +#include +#include +#else #include #include +#endif #endif /* __linux__ */ - -#include -#include -#include -#include -#include - -#ifdef __linux__ -#include +#ifdef DUMP_MACOSX +#include "darwin.h" #endif - #include "restore.h" #include "extern.h" @@ -78,7 +85,7 @@ static const char rcsid[] = void pathcheck(char *name) { - register char *cp; + char *cp; struct entry *ep; char *start; @@ -157,7 +164,6 @@ void newnode(struct entry *np) { char *cp; - if (np->e_type != NODE) badentry(np, "newnode: not a node"); cp = myname(np); @@ -181,8 +187,13 @@ removenode(struct entry *ep) if (ep->e_type != NODE) badentry(ep, "removenode: not a node"); - if (ep->e_entries != NULL) - badentry(ep, "removenode: non-empty directory"); + if (ep->e_entries != NULL) { + int i; + for (i = 0; i < DIRHASH_SIZE; i++) { + if (ep->e_entries[i] != NULL) + badentry(ep, "removenode: non-empty directory"); + } + } ep->e_flags |= REMOVED; ep->e_flags &= ~TMPNAME; cp = myname(ep); @@ -237,7 +248,7 @@ linkit(char *existing, char *new, int type) if (!Nflag && (ret = link(existing, new)) < 0) { -#ifndef __linux__ +#if !defined(__linux__) && !defined(sunos) struct stat s; /* @@ -249,6 +260,21 @@ linkit(char *existing, char *new, int type) ret = link(existing, new); chflags(existing, s.st_flags); } +#else + unsigned long s; + + /* + * Most likely, the immutable or append-only attribute + * is set. Clear the attributes and try again. + */ +#ifdef sunos +#else + if (lgetflags (existing, &s) != -1 && + lsetflags (existing, 0) != -1) { + ret = link(existing, new); + lsetflags(existing, s); + } +#endif #endif if (ret < 0) { warn("warning: cannot create hard link %s->%s", @@ -265,7 +291,7 @@ linkit(char *existing, char *new, int type) return (GOOD); } -#ifndef __linux__ +#if !defined(__linux__) && !defined(sunos) /* * Create a whiteout. */ @@ -305,10 +331,10 @@ delwhiteout(struct entry *ep) /* * find lowest number file (above "start") that needs to be extracted */ -ino_t -lowerbnd(ino_t start) +dump_ino_t +lowerbnd(dump_ino_t start) { - register struct entry *ep; + struct entry *ep; for ( ; start < maxino; start++) { ep = lookupino(start); @@ -323,10 +349,10 @@ lowerbnd(ino_t start) /* * find highest number file (below "start") that needs to be extracted */ -ino_t -upperbnd(ino_t start) +dump_ino_t +upperbnd(dump_ino_t start) { - register struct entry *ep; + struct entry *ep; for ( ; start > ROOTINO; start--) { ep = lookupino(start); @@ -350,8 +376,15 @@ badentry(struct entry *ep, const char *msg) fprintf(stderr, "parent name %s\n", myname(ep->e_parent)); if (ep->e_sibling != NULL) fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling)); - if (ep->e_entries != NULL) - fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries)); + if (ep->e_entries != NULL) { + int i; + for (i = 0; i < DIRHASH_SIZE; i++) { + if (ep->e_entries[i] != NULL) { + fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries[i])); + break; + } + } + } if (ep->e_links != NULL) fprintf(stderr, "next link name: %s\n", myname(ep->e_links)); if (ep->e_next != NULL) @@ -391,11 +424,11 @@ flagvalues(struct entry *ep) /* * Check to see if a name is on a dump tape. */ -ino_t +dump_ino_t dirlookup(const char *name) { struct direct *dp; - ino_t ino; + dump_ino_t ino; ino = ((dp = pathsearch(name)) == NULL) ? 0 : dp->d_ino; @@ -454,8 +487,285 @@ panic(fmt, va_alist) if (yflag) return; if (reply("abort") == GOOD) { - if (reply("dump core") == GOOD) + if (reply("dump core") == GOOD) { + fchdir(wdfd); abort(); + } exit(1); } } + +void resizemaps(dump_ino_t oldmax, dump_ino_t newmax) +{ + char *map; + + if (usedinomap) { + map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY)); + if (map == NULL) + errx(1, "no memory for active inode map"); + memcpy(map, usedinomap, howmany(oldmax, NBBY)); + free(usedinomap); + usedinomap = map; + } + if (dumpmap) { + map = calloc((unsigned)1, (unsigned)howmany(newmax, NBBY)); + if (map == NULL) + errx(1, "no memory for file dump list"); + memcpy(map, dumpmap, howmany(oldmax, NBBY)); + free(dumpmap); + dumpmap = map; + } +} + +void +GetPathFile(char *source, char *path, char *fname) +{ + char *p, *s; + + *path = 0; + *fname = 0; + p = s = source; + while (*s) { + if (*s == '/') { + p = s + 1; + } + s++; + } + if (p == source) { + *path = 0; + } else { + strncpy(path, source, p - source); + path[p - source] = 0; + } + strcpy(fname, p); +} + +#ifdef USE_QFA +/* + * search for ino in QFA file + * + * if exactmatch: + * if ino found return tape number and tape position + * if ino not found return tnum=0 and tpos=0 + * + * if not exactmatch: + * if ino found return tape number and tape position + * if ino not found return tape number and tape position of last smaller ino + * if no smaller inode found return tnum=0 and tpos=0 + */ +int +Inode2Tapepos(dump_ino_t ino, long *tnum, long long *tpos, int exactmatch) +{ + char *p, *pp; + char numbuff[32]; + unsigned long tmpino; + long tmptnum; + long long tmptpos; + + *tpos = 0; + *tnum = 0; + if (fseek(gTapeposfp, gSeekstart, SEEK_SET) == -1) + return errno; + while (1) { + gSeekstart = ftell(gTapeposfp); /* remember for later use */ + if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL) { + return 0; + } + gTps[strlen(gTps) - 1] = 0; /* delete end of line */ + p = gTps; + bzero(numbuff, sizeof(numbuff)); + pp = numbuff; + /* read inode */ + while ((*p != 0) && (*p != '\t')) + *pp++ = *p++; + tmpino = atol(numbuff); + if (*p == 0) + return 1; /* may NOT happen */ + p++; + bzero(numbuff, sizeof(numbuff)); + pp = numbuff; + /* read tapenum */ + while ((*p != 0) && (*p != '\t')) + *pp++ = *p++; + if (*p == 0) + return 1; /* may NOT happen */ + tmptnum = atol(numbuff); + p++; + bzero(numbuff, sizeof(numbuff)); + pp = numbuff; + /* read tapepos */ + while ((*p != 0) && (*p != '\t')) + *pp++ = *p++; + tmptpos = atoll(numbuff); + + if (exactmatch) { + if (tmpino == ino) { + *tnum = tmptnum; + *tpos = tmptpos; + return 0; + } + } else { + if (tmpino > ino) { + return 0; + } else { + *tnum = tmptnum; + *tpos = tmptpos; + } + } + } + return 0; +} + +#ifdef sunos +int +GetSCSIIDFromPath(char *devPath, long *id) +{ + int len; + char fbuff[2048]; + char path[2048]; + char fname[2048]; + char *fpn = fname; + char idstr[32]; + char *ip = idstr; + + bzero(fbuff, sizeof(fbuff)); + if ((len = readlink(devPath, fbuff, 2048)) == -1) { + return errno; + } + fbuff[len] = 0; + GetPathFile(fbuff, path, fname); + (void)memset(idstr, 0, sizeof(idstr)); + while (*fpn && (*fpn != ',')) { + if (*fpn <= '9' && *fpn >= '0') { + *ip = *fpn; + ip++; + } + fpn++; + } + if (*idstr) { + *id = atol(idstr); + } else { + *id = -1; + } + return 0; +} +#endif +#endif /* USE_QFA */ + +#ifdef DUMP_MACOSX +int +CreateAppleDoubleFileRes(char *oFile, FndrFileInfo *finderinfo, mode_t mode, int flags, + struct timeval *timep, u_int32_t uid, u_int32_t gid) +{ + int err = 0; + int fdout; + char *p; + char *pp; + ASDHeaderPtr hp; + ASDEntryPtr ep; + long thesize; + long n; + + + n = 1; /* number of entries in double file ._ only finderinfo */ + /* + no data fork + n++; + currently no resource fork + n++; + */ + + thesize = sizeof(ASDHeader) + (n * sizeof(ASDEntry)) + INFOLEN; + if ((pp = p = (char *)malloc(thesize)) == NULL) { + err = errno; + return err; + } + + hp = (ASDHeaderPtr)p; + p += sizeof(ASDHeader); + ep = (ASDEntryPtr)p; + p += sizeof(ASDEntry) * n; + + hp->magic = ADOUBLE_MAGIC; + hp->version = ASD_VERSION2; + + bzero(&hp->filler, sizeof(hp->filler)); + hp->entries = (short)n; + + ep->entryID = EntryFinderInfo; + ep->offset = p - pp - CORRECT; + ep->len = INFOLEN; /* sizeof(MacFInfo) + sizeof(FXInfo); */ + bzero(p, ep->len); + bcopy(finderinfo, p, sizeof(FndrFileInfo)); + p += ep->len; + ep++; + + if ((fdout = open(oFile, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { + err = errno; + free(pp); + return err; + } + + /* write the ASDHeader */ + if (write(fdout, pp, sizeof(ASDHeader) - CORRECT) == -1) { + err = errno; + close(fdout); + free(pp); + unlink(oFile); + return err; + } + /* write the ASDEntries */ + if (write(fdout, pp + sizeof(ASDHeader), thesize - sizeof(ASDHeader)) == -1) { + err = errno; + close(fdout); + free(pp); + unlink(oFile); + return err; + } + + (void)fchown(fdout, uid, gid); + (void)fchmod(fdout, mode); + close(fdout); + (void)lsetflags(oFile, flags); + utimes(oFile, timep); + free(pp); + return err; +} +#endif /* DUMP_MACOSX */ + +int +lgetflags(const char *path, unsigned long *flags) +{ + int err; + struct STAT sb; + + err = LSTAT(path, &sb); + if (err < 0) + return err; + + if (S_ISLNK(sb.st_mode) || S_ISFIFO(sb.st_mode)) { + // no way to get/set flags on a symlink + *flags = 0; + return 0; + } + else + return fgetflags(path, flags); +} + +int +lsetflags(const char *path, unsigned long flags) +{ + int err; + struct STAT sb; + + err = LSTAT(path, &sb); + if (err < 0) + return err; + + if (S_ISLNK(sb.st_mode) || S_ISFIFO(sb.st_mode)) { + // no way to get/set flags on a symlink + return 0; + } + else + return fsetflags(path, flags); +}