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