/** * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush} */ static DECLCALLBACK(int) rtZipGzip_Flush(void *pvThis) { PRTZIPGZIPSTREAM pThis = (PRTZIPGZIPSTREAM)pvThis; if (!pThis->fDecompress) { int rc = rtZipGzip_FlushIt(pThis, Z_SYNC_FLUSH); if (RT_FAILURE(rc)) return rc; } return RTVfsIoStrmFlush(pThis->hVfsIos); }
/** * Pushes the bytes from the input to the output stream, flushes the output * stream and closes both of them. * * On failure, we will delete the output file, if it's a file. The input file * may be deleted, if we're not told to keep it (--keep, --to-stdout). * * @returns RTEXITCODE_SUCCESS or RTEXITCODE_FAILURE. * @param phVfsSrc The input stream. Set to NIL if closed. * @param pOpts The options. * @param phVfsDst The output stream. Set to NIL if closed. */ static RTEXITCODE gzipPushFlushAndClose(PRTVFSIOSTREAM phVfsSrc, PCRTGZIPCMDOPTS pOpts, PRTVFSIOSTREAM phVfsDst) { /* * Push bytes, flush and close the streams. */ RTEXITCODE rcExit = gzipPush(*phVfsSrc, *phVfsDst); RTVfsIoStrmRelease(*phVfsSrc); *phVfsSrc = NIL_RTVFSIOSTREAM; int rc = RTVfsIoStrmFlush(*phVfsDst); if (RT_FAILURE(rc) && rc != VERR_INVALID_PARAMETER) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to flush the output file: %Rrc", rc); RTVfsIoStrmRelease(*phVfsDst); *phVfsDst = NIL_RTVFSIOSTREAM; /* * Do the cleaning up, if needed. Remove the input file, if that's the * desire of the user, or remove the output file on failure. */ if (!pOpts->fStdOut) { if (rcExit == RTEXITCODE_SUCCESS) { if (!pOpts->fKeep) { rc = RTFileDelete(pOpts->pszInput); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to delete '%s': %Rrc", pOpts->pszInput, rc); } } else { rc = RTFileDelete(pOpts->szOutput); if (RT_FAILURE(rc)) RTMsgError("Failed to delete '%s': %Rrc", pOpts->szOutput, rc); } } return rcExit; }
/** * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush} */ static DECLCALLBACK(int) rtManifestPtIos_Flush(void *pvThis) { PRTMANIFESTPTIOS pThis = (PRTMANIFESTPTIOS)pvThis; return RTVfsIoStrmFlush(pThis->hVfsIos); }
/** * Handles a file on the command line. * * @returns exit code. * @param pszFile The file to handle. * @param fStdOut Whether to output to standard output or not. * @param fForce Whether to output to or input from terminals. * @param phVfsStdOut Pointer to the standard out handle. * (input/output) */ static RTEXITCODE gzipDecompressFile(const char *pszFile, bool fStdOut, bool fForce, PRTVFSIOSTREAM phVfsStdOut) { /* * Open the specified input file. */ const char *pszError; RTVFSIOSTREAM hVfsIn; int rc = RTVfsChainOpenIoStream(pszFile, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE, &hVfsIn, &pszError); if (RT_FAILURE(rc)) { if (pszError && *pszError) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc:\n" " '%s'\n", " %*s^\n", rc, pszFile, pszError - pszFile, ""); return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTVfsChainOpenIoStream failed with rc=%Rrc: '%s'", rc, pszFile); } /* * Output the output file. */ RTVFSIOSTREAM hVfsOut; char szFinal[RTPATH_MAX]; if (fStdOut) { if (*phVfsStdOut == NIL_RTVFSIOSTREAM) { rc = RTVfsIoStrmFromStdHandle(RTHANDLESTD_OUTPUT, 0 /*fOpen*/, true /*fLeaveOpen*/, phVfsStdOut); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to set up standard out: %Rrc", rc); } hVfsOut = *phVfsStdOut; szFinal[0] = '\0'; } else { rc = RTStrCopy(szFinal, sizeof(szFinal), pszFile); /** @todo remove the extension? Or are we supposed * to get the org name from the gzip stream? */ return RTMsgErrorExit(RTEXITCODE_FAILURE, "Decompressing to file is not implemented"); } /* * Do the decompressing, then flush and close the output stream (unless * it is stdout). */ RTEXITCODE rcExit = gzipDecompress(hVfsIn, hVfsOut); RTVfsIoStrmRelease(hVfsIn); rc = RTVfsIoStrmFlush(hVfsOut); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to flush the output file: %Rrc", rc); RTVfsIoStrmRelease(hVfsOut); /* * Remove the input file, if that's the desire of the caller, or * remove the output file on decompression failure. */ if (!fStdOut) { if (rcExit == RTEXITCODE_SUCCESS) { rc = RTFileDelete(pszFile); if (RT_FAILURE(rc)) rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileDelete failed with %rc: '%s'", rc, pszFile); } else { /* should we do this? */ rc = RTFileDelete(szFinal); if (RT_FAILURE(rc)) RTMsgError("RTFileDelete failed with %rc: '%s'", rc, pszFile); } } return rcExit; }