| //======================================================================== |
| // |
| // pdfattach.cc |
| // |
| // This file is licensed under the GPLv2 or later |
| // |
| // Copyright (C) 2019-2022 Albert Astals Cid <aacid@kde.org> |
| // Copyright (C) 2019, 2023 Oliver Sander <oliver.sander@tu-dresden.de> |
| // Copyright (C) 2024 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
| // |
| // To see a description of the changes please see the Changelog file that |
| // came with your tarball or type make ChangeLog if you are building from git |
| // |
| //======================================================================== |
| |
| #include "config.h" |
| #include <poppler-config.h> |
| #include "goo/gbasename.h" |
| #include "parseargs.h" |
| #include "GlobalParams.h" |
| #include "PDFDoc.h" |
| #include "PDFDocFactory.h" |
| #include "Error.h" |
| #include "ErrorCodes.h" |
| #include "UTF.h" |
| #include "Win32Console.h" |
| |
| static bool doReplace = false; |
| static bool printVersion = false; |
| static bool printHelp = false; |
| |
| static const ArgDesc argDesc[] = { { "-replace", argFlag, &doReplace, 0, "replace embedded file with same name (if it exists)" }, |
| { "-v", argFlag, &printVersion, 0, "print copyright and version info" }, |
| { "-h", argFlag, &printHelp, 0, "print usage information" }, |
| { "-help", argFlag, &printHelp, 0, "print usage information" }, |
| { "--help", argFlag, &printHelp, 0, "print usage information" }, |
| { "-?", argFlag, &printHelp, 0, "print usage information" }, |
| {} }; |
| |
| static bool fileExists(const char *filePath) |
| { |
| FILE *f = openFile(filePath, "r"); |
| if (f != nullptr) { |
| fclose(f); |
| return true; |
| } |
| return false; |
| } |
| |
| int main(int argc, char *argv[]) |
| { |
| Win32Console win32Console(&argc, &argv); |
| |
| // parse args |
| const bool ok = parseArgs(argDesc, &argc, argv); |
| if (!ok || argc != 4 || printVersion || printHelp) { |
| fprintf(stderr, "pdfattach version %s\n", PACKAGE_VERSION); |
| fprintf(stderr, "%s\n", popplerCopyright); |
| fprintf(stderr, "%s\n", xpdfCopyright); |
| if (!printVersion) { |
| printUsage("pdfattach", "<input-PDF-file> <file-to-attach> <output-PDF-file>", argDesc); |
| } |
| return 99; |
| } |
| const GooString pdfFileName(argv[1]); |
| const std::string attachFilePath(argv[2]); |
| |
| // init GlobalParams |
| globalParams = std::make_unique<GlobalParams>(); |
| |
| // open PDF file |
| std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(pdfFileName, {}, {})); |
| |
| if (!doc->isOk()) { |
| fprintf(stderr, "Couldn't open %s\n", pdfFileName.c_str()); |
| return 1; |
| } |
| |
| std::unique_ptr<GooFile> attachFile(GooFile::open(attachFilePath)); |
| if (!attachFile) { |
| fprintf(stderr, "Couldn't open %s\n", attachFilePath.c_str()); |
| return 2; |
| } |
| |
| if (fileExists(argv[3])) { |
| fprintf(stderr, "File %s already exists.\n", argv[3]); |
| return 3; |
| } |
| |
| const std::string attachFileName = utf8ToUtf16WithBom(gbasename(attachFilePath.c_str())); |
| |
| if (!doReplace && doc->getCatalog()->hasEmbeddedFile(attachFileName)) { |
| fprintf(stderr, "There is already an embedded file named %s.\n", attachFileName.c_str()); |
| return 4; |
| } |
| |
| doc->getCatalog()->addEmbeddedFile(attachFile.get(), attachFileName); |
| |
| const GooString outputPdfFilePath(argv[3]); |
| const int saveResult = doc->saveAs(outputPdfFilePath); |
| if (saveResult != errNone) { |
| fprintf(stderr, "Couldn't save the file properly.\n"); |
| return 5; |
| } |
| |
| return 0; |
| } |