nulib2/nulib2/Extract.c

181 lines
4.6 KiB
C

/*
* 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;
}