1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "pdfioutdev_gpl.hxx"
23 //#include "SecurityHandler.h"
24 #ifdef WNT
25 # include <io.h>
26 # include <fcntl.h>  /*_O_BINARY*/
27 #endif
28 
29 FILE* g_binary_out=stderr;
30 
31 #ifndef SYSTEM_POPPLER
32 static char ownerPassword[33] = "\001";
33 static char userPassword[33]  = "\001";
34 static char outputFile[256]   = "\001";
35 
36 static ArgDesc argDesc[] = {
37   {(char*)"-f",          argString,      outputFile,     sizeof(outputFile),
38    (char*)"output file for binary streams"},
39   {(char*)"-opw",        argString,      ownerPassword,  sizeof(ownerPassword),
40    (char*)"owner password (for encrypted files)"},
41   {(char*)"-upw",        argString,      userPassword,   sizeof(userPassword),
42    (char*)"user password (for encrypted files)"},
43   {NULL, argString, NULL, 0, NULL }
44 };
45 #else
46 static const char *ownerPassword = "\001";
47 static const char *userPassword  = "\001";
48 static const char *outputFile   = "\001";
49 #endif
50 
main(int argc,char ** argv)51 int main(int argc, char **argv)
52 {
53 #ifndef SYSTEM_POPPLER
54     // parse args; initialize to defaults
55     if( !parseArgs(argDesc, &argc, argv) )
56         return 1;
57 #else
58     int k = 0;
59     while (k < argc)
60     {
61         if (!strcmp(argv[k], "-f"))
62         {
63             outputFile = argv[k+1];
64             --argc;
65             for (int j = k; j < argc; ++j)
66                 argv[j] = argv[j+1];
67         }
68         else if (!strcmp(argv[k], "-opw"))
69         {
70             ownerPassword = argv[k+1];
71             --argc;
72             for (int j = k; j < argc; ++j)
73                 argv[j] = argv[j+1];
74         }
75         else if (!strcmp(argv[k], "-upw"))
76         {
77             userPassword = argv[k+1];
78             --argc;
79             for (int j = k; j < argc; ++j)
80                 argv[j] = argv[j+1];
81         }
82 	++k;
83     }
84 #endif
85 
86     if( argc < 2 )
87         return 1;
88 
89     // read config file
90     globalParams = new GlobalParams(
91 #ifndef SYSTEM_POPPLER
92         (char*)""
93 #endif
94     );
95     globalParams->setErrQuiet(gTrue);
96 #if !defined(SYSTEM_POPPLER) || defined(_MSC_VER)
97     globalParams->setupBaseFonts(NULL);
98 #endif
99 
100     // try to read a possible open password form stdin
101     char aPwBuf[129];
102     aPwBuf[128] = 0;
103     if( ! fgets( aPwBuf, sizeof(aPwBuf)-1, stdin ) )
104         aPwBuf[0] = 0; // mark as empty
105     else
106     {
107         for( unsigned int i = 0; i < sizeof(aPwBuf); i++ )
108         {
109             if( aPwBuf[i] == '\n' )
110             {
111                 aPwBuf[i] = 0;
112                 break;
113             }
114         }
115     }
116 
117     // PDFDoc takes over ownership for all strings below
118     GooString* pFileName    = new GooString(argv[1]);
119     GooString* pTempErrFileName     = new GooString("_err.pdf");
120     GooString* pTempErrFileNamePath = new GooString(argv[0]);
121 
122     GooString* pErrFileName = new GooString(pTempErrFileNamePath,pTempErrFileName);
123 
124 
125     // check for password string(s)
126     GooString* pOwnerPasswordStr( aPwBuf[0] != 0
127                                  ? new GooString( aPwBuf )
128                                  : (ownerPassword[0] != '\001'
129                                     ? new GooString(ownerPassword)
130                                     : (GooString *)NULL ) );
131     GooString* pUserPasswordStr(  userPassword[0] != '\001'
132                                   ? new GooString(userPassword)
133                                   : (GooString *)NULL );
134     if( outputFile[0] != '\001' )
135         g_binary_out = fopen(outputFile,"wb");
136 
137 #ifdef WNT
138     // Win actually modifies output for O_TEXT file mode, so need to
139     // revert to binary here
140     _setmode( _fileno( g_binary_out ), _O_BINARY );
141 #endif
142 
143     PDFDoc aDoc( pFileName,
144                  pOwnerPasswordStr,
145                  pUserPasswordStr );
146 
147     PDFDoc aErrDoc( pErrFileName,
148                  pOwnerPasswordStr,
149                  pUserPasswordStr );
150 
151 
152    // Check various permissions.
153    if ( !aDoc.isOk()||
154         !aDoc.okToPrint() ||
155         !aDoc.okToChange()||
156         !aDoc.okToCopy()||
157         !aDoc.okToAddNotes() )
158    {
159         pdfi::PDFOutDev* pOutDev( new pdfi::PDFOutDev(&aErrDoc) );
160 
161         const int nPages = aErrDoc.isOk() ? aErrDoc.getNumPages() : 0;
162 
163         // tell receiver early - needed for proper progress calculation
164         pOutDev->setPageNum( nPages );
165 
166         // virtual resolution of the PDF OutputDev in dpi
167         static const int PDFI_OUTDEV_RESOLUTION=7200;
168 
169        // do the conversion
170        for( int i=1; i<=nPages; ++i )
171        {
172           aErrDoc.displayPage( pOutDev,
173                             i,
174                             PDFI_OUTDEV_RESOLUTION,
175                             PDFI_OUTDEV_RESOLUTION,
176                             0, gTrue, gTrue, gTrue );
177           aErrDoc.processLinks( pOutDev, i );
178        }
179    }
180    else
181    {
182       pdfi::PDFOutDev* pOutDev( new pdfi::PDFOutDev(&aDoc) );
183 
184       // tell receiver early - needed for proper progress calculation
185       pOutDev->setPageNum( aDoc.getNumPages() );
186 
187       // virtual resolution of the PDF OutputDev in dpi
188       static const int PDFI_OUTDEV_RESOLUTION=7200;
189 
190       // do the conversion
191       const int nPages = aDoc.getNumPages();
192       for( int i=1; i<=nPages; ++i )
193       {
194         aDoc.displayPage( pOutDev,
195                           i,
196                           PDFI_OUTDEV_RESOLUTION,
197                           PDFI_OUTDEV_RESOLUTION,
198                           0, gTrue, gTrue, gTrue );
199         aDoc.processLinks( pOutDev, i );
200       }
201    }
202     return 0;
203 }
204 
205