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