• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 3, as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranties of
10  * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11  * PURPOSE.  See the GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #include "banner.h"
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <stdarg.h>
24 #include <libgen.h>
25 
26 
parse_line(char * line,char ** key,char ** value)27 static int parse_line(char *line, char **key, char **value)
28 {
29     char *p = line;
30 
31     *key = *value = NULL;
32 
33     while (isspace(*p)) p++;
34     if (!*p || *p == '#')
35         return 0;
36 
37     *key = p;
38     while (*p && !isspace(*p))
39         p++;
40     if (!*p)
41         return 1;
42 
43     *p++ = '\0';
44 
45     while (isspace(*p)) p++;
46     if (!*p)
47         return 1;
48 
49     *value = p;
50 
51     /* remove trailing space */
52     while (*p)
53         p++;
54     while (isspace(*--p))
55         *p = '\0';
56 
57     return 1;
58 }
59 
60 
parse_show(char * s)61 static unsigned parse_show(char *s)
62 {
63     unsigned info = 0;
64     char *tok;
65 
66     for (tok = strtok(s, " \t"); tok; tok = strtok(NULL, " \t")) {
67         if (!strcasecmp(tok, "imageable-area"))
68              info |= INFO_IMAGEABLE_AREA;
69         else if (!strcasecmp(tok, "job-billing"))
70             info |= INFO_JOB_BILLING;
71         else if (!strcasecmp(tok, "job-id"))
72             info |= INFO_JOB_ID;
73         else if (!strcasecmp(tok, "job-name"))
74             info |= INFO_JOB_NAME;
75         else if (!strcasecmp(tok, "job-originating-host-name"))
76             info |= INFO_JOB_ORIGINATING_HOST_NAME;
77         else if (!strcasecmp(tok, "job-originating-user-name"))
78             info |= INFO_JOB_ORIGINATING_USER_NAME;
79         else if (!strcasecmp(tok, "job-uuid"))
80             info |= INFO_JOB_UUID;
81         else if (!strcasecmp(tok, "options"))
82             info |= INFO_OPTIONS;
83         else if (!strcasecmp(tok, "paper-name"))
84             info |= INFO_PAPER_NAME;
85         else if (!strcasecmp(tok, "paper-size"))
86             info |= INFO_PAPER_SIZE;
87         else if (!strcasecmp(tok, "printer-driver-name"))
88             info |= INFO_PRINTER_DRIVER_NAME;
89         else if (!strcasecmp(tok, "printer-driver-version"))
90             info |= INFO_PRINTER_DRIVER_VERSION;
91         else if (!strcasecmp(tok, "printer-info"))
92             info |= INFO_PRINTER_INFO;
93         else if (!strcasecmp(tok, "printer-location"))
94             info |= INFO_PRINTER_LOCATION;
95         else if (!strcasecmp(tok, "printer-make-and-model"))
96             info |= INFO_PRINTER_MAKE_AND_MODEL;
97         else if (!strcasecmp(tok, "printer-name"))
98             info |= INFO_PRINTER_NAME;
99         else if (!strcasecmp(tok, "time-at-creation"))
100             info |= INFO_TIME_AT_CREATION;
101         else if (!strcasecmp(tok, "time-at-processing"))
102             info |= INFO_TIME_AT_PROCESSING;
103         else
104             fprintf(stderr, "error: unknown value for 'Show': %s\n", tok);
105     }
106     return info;
107 }
108 
109 
template_path(const char * name)110 static char * template_path(const char *name)
111 {
112     char *datadir, *result;
113 
114     if (name[0] == '/')
115         return strdup(name);
116 
117     if ((datadir = getenv("CUPS_DATADIR")) == NULL) {
118         result = malloc(strlen(BANNERTOPDF_DATADIR) + strlen(name) + 2);
119         sprintf(result, "%s/%s", BANNERTOPDF_DATADIR, name);
120     } else {
121         result = malloc(strlen(datadir) + strlen(name) + 7);
122         sprintf(result, "%s/data/%s", datadir, name);
123     }
124 
125     return result;
126 }
127 
128 
banner_new_from_file(const char * filename,int * num_options,cups_option_t ** options)129 banner_t * banner_new_from_file(const char *filename,
130         int *num_options, cups_option_t **options)
131 {
132     FILE *f;
133     char *line = NULL;
134     size_t len = 0;
135     int linenr = 0;
136     banner_t *banner = NULL;
137 
138     if (!strcmp(filename, "-"))
139         f = stdin;
140     else if (!(f = fopen(filename, "r"))) {
141         perror("Error opening banner file");
142         goto out;
143     }
144 
145     if (getline(&line, &len, f) == -1 ||
146         strncmp(line, "#PDF-BANNER", 11) != 0)
147         goto out;
148 
149     banner = calloc(1, sizeof *banner);
150 
151     while (getline(&line, &len, f) != -1) {
152         char *key, *value;
153 
154         linenr++;
155         if (!parse_line(line, &key, &value))
156             continue;
157 
158         if (!value) {
159             fprintf(stderr, "error: line %d is missing a value\n", linenr);
160             continue;
161         }
162 
163         if (!strcasecmp(key, "template"))
164             banner->template_file = template_path(value);
165         else if (!strcasecmp(key, "header"))
166             banner->header = strdup(value);
167         else if (!strcasecmp(key, "footer"))
168             banner->header = strdup(value);
169         else if (!strcasecmp(key, "font")) {
170             *num_options = cupsAddOption("banner-font",
171                     strdup(value), *num_options, options);
172         }
173         else if (!strcasecmp(key, "font-size")) {
174             *num_options = cupsAddOption("banner-font-size",
175                     strdup(value), *num_options, options);
176         }
177         else if (!strcasecmp(key, "show"))
178             banner->infos = parse_show(value);
179         else if (!strcasecmp(key, "image") ||
180                  !strcasecmp(key, "notice"))
181             fprintf(stderr,
182                     "note:%d: bannertopdf does not support '%s'\n",
183                     linenr, key);
184         else
185             fprintf(stderr,
186                     "error:%d: unknown keyword '%s'\n",
187                     linenr, key);
188     }
189 
190     /* load default template if none was specified */
191     if (!banner->template_file)
192         banner->template_file = template_path ("default.pdf");
193 
194 out:
195     free(line);
196     if (f)
197         fclose(f);
198     return banner;
199 }
200 
201 
banner_free(banner_t * banner)202 void banner_free(banner_t *banner)
203 {
204     if (banner) {
205         free(banner->template_file);
206         free(banner->header);
207         free(banner->footer);
208         free(banner);
209     }
210 }
211 
212