/* * This is the routine used to extract files for the 'x' and 'i' commands. * Efficiently extract a subset of the files on a tape. */ void createfiles(void) { ino_t first, next, last; struct entry *ep; long curvol; vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; getvol((long)1); skipmaps(); skipdirs(); first = lowerbnd(ROOTINO); last = upperbnd(maxino - 1); for (;;) { curvol = volno; first = lowerbnd(first); last = upperbnd(last); /* * Check to see if any files remain to be extracted */ if (first > last) return; if (Dflag) { if (curfile.ino == maxino) return; if((ep = lookupino(curfile.ino)) != NULL && (ep->e_flags & (NEW|EXTRACT))) { goto justgetit; } else { skipfile(); continue; } } /* * Reject any volumes with inodes greater than the last * one needed, so that we can quickly skip backwards to * a volume containing useful inodes. We can't do this * if there are no further volumes available (curfile.ino * >= maxino) or if we are already at the first tape. */ if (curfile.ino > last && curfile.ino < maxino && volno > 1) { curfile.action = SKIP; getvol((long)0); skipmaps(); skipdirs(); continue; } /* * Decide on the next inode needed. * Skip across the inodes until it is found * or a volume change is encountered */ if (curfile.ino < maxino) { next = lowerbnd(curfile.ino); while (next > curfile.ino && volno == curvol) skipfile(); if (volno != curvol) { skipmaps(); skipdirs(); continue; } } else { /* * No further volumes or inodes available. Set * `next' to the first inode, so that a warning * is emitted below for each missing file. */ next = first; } /* * If the current inode is greater than the one we were * looking for then we missed the one we were looking for. * Since we only attempt to extract files listed in the * dump map, the lost files must have been due to a tape * read error, or a file that was removed while the dump * was in progress. Thus we report all requested files * between the one we were looking for, and the one we * found as missing, and delete their request flags. */ while (next < curfile.ino) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); fprintf(stderr, "%s: not found on tape\n", myname(ep)); ep->e_flags &= ~NEW; next = lowerbnd(next); } /* * The current inode is the one that we are looking for, * so extract it per its requested name. */ if (next == curfile.ino && next <= last) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); justgetit: (void) extractfile(myname(ep)); ep->e_flags &= ~NEW; if (volno != curvol) skipmaps(); } } }
/* * This is the routine used to extract files for the 'x' and 'i' commands. * Efficiently extract a subset of the files on a tape. */ void createfiles(void) { ino_t first, next, last; struct entry *ep; long curvol; vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; getvol((long)1); skipmaps(); skipdirs(); first = lowerbnd(UFS_ROOTINO); last = upperbnd(maxino - 1); new_volume: /* * Decide on the next inode needed in this volume. */ next = lowerbnd(curfile.ino); for (;;) { first = lowerbnd(first); last = upperbnd(last); /* * Check to see if any files remain to be extracted */ if (first > last) return; /* * Reject any volumes with inodes greater * than the last one needed */ if (curfile.ino > last) { do { curfile.action = SKIP; getvol((long)0); skipmaps(); skipdirs(); } while (curfile.ino > last); goto new_volume; } /* * Skip across the inodes until the next inode is found * or an out of order volume change is encountered */ do { curvol = volno; while (next > curfile.ino && volno == curvol) skipfile(); skipmaps(); skipdirs(); } while (volno == curvol + 1); /* * If volume change out of order occurred the * current state must be recalculated */ if (volno != curvol) goto new_volume; /* * If the current inode is greater than the one we were * looking for then we missed the one we were looking for. * Since we only attempt to extract files listed in the * dump map, the lost files must have been due to a tape * read error, or a file that was removed while the dump * was in progress. Thus we report all requested files * between the one we were looking for, and the one we * found as missing, and delete their request flags. */ while (next < curfile.ino) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); fprintf(stderr, "%s: not found on tape\n", myname(ep)); ep->e_flags &= ~NEW; next = lowerbnd(next); } /* * The current inode is the one that we are looking for, * so extract it per its requested name. */ if (next == curfile.ino && next <= last) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); (void) extractfile(myname(ep)); ep->e_flags &= ~NEW; if (volno != curvol) { skipmaps(); goto new_volume; } /* * Decide the next inode. Note that curfile.ino * already updated to the next file on the tape, * and we can't used it since it may be greater * than `next'. */ next = lowerbnd(next); } } }