]> git.ipfire.org Git - thirdparty/cups.git/blob - cups/pwg-file.c
Merge changes from CUPS 1.5svn-r9041.
[thirdparty/cups.git] / cups / pwg-file.c
1 /*
2 * "$Id$"
3 *
4 * PWG load/save API implementation for CUPS.
5 *
6 * Copyright 2010 by Apple Inc.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
13 *
14 * This file is subject to the Apple OS-Developed Software exception.
15 *
16 * Contents:
17 *
18 * _pwgCreateWithFile() - Create PWG mapping data from a written file.
19 * _pwgDestroy() - Free all memory used for PWG mapping data.
20 * _pwgWriteFile() - Write PWG mapping data to a file.
21 */
22
23 /*
24 * Include necessary headers...
25 */
26
27 #include "pwg-private.h"
28 #include "globals.h"
29 #include "string.h"
30 #include "debug.h"
31 #include <math.h>
32
33
34 /*
35 * '_pwgCreateWithFile()' - Create PWG mapping data from a written file.
36 *
37 * Use the @link _pwgWriteFile@ function to write PWG mapping data to a file.
38 */
39
40 _pwg_t * /* O - PWG mapping data */
41 _pwgCreateWithFile(const char *filename)/* I - File to read */
42 {
43 cups_file_t *fp; /* File */
44 _pwg_t *pwg; /* PWG mapping data */
45 _pwg_size_t *size; /* Current size */
46 _pwg_map_t *map; /* Current map */
47 int linenum, /* Current line number */
48 num_sizes, /* Number of sizes in file */
49 num_sources, /* Number of sources in file */
50 num_types; /* Number of types in file */
51 char line[512], /* Current line */
52 *value, /* Pointer to value in line */
53 pwg_keyword[128], /* PWG keyword */
54 ppd_keyword[PPD_MAX_NAME];
55 /* PPD keyword */
56
57
58 DEBUG_printf(("_pwgCreateWithFile(filename=\"%s\")", filename));
59
60 /*
61 * Range check input...
62 */
63
64 if (!filename)
65 {
66 _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
67 return (NULL);
68 }
69
70 /*
71 * Open the file...
72 */
73
74 if ((fp = cupsFileOpen(filename, "r")) == NULL)
75 {
76 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
77 return (NULL);
78 }
79
80 /*
81 * Allocate the mapping data structure...
82 */
83
84 if ((pwg = calloc(1, sizeof(_pwg_t))) == NULL)
85 {
86 DEBUG_puts("_pwgCreateWithFile: Unable to allocate pwg_t.");
87 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
88 goto create_error;
89 }
90
91 /*
92 * Read the file...
93 */
94
95 linenum = 0;
96 num_sizes = 0;
97 num_sources = 0;
98 num_types = 0;
99
100 while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
101 {
102 DEBUG_printf(("_pwgCreateWithFile: line=\"%s\", value=\"%s\", linenum=%d",
103 line, value, linenum));
104
105 if (!value)
106 {
107 DEBUG_printf(("_pwgCreateWithFile: Missing value on line %d.", linenum));
108 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
109 goto create_error;
110 }
111 else if (!strcasecmp(line, "NumSizes"))
112 {
113 if (num_sizes > 0)
114 {
115 DEBUG_puts("_pwgCreateWithFile: NumSizes listed multiple times.");
116 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
117 goto create_error;
118 }
119
120 if ((num_sizes = atoi(value)) <= 0 || num_sizes > 65536)
121 {
122 DEBUG_printf(("_pwgCreateWithFile: Bad NumSizes value %d on line %d.",
123 num_sizes, linenum));
124 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
125 goto create_error;
126 }
127
128 if ((pwg->sizes = calloc(num_sizes, sizeof(_pwg_size_t))) == NULL)
129 {
130 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sizes.",
131 num_sizes));
132 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
133 goto create_error;
134 }
135 }
136 else if (!strcasecmp(line, "Size"))
137 {
138 if (pwg->num_sizes >= num_sizes)
139 {
140 DEBUG_printf(("_pwgCreateWithFile: Too many Size's on line %d.",
141 linenum));
142 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
143 goto create_error;
144 }
145
146 size = pwg->sizes + pwg->num_sizes;
147
148 if (sscanf(value, "%127s%40s%d%d%d%d%d%d", pwg_keyword, ppd_keyword,
149 &(size->width), &(size->length), &(size->left),
150 &(size->bottom), &(size->right), &(size->top)) != 8)
151 {
152 DEBUG_printf(("_pwgCreateWithFile: Bad Size on line %d.", linenum));
153 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
154 goto create_error;
155 }
156
157 size->map.pwg = _cupsStrAlloc(pwg_keyword);
158 size->map.ppd = _cupsStrAlloc(ppd_keyword);
159
160 pwg->num_sizes ++;
161 }
162 else if (!strcasecmp(line, "CustomSize"))
163 {
164 if (pwg->custom_max_width > 0)
165 {
166 DEBUG_printf(("_pwgCreateWithFile: Too many CustomSize's on line %d.",
167 linenum));
168 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
169 goto create_error;
170 }
171
172 if (sscanf(value, "%d%d%d%d%d%d%d%d", &(pwg->custom_max_width),
173 &(pwg->custom_max_length), &(pwg->custom_min_width),
174 &(pwg->custom_min_length), &(pwg->custom_size.left),
175 &(pwg->custom_size.bottom), &(pwg->custom_size.right),
176 &(pwg->custom_size.top)) != 8)
177 {
178 DEBUG_printf(("_pwgCreateWithFile: Bad CustomSize on line %d.", linenum));
179 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
180 goto create_error;
181 }
182
183 _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "max",
184 pwg->custom_max_width, pwg->custom_max_length);
185 pwg->custom_max_keyword = _cupsStrAlloc(pwg_keyword);
186
187 _pwgGenerateSize(pwg_keyword, sizeof(pwg_keyword), "custom", "min",
188 pwg->custom_min_width, pwg->custom_min_length);
189 pwg->custom_min_keyword = _cupsStrAlloc(pwg_keyword);
190 }
191 else if (!strcasecmp(line, "NumSources"))
192 {
193 if (num_sources > 0)
194 {
195 DEBUG_puts("_pwgCreateWithFile: NumSources listed multiple times.");
196 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
197 goto create_error;
198 }
199
200 if ((num_sources = atoi(value)) <= 0 || num_sources > 65536)
201 {
202 DEBUG_printf(("_pwgCreateWithFile: Bad NumSources value %d on line %d.",
203 num_sources, linenum));
204 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
205 goto create_error;
206 }
207
208 if ((pwg->sources = calloc(num_sources, sizeof(_pwg_map_t))) == NULL)
209 {
210 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d sources.",
211 num_sources));
212 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
213 goto create_error;
214 }
215 }
216 else if (!strcasecmp(line, "Source"))
217 {
218 if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
219 {
220 DEBUG_printf(("_pwgCreateWithFile: Bad Source on line %d.", linenum));
221 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
222 goto create_error;
223 }
224
225 if (pwg->num_sources >= num_sources)
226 {
227 DEBUG_printf(("_pwgCreateWithFile: Too many Source's on line %d.",
228 linenum));
229 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
230 goto create_error;
231 }
232
233 map = pwg->sources + pwg->num_sources;
234 map->pwg = _cupsStrAlloc(pwg_keyword);
235 map->ppd = _cupsStrAlloc(ppd_keyword);
236
237 pwg->num_sources ++;
238 }
239 else if (!strcasecmp(line, "NumTypes"))
240 {
241 if (num_types > 0)
242 {
243 DEBUG_puts("_pwgCreateWithFile: NumTypes listed multiple times.");
244 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
245 goto create_error;
246 }
247
248 if ((num_types = atoi(value)) <= 0 || num_types > 65536)
249 {
250 DEBUG_printf(("_pwgCreateWithFile: Bad NumTypes value %d on line %d.",
251 num_types, linenum));
252 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
253 goto create_error;
254 }
255
256 if ((pwg->types = calloc(num_types, sizeof(_pwg_map_t))) == NULL)
257 {
258 DEBUG_printf(("_pwgCreateWithFile: Unable to allocate %d types.",
259 num_types));
260 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
261 goto create_error;
262 }
263 }
264 else if (!strcasecmp(line, "Type"))
265 {
266 if (sscanf(value, "%127s%40s", pwg_keyword, ppd_keyword) != 2)
267 {
268 DEBUG_printf(("_pwgCreateWithFile: Bad Type on line %d.", linenum));
269 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
270 goto create_error;
271 }
272
273 if (pwg->num_types >= num_types)
274 {
275 DEBUG_printf(("_pwgCreateWithFile: Too many Type's on line %d.",
276 linenum));
277 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
278 goto create_error;
279 }
280
281 map = pwg->types + pwg->num_types;
282 map->pwg = _cupsStrAlloc(pwg_keyword);
283 map->ppd = _cupsStrAlloc(ppd_keyword);
284
285 pwg->num_types ++;
286 }
287 else
288 {
289 DEBUG_printf(("_pwgCreateWithFile: Unknown %s on line %d.", line,
290 linenum));
291 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
292 goto create_error;
293 }
294 }
295
296 if (pwg->num_sizes < num_sizes)
297 {
298 DEBUG_printf(("_pwgCreateWithFile: Not enough sizes (%d < %d).",
299 pwg->num_sizes, num_sizes));
300 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
301 goto create_error;
302 }
303
304 if (pwg->num_sources < num_sources)
305 {
306 DEBUG_printf(("_pwgCreateWithFile: Not enough sources (%d < %d).",
307 pwg->num_sources, num_sources));
308 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
309 goto create_error;
310 }
311
312 if (pwg->num_types < num_types)
313 {
314 DEBUG_printf(("_pwgCreateWithFile: Not enough types (%d < %d).",
315 pwg->num_types, num_types));
316 _cupsSetError(IPP_INTERNAL_ERROR, _("Bad PWG mapping file."), 1);
317 goto create_error;
318 }
319
320 cupsFileClose(fp);
321
322 return (pwg);
323
324 /*
325 * If we get here the file was bad - free any data and return...
326 */
327
328 create_error:
329
330 cupsFileClose(fp);
331 _pwgDestroy(pwg);
332
333 return (NULL);
334 }
335
336
337 /*
338 * '_pwgDestroy()' - Free all memory used for PWG mapping data.
339 */
340
341 void
342 _pwgDestroy(_pwg_t *pwg) /* I - PWG mapping data */
343 {
344 int i; /* Looping var */
345 _pwg_map_t *map; /* Current map */
346 _pwg_size_t *size; /* Current size */
347
348
349 /*
350 * Range check input...
351 */
352
353 if (!pwg)
354 return;
355
356 /*
357 * Free memory as needed...
358 */
359
360 if (pwg->sizes)
361 {
362 for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
363 {
364 _cupsStrFree(size->map.pwg);
365 _cupsStrFree(size->map.ppd);
366 }
367
368 free(pwg->sizes);
369 }
370
371 if (pwg->sources)
372 {
373 for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++)
374 {
375 _cupsStrFree(map->pwg);
376 _cupsStrFree(map->ppd);
377 }
378
379 free(pwg->sources);
380 }
381
382 if (pwg->types)
383 {
384 for (i = pwg->num_types, map = pwg->types; i > 0; i --, map ++)
385 {
386 _cupsStrFree(map->pwg);
387 _cupsStrFree(map->ppd);
388 }
389
390 free(pwg->types);
391 }
392
393 if (pwg->custom_max_keyword)
394 _cupsStrFree(pwg->custom_max_keyword);
395
396 if (pwg->custom_min_keyword)
397 _cupsStrFree(pwg->custom_min_keyword);
398
399 free(pwg);
400 }
401
402
403 /*
404 * '_pwgWriteFile()' - Write PWG mapping data to a file.
405 */
406
407 int /* O - 1 on success, 0 on failure */
408 _pwgWriteFile(_pwg_t *pwg, /* I - PWG mapping data */
409 const char *filename) /* I - File to write */
410 {
411 int i; /* Looping var */
412 cups_file_t *fp; /* Output file */
413 _pwg_size_t *size; /* Current size */
414 _pwg_map_t *map; /* Current map */
415
416
417 /*
418 * Range check input...
419 */
420
421 if (!pwg || !filename)
422 {
423 _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
424 return (0);
425 }
426
427 /*
428 * Open the file and write with compression...
429 */
430
431 if ((fp = cupsFileOpen(filename, "w9")) == NULL)
432 {
433 _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno), 0);
434 return (0);
435 }
436
437 /*
438 * Standard header...
439 */
440
441 cupsFilePuts(fp, "#CUPS-PWGPPD\n");
442
443 /*
444 * Media sizes...
445 */
446
447 cupsFilePrintf(fp, "NumSizes %d\n", pwg->num_sizes);
448 for (i = pwg->num_sizes, size = pwg->sizes; i > 0; i --, size ++)
449 cupsFilePrintf(fp, "Size %s %s %d %d %d %d %d %d\n", size->map.pwg,
450 size->map.ppd, size->width, size->length, size->left,
451 size->bottom, size->right, size->top);
452 if (pwg->custom_max_width > 0)
453 cupsFilePrintf(fp, "CustomSize %d %d %d %d %d %d %d %d\n",
454 pwg->custom_max_width, pwg->custom_max_length,
455 pwg->custom_min_width, pwg->custom_min_length,
456 pwg->custom_size.left, pwg->custom_size.bottom,
457 pwg->custom_size.right, pwg->custom_size.top);
458
459 /*
460 * Media sources...
461 */
462
463 if (pwg->num_sources > 0)
464 {
465 cupsFilePrintf(fp, "NumSources %d\n", pwg->num_sources);
466 for (i = pwg->num_sources, map = pwg->sources; i > 0; i --, map ++)
467 cupsFilePrintf(fp, "Source %s %s\n", map->pwg, map->ppd);
468 }
469
470 /*
471 * Media types...
472 */
473
474 if (pwg->num_types > 0)
475 {
476 cupsFilePrintf(fp, "NumTypes %d\n", pwg->num_types);
477 for (i = pwg->num_types, map = pwg->types; i > 0; i --, map ++)
478 cupsFilePrintf(fp, "Type %s %s\n", map->pwg, map->ppd);
479 }
480
481 /*
482 * Close and return...
483 */
484
485 return (!cupsFileClose(fp));
486 }
487
488
489 /*
490 * End of "$Id$".
491 */