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