1 /*
2 **
3 ** save.c
4 **
5 ** Copyright (C) 1995, 1996, 1997 Johannes Plass
6 ** Copyrigth (C) 2004 Jose E. Marchesi
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 3 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with GNU gv; see the file COPYING. If not, write to
20 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA 02111-1307, USA.
22 **
23 ** Author: Johannes Plass (plass@thep.physik.uni-mainz.de)
24 ** Department of Physics
25 ** Johannes Gutenberg-University
26 ** Mainz, Germany
27 **
28 ** Jose E. Marchesi (jemarch@gnu.org)
29 ** GNU Project
30 **
31 */
32 #include "ac_config.h"
33
34 /*
35 #define MESSAGES
36 */
37 #include "message.h"
38
39 #include <stdlib.h>
40 #include <stdio.h>
41
42 #include "paths.h"
43 #include INC_X11(Intrinsic.h)
44 #include "Ghostview.h"
45
46 #include "types.h"
47 #include "config.h"
48 #include "error.h"
49 #include "file.h"
50 #include "main_resources.h"
51 #include "main_globals.h"
52 #include "misc.h"
53 #include "note.h"
54 #include "process.h"
55 #include "ps.h"
56 #include "doc_misc.h"
57 #include "save.h"
58
59
60 # include <sys/types.h>
61 # include <unistd.h>
62
63
64 /*############################################################*/
65 /* save_alllocSaveData */
66 /*############################################################*/
67
68 SaveData
save_allocSaveData(void)69 save_allocSaveData(void)
70 {
71 SaveData sd;
72 Cardinal size = sizeof(SaveDataStruct);
73
74 BEGINMESSAGE(save_alllocSaveData)
75 sd = (SaveData) XtMalloc(size);
76 memset((void*) sd ,0,(size_t)size);
77 ENDMESSAGE(save_allocSaveData)
78 return(sd);
79 }
80
81 /*############################################################*/
82 /* save_freeSaveData */
83 /*############################################################*/
84
85 void
save_freeSaveData(SaveData sd)86 save_freeSaveData(SaveData sd)
87 {
88 BEGINMESSAGE(save_freeSaveData)
89 XtFree(sd->save_fn);
90 XtFree(sd->src_fn);
91 XtFree(sd->conv_fn);
92 XtFree(sd->pagelist);
93 XtFree(sd->print_cmd);
94 XtFree((XtPointer)sd);
95 ENDMESSAGE(save_freeSaveData)
96 }
97
98 /*------------------------------------------------------------*/
99 /* print_file */
100 /*------------------------------------------------------------*/
101
102
103 # define SYSTEM_SUCCEEDED_ON(bbb) (system(bbb) == 0)
104 # define SYSTEM_FAILED_ON(bbb) (system(bbb) != 0)
105
106
107 static String
print_file(String print_command,String print_filename)108 print_file(String print_command, String print_filename)
109 {
110 String error=NULL;
111 char *print_quoted_filename;
112 char *c,*p;
113 Cardinal m,n;
114 String printfail=GV_ERROR_PRINT_FAIL;
115
116 BEGINMESSAGE(print_file)
117
118 print_quoted_filename = quote_filename(print_filename);
119 p = XtNewString(print_command);
120 n=0;
121 c=p;
122 while ((c=strstr(c,"%s"))) { c+=2; n++; }
123 m = (strlen(p)+(n>0?n:1)*strlen(print_quoted_filename)+5)*sizeof(char);
124 c = (char*) XtMalloc(m);
125 if (n>0) {
126 char *e,*s;
127 e=s=p;
128 c[0]='\0';
129 while (s) {
130 s=strstr(e,"%s");
131 if (s) *s='\0';
132 strcat(c,e);
133 if (s) {
134 strcat(c,print_quoted_filename);
135 e=s+2;
136 }
137 else s=NULL;
138 }
139 } else {
140 sprintf(c, "%s %s",p,print_quoted_filename);
141 }
142 INFSMESSAGE(printing:,c)
143 if (SYSTEM_FAILED_ON(c)) {
144 m = (strlen(printfail)+strlen(c)+1)*sizeof(char);
145 error = (char*) XtMalloc(m);
146 sprintf(error,printfail,c);
147 }
148 XtFree(c);
149 XtFree(p);
150 XtFree(print_quoted_filename);
151 ENDMESSAGE(print_file)
152 return(error);
153 }
154
155 /*------------------------------------------------------------*/
156 /* save_forkPDFToPSConversionDone */
157 /*------------------------------------------------------------*/
158
159 static void
save_forkPDFToPSConversionDone(XtPointer client_data,int type)160 save_forkPDFToPSConversionDone(XtPointer client_data, int type)
161 {
162 char *error=NULL;
163 SaveData sd = (SaveData) client_data;
164
165 BEGINMESSAGE(save_forkPDFToPSConversionDone)
166
167 if (type==PROCESS_NOTIFY) {
168 INFMESSAGE(call is of type PROCESS_NOTIFY)
169 error = save_saveFile(sd);
170 if (error) {
171 NotePopupShowMessage(error);
172 XtFree(error);
173 }
174 } else if (type==PROCESS_KILL) {
175 INFMESSAGE(call is of type PROCESS_KILL)
176 if (sd->conv_fn) {
177 INFSMESSAGE(deleting file, sd->conv_fn)
178 unlink(sd->conv_fn);
179 }
180 save_freeSaveData(sd);
181 }
182
183 ENDMESSAGE(save_forkPDFToPSConversionDone)
184 }
185
186 /*------------------------------------------------------------*/
187 /* save_forkPDFToPSConversion */
188 /*------------------------------------------------------------*/
189
190 static String
save_forkPDFToPSConversion(SaveData sd)191 save_forkPDFToPSConversion(SaveData sd)
192 {
193 char command[512], tmp[512];
194 char proc_name[256];
195 char *error=NULL;
196 char *pos;
197 char *pdfpos;
198 char *pspos;
199 char *quoted_src_fn, *quoted_conv_fn;
200 char* src = command;
201 char* dest = tmp;
202 int spaceFound = 0;
203
204 BEGINMESSAGE(save_forkPDFToPSConversion)
205
206 pos=file_locateFilename(sd->src_fn);
207 strcpy(proc_name,pos);
208 strcat(proc_name," conversion");
209
210 quoted_src_fn = quote_filename(sd->src_fn);
211 quoted_conv_fn = quote_filename(sd->conv_fn);
212 if ((pdfpos = strstr(gv_gs_cmd_conv_pdf,"%pdf")) &&
213 (pspos = strstr(gv_gs_cmd_conv_pdf,"%ps"))) {
214 command[0] = '\0';
215 if (pdfpos < pspos) {
216 strncat(command,gv_gs_cmd_conv_pdf,(pdfpos-gv_gs_cmd_conv_pdf));
217 strcat(command,quoted_src_fn);
218 strncat(command,pdfpos+4,(pspos-pdfpos-4));
219 strcat(command,quoted_conv_fn);
220 strcat(command,pspos+3);
221 } else {
222 strncat(command,gv_gs_cmd_conv_pdf,(pspos-gv_gs_cmd_conv_pdf));
223 strcat(command,quoted_conv_fn);
224 strncat(command,pspos+3,(pdfpos-pspos-3));
225 strcat(command,quoted_src_fn);
226 strcat(command,pdfpos+4);
227 }
228 } else {
229 sprintf(command,gv_gs_cmd_conv_pdf,quoted_conv_fn,quoted_src_fn);
230 }
231 XtFree(quoted_src_fn);
232 XtFree(quoted_conv_fn);
233
234 if (strstr(gv_gs_cmd_scan_pdf, "-P") || !gv_gs_safer)
235 strcpy(tmp, gv_gs_cmd_scan_pdf);
236 else
237 {
238 while (*src)
239 {
240 int isSpace = *src == ' ';
241 *(dest++) = *(src++);
242 if (!spaceFound && isSpace)
243 {
244 strcpy(dest, "-P- -dSAFER ");
245 dest+=12;
246 spaceFound = 1;
247 }
248 }
249 *dest = 0;
250 }
251
252 INFSMESSAGE(starting conversion:,tmp)
253 process_fork(proc_name,tmp,save_forkPDFToPSConversionDone,(XtPointer)sd);
254 ENDMESSAGE(save_forkPDFToPSConversion)
255 return(error);
256 }
257
258 /*------------------------------------------------------------*/
259 /* save_copyToFile */
260 /*------------------------------------------------------------*/
261
262 static String
save_copyToFile(String save_filename,String src_filename,char * pagelist,int scanstyle)263 save_copyToFile(String save_filename, String src_filename, char *pagelist, int scanstyle)
264 {
265 FILE *save_file=NULL;
266 FILE *src_file=NULL;
267 String error=NULL;
268 String openfail=GV_ERROR_OPEN_FAIL;
269 char *tmp;
270
271 BEGINMESSAGE(save_copyToFile)
272
273 if ((save_file = fopen(save_filename, "w")) == NULL)
274 error = open_fail_error(errno,openfail,save_filename,0);
275 if (!error && (src_file=fopen(src_filename,"r"))==NULL)
276 error = open_fail_error(errno,openfail,src_filename,0);
277 if (!error) {
278 if (pagelist) {
279 Document src_doc=NULL;
280 String s = XtNewString(src_filename);
281 s = file_getUsefulName(s);
282 INFMESSAGE(scanning document)
283 doc_scanFile(&src_file,&src_doc,src_filename,s,NULL,NULL,NULL,NULL,scanstyle,gv_gs_safeDir);
284 if (src_doc) {
285 INFMESSAGE(calling pscopydoc)
286 pscopydoc(save_file,src_filename,src_doc,pagelist);
287 psfree(src_doc);
288 } else {
289 char *error_scan_fail = "Failed to scan file %s\n";
290 char tmp[512];
291 sprintf(tmp,error_scan_fail,src_filename);
292 error=XtNewString(tmp);
293 }
294 } else {
295 char buf[BUFSIZ];
296 int bytes;
297 INFMESSAGE(copying file literaly)
298 while ((bytes = read(fileno(src_file),buf,BUFSIZ)))
299 bytes = write(fileno(save_file), buf, bytes);
300 }
301 }
302 tmp = close_file(src_file,src_filename); if (!error) error = tmp;
303 tmp = close_file(save_file,save_filename); if (!error) error = tmp;
304
305 ENDMESSAGE(save_copyToFile)
306 return(error);
307 }
308
309 /*############################################################*/
310 /* save_saveFile */
311 /*############################################################*/
312
313 String
save_saveFile(sd)314 save_saveFile(sd)
315 SaveData sd;
316 {
317 char *src_fn;
318 String error=NULL,s;
319
320 BEGINMESSAGE(save_saveFile)
321
322 if (!sd->save_fn && !sd->print_cmd && sd->save_to_file) {
323 INFMESSAGE(save_filename not useful)
324 ENDMESSAGE(save_saveFile)
325 return(error);
326 }
327
328 if (!error && sd->convert && !sd->conv_fn)
329 {
330
331 s = sd->save_fn ? sd->save_fn : sd->src_fn;
332 s = XtNewString(s);
333 s = file_getUsefulName(s);
334 s = file_pdfname2psname(s);
335 sd->conv_fn = file_getTmpFilename(NULL, s, NULL);
336 XtFree(s);
337 if (sd->conv_fn == NULL)
338 return XtNewString("Cannot create temporary file!");
339 INFSMESSAGE(converting from file,sd->src_fn)
340 INFSMESSAGE(converting to file,sd->conv_fn)
341 error = save_forkPDFToPSConversion(sd);
342 ENDMESSAGE(save_saveFile)
343 return(error);
344 }
345
346 src_fn = sd->src_fn;
347 if (sd->conv_fn) src_fn = sd->conv_fn;
348
349 if (!error && sd->save_to_file) {
350 if (!sd->save_fn) {
351 s = XtNewString(sd->src_fn);
352 s = file_getUsefulName(s);
353 s = file_pdfname2psname(s);
354 sd->save_fn = file_getTmpFilename(NULL, s, NULL);
355 XtFree(s);
356 }
357 if (!sd->save_fn) {
358 error = XtNewString("Cannot create temporary file!");
359 } else {
360 INFSMESSAGE(saving from file,src_fn)
361 INFSMESSAGE(saving to file,sd->save_fn)
362 error = save_copyToFile(sd->save_fn,src_fn,sd->pagelist,sd->scanstyle);
363 src_fn = sd->save_fn;
364 }
365 }
366
367 if (!error && sd->save_to_printer) {
368 INFSMESSAGE(saving to printer from file,src_fn)
369 error = print_file(sd->print_cmd,src_fn);
370 if (src_fn != sd->src_fn && !(sd->print_kills_file)) {
371 INFSMESSAGE(deleting file, src_fn)
372 unlink(src_fn);
373 }
374 }
375
376 if (sd->conv_fn) {
377 INFSMESSAGE(deleting file, sd->conv_fn)
378 unlink(sd->conv_fn);
379 }
380 save_freeSaveData(sd);
381
382 ENDMESSAGE(save_saveFile)
383 return(error);
384 }
385