2 * Status buffer routines for the CUPS scheduler.
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
19 * 'cupsdStatBufDelete()' - Destroy a status buffer.
23 cupsdStatBufDelete(cupsd_statbuf_t *sb) /* I - Status buffer */
26 * Range check input...
33 * Close the status pipe and free memory used...
43 * 'cupsdStatBufNew()' - Create a new status buffer.
46 cupsd_statbuf_t * /* O - New status buffer */
47 cupsdStatBufNew(int fd, /* I - File descriptor of pipe */
48 const char *prefix, /* I - Printf-style prefix string */
49 ...) /* I - Additional args as needed */
51 cupsd_statbuf_t *sb; /* New status buffer */
52 va_list ap; /* Argument list */
56 * Range check input...
63 * Allocate the status buffer...
66 if ((sb = calloc(1, sizeof(cupsd_statbuf_t))) != NULL)
69 * Assign the file descriptor...
75 * Format the prefix string, if any. This is usually "[Job 123]"
76 * or "[Sub 123]", and so forth.
82 * Printf-style prefix string...
86 vsnprintf(sb->prefix, sizeof(sb->prefix), prefix, ap);
104 * 'cupsdStatBufUpdate()' - Update the status buffer.
107 char * /* O - Line from buffer, "", or NULL */
109 cupsd_statbuf_t *sb, /* I - Status buffer */
110 int *loglevel, /* O - Log level */
111 char *line, /* I - Line buffer */
112 int linelen) /* I - Size of line buffer */
114 int bytes; /* Number of bytes read */
115 char *lineptr, /* Pointer to end of line in buffer */
116 *message; /* Pointer to message text */
120 * Check if the buffer already contains a full line...
123 if ((lineptr = strchr(sb->buffer, '\n')) == NULL)
126 * No, read more data...
129 if ((bytes = read(sb->fd, sb->buffer + sb->bufused, (size_t)(CUPSD_SB_BUFFER_SIZE - sb->bufused - 1))) > 0)
131 sb->bufused += bytes;
132 sb->buffer[sb->bufused] = '\0';
135 * Guard against a line longer than the max buffer size...
138 if ((lineptr = strchr(sb->buffer, '\n')) == NULL &&
139 sb->bufused == (CUPSD_SB_BUFFER_SIZE - 1))
140 lineptr = sb->buffer + sb->bufused;
142 else if (bytes < 0 && errno == EINTR)
145 * Return an empty line if we are interrupted...
148 *loglevel = CUPSD_LOG_NONE;
156 * End-of-file, so use the whole buffer...
159 lineptr = sb->buffer + sb->bufused;
164 * Final check for end-of-file...
167 if (sb->bufused == 0 && bytes == 0)
177 *loglevel = CUPSD_LOG_NONE;
184 * Terminate the line and process it...
190 * Figure out the logging level...
193 if (!strncmp(sb->buffer, "EMERG:", 6))
195 *loglevel = CUPSD_LOG_EMERG;
196 message = sb->buffer + 6;
198 else if (!strncmp(sb->buffer, "ALERT:", 6))
200 *loglevel = CUPSD_LOG_ALERT;
201 message = sb->buffer + 6;
203 else if (!strncmp(sb->buffer, "CRIT:", 5))
205 *loglevel = CUPSD_LOG_CRIT;
206 message = sb->buffer + 5;
208 else if (!strncmp(sb->buffer, "ERROR:", 6))
210 *loglevel = CUPSD_LOG_ERROR;
211 message = sb->buffer + 6;
213 else if (!strncmp(sb->buffer, "WARNING:", 8))
215 *loglevel = CUPSD_LOG_WARN;
216 message = sb->buffer + 8;
218 else if (!strncmp(sb->buffer, "NOTICE:", 7))
220 *loglevel = CUPSD_LOG_NOTICE;
221 message = sb->buffer + 7;
223 else if (!strncmp(sb->buffer, "INFO:", 5))
225 *loglevel = CUPSD_LOG_INFO;
226 message = sb->buffer + 5;
228 else if (!strncmp(sb->buffer, "DEBUG:", 6))
230 *loglevel = CUPSD_LOG_DEBUG;
231 message = sb->buffer + 6;
233 else if (!strncmp(sb->buffer, "DEBUG2:", 7))
235 *loglevel = CUPSD_LOG_DEBUG2;
236 message = sb->buffer + 7;
238 else if (!strncmp(sb->buffer, "PAGE:", 5))
240 *loglevel = CUPSD_LOG_PAGE;
241 message = sb->buffer + 5;
243 else if (!strncmp(sb->buffer, "STATE:", 6))
245 *loglevel = CUPSD_LOG_STATE;
246 message = sb->buffer + 6;
248 else if (!strncmp(sb->buffer, "JOBSTATE:", 9))
250 *loglevel = CUPSD_LOG_JOBSTATE;
251 message = sb->buffer + 9;
253 else if (!strncmp(sb->buffer, "ATTR:", 5))
255 *loglevel = CUPSD_LOG_ATTR;
256 message = sb->buffer + 5;
258 else if (!strncmp(sb->buffer, "PPD:", 4))
260 *loglevel = CUPSD_LOG_PPD;
261 message = sb->buffer + 4;
265 *loglevel = CUPSD_LOG_DEBUG;
266 message = sb->buffer;
270 * Skip leading whitespace in the message...
273 while (isspace(*message & 255))
277 * Send it to the log file as needed...
282 if (*loglevel > CUPSD_LOG_NONE &&
283 (*loglevel != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG))
286 * General status message; send it to the error_log file...
289 if (message[0] == '[')
290 cupsdLogMessage(*loglevel, "%s", message);
292 cupsdLogMessage(*loglevel, "%s %s", sb->prefix, message);
294 else if (*loglevel < CUPSD_LOG_NONE && LogLevel >= CUPSD_LOG_DEBUG)
295 cupsdLogMessage(CUPSD_LOG_DEBUG2, "%s %s", sb->prefix, sb->buffer);
299 * Copy the message to the line buffer...
302 strlcpy(line, message, (size_t)linelen);
305 * Copy over the buffer data we've used up...
308 if (lineptr < sb->buffer + sb->bufused)
309 _cups_strcpy(sb->buffer, lineptr);
311 sb->bufused -= lineptr - sb->buffer;