]> git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/statbuf.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / scheduler / statbuf.c
1 /*
2 * Status buffer routines for the CUPS scheduler.
3 *
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
6 *
7 * These coded instructions, statements, and computer programs are the
8 * property of Apple Inc. and are protected by Federal copyright
9 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 * which should have been included with this file. If this file is
11 * missing or damaged, see the license at "http://www.cups.org/".
12 */
13
14 /*
15 * Include necessary headers...
16 */
17
18 #include "cupsd.h"
19 #include <stdarg.h>
20
21
22 /*
23 * 'cupsdStatBufDelete()' - Destroy a status buffer.
24 */
25
26 void
27 cupsdStatBufDelete(cupsd_statbuf_t *sb) /* I - Status buffer */
28 {
29 /*
30 * Range check input...
31 */
32
33 if (!sb)
34 return;
35
36 /*
37 * Close the status pipe and free memory used...
38 */
39
40 close(sb->fd);
41
42 free(sb);
43 }
44
45
46 /*
47 * 'cupsdStatBufNew()' - Create a new status buffer.
48 */
49
50 cupsd_statbuf_t * /* O - New status buffer */
51 cupsdStatBufNew(int fd, /* I - File descriptor of pipe */
52 const char *prefix, /* I - Printf-style prefix string */
53 ...) /* I - Additional args as needed */
54 {
55 cupsd_statbuf_t *sb; /* New status buffer */
56 va_list ap; /* Argument list */
57
58
59 /*
60 * Range check input...
61 */
62
63 if (fd < 0)
64 return (NULL);
65
66 /*
67 * Allocate the status buffer...
68 */
69
70 if ((sb = calloc(1, sizeof(cupsd_statbuf_t))) != NULL)
71 {
72 /*
73 * Assign the file descriptor...
74 */
75
76 sb->fd = fd;
77
78 /*
79 * Format the prefix string, if any. This is usually "[Job 123]"
80 * or "[Sub 123]", and so forth.
81 */
82
83 if (prefix)
84 {
85 /*
86 * Printf-style prefix string...
87 */
88
89 va_start(ap, prefix);
90 vsnprintf(sb->prefix, sizeof(sb->prefix), prefix, ap);
91 va_end(ap);
92 }
93 else
94 {
95 /*
96 * No prefix string...
97 */
98
99 sb->prefix[0] = '\0';
100 }
101 }
102
103 return (sb);
104 }
105
106
107 /*
108 * 'cupsdStatBufUpdate()' - Update the status buffer.
109 */
110
111 char * /* O - Line from buffer, "", or NULL */
112 cupsdStatBufUpdate(
113 cupsd_statbuf_t *sb, /* I - Status buffer */
114 int *loglevel, /* O - Log level */
115 char *line, /* I - Line buffer */
116 int linelen) /* I - Size of line buffer */
117 {
118 int bytes; /* Number of bytes read */
119 char *lineptr, /* Pointer to end of line in buffer */
120 *message; /* Pointer to message text */
121
122
123 /*
124 * Check if the buffer already contains a full line...
125 */
126
127 if ((lineptr = strchr(sb->buffer, '\n')) == NULL)
128 {
129 /*
130 * No, read more data...
131 */
132
133 if ((bytes = read(sb->fd, sb->buffer + sb->bufused, (size_t)(CUPSD_SB_BUFFER_SIZE - sb->bufused - 1))) > 0)
134 {
135 sb->bufused += bytes;
136 sb->buffer[sb->bufused] = '\0';
137
138 /*
139 * Guard against a line longer than the max buffer size...
140 */
141
142 if ((lineptr = strchr(sb->buffer, '\n')) == NULL &&
143 sb->bufused == (CUPSD_SB_BUFFER_SIZE - 1))
144 lineptr = sb->buffer + sb->bufused;
145 }
146 else if (bytes < 0 && errno == EINTR)
147 {
148 /*
149 * Return an empty line if we are interrupted...
150 */
151
152 *loglevel = CUPSD_LOG_NONE;
153 line[0] = '\0';
154
155 return (line);
156 }
157 else
158 {
159 /*
160 * End-of-file, so use the whole buffer...
161 */
162
163 lineptr = sb->buffer + sb->bufused;
164 *lineptr = '\0';
165 }
166
167 /*
168 * Final check for end-of-file...
169 */
170
171 if (sb->bufused == 0 && bytes == 0)
172 lineptr = NULL;
173 }
174
175 if (!lineptr)
176 {
177 /*
178 * End of file...
179 */
180
181 *loglevel = CUPSD_LOG_NONE;
182 line[0] = '\0';
183
184 return (NULL);
185 }
186
187 /*
188 * Terminate the line and process it...
189 */
190
191 *lineptr++ = '\0';
192
193 /*
194 * Figure out the logging level...
195 */
196
197 if (!strncmp(sb->buffer, "EMERG:", 6))
198 {
199 *loglevel = CUPSD_LOG_EMERG;
200 message = sb->buffer + 6;
201 }
202 else if (!strncmp(sb->buffer, "ALERT:", 6))
203 {
204 *loglevel = CUPSD_LOG_ALERT;
205 message = sb->buffer + 6;
206 }
207 else if (!strncmp(sb->buffer, "CRIT:", 5))
208 {
209 *loglevel = CUPSD_LOG_CRIT;
210 message = sb->buffer + 5;
211 }
212 else if (!strncmp(sb->buffer, "ERROR:", 6))
213 {
214 *loglevel = CUPSD_LOG_ERROR;
215 message = sb->buffer + 6;
216 }
217 else if (!strncmp(sb->buffer, "WARNING:", 8))
218 {
219 *loglevel = CUPSD_LOG_WARN;
220 message = sb->buffer + 8;
221 }
222 else if (!strncmp(sb->buffer, "NOTICE:", 7))
223 {
224 *loglevel = CUPSD_LOG_NOTICE;
225 message = sb->buffer + 7;
226 }
227 else if (!strncmp(sb->buffer, "INFO:", 5))
228 {
229 *loglevel = CUPSD_LOG_INFO;
230 message = sb->buffer + 5;
231 }
232 else if (!strncmp(sb->buffer, "DEBUG:", 6))
233 {
234 *loglevel = CUPSD_LOG_DEBUG;
235 message = sb->buffer + 6;
236 }
237 else if (!strncmp(sb->buffer, "DEBUG2:", 7))
238 {
239 *loglevel = CUPSD_LOG_DEBUG2;
240 message = sb->buffer + 7;
241 }
242 else if (!strncmp(sb->buffer, "PAGE:", 5))
243 {
244 *loglevel = CUPSD_LOG_PAGE;
245 message = sb->buffer + 5;
246 }
247 else if (!strncmp(sb->buffer, "STATE:", 6))
248 {
249 *loglevel = CUPSD_LOG_STATE;
250 message = sb->buffer + 6;
251 }
252 else if (!strncmp(sb->buffer, "JOBSTATE:", 9))
253 {
254 *loglevel = CUPSD_LOG_JOBSTATE;
255 message = sb->buffer + 9;
256 }
257 else if (!strncmp(sb->buffer, "ATTR:", 5))
258 {
259 *loglevel = CUPSD_LOG_ATTR;
260 message = sb->buffer + 5;
261 }
262 else if (!strncmp(sb->buffer, "PPD:", 4))
263 {
264 *loglevel = CUPSD_LOG_PPD;
265 message = sb->buffer + 4;
266 }
267 else
268 {
269 *loglevel = CUPSD_LOG_DEBUG;
270 message = sb->buffer;
271 }
272
273 /*
274 * Skip leading whitespace in the message...
275 */
276
277 while (isspace(*message & 255))
278 message ++;
279
280 /*
281 * Send it to the log file as needed...
282 */
283
284 if (sb->prefix[0])
285 {
286 if (*loglevel > CUPSD_LOG_NONE &&
287 (*loglevel != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG))
288 {
289 /*
290 * General status message; send it to the error_log file...
291 */
292
293 if (message[0] == '[')
294 cupsdLogMessage(*loglevel, "%s", message);
295 else
296 cupsdLogMessage(*loglevel, "%s %s", sb->prefix, message);
297 }
298 else if (*loglevel < CUPSD_LOG_NONE && LogLevel >= CUPSD_LOG_DEBUG)
299 cupsdLogMessage(CUPSD_LOG_DEBUG2, "%s %s", sb->prefix, sb->buffer);
300 }
301
302 /*
303 * Copy the message to the line buffer...
304 */
305
306 strlcpy(line, message, (size_t)linelen);
307
308 /*
309 * Copy over the buffer data we've used up...
310 */
311
312 if (lineptr < sb->buffer + sb->bufused)
313 _cups_strcpy(sb->buffer, lineptr);
314
315 sb->bufused -= lineptr - sb->buffer;
316
317 if (sb->bufused < 0)
318 sb->bufused = 0;
319
320 return (line);
321 }