summaryrefslogtreecommitdiff
path: root/utils/pdfattach.cc
blob: 7aed4b217e1615fca91f01b20643ceb3c5a683db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//========================================================================
//
// pdfattach.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright (C) 2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2019 Oliver Sander <oliver.sander@tu-dresden.de>
//
// 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 "gbasename.h"
#include "parseargs.h"
#include "GlobalParams.h"
#include "PDFDoc.h"
#include "PDFDocFactory.h"
#include "Error.h"
#include "ErrorCodes.h"
#include "Win32Console.h"

static bool doReplace = false;
static bool printVersion = false;
static bool printHelp = false;

static 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 GooString attachFilePath(argv[2]);

  // init GlobalParams
  globalParams = std::make_unique<GlobalParams>();

  // open PDF file
  std::unique_ptr<PDFDoc> doc(PDFDocFactory().createPDFDoc(pdfFileName, nullptr, nullptr));

  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 = 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;
}