X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Futilities.c;h=f17bd9ce458a7214ab50050f787c794d79a033a1;hp=1d88c855b36f0fe190f5d5454cda23683a667512;hb=f32a70b091d3ee6524e760ec2cb21080f67fe2ee;hpb=e4a8bde40a6d8319d1b28e054e1a419ba3df2363 diff --git a/restore/utilities.c b/restore/utilities.c index 1d88c85..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-2000 - * Stelian Pop - Alcôve , 2000 + * 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. * @@ -41,10 +37,12 @@ #ifndef lint static const char rcsid[] = - "$Id: utilities.c,v 1.16 2001/06/18 10:58:28 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 @@ -57,6 +55,7 @@ static const char rcsid[] = #ifdef __linux__ #include #include +#include #ifdef HAVE_EXT2FS_EXT2_FS_H #include #else @@ -65,10 +64,18 @@ static const char rcsid[] = #include #include #else /* __linux__ */ +#ifdef sunos +#include +#include +#include +#else #include #include +#endif #endif /* __linux__ */ - +#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; @@ -180,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); @@ -236,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; /* @@ -255,11 +267,14 @@ linkit(char *existing, char *new, int type) * Most likely, the immutable or append-only attribute * is set. Clear the attributes and try again. */ - if (fgetflags (existing, &s) != -1 && - fsetflags (existing, 0) != -1) { +#ifdef sunos +#else + if (lgetflags (existing, &s) != -1 && + lsetflags (existing, 0) != -1) { ret = link(existing, new); - fsetflags(existing, s); + lsetflags(existing, s); } +#endif #endif if (ret < 0) { warn("warning: cannot create hard link %s->%s", @@ -276,7 +291,7 @@ linkit(char *existing, char *new, int type) return (GOOD); } -#ifndef __linux__ +#if !defined(__linux__) && !defined(sunos) /* * Create a whiteout. */ @@ -319,7 +334,7 @@ delwhiteout(struct entry *ep) dump_ino_t lowerbnd(dump_ino_t start) { - register struct entry *ep; + struct entry *ep; for ( ; start < maxino; start++) { ep = lookupino(start); @@ -337,7 +352,7 @@ lowerbnd(dump_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); @@ -361,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) @@ -465,12 +487,59 @@ 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 @@ -485,19 +554,23 @@ panic(fmt, va_alist) * if no smaller inode found return tnum=0 and tpos=0 */ int -Inode2Tapepos(dump_ino_t ino, long *tnum, long *tpos, int exactmatch) +Inode2Tapepos(dump_ino_t ino, long *tnum, long long *tpos, int exactmatch) { char *p, *pp; char numbuff[32]; unsigned long tmpino; long tmptnum; - long tmptpos; + long long tmptpos; *tpos = 0; *tnum = 0; if (fseek(gTapeposfp, gSeekstart, SEEK_SET) == -1) return errno; - while (fgets(gTps, sizeof(gTps), gTapeposfp) != NULL) { + 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)); @@ -523,7 +596,7 @@ Inode2Tapepos(dump_ino_t ino, long *tnum, long *tpos, int exactmatch) /* read tapepos */ while ((*p != 0) && (*p != '\t')) *pp++ = *p++; - tmptpos = atol(numbuff); + tmptpos = atoll(numbuff); if (exactmatch) { if (tmpino == ino) { @@ -542,4 +615,157 @@ Inode2Tapepos(dump_ino_t ino, long *tnum, long *tpos, int exactmatch) } 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); +}