1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Debugging functions for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2008-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker *
6*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
7*5e7646d2SAndroid Build Coastguard Worker * information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
15*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "thread-private.h"
17*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
18*5e7646d2SAndroid Build Coastguard Worker # include <sys/timeb.h>
19*5e7646d2SAndroid Build Coastguard Worker # include <time.h>
20*5e7646d2SAndroid Build Coastguard Worker # include <io.h>
21*5e7646d2SAndroid Build Coastguard Worker # define getpid (int)GetCurrentProcessId
22*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on failure */
_cups_gettimeofday(struct timeval * tv,void * tz)23*5e7646d2SAndroid Build Coastguard Worker _cups_gettimeofday(struct timeval *tv, /* I - Timeval struct */
24*5e7646d2SAndroid Build Coastguard Worker void *tz) /* I - Timezone */
25*5e7646d2SAndroid Build Coastguard Worker {
26*5e7646d2SAndroid Build Coastguard Worker struct _timeb timebuffer; /* Time buffer struct */
27*5e7646d2SAndroid Build Coastguard Worker _ftime(&timebuffer);
28*5e7646d2SAndroid Build Coastguard Worker tv->tv_sec = (long)timebuffer.time;
29*5e7646d2SAndroid Build Coastguard Worker tv->tv_usec = timebuffer.millitm * 1000;
30*5e7646d2SAndroid Build Coastguard Worker return 0;
31*5e7646d2SAndroid Build Coastguard Worker }
32*5e7646d2SAndroid Build Coastguard Worker #else
33*5e7646d2SAndroid Build Coastguard Worker # include <sys/time.h>
34*5e7646d2SAndroid Build Coastguard Worker # include <unistd.h>
35*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
36*5e7646d2SAndroid Build Coastguard Worker #include <regex.h>
37*5e7646d2SAndroid Build Coastguard Worker #include <fcntl.h>
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker
40*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
41*5e7646d2SAndroid Build Coastguard Worker /*
42*5e7646d2SAndroid Build Coastguard Worker * Globals...
43*5e7646d2SAndroid Build Coastguard Worker */
44*5e7646d2SAndroid Build Coastguard Worker
45*5e7646d2SAndroid Build Coastguard Worker int _cups_debug_fd = -1;
46*5e7646d2SAndroid Build Coastguard Worker /* Debug log file descriptor */
47*5e7646d2SAndroid Build Coastguard Worker int _cups_debug_level = 1;
48*5e7646d2SAndroid Build Coastguard Worker /* Log level (0 to 9) */
49*5e7646d2SAndroid Build Coastguard Worker
50*5e7646d2SAndroid Build Coastguard Worker
51*5e7646d2SAndroid Build Coastguard Worker /*
52*5e7646d2SAndroid Build Coastguard Worker * Local globals...
53*5e7646d2SAndroid Build Coastguard Worker */
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker static regex_t *debug_filter = NULL;
56*5e7646d2SAndroid Build Coastguard Worker /* Filter expression for messages */
57*5e7646d2SAndroid Build Coastguard Worker static int debug_init = 0; /* Did we initialize debugging? */
58*5e7646d2SAndroid Build Coastguard Worker static _cups_mutex_t debug_init_mutex = _CUPS_MUTEX_INITIALIZER,
59*5e7646d2SAndroid Build Coastguard Worker /* Mutex to control initialization */
60*5e7646d2SAndroid Build Coastguard Worker debug_log_mutex = _CUPS_MUTEX_INITIALIZER;
61*5e7646d2SAndroid Build Coastguard Worker /* Mutex to serialize log entries */
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker /*
65*5e7646d2SAndroid Build Coastguard Worker * 'debug_thread_id()' - Return an integer representing the current thread.
66*5e7646d2SAndroid Build Coastguard Worker */
67*5e7646d2SAndroid Build Coastguard Worker
68*5e7646d2SAndroid Build Coastguard Worker static int /* O - Local thread ID */
debug_thread_id(void)69*5e7646d2SAndroid Build Coastguard Worker debug_thread_id(void)
70*5e7646d2SAndroid Build Coastguard Worker {
71*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals(); /* Global data */
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker
74*5e7646d2SAndroid Build Coastguard Worker return (cg->thread_id);
75*5e7646d2SAndroid Build Coastguard Worker }
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker
78*5e7646d2SAndroid Build Coastguard Worker /*
79*5e7646d2SAndroid Build Coastguard Worker * '_cups_debug_printf()' - Write a formatted line to the log.
80*5e7646d2SAndroid Build Coastguard Worker */
81*5e7646d2SAndroid Build Coastguard Worker
82*5e7646d2SAndroid Build Coastguard Worker void
_cups_debug_printf(const char * format,...)83*5e7646d2SAndroid Build Coastguard Worker _cups_debug_printf(const char *format, /* I - Printf-style format string */
84*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional arguments as needed */
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Pointer to arguments */
87*5e7646d2SAndroid Build Coastguard Worker struct timeval curtime; /* Current time */
88*5e7646d2SAndroid Build Coastguard Worker char buffer[2048]; /* Output buffer */
89*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Number of bytes in buffer */
90*5e7646d2SAndroid Build Coastguard Worker int level; /* Log level in message */
91*5e7646d2SAndroid Build Coastguard Worker
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker /*
94*5e7646d2SAndroid Build Coastguard Worker * See if we need to do any logging...
95*5e7646d2SAndroid Build Coastguard Worker */
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker if (!debug_init)
98*5e7646d2SAndroid Build Coastguard Worker _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"),
99*5e7646d2SAndroid Build Coastguard Worker getenv("CUPS_DEBUG_FILTER"), 0);
100*5e7646d2SAndroid Build Coastguard Worker
101*5e7646d2SAndroid Build Coastguard Worker if (_cups_debug_fd < 0)
102*5e7646d2SAndroid Build Coastguard Worker return;
103*5e7646d2SAndroid Build Coastguard Worker
104*5e7646d2SAndroid Build Coastguard Worker /*
105*5e7646d2SAndroid Build Coastguard Worker * Filter as needed...
106*5e7646d2SAndroid Build Coastguard Worker */
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker if (isdigit(format[0]))
109*5e7646d2SAndroid Build Coastguard Worker level = *format++ - '0';
110*5e7646d2SAndroid Build Coastguard Worker else
111*5e7646d2SAndroid Build Coastguard Worker level = 0;
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker if (level > _cups_debug_level)
114*5e7646d2SAndroid Build Coastguard Worker return;
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker if (debug_filter)
117*5e7646d2SAndroid Build Coastguard Worker {
118*5e7646d2SAndroid Build Coastguard Worker int result; /* Filter result */
119*5e7646d2SAndroid Build Coastguard Worker
120*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&debug_init_mutex);
121*5e7646d2SAndroid Build Coastguard Worker result = regexec(debug_filter, format, 0, NULL, 0);
122*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&debug_init_mutex);
123*5e7646d2SAndroid Build Coastguard Worker
124*5e7646d2SAndroid Build Coastguard Worker if (result)
125*5e7646d2SAndroid Build Coastguard Worker return;
126*5e7646d2SAndroid Build Coastguard Worker }
127*5e7646d2SAndroid Build Coastguard Worker
128*5e7646d2SAndroid Build Coastguard Worker /*
129*5e7646d2SAndroid Build Coastguard Worker * Format the message...
130*5e7646d2SAndroid Build Coastguard Worker */
131*5e7646d2SAndroid Build Coastguard Worker
132*5e7646d2SAndroid Build Coastguard Worker gettimeofday(&curtime, NULL);
133*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), "T%03d %02d:%02d:%02d.%03d ",
134*5e7646d2SAndroid Build Coastguard Worker debug_thread_id(), (int)((curtime.tv_sec / 3600) % 24),
135*5e7646d2SAndroid Build Coastguard Worker (int)((curtime.tv_sec / 60) % 60),
136*5e7646d2SAndroid Build Coastguard Worker (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000));
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker va_start(ap, format);
139*5e7646d2SAndroid Build Coastguard Worker bytes = _cups_safe_vsnprintf(buffer + 19, sizeof(buffer) - 20, format, ap) + 19;
140*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
141*5e7646d2SAndroid Build Coastguard Worker
142*5e7646d2SAndroid Build Coastguard Worker if ((size_t)bytes >= (sizeof(buffer) - 1))
143*5e7646d2SAndroid Build Coastguard Worker {
144*5e7646d2SAndroid Build Coastguard Worker buffer[sizeof(buffer) - 2] = '\n';
145*5e7646d2SAndroid Build Coastguard Worker bytes = sizeof(buffer) - 1;
146*5e7646d2SAndroid Build Coastguard Worker }
147*5e7646d2SAndroid Build Coastguard Worker else if (buffer[bytes - 1] != '\n')
148*5e7646d2SAndroid Build Coastguard Worker {
149*5e7646d2SAndroid Build Coastguard Worker buffer[bytes++] = '\n';
150*5e7646d2SAndroid Build Coastguard Worker buffer[bytes] = '\0';
151*5e7646d2SAndroid Build Coastguard Worker }
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker /*
154*5e7646d2SAndroid Build Coastguard Worker * Write it out...
155*5e7646d2SAndroid Build Coastguard Worker */
156*5e7646d2SAndroid Build Coastguard Worker
157*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&debug_log_mutex);
158*5e7646d2SAndroid Build Coastguard Worker write(_cups_debug_fd, buffer, (size_t)bytes);
159*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&debug_log_mutex);
160*5e7646d2SAndroid Build Coastguard Worker }
161*5e7646d2SAndroid Build Coastguard Worker
162*5e7646d2SAndroid Build Coastguard Worker
163*5e7646d2SAndroid Build Coastguard Worker /*
164*5e7646d2SAndroid Build Coastguard Worker * '_cups_debug_puts()' - Write a single line to the log.
165*5e7646d2SAndroid Build Coastguard Worker */
166*5e7646d2SAndroid Build Coastguard Worker
167*5e7646d2SAndroid Build Coastguard Worker void
_cups_debug_puts(const char * s)168*5e7646d2SAndroid Build Coastguard Worker _cups_debug_puts(const char *s) /* I - String to output */
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker struct timeval curtime; /* Current time */
171*5e7646d2SAndroid Build Coastguard Worker char buffer[2048]; /* Output buffer */
172*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Number of bytes in buffer */
173*5e7646d2SAndroid Build Coastguard Worker int level; /* Log level in message */
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker
176*5e7646d2SAndroid Build Coastguard Worker /*
177*5e7646d2SAndroid Build Coastguard Worker * See if we need to do any logging...
178*5e7646d2SAndroid Build Coastguard Worker */
179*5e7646d2SAndroid Build Coastguard Worker
180*5e7646d2SAndroid Build Coastguard Worker if (!debug_init)
181*5e7646d2SAndroid Build Coastguard Worker _cups_debug_set(getenv("CUPS_DEBUG_LOG"), getenv("CUPS_DEBUG_LEVEL"),
182*5e7646d2SAndroid Build Coastguard Worker getenv("CUPS_DEBUG_FILTER"), 0);
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker if (_cups_debug_fd < 0)
185*5e7646d2SAndroid Build Coastguard Worker return;
186*5e7646d2SAndroid Build Coastguard Worker
187*5e7646d2SAndroid Build Coastguard Worker /*
188*5e7646d2SAndroid Build Coastguard Worker * Filter as needed...
189*5e7646d2SAndroid Build Coastguard Worker */
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker if (isdigit(s[0]))
192*5e7646d2SAndroid Build Coastguard Worker level = *s++ - '0';
193*5e7646d2SAndroid Build Coastguard Worker else
194*5e7646d2SAndroid Build Coastguard Worker level = 0;
195*5e7646d2SAndroid Build Coastguard Worker
196*5e7646d2SAndroid Build Coastguard Worker if (level > _cups_debug_level)
197*5e7646d2SAndroid Build Coastguard Worker return;
198*5e7646d2SAndroid Build Coastguard Worker
199*5e7646d2SAndroid Build Coastguard Worker if (debug_filter)
200*5e7646d2SAndroid Build Coastguard Worker {
201*5e7646d2SAndroid Build Coastguard Worker int result; /* Filter result */
202*5e7646d2SAndroid Build Coastguard Worker
203*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&debug_init_mutex);
204*5e7646d2SAndroid Build Coastguard Worker result = regexec(debug_filter, s, 0, NULL, 0);
205*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&debug_init_mutex);
206*5e7646d2SAndroid Build Coastguard Worker
207*5e7646d2SAndroid Build Coastguard Worker if (result)
208*5e7646d2SAndroid Build Coastguard Worker return;
209*5e7646d2SAndroid Build Coastguard Worker }
210*5e7646d2SAndroid Build Coastguard Worker
211*5e7646d2SAndroid Build Coastguard Worker /*
212*5e7646d2SAndroid Build Coastguard Worker * Format the message...
213*5e7646d2SAndroid Build Coastguard Worker */
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker gettimeofday(&curtime, NULL);
216*5e7646d2SAndroid Build Coastguard Worker bytes = snprintf(buffer, sizeof(buffer), "T%03d %02d:%02d:%02d.%03d %s",
217*5e7646d2SAndroid Build Coastguard Worker debug_thread_id(), (int)((curtime.tv_sec / 3600) % 24),
218*5e7646d2SAndroid Build Coastguard Worker (int)((curtime.tv_sec / 60) % 60),
219*5e7646d2SAndroid Build Coastguard Worker (int)(curtime.tv_sec % 60), (int)(curtime.tv_usec / 1000),
220*5e7646d2SAndroid Build Coastguard Worker s);
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker if ((size_t)bytes >= (sizeof(buffer) - 1))
223*5e7646d2SAndroid Build Coastguard Worker {
224*5e7646d2SAndroid Build Coastguard Worker buffer[sizeof(buffer) - 2] = '\n';
225*5e7646d2SAndroid Build Coastguard Worker bytes = sizeof(buffer) - 1;
226*5e7646d2SAndroid Build Coastguard Worker }
227*5e7646d2SAndroid Build Coastguard Worker else if (buffer[bytes - 1] != '\n')
228*5e7646d2SAndroid Build Coastguard Worker {
229*5e7646d2SAndroid Build Coastguard Worker buffer[bytes++] = '\n';
230*5e7646d2SAndroid Build Coastguard Worker buffer[bytes] = '\0';
231*5e7646d2SAndroid Build Coastguard Worker }
232*5e7646d2SAndroid Build Coastguard Worker
233*5e7646d2SAndroid Build Coastguard Worker /*
234*5e7646d2SAndroid Build Coastguard Worker * Write it out...
235*5e7646d2SAndroid Build Coastguard Worker */
236*5e7646d2SAndroid Build Coastguard Worker
237*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&debug_log_mutex);
238*5e7646d2SAndroid Build Coastguard Worker write(_cups_debug_fd, buffer, (size_t)bytes);
239*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&debug_log_mutex);
240*5e7646d2SAndroid Build Coastguard Worker }
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker
243*5e7646d2SAndroid Build Coastguard Worker /*
244*5e7646d2SAndroid Build Coastguard Worker * '_cups_debug_set()' - Enable or disable debug logging.
245*5e7646d2SAndroid Build Coastguard Worker */
246*5e7646d2SAndroid Build Coastguard Worker
247*5e7646d2SAndroid Build Coastguard Worker void
_cups_debug_set(const char * logfile,const char * level,const char * filter,int force)248*5e7646d2SAndroid Build Coastguard Worker _cups_debug_set(const char *logfile, /* I - Log file or NULL */
249*5e7646d2SAndroid Build Coastguard Worker const char *level, /* I - Log level or NULL */
250*5e7646d2SAndroid Build Coastguard Worker const char *filter, /* I - Filter string or NULL */
251*5e7646d2SAndroid Build Coastguard Worker int force) /* I - Force initialization */
252*5e7646d2SAndroid Build Coastguard Worker {
253*5e7646d2SAndroid Build Coastguard Worker _cupsMutexLock(&debug_init_mutex);
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker if (!debug_init || force)
256*5e7646d2SAndroid Build Coastguard Worker {
257*5e7646d2SAndroid Build Coastguard Worker /*
258*5e7646d2SAndroid Build Coastguard Worker * Restore debug settings to defaults...
259*5e7646d2SAndroid Build Coastguard Worker */
260*5e7646d2SAndroid Build Coastguard Worker
261*5e7646d2SAndroid Build Coastguard Worker if (_cups_debug_fd != -1)
262*5e7646d2SAndroid Build Coastguard Worker {
263*5e7646d2SAndroid Build Coastguard Worker close(_cups_debug_fd);
264*5e7646d2SAndroid Build Coastguard Worker _cups_debug_fd = -1;
265*5e7646d2SAndroid Build Coastguard Worker }
266*5e7646d2SAndroid Build Coastguard Worker
267*5e7646d2SAndroid Build Coastguard Worker if (debug_filter)
268*5e7646d2SAndroid Build Coastguard Worker {
269*5e7646d2SAndroid Build Coastguard Worker regfree((regex_t *)debug_filter);
270*5e7646d2SAndroid Build Coastguard Worker debug_filter = NULL;
271*5e7646d2SAndroid Build Coastguard Worker }
272*5e7646d2SAndroid Build Coastguard Worker
273*5e7646d2SAndroid Build Coastguard Worker _cups_debug_level = 1;
274*5e7646d2SAndroid Build Coastguard Worker
275*5e7646d2SAndroid Build Coastguard Worker /*
276*5e7646d2SAndroid Build Coastguard Worker * Open logs, set log levels, etc.
277*5e7646d2SAndroid Build Coastguard Worker */
278*5e7646d2SAndroid Build Coastguard Worker
279*5e7646d2SAndroid Build Coastguard Worker if (!logfile)
280*5e7646d2SAndroid Build Coastguard Worker _cups_debug_fd = -1;
281*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(logfile, "-"))
282*5e7646d2SAndroid Build Coastguard Worker _cups_debug_fd = 2;
283*5e7646d2SAndroid Build Coastguard Worker else
284*5e7646d2SAndroid Build Coastguard Worker {
285*5e7646d2SAndroid Build Coastguard Worker char buffer[1024]; /* Filename buffer */
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, sizeof(buffer), logfile, getpid());
288*5e7646d2SAndroid Build Coastguard Worker
289*5e7646d2SAndroid Build Coastguard Worker if (buffer[0] == '+')
290*5e7646d2SAndroid Build Coastguard Worker _cups_debug_fd = open(buffer + 1, O_WRONLY | O_APPEND | O_CREAT, 0644);
291*5e7646d2SAndroid Build Coastguard Worker else
292*5e7646d2SAndroid Build Coastguard Worker _cups_debug_fd = open(buffer, O_WRONLY | O_TRUNC | O_CREAT, 0644);
293*5e7646d2SAndroid Build Coastguard Worker }
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker if (level)
296*5e7646d2SAndroid Build Coastguard Worker _cups_debug_level = atoi(level);
297*5e7646d2SAndroid Build Coastguard Worker
298*5e7646d2SAndroid Build Coastguard Worker if (filter)
299*5e7646d2SAndroid Build Coastguard Worker {
300*5e7646d2SAndroid Build Coastguard Worker if ((debug_filter = (regex_t *)calloc(1, sizeof(regex_t))) == NULL)
301*5e7646d2SAndroid Build Coastguard Worker fputs("Unable to allocate memory for CUPS_DEBUG_FILTER - results not "
302*5e7646d2SAndroid Build Coastguard Worker "filtered!\n", stderr);
303*5e7646d2SAndroid Build Coastguard Worker else if (regcomp(debug_filter, filter, REG_EXTENDED))
304*5e7646d2SAndroid Build Coastguard Worker {
305*5e7646d2SAndroid Build Coastguard Worker fputs("Bad regular expression in CUPS_DEBUG_FILTER - results not "
306*5e7646d2SAndroid Build Coastguard Worker "filtered!\n", stderr);
307*5e7646d2SAndroid Build Coastguard Worker free(debug_filter);
308*5e7646d2SAndroid Build Coastguard Worker debug_filter = NULL;
309*5e7646d2SAndroid Build Coastguard Worker }
310*5e7646d2SAndroid Build Coastguard Worker }
311*5e7646d2SAndroid Build Coastguard Worker
312*5e7646d2SAndroid Build Coastguard Worker debug_init = 1;
313*5e7646d2SAndroid Build Coastguard Worker }
314*5e7646d2SAndroid Build Coastguard Worker
315*5e7646d2SAndroid Build Coastguard Worker _cupsMutexUnlock(&debug_init_mutex);
316*5e7646d2SAndroid Build Coastguard Worker }
317*5e7646d2SAndroid Build Coastguard Worker
318*5e7646d2SAndroid Build Coastguard Worker
319*5e7646d2SAndroid Build Coastguard Worker #else
320*5e7646d2SAndroid Build Coastguard Worker /*
321*5e7646d2SAndroid Build Coastguard Worker * '_cups_debug_set()' - Enable or disable debug logging.
322*5e7646d2SAndroid Build Coastguard Worker */
323*5e7646d2SAndroid Build Coastguard Worker
324*5e7646d2SAndroid Build Coastguard Worker void
_cups_debug_set(const char * logfile,const char * level,const char * filter,int force)325*5e7646d2SAndroid Build Coastguard Worker _cups_debug_set(const char *logfile, /* I - Log file or NULL */
326*5e7646d2SAndroid Build Coastguard Worker const char *level, /* I - Log level or NULL */
327*5e7646d2SAndroid Build Coastguard Worker const char *filter, /* I - Filter string or NULL */
328*5e7646d2SAndroid Build Coastguard Worker int force) /* I - Force initialization */
329*5e7646d2SAndroid Build Coastguard Worker {
330*5e7646d2SAndroid Build Coastguard Worker (void)logfile;
331*5e7646d2SAndroid Build Coastguard Worker (void)level;
332*5e7646d2SAndroid Build Coastguard Worker (void)filter;
333*5e7646d2SAndroid Build Coastguard Worker (void)force;
334*5e7646d2SAndroid Build Coastguard Worker }
335*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
336*5e7646d2SAndroid Build Coastguard Worker
337*5e7646d2SAndroid Build Coastguard Worker
338*5e7646d2SAndroid Build Coastguard Worker /*
339*5e7646d2SAndroid Build Coastguard Worker * '_cups_safe_vsnprintf()' - Format a string into a fixed size buffer,
340*5e7646d2SAndroid Build Coastguard Worker * quoting special characters.
341*5e7646d2SAndroid Build Coastguard Worker */
342*5e7646d2SAndroid Build Coastguard Worker
343*5e7646d2SAndroid Build Coastguard Worker ssize_t /* O - Number of bytes formatted */
_cups_safe_vsnprintf(char * buffer,size_t bufsize,const char * format,va_list ap)344*5e7646d2SAndroid Build Coastguard Worker _cups_safe_vsnprintf(
345*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* O - Output buffer */
346*5e7646d2SAndroid Build Coastguard Worker size_t bufsize, /* O - Size of output buffer */
347*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - printf-style format string */
348*5e7646d2SAndroid Build Coastguard Worker va_list ap) /* I - Pointer to additional arguments */
349*5e7646d2SAndroid Build Coastguard Worker {
350*5e7646d2SAndroid Build Coastguard Worker char *bufptr, /* Pointer to position in buffer */
351*5e7646d2SAndroid Build Coastguard Worker *bufend, /* Pointer to end of buffer */
352*5e7646d2SAndroid Build Coastguard Worker size, /* Size character (h, l, L) */
353*5e7646d2SAndroid Build Coastguard Worker type; /* Format type character */
354*5e7646d2SAndroid Build Coastguard Worker int width, /* Width of field */
355*5e7646d2SAndroid Build Coastguard Worker prec; /* Number of characters of precision */
356*5e7646d2SAndroid Build Coastguard Worker char tformat[100], /* Temporary format string for snprintf() */
357*5e7646d2SAndroid Build Coastguard Worker *tptr, /* Pointer into temporary format */
358*5e7646d2SAndroid Build Coastguard Worker temp[1024]; /* Buffer for formatted numbers */
359*5e7646d2SAndroid Build Coastguard Worker char *s; /* Pointer to string */
360*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Total number of bytes needed */
361*5e7646d2SAndroid Build Coastguard Worker
362*5e7646d2SAndroid Build Coastguard Worker
363*5e7646d2SAndroid Build Coastguard Worker if (!buffer || bufsize < 2 || !format)
364*5e7646d2SAndroid Build Coastguard Worker return (-1);
365*5e7646d2SAndroid Build Coastguard Worker
366*5e7646d2SAndroid Build Coastguard Worker /*
367*5e7646d2SAndroid Build Coastguard Worker * Loop through the format string, formatting as needed...
368*5e7646d2SAndroid Build Coastguard Worker */
369*5e7646d2SAndroid Build Coastguard Worker
370*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
371*5e7646d2SAndroid Build Coastguard Worker bufend = buffer + bufsize - 1;
372*5e7646d2SAndroid Build Coastguard Worker bytes = 0;
373*5e7646d2SAndroid Build Coastguard Worker
374*5e7646d2SAndroid Build Coastguard Worker while (*format)
375*5e7646d2SAndroid Build Coastguard Worker {
376*5e7646d2SAndroid Build Coastguard Worker if (*format == '%')
377*5e7646d2SAndroid Build Coastguard Worker {
378*5e7646d2SAndroid Build Coastguard Worker tptr = tformat;
379*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format++;
380*5e7646d2SAndroid Build Coastguard Worker
381*5e7646d2SAndroid Build Coastguard Worker if (*format == '%')
382*5e7646d2SAndroid Build Coastguard Worker {
383*5e7646d2SAndroid Build Coastguard Worker if (bufptr < bufend)
384*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *format;
385*5e7646d2SAndroid Build Coastguard Worker bytes ++;
386*5e7646d2SAndroid Build Coastguard Worker format ++;
387*5e7646d2SAndroid Build Coastguard Worker continue;
388*5e7646d2SAndroid Build Coastguard Worker }
389*5e7646d2SAndroid Build Coastguard Worker else if (strchr(" -+#\'", *format))
390*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format++;
391*5e7646d2SAndroid Build Coastguard Worker
392*5e7646d2SAndroid Build Coastguard Worker if (*format == '*')
393*5e7646d2SAndroid Build Coastguard Worker {
394*5e7646d2SAndroid Build Coastguard Worker /*
395*5e7646d2SAndroid Build Coastguard Worker * Get width from argument...
396*5e7646d2SAndroid Build Coastguard Worker */
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker format ++;
399*5e7646d2SAndroid Build Coastguard Worker width = va_arg(ap, int);
400*5e7646d2SAndroid Build Coastguard Worker
401*5e7646d2SAndroid Build Coastguard Worker snprintf(tptr, sizeof(tformat) - (size_t)(tptr - tformat), "%d", width);
402*5e7646d2SAndroid Build Coastguard Worker tptr += strlen(tptr);
403*5e7646d2SAndroid Build Coastguard Worker }
404*5e7646d2SAndroid Build Coastguard Worker else
405*5e7646d2SAndroid Build Coastguard Worker {
406*5e7646d2SAndroid Build Coastguard Worker width = 0;
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker while (isdigit(*format & 255))
409*5e7646d2SAndroid Build Coastguard Worker {
410*5e7646d2SAndroid Build Coastguard Worker if (tptr < (tformat + sizeof(tformat) - 1))
411*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format;
412*5e7646d2SAndroid Build Coastguard Worker
413*5e7646d2SAndroid Build Coastguard Worker width = width * 10 + *format++ - '0';
414*5e7646d2SAndroid Build Coastguard Worker }
415*5e7646d2SAndroid Build Coastguard Worker }
416*5e7646d2SAndroid Build Coastguard Worker
417*5e7646d2SAndroid Build Coastguard Worker if (*format == '.')
418*5e7646d2SAndroid Build Coastguard Worker {
419*5e7646d2SAndroid Build Coastguard Worker if (tptr < (tformat + sizeof(tformat) - 1))
420*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format;
421*5e7646d2SAndroid Build Coastguard Worker
422*5e7646d2SAndroid Build Coastguard Worker format ++;
423*5e7646d2SAndroid Build Coastguard Worker
424*5e7646d2SAndroid Build Coastguard Worker if (*format == '*')
425*5e7646d2SAndroid Build Coastguard Worker {
426*5e7646d2SAndroid Build Coastguard Worker /*
427*5e7646d2SAndroid Build Coastguard Worker * Get precision from argument...
428*5e7646d2SAndroid Build Coastguard Worker */
429*5e7646d2SAndroid Build Coastguard Worker
430*5e7646d2SAndroid Build Coastguard Worker format ++;
431*5e7646d2SAndroid Build Coastguard Worker prec = va_arg(ap, int);
432*5e7646d2SAndroid Build Coastguard Worker
433*5e7646d2SAndroid Build Coastguard Worker snprintf(tptr, sizeof(tformat) - (size_t)(tptr - tformat), "%d", prec);
434*5e7646d2SAndroid Build Coastguard Worker tptr += strlen(tptr);
435*5e7646d2SAndroid Build Coastguard Worker }
436*5e7646d2SAndroid Build Coastguard Worker else
437*5e7646d2SAndroid Build Coastguard Worker {
438*5e7646d2SAndroid Build Coastguard Worker prec = 0;
439*5e7646d2SAndroid Build Coastguard Worker
440*5e7646d2SAndroid Build Coastguard Worker while (isdigit(*format & 255))
441*5e7646d2SAndroid Build Coastguard Worker {
442*5e7646d2SAndroid Build Coastguard Worker if (tptr < (tformat + sizeof(tformat) - 1))
443*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format;
444*5e7646d2SAndroid Build Coastguard Worker
445*5e7646d2SAndroid Build Coastguard Worker prec = prec * 10 + *format++ - '0';
446*5e7646d2SAndroid Build Coastguard Worker }
447*5e7646d2SAndroid Build Coastguard Worker }
448*5e7646d2SAndroid Build Coastguard Worker }
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker if (*format == 'l' && format[1] == 'l')
451*5e7646d2SAndroid Build Coastguard Worker {
452*5e7646d2SAndroid Build Coastguard Worker size = 'L';
453*5e7646d2SAndroid Build Coastguard Worker
454*5e7646d2SAndroid Build Coastguard Worker if (tptr < (tformat + sizeof(tformat) - 2))
455*5e7646d2SAndroid Build Coastguard Worker {
456*5e7646d2SAndroid Build Coastguard Worker *tptr++ = 'l';
457*5e7646d2SAndroid Build Coastguard Worker *tptr++ = 'l';
458*5e7646d2SAndroid Build Coastguard Worker }
459*5e7646d2SAndroid Build Coastguard Worker
460*5e7646d2SAndroid Build Coastguard Worker format += 2;
461*5e7646d2SAndroid Build Coastguard Worker }
462*5e7646d2SAndroid Build Coastguard Worker else if (*format == 'h' || *format == 'l' || *format == 'L')
463*5e7646d2SAndroid Build Coastguard Worker {
464*5e7646d2SAndroid Build Coastguard Worker if (tptr < (tformat + sizeof(tformat) - 1))
465*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format;
466*5e7646d2SAndroid Build Coastguard Worker
467*5e7646d2SAndroid Build Coastguard Worker size = *format++;
468*5e7646d2SAndroid Build Coastguard Worker }
469*5e7646d2SAndroid Build Coastguard Worker else
470*5e7646d2SAndroid Build Coastguard Worker size = 0;
471*5e7646d2SAndroid Build Coastguard Worker
472*5e7646d2SAndroid Build Coastguard Worker if (!*format)
473*5e7646d2SAndroid Build Coastguard Worker break;
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker if (tptr < (tformat + sizeof(tformat) - 1))
476*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *format;
477*5e7646d2SAndroid Build Coastguard Worker
478*5e7646d2SAndroid Build Coastguard Worker type = *format++;
479*5e7646d2SAndroid Build Coastguard Worker *tptr = '\0';
480*5e7646d2SAndroid Build Coastguard Worker
481*5e7646d2SAndroid Build Coastguard Worker switch (type)
482*5e7646d2SAndroid Build Coastguard Worker {
483*5e7646d2SAndroid Build Coastguard Worker case 'E' : /* Floating point formats */
484*5e7646d2SAndroid Build Coastguard Worker case 'G' :
485*5e7646d2SAndroid Build Coastguard Worker case 'e' :
486*5e7646d2SAndroid Build Coastguard Worker case 'f' :
487*5e7646d2SAndroid Build Coastguard Worker case 'g' :
488*5e7646d2SAndroid Build Coastguard Worker if ((size_t)(width + 2) > sizeof(temp))
489*5e7646d2SAndroid Build Coastguard Worker break;
490*5e7646d2SAndroid Build Coastguard Worker
491*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), tformat, va_arg(ap, double));
492*5e7646d2SAndroid Build Coastguard Worker
493*5e7646d2SAndroid Build Coastguard Worker bytes += (int)strlen(temp);
494*5e7646d2SAndroid Build Coastguard Worker
495*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
496*5e7646d2SAndroid Build Coastguard Worker {
497*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
498*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
499*5e7646d2SAndroid Build Coastguard Worker }
500*5e7646d2SAndroid Build Coastguard Worker break;
501*5e7646d2SAndroid Build Coastguard Worker
502*5e7646d2SAndroid Build Coastguard Worker case 'B' : /* Integer formats */
503*5e7646d2SAndroid Build Coastguard Worker case 'X' :
504*5e7646d2SAndroid Build Coastguard Worker case 'b' :
505*5e7646d2SAndroid Build Coastguard Worker case 'd' :
506*5e7646d2SAndroid Build Coastguard Worker case 'i' :
507*5e7646d2SAndroid Build Coastguard Worker case 'o' :
508*5e7646d2SAndroid Build Coastguard Worker case 'u' :
509*5e7646d2SAndroid Build Coastguard Worker case 'x' :
510*5e7646d2SAndroid Build Coastguard Worker if ((size_t)(width + 2) > sizeof(temp))
511*5e7646d2SAndroid Build Coastguard Worker break;
512*5e7646d2SAndroid Build Coastguard Worker
513*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_LONG_LONG
514*5e7646d2SAndroid Build Coastguard Worker if (size == 'L')
515*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), tformat, va_arg(ap, long long));
516*5e7646d2SAndroid Build Coastguard Worker else
517*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_LONG_LONG */
518*5e7646d2SAndroid Build Coastguard Worker if (size == 'l')
519*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), tformat, va_arg(ap, long));
520*5e7646d2SAndroid Build Coastguard Worker else
521*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), tformat, va_arg(ap, int));
522*5e7646d2SAndroid Build Coastguard Worker
523*5e7646d2SAndroid Build Coastguard Worker bytes += (int)strlen(temp);
524*5e7646d2SAndroid Build Coastguard Worker
525*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
526*5e7646d2SAndroid Build Coastguard Worker {
527*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
528*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
529*5e7646d2SAndroid Build Coastguard Worker }
530*5e7646d2SAndroid Build Coastguard Worker break;
531*5e7646d2SAndroid Build Coastguard Worker
532*5e7646d2SAndroid Build Coastguard Worker case 'p' : /* Pointer value */
533*5e7646d2SAndroid Build Coastguard Worker if ((size_t)(width + 2) > sizeof(temp))
534*5e7646d2SAndroid Build Coastguard Worker break;
535*5e7646d2SAndroid Build Coastguard Worker
536*5e7646d2SAndroid Build Coastguard Worker snprintf(temp, sizeof(temp), tformat, va_arg(ap, void *));
537*5e7646d2SAndroid Build Coastguard Worker
538*5e7646d2SAndroid Build Coastguard Worker bytes += (int)strlen(temp);
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
541*5e7646d2SAndroid Build Coastguard Worker {
542*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, temp, (size_t)(bufend - bufptr));
543*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
544*5e7646d2SAndroid Build Coastguard Worker }
545*5e7646d2SAndroid Build Coastguard Worker break;
546*5e7646d2SAndroid Build Coastguard Worker
547*5e7646d2SAndroid Build Coastguard Worker case 'c' : /* Character or character array */
548*5e7646d2SAndroid Build Coastguard Worker bytes += width;
549*5e7646d2SAndroid Build Coastguard Worker
550*5e7646d2SAndroid Build Coastguard Worker if (bufptr)
551*5e7646d2SAndroid Build Coastguard Worker {
552*5e7646d2SAndroid Build Coastguard Worker if (width <= 1)
553*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (char)va_arg(ap, int);
554*5e7646d2SAndroid Build Coastguard Worker else
555*5e7646d2SAndroid Build Coastguard Worker {
556*5e7646d2SAndroid Build Coastguard Worker if ((bufptr + width) > bufend)
557*5e7646d2SAndroid Build Coastguard Worker width = (int)(bufend - bufptr);
558*5e7646d2SAndroid Build Coastguard Worker
559*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, va_arg(ap, char *), (size_t)width);
560*5e7646d2SAndroid Build Coastguard Worker bufptr += width;
561*5e7646d2SAndroid Build Coastguard Worker }
562*5e7646d2SAndroid Build Coastguard Worker }
563*5e7646d2SAndroid Build Coastguard Worker break;
564*5e7646d2SAndroid Build Coastguard Worker
565*5e7646d2SAndroid Build Coastguard Worker case 's' : /* String */
566*5e7646d2SAndroid Build Coastguard Worker if ((s = va_arg(ap, char *)) == NULL)
567*5e7646d2SAndroid Build Coastguard Worker s = "(null)";
568*5e7646d2SAndroid Build Coastguard Worker
569*5e7646d2SAndroid Build Coastguard Worker /*
570*5e7646d2SAndroid Build Coastguard Worker * Copy the C string, replacing control chars and \ with
571*5e7646d2SAndroid Build Coastguard Worker * C character escapes...
572*5e7646d2SAndroid Build Coastguard Worker */
573*5e7646d2SAndroid Build Coastguard Worker
574*5e7646d2SAndroid Build Coastguard Worker for (bufend --; *s && bufptr < bufend; s ++)
575*5e7646d2SAndroid Build Coastguard Worker {
576*5e7646d2SAndroid Build Coastguard Worker if (*s == '\n')
577*5e7646d2SAndroid Build Coastguard Worker {
578*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
579*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 'n';
580*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
581*5e7646d2SAndroid Build Coastguard Worker }
582*5e7646d2SAndroid Build Coastguard Worker else if (*s == '\r')
583*5e7646d2SAndroid Build Coastguard Worker {
584*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
585*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 'r';
586*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
587*5e7646d2SAndroid Build Coastguard Worker }
588*5e7646d2SAndroid Build Coastguard Worker else if (*s == '\t')
589*5e7646d2SAndroid Build Coastguard Worker {
590*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
591*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 't';
592*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
593*5e7646d2SAndroid Build Coastguard Worker }
594*5e7646d2SAndroid Build Coastguard Worker else if (*s == '\\')
595*5e7646d2SAndroid Build Coastguard Worker {
596*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
597*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
598*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
599*5e7646d2SAndroid Build Coastguard Worker }
600*5e7646d2SAndroid Build Coastguard Worker else if (*s == '\'')
601*5e7646d2SAndroid Build Coastguard Worker {
602*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
603*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\'';
604*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
605*5e7646d2SAndroid Build Coastguard Worker }
606*5e7646d2SAndroid Build Coastguard Worker else if (*s == '\"')
607*5e7646d2SAndroid Build Coastguard Worker {
608*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
609*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\"';
610*5e7646d2SAndroid Build Coastguard Worker bytes += 2;
611*5e7646d2SAndroid Build Coastguard Worker }
612*5e7646d2SAndroid Build Coastguard Worker else if ((*s & 255) < ' ')
613*5e7646d2SAndroid Build Coastguard Worker {
614*5e7646d2SAndroid Build Coastguard Worker if ((bufptr + 2) >= bufend)
615*5e7646d2SAndroid Build Coastguard Worker break;
616*5e7646d2SAndroid Build Coastguard Worker
617*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
618*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '0';
619*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '0' + *s / 8;
620*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '0' + (*s & 7);
621*5e7646d2SAndroid Build Coastguard Worker bytes += 4;
622*5e7646d2SAndroid Build Coastguard Worker }
623*5e7646d2SAndroid Build Coastguard Worker else
624*5e7646d2SAndroid Build Coastguard Worker {
625*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *s;
626*5e7646d2SAndroid Build Coastguard Worker bytes ++;
627*5e7646d2SAndroid Build Coastguard Worker }
628*5e7646d2SAndroid Build Coastguard Worker }
629*5e7646d2SAndroid Build Coastguard Worker
630*5e7646d2SAndroid Build Coastguard Worker bufend ++;
631*5e7646d2SAndroid Build Coastguard Worker break;
632*5e7646d2SAndroid Build Coastguard Worker
633*5e7646d2SAndroid Build Coastguard Worker case 'n' : /* Output number of chars so far */
634*5e7646d2SAndroid Build Coastguard Worker *(va_arg(ap, int *)) = (int)bytes;
635*5e7646d2SAndroid Build Coastguard Worker break;
636*5e7646d2SAndroid Build Coastguard Worker }
637*5e7646d2SAndroid Build Coastguard Worker }
638*5e7646d2SAndroid Build Coastguard Worker else
639*5e7646d2SAndroid Build Coastguard Worker {
640*5e7646d2SAndroid Build Coastguard Worker bytes ++;
641*5e7646d2SAndroid Build Coastguard Worker
642*5e7646d2SAndroid Build Coastguard Worker if (bufptr < bufend)
643*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *format;
644*5e7646d2SAndroid Build Coastguard Worker
645*5e7646d2SAndroid Build Coastguard Worker format ++;
646*5e7646d2SAndroid Build Coastguard Worker }
647*5e7646d2SAndroid Build Coastguard Worker }
648*5e7646d2SAndroid Build Coastguard Worker
649*5e7646d2SAndroid Build Coastguard Worker /*
650*5e7646d2SAndroid Build Coastguard Worker * Nul-terminate the string and return the number of characters needed.
651*5e7646d2SAndroid Build Coastguard Worker */
652*5e7646d2SAndroid Build Coastguard Worker
653*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
654*5e7646d2SAndroid Build Coastguard Worker
655*5e7646d2SAndroid Build Coastguard Worker return (bytes);
656*5e7646d2SAndroid Build Coastguard Worker }
657