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