1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * PPD model-specific attribute routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2015 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "cups-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include "ppd-private.h"
17*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker * 'ppdFindAttr()' - Find the first matching attribute.
22*5e7646d2SAndroid Build Coastguard Worker *
23*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
24*5e7646d2SAndroid Build Coastguard Worker */
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
ppdFindAttr(ppd_file_t * ppd,const char * name,const char * spec)27*5e7646d2SAndroid Build Coastguard Worker ppdFindAttr(ppd_file_t *ppd, /* I - PPD file data */
28*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Attribute name */
29*5e7646d2SAndroid Build Coastguard Worker const char *spec) /* I - Specifier string or @code NULL@ */
30*5e7646d2SAndroid Build Coastguard Worker {
31*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t key, /* Search key */
32*5e7646d2SAndroid Build Coastguard Worker *attr; /* Current attribute */
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker
35*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2ppdFindAttr(ppd=%p, name=\"%s\", spec=\"%s\")", ppd, name,
36*5e7646d2SAndroid Build Coastguard Worker spec));
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker /*
39*5e7646d2SAndroid Build Coastguard Worker * Range check input...
40*5e7646d2SAndroid Build Coastguard Worker */
41*5e7646d2SAndroid Build Coastguard Worker
42*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !name || ppd->num_attrs == 0)
43*5e7646d2SAndroid Build Coastguard Worker return (NULL);
44*5e7646d2SAndroid Build Coastguard Worker
45*5e7646d2SAndroid Build Coastguard Worker /*
46*5e7646d2SAndroid Build Coastguard Worker * Search for a matching attribute...
47*5e7646d2SAndroid Build Coastguard Worker */
48*5e7646d2SAndroid Build Coastguard Worker
49*5e7646d2SAndroid Build Coastguard Worker memset(&key, 0, sizeof(key));
50*5e7646d2SAndroid Build Coastguard Worker strlcpy(key.name, name, sizeof(key.name));
51*5e7646d2SAndroid Build Coastguard Worker
52*5e7646d2SAndroid Build Coastguard Worker /*
53*5e7646d2SAndroid Build Coastguard Worker * Return the first matching attribute, if any...
54*5e7646d2SAndroid Build Coastguard Worker */
55*5e7646d2SAndroid Build Coastguard Worker
56*5e7646d2SAndroid Build Coastguard Worker if ((attr = (ppd_attr_t *)cupsArrayFind(ppd->sorted_attrs, &key)) != NULL)
57*5e7646d2SAndroid Build Coastguard Worker {
58*5e7646d2SAndroid Build Coastguard Worker if (spec)
59*5e7646d2SAndroid Build Coastguard Worker {
60*5e7646d2SAndroid Build Coastguard Worker /*
61*5e7646d2SAndroid Build Coastguard Worker * Loop until we find the first matching attribute for "spec"...
62*5e7646d2SAndroid Build Coastguard Worker */
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker while (attr && _cups_strcasecmp(spec, attr->spec))
65*5e7646d2SAndroid Build Coastguard Worker {
66*5e7646d2SAndroid Build Coastguard Worker if ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL &&
67*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(attr->name, name))
68*5e7646d2SAndroid Build Coastguard Worker attr = NULL;
69*5e7646d2SAndroid Build Coastguard Worker }
70*5e7646d2SAndroid Build Coastguard Worker }
71*5e7646d2SAndroid Build Coastguard Worker }
72*5e7646d2SAndroid Build Coastguard Worker
73*5e7646d2SAndroid Build Coastguard Worker return (attr);
74*5e7646d2SAndroid Build Coastguard Worker }
75*5e7646d2SAndroid Build Coastguard Worker
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker /*
78*5e7646d2SAndroid Build Coastguard Worker * 'ppdFindNextAttr()' - Find the next matching attribute.
79*5e7646d2SAndroid Build Coastguard Worker *
80*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.1.19/macOS 10.3@
81*5e7646d2SAndroid Build Coastguard Worker */
82*5e7646d2SAndroid Build Coastguard Worker
83*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t * /* O - Attribute or @code NULL@ if not found */
ppdFindNextAttr(ppd_file_t * ppd,const char * name,const char * spec)84*5e7646d2SAndroid Build Coastguard Worker ppdFindNextAttr(ppd_file_t *ppd, /* I - PPD file data */
85*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Attribute name */
86*5e7646d2SAndroid Build Coastguard Worker const char *spec) /* I - Specifier string or @code NULL@ */
87*5e7646d2SAndroid Build Coastguard Worker {
88*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *attr; /* Current attribute */
89*5e7646d2SAndroid Build Coastguard Worker
90*5e7646d2SAndroid Build Coastguard Worker
91*5e7646d2SAndroid Build Coastguard Worker /*
92*5e7646d2SAndroid Build Coastguard Worker * Range check input...
93*5e7646d2SAndroid Build Coastguard Worker */
94*5e7646d2SAndroid Build Coastguard Worker
95*5e7646d2SAndroid Build Coastguard Worker if (!ppd || !name || ppd->num_attrs == 0)
96*5e7646d2SAndroid Build Coastguard Worker return (NULL);
97*5e7646d2SAndroid Build Coastguard Worker
98*5e7646d2SAndroid Build Coastguard Worker /*
99*5e7646d2SAndroid Build Coastguard Worker * See if there are more attributes to return...
100*5e7646d2SAndroid Build Coastguard Worker */
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker while ((attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs)) != NULL)
103*5e7646d2SAndroid Build Coastguard Worker {
104*5e7646d2SAndroid Build Coastguard Worker /*
105*5e7646d2SAndroid Build Coastguard Worker * Check the next attribute to see if it is a match...
106*5e7646d2SAndroid Build Coastguard Worker */
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(attr->name, name))
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker /*
111*5e7646d2SAndroid Build Coastguard Worker * Nope, reset the current pointer to the end of the array...
112*5e7646d2SAndroid Build Coastguard Worker */
113*5e7646d2SAndroid Build Coastguard Worker
114*5e7646d2SAndroid Build Coastguard Worker cupsArrayIndex(ppd->sorted_attrs, cupsArrayCount(ppd->sorted_attrs));
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker return (NULL);
117*5e7646d2SAndroid Build Coastguard Worker }
118*5e7646d2SAndroid Build Coastguard Worker
119*5e7646d2SAndroid Build Coastguard Worker if (!spec || !_cups_strcasecmp(attr->spec, spec))
120*5e7646d2SAndroid Build Coastguard Worker break;
121*5e7646d2SAndroid Build Coastguard Worker }
122*5e7646d2SAndroid Build Coastguard Worker
123*5e7646d2SAndroid Build Coastguard Worker /*
124*5e7646d2SAndroid Build Coastguard Worker * Return the next attribute's value...
125*5e7646d2SAndroid Build Coastguard Worker */
126*5e7646d2SAndroid Build Coastguard Worker
127*5e7646d2SAndroid Build Coastguard Worker return (attr);
128*5e7646d2SAndroid Build Coastguard Worker }
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker /*
132*5e7646d2SAndroid Build Coastguard Worker * '_ppdNormalizeMakeAndModel()' - Normalize a product/make-and-model string.
133*5e7646d2SAndroid Build Coastguard Worker *
134*5e7646d2SAndroid Build Coastguard Worker * This function tries to undo the mistakes made by many printer manufacturers
135*5e7646d2SAndroid Build Coastguard Worker * to produce a clean make-and-model string we can use.
136*5e7646d2SAndroid Build Coastguard Worker */
137*5e7646d2SAndroid Build Coastguard Worker
138*5e7646d2SAndroid Build Coastguard Worker char * /* O - Normalized make-and-model string or NULL on error */
_ppdNormalizeMakeAndModel(const char * make_and_model,char * buffer,size_t bufsize)139*5e7646d2SAndroid Build Coastguard Worker _ppdNormalizeMakeAndModel(
140*5e7646d2SAndroid Build Coastguard Worker const char *make_and_model, /* I - Original make-and-model string */
141*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - String buffer */
142*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of string buffer */
143*5e7646d2SAndroid Build Coastguard Worker {
144*5e7646d2SAndroid Build Coastguard Worker char *bufptr; /* Pointer into buffer */
145*5e7646d2SAndroid Build Coastguard Worker
146*5e7646d2SAndroid Build Coastguard Worker
147*5e7646d2SAndroid Build Coastguard Worker if (!make_and_model || !buffer || bufsize < 1)
148*5e7646d2SAndroid Build Coastguard Worker {
149*5e7646d2SAndroid Build Coastguard Worker if (buffer)
150*5e7646d2SAndroid Build Coastguard Worker *buffer = '\0';
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker return (NULL);
153*5e7646d2SAndroid Build Coastguard Worker }
154*5e7646d2SAndroid Build Coastguard Worker
155*5e7646d2SAndroid Build Coastguard Worker /*
156*5e7646d2SAndroid Build Coastguard Worker * Skip leading whitespace...
157*5e7646d2SAndroid Build Coastguard Worker */
158*5e7646d2SAndroid Build Coastguard Worker
159*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*make_and_model))
160*5e7646d2SAndroid Build Coastguard Worker make_and_model ++;
161*5e7646d2SAndroid Build Coastguard Worker
162*5e7646d2SAndroid Build Coastguard Worker /*
163*5e7646d2SAndroid Build Coastguard Worker * Remove parenthesis and add manufacturers as needed...
164*5e7646d2SAndroid Build Coastguard Worker */
165*5e7646d2SAndroid Build Coastguard Worker
166*5e7646d2SAndroid Build Coastguard Worker if (make_and_model[0] == '(')
167*5e7646d2SAndroid Build Coastguard Worker {
168*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, make_and_model + 1, bufsize);
169*5e7646d2SAndroid Build Coastguard Worker
170*5e7646d2SAndroid Build Coastguard Worker if ((bufptr = strrchr(buffer, ')')) != NULL)
171*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
172*5e7646d2SAndroid Build Coastguard Worker }
173*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "XPrint", 6))
174*5e7646d2SAndroid Build Coastguard Worker {
175*5e7646d2SAndroid Build Coastguard Worker /*
176*5e7646d2SAndroid Build Coastguard Worker * Xerox XPrint...
177*5e7646d2SAndroid Build Coastguard Worker */
178*5e7646d2SAndroid Build Coastguard Worker
179*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Xerox %s", make_and_model);
180*5e7646d2SAndroid Build Coastguard Worker }
181*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "Eastman", 7))
182*5e7646d2SAndroid Build Coastguard Worker {
183*5e7646d2SAndroid Build Coastguard Worker /*
184*5e7646d2SAndroid Build Coastguard Worker * Kodak...
185*5e7646d2SAndroid Build Coastguard Worker */
186*5e7646d2SAndroid Build Coastguard Worker
187*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Kodak %s", make_and_model + 7);
188*5e7646d2SAndroid Build Coastguard Worker }
189*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "laserwriter", 11))
190*5e7646d2SAndroid Build Coastguard Worker {
191*5e7646d2SAndroid Build Coastguard Worker /*
192*5e7646d2SAndroid Build Coastguard Worker * Apple LaserWriter...
193*5e7646d2SAndroid Build Coastguard Worker */
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Apple LaserWriter%s", make_and_model + 11);
196*5e7646d2SAndroid Build Coastguard Worker }
197*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "colorpoint", 10))
198*5e7646d2SAndroid Build Coastguard Worker {
199*5e7646d2SAndroid Build Coastguard Worker /*
200*5e7646d2SAndroid Build Coastguard Worker * Seiko...
201*5e7646d2SAndroid Build Coastguard Worker */
202*5e7646d2SAndroid Build Coastguard Worker
203*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Seiko %s", make_and_model);
204*5e7646d2SAndroid Build Coastguard Worker }
205*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "fiery", 5))
206*5e7646d2SAndroid Build Coastguard Worker {
207*5e7646d2SAndroid Build Coastguard Worker /*
208*5e7646d2SAndroid Build Coastguard Worker * EFI...
209*5e7646d2SAndroid Build Coastguard Worker */
210*5e7646d2SAndroid Build Coastguard Worker
211*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "EFI %s", make_and_model);
212*5e7646d2SAndroid Build Coastguard Worker }
213*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "ps ", 3) ||
214*5e7646d2SAndroid Build Coastguard Worker !_cups_strncasecmp(make_and_model, "colorpass", 9))
215*5e7646d2SAndroid Build Coastguard Worker {
216*5e7646d2SAndroid Build Coastguard Worker /*
217*5e7646d2SAndroid Build Coastguard Worker * Canon...
218*5e7646d2SAndroid Build Coastguard Worker */
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Canon %s", make_and_model);
221*5e7646d2SAndroid Build Coastguard Worker }
222*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make_and_model, "designjet", 9) ||
223*5e7646d2SAndroid Build Coastguard Worker !_cups_strncasecmp(make_and_model, "deskjet", 7))
224*5e7646d2SAndroid Build Coastguard Worker {
225*5e7646d2SAndroid Build Coastguard Worker /*
226*5e7646d2SAndroid Build Coastguard Worker * HP...
227*5e7646d2SAndroid Build Coastguard Worker */
228*5e7646d2SAndroid Build Coastguard Worker
229*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "HP %s", make_and_model);
230*5e7646d2SAndroid Build Coastguard Worker }
231*5e7646d2SAndroid Build Coastguard Worker else
232*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, make_and_model, bufsize);
233*5e7646d2SAndroid Build Coastguard Worker
234*5e7646d2SAndroid Build Coastguard Worker /*
235*5e7646d2SAndroid Build Coastguard Worker * Clean up the make...
236*5e7646d2SAndroid Build Coastguard Worker */
237*5e7646d2SAndroid Build Coastguard Worker
238*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(buffer, "agfa", 4))
239*5e7646d2SAndroid Build Coastguard Worker {
240*5e7646d2SAndroid Build Coastguard Worker /*
241*5e7646d2SAndroid Build Coastguard Worker * Replace with AGFA (all uppercase)...
242*5e7646d2SAndroid Build Coastguard Worker */
243*5e7646d2SAndroid Build Coastguard Worker
244*5e7646d2SAndroid Build Coastguard Worker buffer[0] = 'A';
245*5e7646d2SAndroid Build Coastguard Worker buffer[1] = 'G';
246*5e7646d2SAndroid Build Coastguard Worker buffer[2] = 'F';
247*5e7646d2SAndroid Build Coastguard Worker buffer[3] = 'A';
248*5e7646d2SAndroid Build Coastguard Worker }
249*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(buffer, "Hewlett-Packard hp ", 19))
250*5e7646d2SAndroid Build Coastguard Worker {
251*5e7646d2SAndroid Build Coastguard Worker /*
252*5e7646d2SAndroid Build Coastguard Worker * Just put "HP" on the front...
253*5e7646d2SAndroid Build Coastguard Worker */
254*5e7646d2SAndroid Build Coastguard Worker
255*5e7646d2SAndroid Build Coastguard Worker buffer[0] = 'H';
256*5e7646d2SAndroid Build Coastguard Worker buffer[1] = 'P';
257*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(buffer + 2, buffer + 18);
258*5e7646d2SAndroid Build Coastguard Worker }
259*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(buffer, "Hewlett-Packard ", 16))
260*5e7646d2SAndroid Build Coastguard Worker {
261*5e7646d2SAndroid Build Coastguard Worker /*
262*5e7646d2SAndroid Build Coastguard Worker * Just put "HP" on the front...
263*5e7646d2SAndroid Build Coastguard Worker */
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker buffer[0] = 'H';
266*5e7646d2SAndroid Build Coastguard Worker buffer[1] = 'P';
267*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(buffer + 2, buffer + 15);
268*5e7646d2SAndroid Build Coastguard Worker }
269*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(buffer, "Lexmark International", 21))
270*5e7646d2SAndroid Build Coastguard Worker {
271*5e7646d2SAndroid Build Coastguard Worker /*
272*5e7646d2SAndroid Build Coastguard Worker * Strip "International"...
273*5e7646d2SAndroid Build Coastguard Worker */
274*5e7646d2SAndroid Build Coastguard Worker
275*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(buffer + 8, buffer + 21);
276*5e7646d2SAndroid Build Coastguard Worker }
277*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(buffer, "herk", 4))
278*5e7646d2SAndroid Build Coastguard Worker {
279*5e7646d2SAndroid Build Coastguard Worker /*
280*5e7646d2SAndroid Build Coastguard Worker * Replace with LHAG...
281*5e7646d2SAndroid Build Coastguard Worker */
282*5e7646d2SAndroid Build Coastguard Worker
283*5e7646d2SAndroid Build Coastguard Worker buffer[0] = 'L';
284*5e7646d2SAndroid Build Coastguard Worker buffer[1] = 'H';
285*5e7646d2SAndroid Build Coastguard Worker buffer[2] = 'A';
286*5e7646d2SAndroid Build Coastguard Worker buffer[3] = 'G';
287*5e7646d2SAndroid Build Coastguard Worker }
288*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(buffer, "linotype", 8))
289*5e7646d2SAndroid Build Coastguard Worker {
290*5e7646d2SAndroid Build Coastguard Worker /*
291*5e7646d2SAndroid Build Coastguard Worker * Replace with LHAG...
292*5e7646d2SAndroid Build Coastguard Worker */
293*5e7646d2SAndroid Build Coastguard Worker
294*5e7646d2SAndroid Build Coastguard Worker buffer[0] = 'L';
295*5e7646d2SAndroid Build Coastguard Worker buffer[1] = 'H';
296*5e7646d2SAndroid Build Coastguard Worker buffer[2] = 'A';
297*5e7646d2SAndroid Build Coastguard Worker buffer[3] = 'G';
298*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(buffer + 4, buffer + 8);
299*5e7646d2SAndroid Build Coastguard Worker }
300*5e7646d2SAndroid Build Coastguard Worker
301*5e7646d2SAndroid Build Coastguard Worker /*
302*5e7646d2SAndroid Build Coastguard Worker * Remove trailing whitespace and return...
303*5e7646d2SAndroid Build Coastguard Worker */
304*5e7646d2SAndroid Build Coastguard Worker
305*5e7646d2SAndroid Build Coastguard Worker for (bufptr = buffer + strlen(buffer) - 1;
306*5e7646d2SAndroid Build Coastguard Worker bufptr >= buffer && _cups_isspace(*bufptr);
307*5e7646d2SAndroid Build Coastguard Worker bufptr --);
308*5e7646d2SAndroid Build Coastguard Worker
309*5e7646d2SAndroid Build Coastguard Worker bufptr[1] = '\0';
310*5e7646d2SAndroid Build Coastguard Worker
311*5e7646d2SAndroid Build Coastguard Worker return (buffer[0] ? buffer : NULL);
312*5e7646d2SAndroid Build Coastguard Worker }
313