/* * 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; }
/* * Dump the contents from the streaming input. * * If we're not interested in handling an archive on stdin, we could just * pass the filename in here and use NuOpenRO instead. */ int DoStreamStuff(FILE* fp) { NuError err; NuArchive* pArchive = nil; err = NuStreamOpenRO(fp, &pArchive); if (err != kNuErrNone) { fprintf(stderr, "ERROR: unable to open stream archive (err=%d)\n", err); goto bail; } printf("*** Streaming contents!\n"); err = NuContents(pArchive, ShowContents); if (err != kNuErrNone) { fprintf(stderr, "ERROR: NuContents failed (err=%d)\n", err); goto bail; } bail: if (pArchive != nil) { NuError err2 = NuClose(pArchive); if (err == kNuErrNone) err = err2; } return err; }
void ExerciserState_Free(ExerciserState* pExerState) { if (pExerState == NULL) return; if (pExerState->pArchive != NULL) { printf("Exerciser: aborting open archive\n"); (void) NuAbort(pExerState->pArchive); (void) NuClose(pExerState->pArchive); } if (pExerState->archivePath != NULL) free(pExerState->archivePath); free(pExerState); }
/* * cl - close archive */ static NuError CloseFunc(ExerciserState* pState, int argc, char** argv) { NuError err; (void) pState, (void) argc, (void) argv; /* shut up, gcc */ assert(ExerciserState_GetNuArchive(pState) != NULL); assert(argc == 1); err = NuClose(ExerciserState_GetNuArchive(pState)); if (err == kNuErrNone) { ExerciserState_SetNuArchive(pState, NULL); ExerciserState_SetArchivePath(pState, NULL); } 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; }
/* * Interpret commands, do clever things. */ static NuError CommandLoop(void) { NuError err = kNuErrNone; ExerciserState* pState = ExerciserState_New(); CommandFunc func; char lineBuf[128]; int argc; char** argv = nil; while (1) { printf("\nEnter command (%s)> ", ExerciserState_GetArchiveFile(pState)); fflush(stdout); if (fgets(lineBuf, sizeof(lineBuf), stdin) == nil) { printf("\n"); break; } if (argv != nil) { free(argv); argv = nil; } func = nil; /* sanity check */ err = ParseLine(lineBuf, pState, &func, &argc, &argv); if (err != kNuErrNone) continue; assert(func != nil); if (func == QuitFunc) break; err = (*func)(pState, argc, argv); if (err < 0) printf("Exerciser: received error %d (%s)\n", err, NuStrError(err)); else if (err > 0) printf("Exerciser: received error %d\n", err); if (argv != nil) { free(argv); argv = nil; } } if (ExerciserState_GetNuArchive(pState) != nil) { /* ought to query the archive before saying something like this... */ printf("Exerciser: aborting any un-flushed changes in archive %s\n", ExerciserState_GetArchivePath(pState)); (void) NuAbort(ExerciserState_GetNuArchive(pState)); err = NuClose(ExerciserState_GetNuArchive(pState)); if (err != kNuErrNone) printf("Exerciser: got error %d closing archive\n", err); ExerciserState_SetNuArchive(pState, nil); } if (pState != nil) ExerciserState_Free(pState); if (argv != nil) free(argv); return kNuErrNone; }
/* * Open the archive in read-write mode, for purposes of adding, deleting, * or updating files. We don't plan on extracting anything with this. * * "Streaming mode" isn't allowed. */ NuError OpenArchiveReadWrite(NulibState* pState) { NuError err = kNuErrNone; NuArchive* pArchive = NULL; char* tempName = NULL; Assert(pState != NULL); Assert(IsFilenameStdin(NState_GetArchiveFilename(pState)) == false); tempName = MakeTempArchiveName(pState); if (tempName == NULL) goto bail; DBUG(("TEMP NAME = '%s'\n", tempName)); err = NuOpenRW(NState_GetArchiveFilename(pState), tempName, kNuOpenCreat, &pArchive); if (err != kNuErrNone) { ReportError(err, "unable to open '%s'", NState_GetArchiveFilename(pState)); goto bail; } /* introduce them */ NState_SetNuArchive(pState, pArchive); err = NuSetExtraData(pArchive, pState); BailError(err); NuSetSelectionFilter(pArchive, SelectionFilter); NuSetProgressUpdater(pArchive, ProgressUpdater); NuSetErrorHandler(pArchive, ErrorHandler); /*NuSetErrorMessageHandler(pArchive, ErrorMessageHandler);*/ /* handle "-0" flag */ if (NState_GetModNoCompression(pState)) { err = NuSetValue(pArchive, kNuValueDataCompression, kNuCompressNone); BailError(err); } /* handle "-z" flag */ if (NState_GetModCompressDeflate(pState)) { err = NuSetValue(pArchive, kNuValueDataCompression, kNuCompressDeflate); BailError(err); } /* handle "-zz" flag */ if (NState_GetModCompressBzip2(pState)) { err = NuSetValue(pArchive, kNuValueDataCompression, kNuCompressBzip2); BailError(err); } /* handle "-f" and "-u" flags */ /* (BUG: if "-f" is set, creating a new archive is impossible) */ if (NState_GetModFreshen(pState) || NState_GetModUpdate(pState)) { err = NuSetValue(pArchive, kNuValueOnlyUpdateOlder, true); BailError(err); } if (NState_GetModFreshen(pState)) { err = NuSetValue(pArchive, kNuValueHandleExisting, kNuMustOverwrite); BailError(err); } DBUG(("--- enabling ShrinkIt compatibility mode\n")); err = NuSetValue(pArchive, kNuValueMimicSHK, true); BailError(err); /* this probably isn't needed here, but set it anyway */ if (strcmp(SYSTEM_DEFAULT_EOL, "\r") == 0) err = NuSetValue(pArchive, kNuValueEOL, kNuEOLCR); else if (strcmp(SYSTEM_DEFAULT_EOL, "\n") == 0) err = NuSetValue(pArchive, kNuValueEOL, kNuEOLLF); else if (strcmp(SYSTEM_DEFAULT_EOL, "\r\n") == 0) err = NuSetValue(pArchive, kNuValueEOL, kNuEOLCRLF); else { Assert(0); err = kNuErrInternal; ReportError(err, "Unknown SYSTEM_DEFAULT_EOL '%s'", SYSTEM_DEFAULT_EOL); goto bail; } BailError(err); /*(void) NuSetValue(pArchive, kNuValueAllowDuplicates, true);*/ bail: Free(tempName); if (err != kNuErrNone && pArchive != NULL) { /* clean up */ NuAbort(pArchive); (void) NuClose(pArchive); NState_SetNuArchive(pState, NULL); } return err; }
/* * Open the archive in read-only mode. We use "file mode" for a file, or * "streaming mode" for stdin. */ NuError OpenArchiveReadOnly(NulibState* pState) { NuError err; NuArchive* pArchive = NULL; Assert(pState != NULL); if (IsFilenameStdin(NState_GetArchiveFilename(pState))) { err = NuStreamOpenRO(stdin, &pArchive); if (err != kNuErrNone) { ReportError(err, "unable to open stdin archive"); if (err == kNuErrIsBinary2) err = kNuErrNotNuFX; /* we can't seek back, so forget BNY */ goto bail; } /* * Since the archive is on stdin, we can't ask the user questions. * On a UNIX system we could open /dev/tty, but that's not portable, * and I don't think archives on stdin are going to be popular * enough to make this worth doing. */ NState_SetInputUnavailable(pState, true); } else { err = NuOpenRO(NState_GetArchiveFilename(pState), &pArchive); if (err != kNuErrNone) { if (err != kNuErrIsBinary2) { ReportError(err, "unable to open '%s'", NState_GetArchiveFilename(pState)); } goto bail; } } /* introduce them */ NState_SetNuArchive(pState, pArchive); err = NuSetExtraData(pArchive, pState); NuSetSelectionFilter(pArchive, SelectionFilter); NuSetOutputPathnameFilter(pArchive, OutputPathnameFilter); NuSetProgressUpdater(pArchive, ProgressUpdater); NuSetErrorHandler(pArchive, ErrorHandler); /*NuSetErrorMessageHandler(pArchive, ErrorMessageHandler);*/ /* set the EOL conversion */ if (NState_GetModConvertAll(pState)) err = NuSetValue(pArchive, kNuValueConvertExtractedEOL, kNuConvertOn); else if (NState_GetModConvertText(pState)) err = NuSetValue(pArchive, kNuValueConvertExtractedEOL, kNuConvertAuto); else err = NuSetValue(pArchive, kNuValueConvertExtractedEOL, kNuConvertOff); BailError(err); /* if we're converting EOL, we probably ought to do this too */ err = NuSetValue(pArchive, kNuValueStripHighASCII, true); BailError(err); /* handle "-s" flag */ if (NState_GetModOverwriteExisting(pState)) { err = NuSetValue(pArchive, kNuValueHandleExisting, kNuAlwaysOverwrite); BailError(err); } /* handle "-f" and "-u" flags (this overrides "-s" during extraction) */ if (NState_GetModFreshen(pState) || NState_GetModUpdate(pState)) { err = NuSetValue(pArchive, kNuValueOnlyUpdateOlder, true); BailError(err); } if (NState_GetModFreshen(pState)) { err = NuSetValue(pArchive, kNuValueHandleExisting, kNuMustOverwrite); BailError(err); } DBUG(("--- enabling ShrinkIt compatibility mode\n")); err = NuSetValue(pArchive, kNuValueMimicSHK, true); BailError(err); /* handy for some malformed archives */ err = NuSetValue(pArchive, kNuValueHandleBadMac, true); BailError(err); /* DBUG(("--- enabling 'mask dataless' mode\n")); err = NuSetValue(pArchive, kNuValueMaskDataless, true); BailError(err); */ if (strcmp(SYSTEM_DEFAULT_EOL, "\r") == 0) err = NuSetValue(pArchive, kNuValueEOL, kNuEOLCR); else if (strcmp(SYSTEM_DEFAULT_EOL, "\n") == 0) err = NuSetValue(pArchive, kNuValueEOL, kNuEOLLF); else if (strcmp(SYSTEM_DEFAULT_EOL, "\r\n") == 0) err = NuSetValue(pArchive, kNuValueEOL, kNuEOLCRLF); else { Assert(0); err = kNuErrInternal; ReportError(err, "Unknown SYSTEM_DEFAULT_EOL '%s'", SYSTEM_DEFAULT_EOL); goto bail; } BailError(err); bail: if (err != kNuErrNone && pArchive != NULL) { /* clean up */ (void) NuClose(pArchive); NState_SetNuArchive(pState, NULL); } return err; }