/* * NuLib2 * Copyright (C) 2000-2007 by Andy McFadden, All Rights Reserved. * This is free software; you can redistribute it and/or modify it under the * terms of the BSD License, see the file COPYING. * * Extract files and test archives. */ #include "NuLib2.h" /* * Extract all of the records from the archive, pulling out and displaying * comment threads. * * The "bulk extract" call doesn't deal with comments. Since we want to * show them while we're extracting the files, we have to manually find * and extract them. */ static NuError ExtractAllRecords(NulibState* pState, NuArchive* pArchive) { NuError err; const NuRecord* pRecord; const NuThread* pThread; NuRecordIdx recordIdx; NuAttr numRecords; int idx, threadIdx; DBUG(("--- doing manual extract\n")); Assert(NState_GetCommand(pState) == kCommandExtract); /* no "-p" here */ err = NuGetAttr(pArchive, kNuAttrNumRecords, &numRecords); for (idx = 0; idx < (int) numRecords; idx++) { err = NuGetRecordIdxByPosition(pArchive, idx, &recordIdx); if (err != kNuErrNone) { fprintf(stderr, "ERROR: couldn't get record #%d (err=%d)\n", idx, err); goto bail; } err = NuGetRecord(pArchive, recordIdx, &pRecord); if (err != kNuErrNone) { fprintf(stderr, "ERROR: unable to get recordIdx %u\n", recordIdx); goto bail; } /* do we want to extract this record? */ if (!IsSpecified(pState, pRecord)) continue; NState_IncMatchCount(pState); /* * Look for a comment thread. */ for (threadIdx = 0; (uint32_t)threadIdx < pRecord->recTotalThreads; threadIdx++) { pThread = NuGetThread(pRecord, threadIdx); Assert(pThread != NULL); if (NuGetThreadID(pThread) == kNuThreadIDComment && pThread->actualThreadEOF > 0) { UNICHAR* filenameUNI = CopyMORToUNI(pRecord->filenameMOR); printf("----- '%s':\n", filenameUNI); free(filenameUNI); err = NuExtractThread(pArchive, pThread->threadIdx, NState_GetCommentSink(pState)); if (err != kNuErrNone) { printf("[comment extraction failed, continuing\n"); } else { printf("\n-----\n"); } } } /* extract the record, using the usual mechanisms */ err = NuExtractRecord(pArchive, recordIdx); if (err != kNuErrNone) goto bail; } bail: return err; } /* * Extract the specified files. */ NuError DoExtract(NulibState* pState) { NuError err; NuArchive* pArchive = NULL; Assert(pState != NULL); if (NState_GetModBinaryII(pState)) return BNYDoExtract(pState); err = OpenArchiveReadOnly(pState); if (err == kNuErrIsBinary2) return BNYDoExtract(pState); if (err != kNuErrNone) goto bail; pArchive = NState_GetNuArchive(pState); Assert(pArchive != NULL); NState_SetMatchCount(pState, 0); /* * If we're not interested in comments, just use the "bulk" extract * call. If we want comments, we need to do this one at a time. */ if (!NState_GetModComments(pState)) { err = NuExtract(pArchive); if (err != kNuErrNone) goto bail; } else { err = ExtractAllRecords(pState, pArchive); if (err != kNuErrNone) goto bail; } if (!NState_GetMatchCount(pState)) printf("%s: no records match\n", gProgName); bail: if (pArchive != NULL) (void) NuClose(pArchive); return err; } /* * Extract the specified files to stdout. */ NuError DoExtractToPipe(NulibState* pState) { /* we handle the "to pipe" part farther down */ return DoExtract(pState); } /* * Do an integrity check on one or more records in the archive. */ NuError DoTest(NulibState* pState) { NuError err; NuArchive* pArchive = NULL; Assert(pState != NULL); if (NState_GetModBinaryII(pState)) return BNYDoTest(pState); err = OpenArchiveReadOnly(pState); if (err == kNuErrIsBinary2) return BNYDoTest(pState); if (err != kNuErrNone) goto bail; pArchive = NState_GetNuArchive(pState); Assert(pArchive != NULL); NState_SetMatchCount(pState, 0); err = NuTest(pArchive); if (err != kNuErrNone) goto bail; if (!NState_GetMatchCount(pState)) printf("%s: no records match\n", gProgName); bail: if (pArchive != NULL) (void) NuClose(pArchive); return err; }