1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * File functions for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Since stdio files max out at 256 files on many systems, we have to
5*5e7646d2SAndroid Build Coastguard Worker * write similar functions without this limit. At the same time, using
6*5e7646d2SAndroid Build Coastguard Worker * our own file functions allows us to provide transparent support of
7*5e7646d2SAndroid Build Coastguard Worker * different line endings, gzip'd print files, PPD files, etc.
8*5e7646d2SAndroid Build Coastguard Worker *
9*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2019 by Apple Inc.
10*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
11*5e7646d2SAndroid Build Coastguard Worker *
12*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
13*5e7646d2SAndroid Build Coastguard Worker * information.
14*5e7646d2SAndroid Build Coastguard Worker */
15*5e7646d2SAndroid Build Coastguard Worker
16*5e7646d2SAndroid Build Coastguard Worker /*
17*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
18*5e7646d2SAndroid Build Coastguard Worker */
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker #include "file-private.h"
21*5e7646d2SAndroid Build Coastguard Worker #include "debug-internal.h"
22*5e7646d2SAndroid Build Coastguard Worker #include <sys/stat.h>
23*5e7646d2SAndroid Build Coastguard Worker #include <sys/types.h>
24*5e7646d2SAndroid Build Coastguard Worker
25*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_LIBZ
26*5e7646d2SAndroid Build Coastguard Worker # include <zlib.h>
27*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_LIBZ */
28*5e7646d2SAndroid Build Coastguard Worker
29*5e7646d2SAndroid Build Coastguard Worker
30*5e7646d2SAndroid Build Coastguard Worker /*
31*5e7646d2SAndroid Build Coastguard Worker * Internal structures...
32*5e7646d2SAndroid Build Coastguard Worker */
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker struct _cups_file_s /**** CUPS file structure... ****/
35*5e7646d2SAndroid Build Coastguard Worker
36*5e7646d2SAndroid Build Coastguard Worker {
37*5e7646d2SAndroid Build Coastguard Worker int fd; /* File descriptor */
38*5e7646d2SAndroid Build Coastguard Worker char mode, /* Mode ('r' or 'w') */
39*5e7646d2SAndroid Build Coastguard Worker compressed, /* Compression used? */
40*5e7646d2SAndroid Build Coastguard Worker is_stdio, /* stdin/out/err? */
41*5e7646d2SAndroid Build Coastguard Worker eof, /* End of file? */
42*5e7646d2SAndroid Build Coastguard Worker buf[4096], /* Buffer */
43*5e7646d2SAndroid Build Coastguard Worker *ptr, /* Pointer into buffer */
44*5e7646d2SAndroid Build Coastguard Worker *end; /* End of buffer data */
45*5e7646d2SAndroid Build Coastguard Worker off_t pos, /* Position in file */
46*5e7646d2SAndroid Build Coastguard Worker bufpos; /* File position for start of buffer */
47*5e7646d2SAndroid Build Coastguard Worker
48*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
49*5e7646d2SAndroid Build Coastguard Worker z_stream stream; /* (De)compression stream */
50*5e7646d2SAndroid Build Coastguard Worker Bytef cbuf[4096]; /* (De)compression buffer */
51*5e7646d2SAndroid Build Coastguard Worker uLong crc; /* (De)compression CRC */
52*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
53*5e7646d2SAndroid Build Coastguard Worker
54*5e7646d2SAndroid Build Coastguard Worker char *printf_buffer; /* cupsFilePrintf buffer */
55*5e7646d2SAndroid Build Coastguard Worker size_t printf_size; /* Size of cupsFilePrintf buffer */
56*5e7646d2SAndroid Build Coastguard Worker };
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker
59*5e7646d2SAndroid Build Coastguard Worker /*
60*5e7646d2SAndroid Build Coastguard Worker * Local functions...
61*5e7646d2SAndroid Build Coastguard Worker */
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
64*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_compress(cups_file_t *fp, const char *buf, size_t bytes);
65*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
66*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_fill(cups_file_t *fp);
67*5e7646d2SAndroid Build Coastguard Worker static int cups_open(const char *filename, int mode);
68*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes);
69*5e7646d2SAndroid Build Coastguard Worker static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes);
70*5e7646d2SAndroid Build Coastguard Worker
71*5e7646d2SAndroid Build Coastguard Worker
72*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
73*5e7646d2SAndroid Build Coastguard Worker /*
74*5e7646d2SAndroid Build Coastguard Worker * '_cupsFileCheck()' - Check the permissions of the given filename.
75*5e7646d2SAndroid Build Coastguard Worker */
76*5e7646d2SAndroid Build Coastguard Worker
77*5e7646d2SAndroid Build Coastguard Worker _cups_fc_result_t /* O - Check result */
_cupsFileCheck(const char * filename,_cups_fc_filetype_t filetype,int dorootchecks,_cups_fc_func_t cb,void * context)78*5e7646d2SAndroid Build Coastguard Worker _cupsFileCheck(
79*5e7646d2SAndroid Build Coastguard Worker const char *filename, /* I - Filename to check */
80*5e7646d2SAndroid Build Coastguard Worker _cups_fc_filetype_t filetype, /* I - Type of file checks? */
81*5e7646d2SAndroid Build Coastguard Worker int dorootchecks, /* I - Check for root permissions? */
82*5e7646d2SAndroid Build Coastguard Worker _cups_fc_func_t cb, /* I - Callback function */
83*5e7646d2SAndroid Build Coastguard Worker void *context) /* I - Context pointer for callback */
84*5e7646d2SAndroid Build Coastguard Worker
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker struct stat fileinfo; /* File information */
87*5e7646d2SAndroid Build Coastguard Worker char message[1024], /* Message string */
88*5e7646d2SAndroid Build Coastguard Worker temp[1024], /* Parent directory filename */
89*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into parent directory */
90*5e7646d2SAndroid Build Coastguard Worker _cups_fc_result_t result; /* Check result */
91*5e7646d2SAndroid Build Coastguard Worker
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker /*
94*5e7646d2SAndroid Build Coastguard Worker * Does the filename contain a relative path ("../")?
95*5e7646d2SAndroid Build Coastguard Worker */
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker if (strstr(filename, "../"))
98*5e7646d2SAndroid Build Coastguard Worker {
99*5e7646d2SAndroid Build Coastguard Worker /*
100*5e7646d2SAndroid Build Coastguard Worker * Yes, fail it!
101*5e7646d2SAndroid Build Coastguard Worker */
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_RELATIVE_PATH;
104*5e7646d2SAndroid Build Coastguard Worker goto finishup;
105*5e7646d2SAndroid Build Coastguard Worker }
106*5e7646d2SAndroid Build Coastguard Worker
107*5e7646d2SAndroid Build Coastguard Worker /*
108*5e7646d2SAndroid Build Coastguard Worker * Does the program even exist and is it accessible?
109*5e7646d2SAndroid Build Coastguard Worker */
110*5e7646d2SAndroid Build Coastguard Worker
111*5e7646d2SAndroid Build Coastguard Worker if (stat(filename, &fileinfo))
112*5e7646d2SAndroid Build Coastguard Worker {
113*5e7646d2SAndroid Build Coastguard Worker /*
114*5e7646d2SAndroid Build Coastguard Worker * Nope...
115*5e7646d2SAndroid Build Coastguard Worker */
116*5e7646d2SAndroid Build Coastguard Worker
117*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_MISSING;
118*5e7646d2SAndroid Build Coastguard Worker goto finishup;
119*5e7646d2SAndroid Build Coastguard Worker }
120*5e7646d2SAndroid Build Coastguard Worker
121*5e7646d2SAndroid Build Coastguard Worker /*
122*5e7646d2SAndroid Build Coastguard Worker * Check the execute bit...
123*5e7646d2SAndroid Build Coastguard Worker */
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_OK;
126*5e7646d2SAndroid Build Coastguard Worker
127*5e7646d2SAndroid Build Coastguard Worker switch (filetype)
128*5e7646d2SAndroid Build Coastguard Worker {
129*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_DIRECTORY :
130*5e7646d2SAndroid Build Coastguard Worker if (!S_ISDIR(fileinfo.st_mode))
131*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_WRONG_TYPE;
132*5e7646d2SAndroid Build Coastguard Worker break;
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker default :
135*5e7646d2SAndroid Build Coastguard Worker if (!S_ISREG(fileinfo.st_mode))
136*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_WRONG_TYPE;
137*5e7646d2SAndroid Build Coastguard Worker break;
138*5e7646d2SAndroid Build Coastguard Worker }
139*5e7646d2SAndroid Build Coastguard Worker
140*5e7646d2SAndroid Build Coastguard Worker if (result)
141*5e7646d2SAndroid Build Coastguard Worker goto finishup;
142*5e7646d2SAndroid Build Coastguard Worker
143*5e7646d2SAndroid Build Coastguard Worker /*
144*5e7646d2SAndroid Build Coastguard Worker * Are we doing root checks?
145*5e7646d2SAndroid Build Coastguard Worker */
146*5e7646d2SAndroid Build Coastguard Worker
147*5e7646d2SAndroid Build Coastguard Worker if (!dorootchecks)
148*5e7646d2SAndroid Build Coastguard Worker {
149*5e7646d2SAndroid Build Coastguard Worker /*
150*5e7646d2SAndroid Build Coastguard Worker * Nope, so anything (else) goes...
151*5e7646d2SAndroid Build Coastguard Worker */
152*5e7646d2SAndroid Build Coastguard Worker
153*5e7646d2SAndroid Build Coastguard Worker goto finishup;
154*5e7646d2SAndroid Build Coastguard Worker }
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker /*
157*5e7646d2SAndroid Build Coastguard Worker * Verify permission of the file itself:
158*5e7646d2SAndroid Build Coastguard Worker *
159*5e7646d2SAndroid Build Coastguard Worker * 1. Must be owned by root
160*5e7646d2SAndroid Build Coastguard Worker * 2. Must not be writable by group
161*5e7646d2SAndroid Build Coastguard Worker * 3. Must not be setuid
162*5e7646d2SAndroid Build Coastguard Worker * 4. Must not be writable by others
163*5e7646d2SAndroid Build Coastguard Worker */
164*5e7646d2SAndroid Build Coastguard Worker
165*5e7646d2SAndroid Build Coastguard Worker if (fileinfo.st_uid || /* 1. Must be owned by root */
166*5e7646d2SAndroid Build Coastguard Worker (fileinfo.st_mode & S_IWGRP) || /* 2. Must not be writable by group */
167*5e7646d2SAndroid Build Coastguard Worker (fileinfo.st_mode & S_ISUID) || /* 3. Must not be setuid */
168*5e7646d2SAndroid Build Coastguard Worker (fileinfo.st_mode & S_IWOTH)) /* 4. Must not be writable by others */
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_PERMISSIONS;
171*5e7646d2SAndroid Build Coastguard Worker goto finishup;
172*5e7646d2SAndroid Build Coastguard Worker }
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker if (filetype == _CUPS_FILE_CHECK_DIRECTORY ||
175*5e7646d2SAndroid Build Coastguard Worker filetype == _CUPS_FILE_CHECK_FILE_ONLY)
176*5e7646d2SAndroid Build Coastguard Worker goto finishup;
177*5e7646d2SAndroid Build Coastguard Worker
178*5e7646d2SAndroid Build Coastguard Worker /*
179*5e7646d2SAndroid Build Coastguard Worker * Now check the containing directory...
180*5e7646d2SAndroid Build Coastguard Worker */
181*5e7646d2SAndroid Build Coastguard Worker
182*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, filename, sizeof(temp));
183*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strrchr(temp, '/')) != NULL)
184*5e7646d2SAndroid Build Coastguard Worker {
185*5e7646d2SAndroid Build Coastguard Worker if (ptr == temp)
186*5e7646d2SAndroid Build Coastguard Worker ptr[1] = '\0';
187*5e7646d2SAndroid Build Coastguard Worker else
188*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
189*5e7646d2SAndroid Build Coastguard Worker }
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker if (stat(temp, &fileinfo))
192*5e7646d2SAndroid Build Coastguard Worker {
193*5e7646d2SAndroid Build Coastguard Worker /*
194*5e7646d2SAndroid Build Coastguard Worker * Doesn't exist?!?
195*5e7646d2SAndroid Build Coastguard Worker */
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_MISSING;
198*5e7646d2SAndroid Build Coastguard Worker filetype = _CUPS_FILE_CHECK_DIRECTORY;
199*5e7646d2SAndroid Build Coastguard Worker filename = temp;
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker goto finishup;
202*5e7646d2SAndroid Build Coastguard Worker }
203*5e7646d2SAndroid Build Coastguard Worker
204*5e7646d2SAndroid Build Coastguard Worker if (fileinfo.st_uid || /* 1. Must be owned by root */
205*5e7646d2SAndroid Build Coastguard Worker (fileinfo.st_mode & S_IWGRP) || /* 2. Must not be writable by group */
206*5e7646d2SAndroid Build Coastguard Worker (fileinfo.st_mode & S_ISUID) || /* 3. Must not be setuid */
207*5e7646d2SAndroid Build Coastguard Worker (fileinfo.st_mode & S_IWOTH)) /* 4. Must not be writable by others */
208*5e7646d2SAndroid Build Coastguard Worker {
209*5e7646d2SAndroid Build Coastguard Worker result = _CUPS_FILE_CHECK_PERMISSIONS;
210*5e7646d2SAndroid Build Coastguard Worker filetype = _CUPS_FILE_CHECK_DIRECTORY;
211*5e7646d2SAndroid Build Coastguard Worker filename = temp;
212*5e7646d2SAndroid Build Coastguard Worker }
213*5e7646d2SAndroid Build Coastguard Worker
214*5e7646d2SAndroid Build Coastguard Worker /*
215*5e7646d2SAndroid Build Coastguard Worker * Common return point...
216*5e7646d2SAndroid Build Coastguard Worker */
217*5e7646d2SAndroid Build Coastguard Worker
218*5e7646d2SAndroid Build Coastguard Worker finishup:
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker if (cb)
221*5e7646d2SAndroid Build Coastguard Worker {
222*5e7646d2SAndroid Build Coastguard Worker cups_lang_t *lang = cupsLangDefault();
223*5e7646d2SAndroid Build Coastguard Worker /* Localization information */
224*5e7646d2SAndroid Build Coastguard Worker
225*5e7646d2SAndroid Build Coastguard Worker switch (result)
226*5e7646d2SAndroid Build Coastguard Worker {
227*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_OK :
228*5e7646d2SAndroid Build Coastguard Worker if (filetype == _CUPS_FILE_CHECK_DIRECTORY)
229*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
230*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("Directory \"%s\" permissions OK "
231*5e7646d2SAndroid Build Coastguard Worker "(0%o/uid=%d/gid=%d).")),
232*5e7646d2SAndroid Build Coastguard Worker filename, fileinfo.st_mode, (int)fileinfo.st_uid,
233*5e7646d2SAndroid Build Coastguard Worker (int)fileinfo.st_gid);
234*5e7646d2SAndroid Build Coastguard Worker else
235*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
236*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("File \"%s\" permissions OK "
237*5e7646d2SAndroid Build Coastguard Worker "(0%o/uid=%d/gid=%d).")),
238*5e7646d2SAndroid Build Coastguard Worker filename, fileinfo.st_mode, (int)fileinfo.st_uid,
239*5e7646d2SAndroid Build Coastguard Worker (int)fileinfo.st_gid);
240*5e7646d2SAndroid Build Coastguard Worker break;
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_MISSING :
243*5e7646d2SAndroid Build Coastguard Worker if (filetype == _CUPS_FILE_CHECK_DIRECTORY)
244*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
245*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("Directory \"%s\" not available: "
246*5e7646d2SAndroid Build Coastguard Worker "%s")),
247*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
248*5e7646d2SAndroid Build Coastguard Worker else
249*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
250*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("File \"%s\" not available: %s")),
251*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
252*5e7646d2SAndroid Build Coastguard Worker break;
253*5e7646d2SAndroid Build Coastguard Worker
254*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_PERMISSIONS :
255*5e7646d2SAndroid Build Coastguard Worker if (filetype == _CUPS_FILE_CHECK_DIRECTORY)
256*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
257*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("Directory \"%s\" has insecure "
258*5e7646d2SAndroid Build Coastguard Worker "permissions "
259*5e7646d2SAndroid Build Coastguard Worker "(0%o/uid=%d/gid=%d).")),
260*5e7646d2SAndroid Build Coastguard Worker filename, fileinfo.st_mode, (int)fileinfo.st_uid,
261*5e7646d2SAndroid Build Coastguard Worker (int)fileinfo.st_gid);
262*5e7646d2SAndroid Build Coastguard Worker else
263*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
264*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("File \"%s\" has insecure "
265*5e7646d2SAndroid Build Coastguard Worker "permissions "
266*5e7646d2SAndroid Build Coastguard Worker "(0%o/uid=%d/gid=%d).")),
267*5e7646d2SAndroid Build Coastguard Worker filename, fileinfo.st_mode, (int)fileinfo.st_uid,
268*5e7646d2SAndroid Build Coastguard Worker (int)fileinfo.st_gid);
269*5e7646d2SAndroid Build Coastguard Worker break;
270*5e7646d2SAndroid Build Coastguard Worker
271*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_WRONG_TYPE :
272*5e7646d2SAndroid Build Coastguard Worker if (filetype == _CUPS_FILE_CHECK_DIRECTORY)
273*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
274*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("Directory \"%s\" is a file.")),
275*5e7646d2SAndroid Build Coastguard Worker filename);
276*5e7646d2SAndroid Build Coastguard Worker else
277*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
278*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("File \"%s\" is a directory.")),
279*5e7646d2SAndroid Build Coastguard Worker filename);
280*5e7646d2SAndroid Build Coastguard Worker break;
281*5e7646d2SAndroid Build Coastguard Worker
282*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_RELATIVE_PATH :
283*5e7646d2SAndroid Build Coastguard Worker if (filetype == _CUPS_FILE_CHECK_DIRECTORY)
284*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
285*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("Directory \"%s\" contains a "
286*5e7646d2SAndroid Build Coastguard Worker "relative path.")), filename);
287*5e7646d2SAndroid Build Coastguard Worker else
288*5e7646d2SAndroid Build Coastguard Worker snprintf(message, sizeof(message),
289*5e7646d2SAndroid Build Coastguard Worker _cupsLangString(lang, _("File \"%s\" contains a relative "
290*5e7646d2SAndroid Build Coastguard Worker "path.")), filename);
291*5e7646d2SAndroid Build Coastguard Worker break;
292*5e7646d2SAndroid Build Coastguard Worker }
293*5e7646d2SAndroid Build Coastguard Worker
294*5e7646d2SAndroid Build Coastguard Worker (*cb)(context, result, message);
295*5e7646d2SAndroid Build Coastguard Worker }
296*5e7646d2SAndroid Build Coastguard Worker
297*5e7646d2SAndroid Build Coastguard Worker return (result);
298*5e7646d2SAndroid Build Coastguard Worker }
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker
301*5e7646d2SAndroid Build Coastguard Worker /*
302*5e7646d2SAndroid Build Coastguard Worker * '_cupsFileCheckFilter()' - Report file check results as CUPS filter messages.
303*5e7646d2SAndroid Build Coastguard Worker */
304*5e7646d2SAndroid Build Coastguard Worker
305*5e7646d2SAndroid Build Coastguard Worker void
_cupsFileCheckFilter(void * context,_cups_fc_result_t result,const char * message)306*5e7646d2SAndroid Build Coastguard Worker _cupsFileCheckFilter(
307*5e7646d2SAndroid Build Coastguard Worker void *context, /* I - Context pointer (unused) */
308*5e7646d2SAndroid Build Coastguard Worker _cups_fc_result_t result, /* I - Result code */
309*5e7646d2SAndroid Build Coastguard Worker const char *message) /* I - Message text */
310*5e7646d2SAndroid Build Coastguard Worker {
311*5e7646d2SAndroid Build Coastguard Worker const char *prefix; /* Messaging prefix */
312*5e7646d2SAndroid Build Coastguard Worker
313*5e7646d2SAndroid Build Coastguard Worker
314*5e7646d2SAndroid Build Coastguard Worker (void)context;
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker switch (result)
317*5e7646d2SAndroid Build Coastguard Worker {
318*5e7646d2SAndroid Build Coastguard Worker default :
319*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_OK :
320*5e7646d2SAndroid Build Coastguard Worker prefix = "DEBUG2";
321*5e7646d2SAndroid Build Coastguard Worker break;
322*5e7646d2SAndroid Build Coastguard Worker
323*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_MISSING :
324*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_WRONG_TYPE :
325*5e7646d2SAndroid Build Coastguard Worker prefix = "ERROR";
326*5e7646d2SAndroid Build Coastguard Worker fputs("STATE: +cups-missing-filter-warning\n", stderr);
327*5e7646d2SAndroid Build Coastguard Worker break;
328*5e7646d2SAndroid Build Coastguard Worker
329*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_PERMISSIONS :
330*5e7646d2SAndroid Build Coastguard Worker case _CUPS_FILE_CHECK_RELATIVE_PATH :
331*5e7646d2SAndroid Build Coastguard Worker prefix = "ERROR";
332*5e7646d2SAndroid Build Coastguard Worker fputs("STATE: +cups-insecure-filter-warning\n", stderr);
333*5e7646d2SAndroid Build Coastguard Worker break;
334*5e7646d2SAndroid Build Coastguard Worker }
335*5e7646d2SAndroid Build Coastguard Worker
336*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "%s: %s\n", prefix, message);
337*5e7646d2SAndroid Build Coastguard Worker }
338*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
339*5e7646d2SAndroid Build Coastguard Worker
340*5e7646d2SAndroid Build Coastguard Worker
341*5e7646d2SAndroid Build Coastguard Worker /*
342*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileClose()' - Close a CUPS file.
343*5e7646d2SAndroid Build Coastguard Worker *
344*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
345*5e7646d2SAndroid Build Coastguard Worker */
346*5e7646d2SAndroid Build Coastguard Worker
347*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on error */
cupsFileClose(cups_file_t * fp)348*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(cups_file_t *fp) /* I - CUPS file */
349*5e7646d2SAndroid Build Coastguard Worker {
350*5e7646d2SAndroid Build Coastguard Worker int fd; /* File descriptor */
351*5e7646d2SAndroid Build Coastguard Worker char mode; /* Open mode */
352*5e7646d2SAndroid Build Coastguard Worker int status; /* Return status */
353*5e7646d2SAndroid Build Coastguard Worker
354*5e7646d2SAndroid Build Coastguard Worker
355*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileClose(fp=%p)", (void *)fp));
356*5e7646d2SAndroid Build Coastguard Worker
357*5e7646d2SAndroid Build Coastguard Worker /*
358*5e7646d2SAndroid Build Coastguard Worker * Range check...
359*5e7646d2SAndroid Build Coastguard Worker */
360*5e7646d2SAndroid Build Coastguard Worker
361*5e7646d2SAndroid Build Coastguard Worker if (!fp)
362*5e7646d2SAndroid Build Coastguard Worker return (-1);
363*5e7646d2SAndroid Build Coastguard Worker
364*5e7646d2SAndroid Build Coastguard Worker /*
365*5e7646d2SAndroid Build Coastguard Worker * Flush pending write data...
366*5e7646d2SAndroid Build Coastguard Worker */
367*5e7646d2SAndroid Build Coastguard Worker
368*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 'w')
369*5e7646d2SAndroid Build Coastguard Worker status = cupsFileFlush(fp);
370*5e7646d2SAndroid Build Coastguard Worker else
371*5e7646d2SAndroid Build Coastguard Worker status = 0;
372*5e7646d2SAndroid Build Coastguard Worker
373*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
374*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed && status >= 0)
375*5e7646d2SAndroid Build Coastguard Worker {
376*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 'r')
377*5e7646d2SAndroid Build Coastguard Worker {
378*5e7646d2SAndroid Build Coastguard Worker /*
379*5e7646d2SAndroid Build Coastguard Worker * Free decompression data...
380*5e7646d2SAndroid Build Coastguard Worker */
381*5e7646d2SAndroid Build Coastguard Worker
382*5e7646d2SAndroid Build Coastguard Worker inflateEnd(&fp->stream);
383*5e7646d2SAndroid Build Coastguard Worker }
384*5e7646d2SAndroid Build Coastguard Worker else
385*5e7646d2SAndroid Build Coastguard Worker {
386*5e7646d2SAndroid Build Coastguard Worker /*
387*5e7646d2SAndroid Build Coastguard Worker * Flush any remaining compressed data...
388*5e7646d2SAndroid Build Coastguard Worker */
389*5e7646d2SAndroid Build Coastguard Worker
390*5e7646d2SAndroid Build Coastguard Worker unsigned char trailer[8]; /* Trailer CRC and length */
391*5e7646d2SAndroid Build Coastguard Worker int done; /* Done writing... */
392*5e7646d2SAndroid Build Coastguard Worker
393*5e7646d2SAndroid Build Coastguard Worker
394*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_in = 0;
395*5e7646d2SAndroid Build Coastguard Worker
396*5e7646d2SAndroid Build Coastguard Worker for (done = 0;;)
397*5e7646d2SAndroid Build Coastguard Worker {
398*5e7646d2SAndroid Build Coastguard Worker if (fp->stream.next_out > fp->cbuf)
399*5e7646d2SAndroid Build Coastguard Worker {
400*5e7646d2SAndroid Build Coastguard Worker if (cups_write(fp, (char *)fp->cbuf,
401*5e7646d2SAndroid Build Coastguard Worker (size_t)(fp->stream.next_out - fp->cbuf)) < 0)
402*5e7646d2SAndroid Build Coastguard Worker status = -1;
403*5e7646d2SAndroid Build Coastguard Worker
404*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_out = fp->cbuf;
405*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_out = sizeof(fp->cbuf);
406*5e7646d2SAndroid Build Coastguard Worker }
407*5e7646d2SAndroid Build Coastguard Worker
408*5e7646d2SAndroid Build Coastguard Worker if (done || status < 0)
409*5e7646d2SAndroid Build Coastguard Worker break;
410*5e7646d2SAndroid Build Coastguard Worker
411*5e7646d2SAndroid Build Coastguard Worker done = deflate(&fp->stream, Z_FINISH) == Z_STREAM_END &&
412*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_out == fp->cbuf;
413*5e7646d2SAndroid Build Coastguard Worker }
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker /*
416*5e7646d2SAndroid Build Coastguard Worker * Write the CRC and length...
417*5e7646d2SAndroid Build Coastguard Worker */
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker trailer[0] = (unsigned char)fp->crc;
420*5e7646d2SAndroid Build Coastguard Worker trailer[1] = (unsigned char)(fp->crc >> 8);
421*5e7646d2SAndroid Build Coastguard Worker trailer[2] = (unsigned char)(fp->crc >> 16);
422*5e7646d2SAndroid Build Coastguard Worker trailer[3] = (unsigned char)(fp->crc >> 24);
423*5e7646d2SAndroid Build Coastguard Worker trailer[4] = (unsigned char)fp->pos;
424*5e7646d2SAndroid Build Coastguard Worker trailer[5] = (unsigned char)(fp->pos >> 8);
425*5e7646d2SAndroid Build Coastguard Worker trailer[6] = (unsigned char)(fp->pos >> 16);
426*5e7646d2SAndroid Build Coastguard Worker trailer[7] = (unsigned char)(fp->pos >> 24);
427*5e7646d2SAndroid Build Coastguard Worker
428*5e7646d2SAndroid Build Coastguard Worker if (cups_write(fp, (char *)trailer, 8) < 0)
429*5e7646d2SAndroid Build Coastguard Worker status = -1;
430*5e7646d2SAndroid Build Coastguard Worker
431*5e7646d2SAndroid Build Coastguard Worker /*
432*5e7646d2SAndroid Build Coastguard Worker * Free all memory used by the compression stream...
433*5e7646d2SAndroid Build Coastguard Worker */
434*5e7646d2SAndroid Build Coastguard Worker
435*5e7646d2SAndroid Build Coastguard Worker deflateEnd(&(fp->stream));
436*5e7646d2SAndroid Build Coastguard Worker }
437*5e7646d2SAndroid Build Coastguard Worker }
438*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
439*5e7646d2SAndroid Build Coastguard Worker
440*5e7646d2SAndroid Build Coastguard Worker /*
441*5e7646d2SAndroid Build Coastguard Worker * If this is one of the cupsFileStdin/out/err files, return now and don't
442*5e7646d2SAndroid Build Coastguard Worker * actually free memory or close (these last the life of the process...)
443*5e7646d2SAndroid Build Coastguard Worker */
444*5e7646d2SAndroid Build Coastguard Worker
445*5e7646d2SAndroid Build Coastguard Worker if (fp->is_stdio)
446*5e7646d2SAndroid Build Coastguard Worker return (status);
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker /*
449*5e7646d2SAndroid Build Coastguard Worker * Save the file descriptor we used and free memory...
450*5e7646d2SAndroid Build Coastguard Worker */
451*5e7646d2SAndroid Build Coastguard Worker
452*5e7646d2SAndroid Build Coastguard Worker fd = fp->fd;
453*5e7646d2SAndroid Build Coastguard Worker mode = fp->mode;
454*5e7646d2SAndroid Build Coastguard Worker
455*5e7646d2SAndroid Build Coastguard Worker if (fp->printf_buffer)
456*5e7646d2SAndroid Build Coastguard Worker free(fp->printf_buffer);
457*5e7646d2SAndroid Build Coastguard Worker
458*5e7646d2SAndroid Build Coastguard Worker free(fp);
459*5e7646d2SAndroid Build Coastguard Worker
460*5e7646d2SAndroid Build Coastguard Worker /*
461*5e7646d2SAndroid Build Coastguard Worker * Close the file, returning the close status...
462*5e7646d2SAndroid Build Coastguard Worker */
463*5e7646d2SAndroid Build Coastguard Worker
464*5e7646d2SAndroid Build Coastguard Worker if (mode == 's')
465*5e7646d2SAndroid Build Coastguard Worker {
466*5e7646d2SAndroid Build Coastguard Worker if (httpAddrClose(NULL, fd) < 0)
467*5e7646d2SAndroid Build Coastguard Worker status = -1;
468*5e7646d2SAndroid Build Coastguard Worker }
469*5e7646d2SAndroid Build Coastguard Worker else if (close(fd) < 0)
470*5e7646d2SAndroid Build Coastguard Worker status = -1;
471*5e7646d2SAndroid Build Coastguard Worker
472*5e7646d2SAndroid Build Coastguard Worker return (status);
473*5e7646d2SAndroid Build Coastguard Worker }
474*5e7646d2SAndroid Build Coastguard Worker
475*5e7646d2SAndroid Build Coastguard Worker
476*5e7646d2SAndroid Build Coastguard Worker /*
477*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileCompression()' - Return whether a file is compressed.
478*5e7646d2SAndroid Build Coastguard Worker *
479*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
480*5e7646d2SAndroid Build Coastguard Worker */
481*5e7646d2SAndroid Build Coastguard Worker
482*5e7646d2SAndroid Build Coastguard Worker int /* O - @code CUPS_FILE_NONE@ or @code CUPS_FILE_GZIP@ */
cupsFileCompression(cups_file_t * fp)483*5e7646d2SAndroid Build Coastguard Worker cupsFileCompression(cups_file_t *fp) /* I - CUPS file */
484*5e7646d2SAndroid Build Coastguard Worker {
485*5e7646d2SAndroid Build Coastguard Worker return (fp ? fp->compressed : CUPS_FILE_NONE);
486*5e7646d2SAndroid Build Coastguard Worker }
487*5e7646d2SAndroid Build Coastguard Worker
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker /*
490*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileEOF()' - Return the end-of-file status.
491*5e7646d2SAndroid Build Coastguard Worker *
492*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
493*5e7646d2SAndroid Build Coastguard Worker */
494*5e7646d2SAndroid Build Coastguard Worker
495*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 on end of file, 0 otherwise */
cupsFileEOF(cups_file_t * fp)496*5e7646d2SAndroid Build Coastguard Worker cupsFileEOF(cups_file_t *fp) /* I - CUPS file */
497*5e7646d2SAndroid Build Coastguard Worker {
498*5e7646d2SAndroid Build Coastguard Worker return (fp ? fp->eof : 1);
499*5e7646d2SAndroid Build Coastguard Worker }
500*5e7646d2SAndroid Build Coastguard Worker
501*5e7646d2SAndroid Build Coastguard Worker
502*5e7646d2SAndroid Build Coastguard Worker /*
503*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileFind()' - Find a file using the specified path.
504*5e7646d2SAndroid Build Coastguard Worker *
505*5e7646d2SAndroid Build Coastguard Worker * This function allows the paths in the path string to be separated by
506*5e7646d2SAndroid Build Coastguard Worker * colons (UNIX standard) or semicolons (Windows standard) and stores the
507*5e7646d2SAndroid Build Coastguard Worker * result in the buffer supplied. If the file cannot be found in any of
508*5e7646d2SAndroid Build Coastguard Worker * the supplied paths, @code NULL@ is returned. A @code NULL@ path only
509*5e7646d2SAndroid Build Coastguard Worker * matches the current directory.
510*5e7646d2SAndroid Build Coastguard Worker *
511*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
512*5e7646d2SAndroid Build Coastguard Worker */
513*5e7646d2SAndroid Build Coastguard Worker
514*5e7646d2SAndroid Build Coastguard Worker const char * /* O - Full path to file or @code NULL@ if not found */
cupsFileFind(const char * filename,const char * path,int executable,char * buffer,int bufsize)515*5e7646d2SAndroid Build Coastguard Worker cupsFileFind(const char *filename, /* I - File to find */
516*5e7646d2SAndroid Build Coastguard Worker const char *path, /* I - Colon/semicolon-separated path */
517*5e7646d2SAndroid Build Coastguard Worker int executable, /* I - 1 = executable files, 0 = any file/dir */
518*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - Filename buffer */
519*5e7646d2SAndroid Build Coastguard Worker int bufsize) /* I - Size of filename buffer */
520*5e7646d2SAndroid Build Coastguard Worker {
521*5e7646d2SAndroid Build Coastguard Worker char *bufptr, /* Current position in buffer */
522*5e7646d2SAndroid Build Coastguard Worker *bufend; /* End of buffer */
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker
525*5e7646d2SAndroid Build Coastguard Worker /*
526*5e7646d2SAndroid Build Coastguard Worker * Range check input...
527*5e7646d2SAndroid Build Coastguard Worker */
528*5e7646d2SAndroid Build Coastguard Worker
529*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileFind(filename=\"%s\", path=\"%s\", executable=%d, buffer=%p, bufsize=%d)", filename, path, executable, (void *)buffer, bufsize));
530*5e7646d2SAndroid Build Coastguard Worker
531*5e7646d2SAndroid Build Coastguard Worker if (!filename || !buffer || bufsize < 2)
532*5e7646d2SAndroid Build Coastguard Worker return (NULL);
533*5e7646d2SAndroid Build Coastguard Worker
534*5e7646d2SAndroid Build Coastguard Worker if (!path)
535*5e7646d2SAndroid Build Coastguard Worker {
536*5e7646d2SAndroid Build Coastguard Worker /*
537*5e7646d2SAndroid Build Coastguard Worker * No path, so check current directory...
538*5e7646d2SAndroid Build Coastguard Worker */
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker if (!access(filename, 0))
541*5e7646d2SAndroid Build Coastguard Worker {
542*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, filename, (size_t)bufsize);
543*5e7646d2SAndroid Build Coastguard Worker return (buffer);
544*5e7646d2SAndroid Build Coastguard Worker }
545*5e7646d2SAndroid Build Coastguard Worker else
546*5e7646d2SAndroid Build Coastguard Worker return (NULL);
547*5e7646d2SAndroid Build Coastguard Worker }
548*5e7646d2SAndroid Build Coastguard Worker
549*5e7646d2SAndroid Build Coastguard Worker /*
550*5e7646d2SAndroid Build Coastguard Worker * Now check each path and return the first match...
551*5e7646d2SAndroid Build Coastguard Worker */
552*5e7646d2SAndroid Build Coastguard Worker
553*5e7646d2SAndroid Build Coastguard Worker bufend = buffer + bufsize - 1;
554*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
555*5e7646d2SAndroid Build Coastguard Worker
556*5e7646d2SAndroid Build Coastguard Worker while (*path)
557*5e7646d2SAndroid Build Coastguard Worker {
558*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
559*5e7646d2SAndroid Build Coastguard Worker if (*path == ';' || (*path == ':' && ((bufptr - buffer) > 1 || !isalpha(buffer[0] & 255))))
560*5e7646d2SAndroid Build Coastguard Worker #else
561*5e7646d2SAndroid Build Coastguard Worker if (*path == ';' || *path == ':')
562*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
563*5e7646d2SAndroid Build Coastguard Worker {
564*5e7646d2SAndroid Build Coastguard Worker if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend)
565*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '/';
566*5e7646d2SAndroid Build Coastguard Worker
567*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, filename, (size_t)(bufend - bufptr));
568*5e7646d2SAndroid Build Coastguard Worker
569*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
570*5e7646d2SAndroid Build Coastguard Worker if (!access(buffer, 0))
571*5e7646d2SAndroid Build Coastguard Worker #else
572*5e7646d2SAndroid Build Coastguard Worker if (!access(buffer, executable ? X_OK : 0))
573*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
574*5e7646d2SAndroid Build Coastguard Worker {
575*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer));
576*5e7646d2SAndroid Build Coastguard Worker return (buffer);
577*5e7646d2SAndroid Build Coastguard Worker }
578*5e7646d2SAndroid Build Coastguard Worker
579*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
580*5e7646d2SAndroid Build Coastguard Worker }
581*5e7646d2SAndroid Build Coastguard Worker else if (bufptr < bufend)
582*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *path;
583*5e7646d2SAndroid Build Coastguard Worker
584*5e7646d2SAndroid Build Coastguard Worker path ++;
585*5e7646d2SAndroid Build Coastguard Worker }
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker /*
588*5e7646d2SAndroid Build Coastguard Worker * Check the last path...
589*5e7646d2SAndroid Build Coastguard Worker */
590*5e7646d2SAndroid Build Coastguard Worker
591*5e7646d2SAndroid Build Coastguard Worker if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend)
592*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '/';
593*5e7646d2SAndroid Build Coastguard Worker
594*5e7646d2SAndroid Build Coastguard Worker strlcpy(bufptr, filename, (size_t)(bufend - bufptr));
595*5e7646d2SAndroid Build Coastguard Worker
596*5e7646d2SAndroid Build Coastguard Worker if (!access(buffer, 0))
597*5e7646d2SAndroid Build Coastguard Worker {
598*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer));
599*5e7646d2SAndroid Build Coastguard Worker return (buffer);
600*5e7646d2SAndroid Build Coastguard Worker }
601*5e7646d2SAndroid Build Coastguard Worker else
602*5e7646d2SAndroid Build Coastguard Worker {
603*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1cupsFileFind: Returning NULL");
604*5e7646d2SAndroid Build Coastguard Worker return (NULL);
605*5e7646d2SAndroid Build Coastguard Worker }
606*5e7646d2SAndroid Build Coastguard Worker }
607*5e7646d2SAndroid Build Coastguard Worker
608*5e7646d2SAndroid Build Coastguard Worker
609*5e7646d2SAndroid Build Coastguard Worker /*
610*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileFlush()' - Flush pending output.
611*5e7646d2SAndroid Build Coastguard Worker *
612*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
613*5e7646d2SAndroid Build Coastguard Worker */
614*5e7646d2SAndroid Build Coastguard Worker
615*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on error */
cupsFileFlush(cups_file_t * fp)616*5e7646d2SAndroid Build Coastguard Worker cupsFileFlush(cups_file_t *fp) /* I - CUPS file */
617*5e7646d2SAndroid Build Coastguard Worker {
618*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes to write */
619*5e7646d2SAndroid Build Coastguard Worker
620*5e7646d2SAndroid Build Coastguard Worker
621*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileFlush(fp=%p)", (void *)fp));
622*5e7646d2SAndroid Build Coastguard Worker
623*5e7646d2SAndroid Build Coastguard Worker /*
624*5e7646d2SAndroid Build Coastguard Worker * Range check input...
625*5e7646d2SAndroid Build Coastguard Worker */
626*5e7646d2SAndroid Build Coastguard Worker
627*5e7646d2SAndroid Build Coastguard Worker if (!fp || fp->mode != 'w')
628*5e7646d2SAndroid Build Coastguard Worker {
629*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("1cupsFileFlush: Attempt to flush a read-only file...");
630*5e7646d2SAndroid Build Coastguard Worker return (-1);
631*5e7646d2SAndroid Build Coastguard Worker }
632*5e7646d2SAndroid Build Coastguard Worker
633*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)(fp->ptr - fp->buf);
634*5e7646d2SAndroid Build Coastguard Worker
635*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileFlush: Flushing " CUPS_LLFMT " bytes...",
636*5e7646d2SAndroid Build Coastguard Worker CUPS_LLCAST bytes));
637*5e7646d2SAndroid Build Coastguard Worker
638*5e7646d2SAndroid Build Coastguard Worker if (bytes > 0)
639*5e7646d2SAndroid Build Coastguard Worker {
640*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
641*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
642*5e7646d2SAndroid Build Coastguard Worker bytes = cups_compress(fp, fp->buf, (size_t)bytes);
643*5e7646d2SAndroid Build Coastguard Worker else
644*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
645*5e7646d2SAndroid Build Coastguard Worker bytes = cups_write(fp, fp->buf, (size_t)bytes);
646*5e7646d2SAndroid Build Coastguard Worker
647*5e7646d2SAndroid Build Coastguard Worker if (bytes < 0)
648*5e7646d2SAndroid Build Coastguard Worker return (-1);
649*5e7646d2SAndroid Build Coastguard Worker
650*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
651*5e7646d2SAndroid Build Coastguard Worker }
652*5e7646d2SAndroid Build Coastguard Worker
653*5e7646d2SAndroid Build Coastguard Worker return (0);
654*5e7646d2SAndroid Build Coastguard Worker }
655*5e7646d2SAndroid Build Coastguard Worker
656*5e7646d2SAndroid Build Coastguard Worker
657*5e7646d2SAndroid Build Coastguard Worker /*
658*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileGetChar()' - Get a single character from a file.
659*5e7646d2SAndroid Build Coastguard Worker *
660*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
661*5e7646d2SAndroid Build Coastguard Worker */
662*5e7646d2SAndroid Build Coastguard Worker
663*5e7646d2SAndroid Build Coastguard Worker int /* O - Character or -1 on end of file */
cupsFileGetChar(cups_file_t * fp)664*5e7646d2SAndroid Build Coastguard Worker cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */
665*5e7646d2SAndroid Build Coastguard Worker {
666*5e7646d2SAndroid Build Coastguard Worker /*
667*5e7646d2SAndroid Build Coastguard Worker * Range check input...
668*5e7646d2SAndroid Build Coastguard Worker */
669*5e7646d2SAndroid Build Coastguard Worker
670*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileGetChar(fp=%p)", (void *)fp));
671*5e7646d2SAndroid Build Coastguard Worker
672*5e7646d2SAndroid Build Coastguard Worker if (!fp || (fp->mode != 'r' && fp->mode != 's'))
673*5e7646d2SAndroid Build Coastguard Worker {
674*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("5cupsFileGetChar: Bad arguments!");
675*5e7646d2SAndroid Build Coastguard Worker return (-1);
676*5e7646d2SAndroid Build Coastguard Worker }
677*5e7646d2SAndroid Build Coastguard Worker
678*5e7646d2SAndroid Build Coastguard Worker if (fp->eof)
679*5e7646d2SAndroid Build Coastguard Worker {
680*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("5cupsFileGetChar: End-of-file!");
681*5e7646d2SAndroid Build Coastguard Worker return (-1);
682*5e7646d2SAndroid Build Coastguard Worker }
683*5e7646d2SAndroid Build Coastguard Worker
684*5e7646d2SAndroid Build Coastguard Worker /*
685*5e7646d2SAndroid Build Coastguard Worker * If the input buffer is empty, try to read more data...
686*5e7646d2SAndroid Build Coastguard Worker */
687*5e7646d2SAndroid Build Coastguard Worker
688*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5cupsFileGetChar: fp->eof=%d, fp->ptr=%p, fp->end=%p", fp->eof, (void *)fp->ptr, (void *)fp->end));
689*5e7646d2SAndroid Build Coastguard Worker
690*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
691*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
692*5e7646d2SAndroid Build Coastguard Worker {
693*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("5cupsFileGetChar: Unable to fill buffer!");
694*5e7646d2SAndroid Build Coastguard Worker return (-1);
695*5e7646d2SAndroid Build Coastguard Worker }
696*5e7646d2SAndroid Build Coastguard Worker
697*5e7646d2SAndroid Build Coastguard Worker /*
698*5e7646d2SAndroid Build Coastguard Worker * Return the next character in the buffer...
699*5e7646d2SAndroid Build Coastguard Worker */
700*5e7646d2SAndroid Build Coastguard Worker
701*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("5cupsFileGetChar: Returning %d...", *(fp->ptr) & 255));
702*5e7646d2SAndroid Build Coastguard Worker
703*5e7646d2SAndroid Build Coastguard Worker fp->pos ++;
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("6cupsFileGetChar: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
706*5e7646d2SAndroid Build Coastguard Worker
707*5e7646d2SAndroid Build Coastguard Worker return (*(fp->ptr)++ & 255);
708*5e7646d2SAndroid Build Coastguard Worker }
709*5e7646d2SAndroid Build Coastguard Worker
710*5e7646d2SAndroid Build Coastguard Worker
711*5e7646d2SAndroid Build Coastguard Worker /*
712*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileGetConf()' - Get a line from a configuration file.
713*5e7646d2SAndroid Build Coastguard Worker *
714*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
715*5e7646d2SAndroid Build Coastguard Worker */
716*5e7646d2SAndroid Build Coastguard Worker
717*5e7646d2SAndroid Build Coastguard Worker char * /* O - Line read or @code NULL@ on end of file or error */
cupsFileGetConf(cups_file_t * fp,char * buf,size_t buflen,char ** value,int * linenum)718*5e7646d2SAndroid Build Coastguard Worker cupsFileGetConf(cups_file_t *fp, /* I - CUPS file */
719*5e7646d2SAndroid Build Coastguard Worker char *buf, /* O - String buffer */
720*5e7646d2SAndroid Build Coastguard Worker size_t buflen, /* I - Size of string buffer */
721*5e7646d2SAndroid Build Coastguard Worker char **value, /* O - Pointer to value */
722*5e7646d2SAndroid Build Coastguard Worker int *linenum) /* IO - Current line number */
723*5e7646d2SAndroid Build Coastguard Worker {
724*5e7646d2SAndroid Build Coastguard Worker char *ptr; /* Pointer into line */
725*5e7646d2SAndroid Build Coastguard Worker
726*5e7646d2SAndroid Build Coastguard Worker
727*5e7646d2SAndroid Build Coastguard Worker /*
728*5e7646d2SAndroid Build Coastguard Worker * Range check input...
729*5e7646d2SAndroid Build Coastguard Worker */
730*5e7646d2SAndroid Build Coastguard Worker
731*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileGetConf(fp=%p, buf=%p, buflen=" CUPS_LLFMT
732*5e7646d2SAndroid Build Coastguard Worker ", value=%p, linenum=%p)", (void *)fp, (void *)buf, CUPS_LLCAST buflen, (void *)value, (void *)linenum));
733*5e7646d2SAndroid Build Coastguard Worker
734*5e7646d2SAndroid Build Coastguard Worker if (!fp || (fp->mode != 'r' && fp->mode != 's') ||
735*5e7646d2SAndroid Build Coastguard Worker !buf || buflen < 2 || !value)
736*5e7646d2SAndroid Build Coastguard Worker {
737*5e7646d2SAndroid Build Coastguard Worker if (value)
738*5e7646d2SAndroid Build Coastguard Worker *value = NULL;
739*5e7646d2SAndroid Build Coastguard Worker
740*5e7646d2SAndroid Build Coastguard Worker return (NULL);
741*5e7646d2SAndroid Build Coastguard Worker }
742*5e7646d2SAndroid Build Coastguard Worker
743*5e7646d2SAndroid Build Coastguard Worker /*
744*5e7646d2SAndroid Build Coastguard Worker * Read the next non-comment line...
745*5e7646d2SAndroid Build Coastguard Worker */
746*5e7646d2SAndroid Build Coastguard Worker
747*5e7646d2SAndroid Build Coastguard Worker *value = NULL;
748*5e7646d2SAndroid Build Coastguard Worker
749*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGets(fp, buf, buflen))
750*5e7646d2SAndroid Build Coastguard Worker {
751*5e7646d2SAndroid Build Coastguard Worker (*linenum) ++;
752*5e7646d2SAndroid Build Coastguard Worker
753*5e7646d2SAndroid Build Coastguard Worker /*
754*5e7646d2SAndroid Build Coastguard Worker * Strip any comments...
755*5e7646d2SAndroid Build Coastguard Worker */
756*5e7646d2SAndroid Build Coastguard Worker
757*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strchr(buf, '#')) != NULL)
758*5e7646d2SAndroid Build Coastguard Worker {
759*5e7646d2SAndroid Build Coastguard Worker if (ptr > buf && ptr[-1] == '\\')
760*5e7646d2SAndroid Build Coastguard Worker {
761*5e7646d2SAndroid Build Coastguard Worker // Unquote the #...
762*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(ptr - 1, ptr);
763*5e7646d2SAndroid Build Coastguard Worker }
764*5e7646d2SAndroid Build Coastguard Worker else
765*5e7646d2SAndroid Build Coastguard Worker {
766*5e7646d2SAndroid Build Coastguard Worker // Strip the comment and any trailing whitespace...
767*5e7646d2SAndroid Build Coastguard Worker while (ptr > buf)
768*5e7646d2SAndroid Build Coastguard Worker {
769*5e7646d2SAndroid Build Coastguard Worker if (!_cups_isspace(ptr[-1]))
770*5e7646d2SAndroid Build Coastguard Worker break;
771*5e7646d2SAndroid Build Coastguard Worker
772*5e7646d2SAndroid Build Coastguard Worker ptr --;
773*5e7646d2SAndroid Build Coastguard Worker }
774*5e7646d2SAndroid Build Coastguard Worker
775*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
776*5e7646d2SAndroid Build Coastguard Worker }
777*5e7646d2SAndroid Build Coastguard Worker }
778*5e7646d2SAndroid Build Coastguard Worker
779*5e7646d2SAndroid Build Coastguard Worker /*
780*5e7646d2SAndroid Build Coastguard Worker * Strip leading whitespace...
781*5e7646d2SAndroid Build Coastguard Worker */
782*5e7646d2SAndroid Build Coastguard Worker
783*5e7646d2SAndroid Build Coastguard Worker for (ptr = buf; _cups_isspace(*ptr); ptr ++);
784*5e7646d2SAndroid Build Coastguard Worker
785*5e7646d2SAndroid Build Coastguard Worker if (ptr > buf)
786*5e7646d2SAndroid Build Coastguard Worker _cups_strcpy(buf, ptr);
787*5e7646d2SAndroid Build Coastguard Worker
788*5e7646d2SAndroid Build Coastguard Worker /*
789*5e7646d2SAndroid Build Coastguard Worker * See if there is anything left...
790*5e7646d2SAndroid Build Coastguard Worker */
791*5e7646d2SAndroid Build Coastguard Worker
792*5e7646d2SAndroid Build Coastguard Worker if (buf[0])
793*5e7646d2SAndroid Build Coastguard Worker {
794*5e7646d2SAndroid Build Coastguard Worker /*
795*5e7646d2SAndroid Build Coastguard Worker * Yes, grab any value and return...
796*5e7646d2SAndroid Build Coastguard Worker */
797*5e7646d2SAndroid Build Coastguard Worker
798*5e7646d2SAndroid Build Coastguard Worker for (ptr = buf; *ptr; ptr ++)
799*5e7646d2SAndroid Build Coastguard Worker if (_cups_isspace(*ptr))
800*5e7646d2SAndroid Build Coastguard Worker break;
801*5e7646d2SAndroid Build Coastguard Worker
802*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
803*5e7646d2SAndroid Build Coastguard Worker {
804*5e7646d2SAndroid Build Coastguard Worker /*
805*5e7646d2SAndroid Build Coastguard Worker * Have a value, skip any other spaces...
806*5e7646d2SAndroid Build Coastguard Worker */
807*5e7646d2SAndroid Build Coastguard Worker
808*5e7646d2SAndroid Build Coastguard Worker while (_cups_isspace(*ptr))
809*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '\0';
810*5e7646d2SAndroid Build Coastguard Worker
811*5e7646d2SAndroid Build Coastguard Worker if (*ptr)
812*5e7646d2SAndroid Build Coastguard Worker *value = ptr;
813*5e7646d2SAndroid Build Coastguard Worker
814*5e7646d2SAndroid Build Coastguard Worker /*
815*5e7646d2SAndroid Build Coastguard Worker * Strip trailing whitespace and > for lines that begin with <...
816*5e7646d2SAndroid Build Coastguard Worker */
817*5e7646d2SAndroid Build Coastguard Worker
818*5e7646d2SAndroid Build Coastguard Worker ptr += strlen(ptr) - 1;
819*5e7646d2SAndroid Build Coastguard Worker
820*5e7646d2SAndroid Build Coastguard Worker if (buf[0] == '<' && *ptr == '>')
821*5e7646d2SAndroid Build Coastguard Worker *ptr-- = '\0';
822*5e7646d2SAndroid Build Coastguard Worker else if (buf[0] == '<' && *ptr != '>')
823*5e7646d2SAndroid Build Coastguard Worker {
824*5e7646d2SAndroid Build Coastguard Worker /*
825*5e7646d2SAndroid Build Coastguard Worker * Syntax error...
826*5e7646d2SAndroid Build Coastguard Worker */
827*5e7646d2SAndroid Build Coastguard Worker
828*5e7646d2SAndroid Build Coastguard Worker *value = NULL;
829*5e7646d2SAndroid Build Coastguard Worker return (buf);
830*5e7646d2SAndroid Build Coastguard Worker }
831*5e7646d2SAndroid Build Coastguard Worker
832*5e7646d2SAndroid Build Coastguard Worker while (ptr > *value && _cups_isspace(*ptr))
833*5e7646d2SAndroid Build Coastguard Worker *ptr-- = '\0';
834*5e7646d2SAndroid Build Coastguard Worker }
835*5e7646d2SAndroid Build Coastguard Worker
836*5e7646d2SAndroid Build Coastguard Worker /*
837*5e7646d2SAndroid Build Coastguard Worker * Return the line...
838*5e7646d2SAndroid Build Coastguard Worker */
839*5e7646d2SAndroid Build Coastguard Worker
840*5e7646d2SAndroid Build Coastguard Worker return (buf);
841*5e7646d2SAndroid Build Coastguard Worker }
842*5e7646d2SAndroid Build Coastguard Worker }
843*5e7646d2SAndroid Build Coastguard Worker
844*5e7646d2SAndroid Build Coastguard Worker return (NULL);
845*5e7646d2SAndroid Build Coastguard Worker }
846*5e7646d2SAndroid Build Coastguard Worker
847*5e7646d2SAndroid Build Coastguard Worker
848*5e7646d2SAndroid Build Coastguard Worker /*
849*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileGetLine()' - Get a CR and/or LF-terminated line that may
850*5e7646d2SAndroid Build Coastguard Worker * contain binary data.
851*5e7646d2SAndroid Build Coastguard Worker *
852*5e7646d2SAndroid Build Coastguard Worker * This function differs from @link cupsFileGets@ in that the trailing CR
853*5e7646d2SAndroid Build Coastguard Worker * and LF are preserved, as is any binary data on the line. The buffer is
854*5e7646d2SAndroid Build Coastguard Worker * nul-terminated, however you should use the returned length to determine
855*5e7646d2SAndroid Build Coastguard Worker * the number of bytes on the line.
856*5e7646d2SAndroid Build Coastguard Worker *
857*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
858*5e7646d2SAndroid Build Coastguard Worker */
859*5e7646d2SAndroid Build Coastguard Worker
860*5e7646d2SAndroid Build Coastguard Worker size_t /* O - Number of bytes on line or 0 on end of file */
cupsFileGetLine(cups_file_t * fp,char * buf,size_t buflen)861*5e7646d2SAndroid Build Coastguard Worker cupsFileGetLine(cups_file_t *fp, /* I - File to read from */
862*5e7646d2SAndroid Build Coastguard Worker char *buf, /* I - Buffer */
863*5e7646d2SAndroid Build Coastguard Worker size_t buflen) /* I - Size of buffer */
864*5e7646d2SAndroid Build Coastguard Worker {
865*5e7646d2SAndroid Build Coastguard Worker int ch; /* Character from file */
866*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Current position in line buffer */
867*5e7646d2SAndroid Build Coastguard Worker *end; /* End of line buffer */
868*5e7646d2SAndroid Build Coastguard Worker
869*5e7646d2SAndroid Build Coastguard Worker
870*5e7646d2SAndroid Build Coastguard Worker /*
871*5e7646d2SAndroid Build Coastguard Worker * Range check input...
872*5e7646d2SAndroid Build Coastguard Worker */
873*5e7646d2SAndroid Build Coastguard Worker
874*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileGetLine(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST buflen));
875*5e7646d2SAndroid Build Coastguard Worker
876*5e7646d2SAndroid Build Coastguard Worker if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 3)
877*5e7646d2SAndroid Build Coastguard Worker return (0);
878*5e7646d2SAndroid Build Coastguard Worker
879*5e7646d2SAndroid Build Coastguard Worker /*
880*5e7646d2SAndroid Build Coastguard Worker * Now loop until we have a valid line...
881*5e7646d2SAndroid Build Coastguard Worker */
882*5e7646d2SAndroid Build Coastguard Worker
883*5e7646d2SAndroid Build Coastguard Worker for (ptr = buf, end = buf + buflen - 2; ptr < end ;)
884*5e7646d2SAndroid Build Coastguard Worker {
885*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
886*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
887*5e7646d2SAndroid Build Coastguard Worker break;
888*5e7646d2SAndroid Build Coastguard Worker
889*5e7646d2SAndroid Build Coastguard Worker *ptr++ = ch = *(fp->ptr)++;
890*5e7646d2SAndroid Build Coastguard Worker fp->pos ++;
891*5e7646d2SAndroid Build Coastguard Worker
892*5e7646d2SAndroid Build Coastguard Worker if (ch == '\r')
893*5e7646d2SAndroid Build Coastguard Worker {
894*5e7646d2SAndroid Build Coastguard Worker /*
895*5e7646d2SAndroid Build Coastguard Worker * Check for CR LF...
896*5e7646d2SAndroid Build Coastguard Worker */
897*5e7646d2SAndroid Build Coastguard Worker
898*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
899*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
900*5e7646d2SAndroid Build Coastguard Worker break;
901*5e7646d2SAndroid Build Coastguard Worker
902*5e7646d2SAndroid Build Coastguard Worker if (*(fp->ptr) == '\n')
903*5e7646d2SAndroid Build Coastguard Worker {
904*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *(fp->ptr)++;
905*5e7646d2SAndroid Build Coastguard Worker fp->pos ++;
906*5e7646d2SAndroid Build Coastguard Worker }
907*5e7646d2SAndroid Build Coastguard Worker
908*5e7646d2SAndroid Build Coastguard Worker break;
909*5e7646d2SAndroid Build Coastguard Worker }
910*5e7646d2SAndroid Build Coastguard Worker else if (ch == '\n')
911*5e7646d2SAndroid Build Coastguard Worker {
912*5e7646d2SAndroid Build Coastguard Worker /*
913*5e7646d2SAndroid Build Coastguard Worker * Line feed ends a line...
914*5e7646d2SAndroid Build Coastguard Worker */
915*5e7646d2SAndroid Build Coastguard Worker
916*5e7646d2SAndroid Build Coastguard Worker break;
917*5e7646d2SAndroid Build Coastguard Worker }
918*5e7646d2SAndroid Build Coastguard Worker }
919*5e7646d2SAndroid Build Coastguard Worker
920*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
921*5e7646d2SAndroid Build Coastguard Worker
922*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileGetLine: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
923*5e7646d2SAndroid Build Coastguard Worker
924*5e7646d2SAndroid Build Coastguard Worker return ((size_t)(ptr - buf));
925*5e7646d2SAndroid Build Coastguard Worker }
926*5e7646d2SAndroid Build Coastguard Worker
927*5e7646d2SAndroid Build Coastguard Worker
928*5e7646d2SAndroid Build Coastguard Worker /*
929*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileGets()' - Get a CR and/or LF-terminated line.
930*5e7646d2SAndroid Build Coastguard Worker *
931*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
932*5e7646d2SAndroid Build Coastguard Worker */
933*5e7646d2SAndroid Build Coastguard Worker
934*5e7646d2SAndroid Build Coastguard Worker char * /* O - Line read or @code NULL@ on end of file or error */
cupsFileGets(cups_file_t * fp,char * buf,size_t buflen)935*5e7646d2SAndroid Build Coastguard Worker cupsFileGets(cups_file_t *fp, /* I - CUPS file */
936*5e7646d2SAndroid Build Coastguard Worker char *buf, /* O - String buffer */
937*5e7646d2SAndroid Build Coastguard Worker size_t buflen) /* I - Size of string buffer */
938*5e7646d2SAndroid Build Coastguard Worker {
939*5e7646d2SAndroid Build Coastguard Worker int ch; /* Character from file */
940*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Current position in line buffer */
941*5e7646d2SAndroid Build Coastguard Worker *end; /* End of line buffer */
942*5e7646d2SAndroid Build Coastguard Worker
943*5e7646d2SAndroid Build Coastguard Worker
944*5e7646d2SAndroid Build Coastguard Worker /*
945*5e7646d2SAndroid Build Coastguard Worker * Range check input...
946*5e7646d2SAndroid Build Coastguard Worker */
947*5e7646d2SAndroid Build Coastguard Worker
948*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileGets(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST buflen));
949*5e7646d2SAndroid Build Coastguard Worker
950*5e7646d2SAndroid Build Coastguard Worker if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 2)
951*5e7646d2SAndroid Build Coastguard Worker return (NULL);
952*5e7646d2SAndroid Build Coastguard Worker
953*5e7646d2SAndroid Build Coastguard Worker /*
954*5e7646d2SAndroid Build Coastguard Worker * Now loop until we have a valid line...
955*5e7646d2SAndroid Build Coastguard Worker */
956*5e7646d2SAndroid Build Coastguard Worker
957*5e7646d2SAndroid Build Coastguard Worker for (ptr = buf, end = buf + buflen - 1; ptr < end ;)
958*5e7646d2SAndroid Build Coastguard Worker {
959*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
960*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
961*5e7646d2SAndroid Build Coastguard Worker {
962*5e7646d2SAndroid Build Coastguard Worker if (ptr == buf)
963*5e7646d2SAndroid Build Coastguard Worker return (NULL);
964*5e7646d2SAndroid Build Coastguard Worker else
965*5e7646d2SAndroid Build Coastguard Worker break;
966*5e7646d2SAndroid Build Coastguard Worker }
967*5e7646d2SAndroid Build Coastguard Worker
968*5e7646d2SAndroid Build Coastguard Worker ch = *(fp->ptr)++;
969*5e7646d2SAndroid Build Coastguard Worker fp->pos ++;
970*5e7646d2SAndroid Build Coastguard Worker
971*5e7646d2SAndroid Build Coastguard Worker if (ch == '\r')
972*5e7646d2SAndroid Build Coastguard Worker {
973*5e7646d2SAndroid Build Coastguard Worker /*
974*5e7646d2SAndroid Build Coastguard Worker * Check for CR LF...
975*5e7646d2SAndroid Build Coastguard Worker */
976*5e7646d2SAndroid Build Coastguard Worker
977*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
978*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
979*5e7646d2SAndroid Build Coastguard Worker break;
980*5e7646d2SAndroid Build Coastguard Worker
981*5e7646d2SAndroid Build Coastguard Worker if (*(fp->ptr) == '\n')
982*5e7646d2SAndroid Build Coastguard Worker {
983*5e7646d2SAndroid Build Coastguard Worker fp->ptr ++;
984*5e7646d2SAndroid Build Coastguard Worker fp->pos ++;
985*5e7646d2SAndroid Build Coastguard Worker }
986*5e7646d2SAndroid Build Coastguard Worker
987*5e7646d2SAndroid Build Coastguard Worker break;
988*5e7646d2SAndroid Build Coastguard Worker }
989*5e7646d2SAndroid Build Coastguard Worker else if (ch == '\n')
990*5e7646d2SAndroid Build Coastguard Worker {
991*5e7646d2SAndroid Build Coastguard Worker /*
992*5e7646d2SAndroid Build Coastguard Worker * Line feed ends a line...
993*5e7646d2SAndroid Build Coastguard Worker */
994*5e7646d2SAndroid Build Coastguard Worker
995*5e7646d2SAndroid Build Coastguard Worker break;
996*5e7646d2SAndroid Build Coastguard Worker }
997*5e7646d2SAndroid Build Coastguard Worker else
998*5e7646d2SAndroid Build Coastguard Worker *ptr++ = (char)ch;
999*5e7646d2SAndroid Build Coastguard Worker }
1000*5e7646d2SAndroid Build Coastguard Worker
1001*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
1002*5e7646d2SAndroid Build Coastguard Worker
1003*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileGets: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1004*5e7646d2SAndroid Build Coastguard Worker
1005*5e7646d2SAndroid Build Coastguard Worker return (buf);
1006*5e7646d2SAndroid Build Coastguard Worker }
1007*5e7646d2SAndroid Build Coastguard Worker
1008*5e7646d2SAndroid Build Coastguard Worker
1009*5e7646d2SAndroid Build Coastguard Worker /*
1010*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileLock()' - Temporarily lock access to a file.
1011*5e7646d2SAndroid Build Coastguard Worker *
1012*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1013*5e7646d2SAndroid Build Coastguard Worker */
1014*5e7646d2SAndroid Build Coastguard Worker
1015*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on error */
cupsFileLock(cups_file_t * fp,int block)1016*5e7646d2SAndroid Build Coastguard Worker cupsFileLock(cups_file_t *fp, /* I - CUPS file */
1017*5e7646d2SAndroid Build Coastguard Worker int block) /* I - 1 to wait for the lock, 0 to fail right away */
1018*5e7646d2SAndroid Build Coastguard Worker {
1019*5e7646d2SAndroid Build Coastguard Worker /*
1020*5e7646d2SAndroid Build Coastguard Worker * Range check...
1021*5e7646d2SAndroid Build Coastguard Worker */
1022*5e7646d2SAndroid Build Coastguard Worker
1023*5e7646d2SAndroid Build Coastguard Worker if (!fp || fp->mode == 's')
1024*5e7646d2SAndroid Build Coastguard Worker return (-1);
1025*5e7646d2SAndroid Build Coastguard Worker
1026*5e7646d2SAndroid Build Coastguard Worker /*
1027*5e7646d2SAndroid Build Coastguard Worker * Try the lock...
1028*5e7646d2SAndroid Build Coastguard Worker */
1029*5e7646d2SAndroid Build Coastguard Worker
1030*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
1031*5e7646d2SAndroid Build Coastguard Worker return (_locking(fp->fd, block ? _LK_LOCK : _LK_NBLCK, 0));
1032*5e7646d2SAndroid Build Coastguard Worker #else
1033*5e7646d2SAndroid Build Coastguard Worker return (lockf(fp->fd, block ? F_LOCK : F_TLOCK, 0));
1034*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
1035*5e7646d2SAndroid Build Coastguard Worker }
1036*5e7646d2SAndroid Build Coastguard Worker
1037*5e7646d2SAndroid Build Coastguard Worker
1038*5e7646d2SAndroid Build Coastguard Worker /*
1039*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileNumber()' - Return the file descriptor associated with a CUPS file.
1040*5e7646d2SAndroid Build Coastguard Worker *
1041*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1042*5e7646d2SAndroid Build Coastguard Worker */
1043*5e7646d2SAndroid Build Coastguard Worker
1044*5e7646d2SAndroid Build Coastguard Worker int /* O - File descriptor */
cupsFileNumber(cups_file_t * fp)1045*5e7646d2SAndroid Build Coastguard Worker cupsFileNumber(cups_file_t *fp) /* I - CUPS file */
1046*5e7646d2SAndroid Build Coastguard Worker {
1047*5e7646d2SAndroid Build Coastguard Worker if (fp)
1048*5e7646d2SAndroid Build Coastguard Worker return (fp->fd);
1049*5e7646d2SAndroid Build Coastguard Worker else
1050*5e7646d2SAndroid Build Coastguard Worker return (-1);
1051*5e7646d2SAndroid Build Coastguard Worker }
1052*5e7646d2SAndroid Build Coastguard Worker
1053*5e7646d2SAndroid Build Coastguard Worker
1054*5e7646d2SAndroid Build Coastguard Worker /*
1055*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileOpen()' - Open a CUPS file.
1056*5e7646d2SAndroid Build Coastguard Worker *
1057*5e7646d2SAndroid Build Coastguard Worker * The "mode" parameter can be "r" to read, "w" to write, overwriting any
1058*5e7646d2SAndroid Build Coastguard Worker * existing file, "a" to append to an existing file or create a new file,
1059*5e7646d2SAndroid Build Coastguard Worker * or "s" to open a socket connection.
1060*5e7646d2SAndroid Build Coastguard Worker *
1061*5e7646d2SAndroid Build Coastguard Worker * When opening for writing ("w"), an optional number from 1 to 9 can be
1062*5e7646d2SAndroid Build Coastguard Worker * supplied which enables Flate compression of the file. Compression is
1063*5e7646d2SAndroid Build Coastguard Worker * not supported for the "a" (append) mode.
1064*5e7646d2SAndroid Build Coastguard Worker *
1065*5e7646d2SAndroid Build Coastguard Worker * When opening a socket connection, the filename is a string of the form
1066*5e7646d2SAndroid Build Coastguard Worker * "address:port" or "hostname:port". The socket will make an IPv4 or IPv6
1067*5e7646d2SAndroid Build Coastguard Worker * connection as needed, generally preferring IPv6 connections when there is
1068*5e7646d2SAndroid Build Coastguard Worker * a choice.
1069*5e7646d2SAndroid Build Coastguard Worker *
1070*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1071*5e7646d2SAndroid Build Coastguard Worker */
1072*5e7646d2SAndroid Build Coastguard Worker
1073*5e7646d2SAndroid Build Coastguard Worker cups_file_t * /* O - CUPS file or @code NULL@ if the file or socket cannot be opened */
cupsFileOpen(const char * filename,const char * mode)1074*5e7646d2SAndroid Build Coastguard Worker cupsFileOpen(const char *filename, /* I - Name of file */
1075*5e7646d2SAndroid Build Coastguard Worker const char *mode) /* I - Open mode */
1076*5e7646d2SAndroid Build Coastguard Worker {
1077*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* New CUPS file */
1078*5e7646d2SAndroid Build Coastguard Worker int fd; /* File descriptor */
1079*5e7646d2SAndroid Build Coastguard Worker char hostname[1024], /* Hostname */
1080*5e7646d2SAndroid Build Coastguard Worker *portname; /* Port "name" (number or service) */
1081*5e7646d2SAndroid Build Coastguard Worker http_addrlist_t *addrlist; /* Host address list */
1082*5e7646d2SAndroid Build Coastguard Worker
1083*5e7646d2SAndroid Build Coastguard Worker
1084*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileOpen(filename=\"%s\", mode=\"%s\")", filename,
1085*5e7646d2SAndroid Build Coastguard Worker mode));
1086*5e7646d2SAndroid Build Coastguard Worker
1087*5e7646d2SAndroid Build Coastguard Worker /*
1088*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1089*5e7646d2SAndroid Build Coastguard Worker */
1090*5e7646d2SAndroid Build Coastguard Worker
1091*5e7646d2SAndroid Build Coastguard Worker if (!filename || !mode ||
1092*5e7646d2SAndroid Build Coastguard Worker (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's') ||
1093*5e7646d2SAndroid Build Coastguard Worker (*mode == 'a' && isdigit(mode[1] & 255)))
1094*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1095*5e7646d2SAndroid Build Coastguard Worker
1096*5e7646d2SAndroid Build Coastguard Worker /*
1097*5e7646d2SAndroid Build Coastguard Worker * Open the file...
1098*5e7646d2SAndroid Build Coastguard Worker */
1099*5e7646d2SAndroid Build Coastguard Worker
1100*5e7646d2SAndroid Build Coastguard Worker switch (*mode)
1101*5e7646d2SAndroid Build Coastguard Worker {
1102*5e7646d2SAndroid Build Coastguard Worker case 'a' : /* Append file */
1103*5e7646d2SAndroid Build Coastguard Worker fd = cups_open(filename,
1104*5e7646d2SAndroid Build Coastguard Worker O_RDWR | O_CREAT | O_APPEND | O_LARGEFILE | O_BINARY);
1105*5e7646d2SAndroid Build Coastguard Worker break;
1106*5e7646d2SAndroid Build Coastguard Worker
1107*5e7646d2SAndroid Build Coastguard Worker case 'r' : /* Read file */
1108*5e7646d2SAndroid Build Coastguard Worker fd = open(filename, O_RDONLY | O_LARGEFILE | O_BINARY, 0);
1109*5e7646d2SAndroid Build Coastguard Worker break;
1110*5e7646d2SAndroid Build Coastguard Worker
1111*5e7646d2SAndroid Build Coastguard Worker case 'w' : /* Write file */
1112*5e7646d2SAndroid Build Coastguard Worker fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY);
1113*5e7646d2SAndroid Build Coastguard Worker if (fd < 0 && errno == ENOENT)
1114*5e7646d2SAndroid Build Coastguard Worker {
1115*5e7646d2SAndroid Build Coastguard Worker fd = cups_open(filename,
1116*5e7646d2SAndroid Build Coastguard Worker O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE | O_BINARY);
1117*5e7646d2SAndroid Build Coastguard Worker if (fd < 0 && errno == EEXIST)
1118*5e7646d2SAndroid Build Coastguard Worker fd = cups_open(filename, O_WRONLY | O_LARGEFILE | O_BINARY);
1119*5e7646d2SAndroid Build Coastguard Worker }
1120*5e7646d2SAndroid Build Coastguard Worker
1121*5e7646d2SAndroid Build Coastguard Worker if (fd >= 0)
1122*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
1123*5e7646d2SAndroid Build Coastguard Worker _chsize(fd, 0);
1124*5e7646d2SAndroid Build Coastguard Worker #else
1125*5e7646d2SAndroid Build Coastguard Worker ftruncate(fd, 0);
1126*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
1127*5e7646d2SAndroid Build Coastguard Worker break;
1128*5e7646d2SAndroid Build Coastguard Worker
1129*5e7646d2SAndroid Build Coastguard Worker case 's' : /* Read/write socket */
1130*5e7646d2SAndroid Build Coastguard Worker strlcpy(hostname, filename, sizeof(hostname));
1131*5e7646d2SAndroid Build Coastguard Worker if ((portname = strrchr(hostname, ':')) != NULL)
1132*5e7646d2SAndroid Build Coastguard Worker *portname++ = '\0';
1133*5e7646d2SAndroid Build Coastguard Worker else
1134*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1135*5e7646d2SAndroid Build Coastguard Worker
1136*5e7646d2SAndroid Build Coastguard Worker /*
1137*5e7646d2SAndroid Build Coastguard Worker * Lookup the hostname and service...
1138*5e7646d2SAndroid Build Coastguard Worker */
1139*5e7646d2SAndroid Build Coastguard Worker
1140*5e7646d2SAndroid Build Coastguard Worker if ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL)
1141*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1142*5e7646d2SAndroid Build Coastguard Worker
1143*5e7646d2SAndroid Build Coastguard Worker /*
1144*5e7646d2SAndroid Build Coastguard Worker * Connect to the server...
1145*5e7646d2SAndroid Build Coastguard Worker */
1146*5e7646d2SAndroid Build Coastguard Worker
1147*5e7646d2SAndroid Build Coastguard Worker if (!httpAddrConnect(addrlist, &fd))
1148*5e7646d2SAndroid Build Coastguard Worker {
1149*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(addrlist);
1150*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1151*5e7646d2SAndroid Build Coastguard Worker }
1152*5e7646d2SAndroid Build Coastguard Worker
1153*5e7646d2SAndroid Build Coastguard Worker httpAddrFreeList(addrlist);
1154*5e7646d2SAndroid Build Coastguard Worker break;
1155*5e7646d2SAndroid Build Coastguard Worker
1156*5e7646d2SAndroid Build Coastguard Worker default : /* Remove bogus compiler warning... */
1157*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1158*5e7646d2SAndroid Build Coastguard Worker }
1159*5e7646d2SAndroid Build Coastguard Worker
1160*5e7646d2SAndroid Build Coastguard Worker if (fd < 0)
1161*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1162*5e7646d2SAndroid Build Coastguard Worker
1163*5e7646d2SAndroid Build Coastguard Worker /*
1164*5e7646d2SAndroid Build Coastguard Worker * Create the CUPS file structure...
1165*5e7646d2SAndroid Build Coastguard Worker */
1166*5e7646d2SAndroid Build Coastguard Worker
1167*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpenFd(fd, mode)) == NULL)
1168*5e7646d2SAndroid Build Coastguard Worker {
1169*5e7646d2SAndroid Build Coastguard Worker if (*mode == 's')
1170*5e7646d2SAndroid Build Coastguard Worker httpAddrClose(NULL, fd);
1171*5e7646d2SAndroid Build Coastguard Worker else
1172*5e7646d2SAndroid Build Coastguard Worker close(fd);
1173*5e7646d2SAndroid Build Coastguard Worker }
1174*5e7646d2SAndroid Build Coastguard Worker
1175*5e7646d2SAndroid Build Coastguard Worker /*
1176*5e7646d2SAndroid Build Coastguard Worker * Return it...
1177*5e7646d2SAndroid Build Coastguard Worker */
1178*5e7646d2SAndroid Build Coastguard Worker
1179*5e7646d2SAndroid Build Coastguard Worker return (fp);
1180*5e7646d2SAndroid Build Coastguard Worker }
1181*5e7646d2SAndroid Build Coastguard Worker
1182*5e7646d2SAndroid Build Coastguard Worker /*
1183*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileOpenFd()' - Open a CUPS file using a file descriptor.
1184*5e7646d2SAndroid Build Coastguard Worker *
1185*5e7646d2SAndroid Build Coastguard Worker * The "mode" parameter can be "r" to read, "w" to write, "a" to append,
1186*5e7646d2SAndroid Build Coastguard Worker * or "s" to treat the file descriptor as a bidirectional socket connection.
1187*5e7646d2SAndroid Build Coastguard Worker *
1188*5e7646d2SAndroid Build Coastguard Worker * When opening for writing ("w"), an optional number from 1 to 9 can be
1189*5e7646d2SAndroid Build Coastguard Worker * supplied which enables Flate compression of the file. Compression is
1190*5e7646d2SAndroid Build Coastguard Worker * not supported for the "a" (append) mode.
1191*5e7646d2SAndroid Build Coastguard Worker *
1192*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1193*5e7646d2SAndroid Build Coastguard Worker */
1194*5e7646d2SAndroid Build Coastguard Worker
1195*5e7646d2SAndroid Build Coastguard Worker cups_file_t * /* O - CUPS file or @code NULL@ if the file could not be opened */
cupsFileOpenFd(int fd,const char * mode)1196*5e7646d2SAndroid Build Coastguard Worker cupsFileOpenFd(int fd, /* I - File descriptor */
1197*5e7646d2SAndroid Build Coastguard Worker const char *mode) /* I - Open mode */
1198*5e7646d2SAndroid Build Coastguard Worker {
1199*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* New CUPS file */
1200*5e7646d2SAndroid Build Coastguard Worker
1201*5e7646d2SAndroid Build Coastguard Worker
1202*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileOpenFd(fd=%d, mode=\"%s\")", fd, mode));
1203*5e7646d2SAndroid Build Coastguard Worker
1204*5e7646d2SAndroid Build Coastguard Worker /*
1205*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1206*5e7646d2SAndroid Build Coastguard Worker */
1207*5e7646d2SAndroid Build Coastguard Worker
1208*5e7646d2SAndroid Build Coastguard Worker if (fd < 0 || !mode ||
1209*5e7646d2SAndroid Build Coastguard Worker (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's') ||
1210*5e7646d2SAndroid Build Coastguard Worker (*mode == 'a' && isdigit(mode[1] & 255)))
1211*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1212*5e7646d2SAndroid Build Coastguard Worker
1213*5e7646d2SAndroid Build Coastguard Worker /*
1214*5e7646d2SAndroid Build Coastguard Worker * Allocate memory...
1215*5e7646d2SAndroid Build Coastguard Worker */
1216*5e7646d2SAndroid Build Coastguard Worker
1217*5e7646d2SAndroid Build Coastguard Worker if ((fp = calloc(1, sizeof(cups_file_t))) == NULL)
1218*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1219*5e7646d2SAndroid Build Coastguard Worker
1220*5e7646d2SAndroid Build Coastguard Worker /*
1221*5e7646d2SAndroid Build Coastguard Worker * Open the file...
1222*5e7646d2SAndroid Build Coastguard Worker */
1223*5e7646d2SAndroid Build Coastguard Worker
1224*5e7646d2SAndroid Build Coastguard Worker fp->fd = fd;
1225*5e7646d2SAndroid Build Coastguard Worker
1226*5e7646d2SAndroid Build Coastguard Worker switch (*mode)
1227*5e7646d2SAndroid Build Coastguard Worker {
1228*5e7646d2SAndroid Build Coastguard Worker case 'a' :
1229*5e7646d2SAndroid Build Coastguard Worker fp->pos = lseek(fd, 0, SEEK_END);
1230*5e7646d2SAndroid Build Coastguard Worker
1231*5e7646d2SAndroid Build Coastguard Worker case 'w' :
1232*5e7646d2SAndroid Build Coastguard Worker fp->mode = 'w';
1233*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
1234*5e7646d2SAndroid Build Coastguard Worker fp->end = fp->buf + sizeof(fp->buf);
1235*5e7646d2SAndroid Build Coastguard Worker
1236*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1237*5e7646d2SAndroid Build Coastguard Worker if (mode[1] >= '1' && mode[1] <= '9')
1238*5e7646d2SAndroid Build Coastguard Worker {
1239*5e7646d2SAndroid Build Coastguard Worker /*
1240*5e7646d2SAndroid Build Coastguard Worker * Open a compressed stream, so write the standard gzip file
1241*5e7646d2SAndroid Build Coastguard Worker * header...
1242*5e7646d2SAndroid Build Coastguard Worker */
1243*5e7646d2SAndroid Build Coastguard Worker
1244*5e7646d2SAndroid Build Coastguard Worker unsigned char header[10]; /* gzip file header */
1245*5e7646d2SAndroid Build Coastguard Worker time_t curtime; /* Current time */
1246*5e7646d2SAndroid Build Coastguard Worker
1247*5e7646d2SAndroid Build Coastguard Worker
1248*5e7646d2SAndroid Build Coastguard Worker curtime = time(NULL);
1249*5e7646d2SAndroid Build Coastguard Worker header[0] = 0x1f;
1250*5e7646d2SAndroid Build Coastguard Worker header[1] = 0x8b;
1251*5e7646d2SAndroid Build Coastguard Worker header[2] = Z_DEFLATED;
1252*5e7646d2SAndroid Build Coastguard Worker header[3] = 0;
1253*5e7646d2SAndroid Build Coastguard Worker header[4] = (unsigned char)curtime;
1254*5e7646d2SAndroid Build Coastguard Worker header[5] = (unsigned char)(curtime >> 8);
1255*5e7646d2SAndroid Build Coastguard Worker header[6] = (unsigned char)(curtime >> 16);
1256*5e7646d2SAndroid Build Coastguard Worker header[7] = (unsigned char)(curtime >> 24);
1257*5e7646d2SAndroid Build Coastguard Worker header[8] = 0;
1258*5e7646d2SAndroid Build Coastguard Worker header[9] = 0x03;
1259*5e7646d2SAndroid Build Coastguard Worker
1260*5e7646d2SAndroid Build Coastguard Worker cups_write(fp, (char *)header, 10);
1261*5e7646d2SAndroid Build Coastguard Worker
1262*5e7646d2SAndroid Build Coastguard Worker /*
1263*5e7646d2SAndroid Build Coastguard Worker * Initialize the compressor...
1264*5e7646d2SAndroid Build Coastguard Worker */
1265*5e7646d2SAndroid Build Coastguard Worker
1266*5e7646d2SAndroid Build Coastguard Worker deflateInit2(&(fp->stream), mode[1] - '0', Z_DEFLATED, -15, 8,
1267*5e7646d2SAndroid Build Coastguard Worker Z_DEFAULT_STRATEGY);
1268*5e7646d2SAndroid Build Coastguard Worker
1269*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_out = fp->cbuf;
1270*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_out = sizeof(fp->cbuf);
1271*5e7646d2SAndroid Build Coastguard Worker fp->compressed = 1;
1272*5e7646d2SAndroid Build Coastguard Worker fp->crc = crc32(0L, Z_NULL, 0);
1273*5e7646d2SAndroid Build Coastguard Worker }
1274*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1275*5e7646d2SAndroid Build Coastguard Worker break;
1276*5e7646d2SAndroid Build Coastguard Worker
1277*5e7646d2SAndroid Build Coastguard Worker case 'r' :
1278*5e7646d2SAndroid Build Coastguard Worker fp->mode = 'r';
1279*5e7646d2SAndroid Build Coastguard Worker break;
1280*5e7646d2SAndroid Build Coastguard Worker
1281*5e7646d2SAndroid Build Coastguard Worker case 's' :
1282*5e7646d2SAndroid Build Coastguard Worker fp->mode = 's';
1283*5e7646d2SAndroid Build Coastguard Worker break;
1284*5e7646d2SAndroid Build Coastguard Worker
1285*5e7646d2SAndroid Build Coastguard Worker default : /* Remove bogus compiler warning... */
1286*5e7646d2SAndroid Build Coastguard Worker return (NULL);
1287*5e7646d2SAndroid Build Coastguard Worker }
1288*5e7646d2SAndroid Build Coastguard Worker
1289*5e7646d2SAndroid Build Coastguard Worker /*
1290*5e7646d2SAndroid Build Coastguard Worker * Don't pass this file to child processes...
1291*5e7646d2SAndroid Build Coastguard Worker */
1292*5e7646d2SAndroid Build Coastguard Worker
1293*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
1294*5e7646d2SAndroid Build Coastguard Worker fcntl(fp->fd, F_SETFD, fcntl(fp->fd, F_GETFD) | FD_CLOEXEC);
1295*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
1296*5e7646d2SAndroid Build Coastguard Worker
1297*5e7646d2SAndroid Build Coastguard Worker return (fp);
1298*5e7646d2SAndroid Build Coastguard Worker }
1299*5e7646d2SAndroid Build Coastguard Worker
1300*5e7646d2SAndroid Build Coastguard Worker
1301*5e7646d2SAndroid Build Coastguard Worker /*
1302*5e7646d2SAndroid Build Coastguard Worker * '_cupsFilePeekAhead()' - See if the requested character is buffered up.
1303*5e7646d2SAndroid Build Coastguard Worker */
1304*5e7646d2SAndroid Build Coastguard Worker
1305*5e7646d2SAndroid Build Coastguard Worker int /* O - 1 if present, 0 otherwise */
_cupsFilePeekAhead(cups_file_t * fp,int ch)1306*5e7646d2SAndroid Build Coastguard Worker _cupsFilePeekAhead(cups_file_t *fp, /* I - CUPS file */
1307*5e7646d2SAndroid Build Coastguard Worker int ch) /* I - Character */
1308*5e7646d2SAndroid Build Coastguard Worker {
1309*5e7646d2SAndroid Build Coastguard Worker return (fp && fp->ptr && memchr(fp->ptr, ch, (size_t)(fp->end - fp->ptr)));
1310*5e7646d2SAndroid Build Coastguard Worker }
1311*5e7646d2SAndroid Build Coastguard Worker
1312*5e7646d2SAndroid Build Coastguard Worker
1313*5e7646d2SAndroid Build Coastguard Worker /*
1314*5e7646d2SAndroid Build Coastguard Worker * 'cupsFilePeekChar()' - Peek at the next character from a file.
1315*5e7646d2SAndroid Build Coastguard Worker *
1316*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1317*5e7646d2SAndroid Build Coastguard Worker */
1318*5e7646d2SAndroid Build Coastguard Worker
1319*5e7646d2SAndroid Build Coastguard Worker int /* O - Character or -1 on end of file */
cupsFilePeekChar(cups_file_t * fp)1320*5e7646d2SAndroid Build Coastguard Worker cupsFilePeekChar(cups_file_t *fp) /* I - CUPS file */
1321*5e7646d2SAndroid Build Coastguard Worker {
1322*5e7646d2SAndroid Build Coastguard Worker /*
1323*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1324*5e7646d2SAndroid Build Coastguard Worker */
1325*5e7646d2SAndroid Build Coastguard Worker
1326*5e7646d2SAndroid Build Coastguard Worker if (!fp || (fp->mode != 'r' && fp->mode != 's'))
1327*5e7646d2SAndroid Build Coastguard Worker return (-1);
1328*5e7646d2SAndroid Build Coastguard Worker
1329*5e7646d2SAndroid Build Coastguard Worker /*
1330*5e7646d2SAndroid Build Coastguard Worker * If the input buffer is empty, try to read more data...
1331*5e7646d2SAndroid Build Coastguard Worker */
1332*5e7646d2SAndroid Build Coastguard Worker
1333*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
1334*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
1335*5e7646d2SAndroid Build Coastguard Worker return (-1);
1336*5e7646d2SAndroid Build Coastguard Worker
1337*5e7646d2SAndroid Build Coastguard Worker /*
1338*5e7646d2SAndroid Build Coastguard Worker * Return the next character in the buffer...
1339*5e7646d2SAndroid Build Coastguard Worker */
1340*5e7646d2SAndroid Build Coastguard Worker
1341*5e7646d2SAndroid Build Coastguard Worker return (*(fp->ptr) & 255);
1342*5e7646d2SAndroid Build Coastguard Worker }
1343*5e7646d2SAndroid Build Coastguard Worker
1344*5e7646d2SAndroid Build Coastguard Worker
1345*5e7646d2SAndroid Build Coastguard Worker /*
1346*5e7646d2SAndroid Build Coastguard Worker * 'cupsFilePrintf()' - Write a formatted string.
1347*5e7646d2SAndroid Build Coastguard Worker *
1348*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1349*5e7646d2SAndroid Build Coastguard Worker */
1350*5e7646d2SAndroid Build Coastguard Worker
1351*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of bytes written or -1 on error */
cupsFilePrintf(cups_file_t * fp,const char * format,...)1352*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(cups_file_t *fp, /* I - CUPS file */
1353*5e7646d2SAndroid Build Coastguard Worker const char *format, /* I - Printf-style format string */
1354*5e7646d2SAndroid Build Coastguard Worker ...) /* I - Additional args as necessary */
1355*5e7646d2SAndroid Build Coastguard Worker {
1356*5e7646d2SAndroid Build Coastguard Worker va_list ap; /* Argument list */
1357*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Formatted size */
1358*5e7646d2SAndroid Build Coastguard Worker
1359*5e7646d2SAndroid Build Coastguard Worker
1360*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFilePrintf(fp=%p, format=\"%s\", ...)", (void *)fp, format));
1361*5e7646d2SAndroid Build Coastguard Worker
1362*5e7646d2SAndroid Build Coastguard Worker if (!fp || !format || (fp->mode != 'w' && fp->mode != 's'))
1363*5e7646d2SAndroid Build Coastguard Worker return (-1);
1364*5e7646d2SAndroid Build Coastguard Worker
1365*5e7646d2SAndroid Build Coastguard Worker if (!fp->printf_buffer)
1366*5e7646d2SAndroid Build Coastguard Worker {
1367*5e7646d2SAndroid Build Coastguard Worker /*
1368*5e7646d2SAndroid Build Coastguard Worker * Start with an 1k printf buffer...
1369*5e7646d2SAndroid Build Coastguard Worker */
1370*5e7646d2SAndroid Build Coastguard Worker
1371*5e7646d2SAndroid Build Coastguard Worker if ((fp->printf_buffer = malloc(1024)) == NULL)
1372*5e7646d2SAndroid Build Coastguard Worker return (-1);
1373*5e7646d2SAndroid Build Coastguard Worker
1374*5e7646d2SAndroid Build Coastguard Worker fp->printf_size = 1024;
1375*5e7646d2SAndroid Build Coastguard Worker }
1376*5e7646d2SAndroid Build Coastguard Worker
1377*5e7646d2SAndroid Build Coastguard Worker va_start(ap, format);
1378*5e7646d2SAndroid Build Coastguard Worker bytes = vsnprintf(fp->printf_buffer, fp->printf_size, format, ap);
1379*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
1380*5e7646d2SAndroid Build Coastguard Worker
1381*5e7646d2SAndroid Build Coastguard Worker if (bytes >= (ssize_t)fp->printf_size)
1382*5e7646d2SAndroid Build Coastguard Worker {
1383*5e7646d2SAndroid Build Coastguard Worker /*
1384*5e7646d2SAndroid Build Coastguard Worker * Expand the printf buffer...
1385*5e7646d2SAndroid Build Coastguard Worker */
1386*5e7646d2SAndroid Build Coastguard Worker
1387*5e7646d2SAndroid Build Coastguard Worker char *temp; /* Temporary buffer pointer */
1388*5e7646d2SAndroid Build Coastguard Worker
1389*5e7646d2SAndroid Build Coastguard Worker
1390*5e7646d2SAndroid Build Coastguard Worker if (bytes > 65535)
1391*5e7646d2SAndroid Build Coastguard Worker return (-1);
1392*5e7646d2SAndroid Build Coastguard Worker
1393*5e7646d2SAndroid Build Coastguard Worker if ((temp = realloc(fp->printf_buffer, (size_t)(bytes + 1))) == NULL)
1394*5e7646d2SAndroid Build Coastguard Worker return (-1);
1395*5e7646d2SAndroid Build Coastguard Worker
1396*5e7646d2SAndroid Build Coastguard Worker fp->printf_buffer = temp;
1397*5e7646d2SAndroid Build Coastguard Worker fp->printf_size = (size_t)(bytes + 1);
1398*5e7646d2SAndroid Build Coastguard Worker
1399*5e7646d2SAndroid Build Coastguard Worker va_start(ap, format);
1400*5e7646d2SAndroid Build Coastguard Worker bytes = vsnprintf(fp->printf_buffer, fp->printf_size, format, ap);
1401*5e7646d2SAndroid Build Coastguard Worker va_end(ap);
1402*5e7646d2SAndroid Build Coastguard Worker }
1403*5e7646d2SAndroid Build Coastguard Worker
1404*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
1405*5e7646d2SAndroid Build Coastguard Worker {
1406*5e7646d2SAndroid Build Coastguard Worker if (cups_write(fp, fp->printf_buffer, (size_t)bytes) < 0)
1407*5e7646d2SAndroid Build Coastguard Worker return (-1);
1408*5e7646d2SAndroid Build Coastguard Worker
1409*5e7646d2SAndroid Build Coastguard Worker fp->pos += bytes;
1410*5e7646d2SAndroid Build Coastguard Worker
1411*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFilePrintf: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1412*5e7646d2SAndroid Build Coastguard Worker
1413*5e7646d2SAndroid Build Coastguard Worker return ((int)bytes);
1414*5e7646d2SAndroid Build Coastguard Worker }
1415*5e7646d2SAndroid Build Coastguard Worker
1416*5e7646d2SAndroid Build Coastguard Worker if ((fp->ptr + bytes) > fp->end)
1417*5e7646d2SAndroid Build Coastguard Worker if (cupsFileFlush(fp))
1418*5e7646d2SAndroid Build Coastguard Worker return (-1);
1419*5e7646d2SAndroid Build Coastguard Worker
1420*5e7646d2SAndroid Build Coastguard Worker fp->pos += bytes;
1421*5e7646d2SAndroid Build Coastguard Worker
1422*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFilePrintf: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1423*5e7646d2SAndroid Build Coastguard Worker
1424*5e7646d2SAndroid Build Coastguard Worker if ((size_t)bytes > sizeof(fp->buf))
1425*5e7646d2SAndroid Build Coastguard Worker {
1426*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1427*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
1428*5e7646d2SAndroid Build Coastguard Worker return ((int)cups_compress(fp, fp->printf_buffer, (size_t)bytes));
1429*5e7646d2SAndroid Build Coastguard Worker else
1430*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1431*5e7646d2SAndroid Build Coastguard Worker return ((int)cups_write(fp, fp->printf_buffer, (size_t)bytes));
1432*5e7646d2SAndroid Build Coastguard Worker }
1433*5e7646d2SAndroid Build Coastguard Worker else
1434*5e7646d2SAndroid Build Coastguard Worker {
1435*5e7646d2SAndroid Build Coastguard Worker memcpy(fp->ptr, fp->printf_buffer, (size_t)bytes);
1436*5e7646d2SAndroid Build Coastguard Worker fp->ptr += bytes;
1437*5e7646d2SAndroid Build Coastguard Worker
1438*5e7646d2SAndroid Build Coastguard Worker if (fp->is_stdio && cupsFileFlush(fp))
1439*5e7646d2SAndroid Build Coastguard Worker return (-1);
1440*5e7646d2SAndroid Build Coastguard Worker else
1441*5e7646d2SAndroid Build Coastguard Worker return ((int)bytes);
1442*5e7646d2SAndroid Build Coastguard Worker }
1443*5e7646d2SAndroid Build Coastguard Worker }
1444*5e7646d2SAndroid Build Coastguard Worker
1445*5e7646d2SAndroid Build Coastguard Worker
1446*5e7646d2SAndroid Build Coastguard Worker /*
1447*5e7646d2SAndroid Build Coastguard Worker * 'cupsFilePutChar()' - Write a character.
1448*5e7646d2SAndroid Build Coastguard Worker *
1449*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1450*5e7646d2SAndroid Build Coastguard Worker */
1451*5e7646d2SAndroid Build Coastguard Worker
1452*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on error */
cupsFilePutChar(cups_file_t * fp,int c)1453*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(cups_file_t *fp, /* I - CUPS file */
1454*5e7646d2SAndroid Build Coastguard Worker int c) /* I - Character to write */
1455*5e7646d2SAndroid Build Coastguard Worker {
1456*5e7646d2SAndroid Build Coastguard Worker /*
1457*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1458*5e7646d2SAndroid Build Coastguard Worker */
1459*5e7646d2SAndroid Build Coastguard Worker
1460*5e7646d2SAndroid Build Coastguard Worker if (!fp || (fp->mode != 'w' && fp->mode != 's'))
1461*5e7646d2SAndroid Build Coastguard Worker return (-1);
1462*5e7646d2SAndroid Build Coastguard Worker
1463*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
1464*5e7646d2SAndroid Build Coastguard Worker {
1465*5e7646d2SAndroid Build Coastguard Worker /*
1466*5e7646d2SAndroid Build Coastguard Worker * Send character immediately over socket...
1467*5e7646d2SAndroid Build Coastguard Worker */
1468*5e7646d2SAndroid Build Coastguard Worker
1469*5e7646d2SAndroid Build Coastguard Worker char ch; /* Output character */
1470*5e7646d2SAndroid Build Coastguard Worker
1471*5e7646d2SAndroid Build Coastguard Worker
1472*5e7646d2SAndroid Build Coastguard Worker ch = (char)c;
1473*5e7646d2SAndroid Build Coastguard Worker
1474*5e7646d2SAndroid Build Coastguard Worker if (send(fp->fd, &ch, 1, 0) < 1)
1475*5e7646d2SAndroid Build Coastguard Worker return (-1);
1476*5e7646d2SAndroid Build Coastguard Worker }
1477*5e7646d2SAndroid Build Coastguard Worker else
1478*5e7646d2SAndroid Build Coastguard Worker {
1479*5e7646d2SAndroid Build Coastguard Worker /*
1480*5e7646d2SAndroid Build Coastguard Worker * Buffer it up...
1481*5e7646d2SAndroid Build Coastguard Worker */
1482*5e7646d2SAndroid Build Coastguard Worker
1483*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
1484*5e7646d2SAndroid Build Coastguard Worker if (cupsFileFlush(fp))
1485*5e7646d2SAndroid Build Coastguard Worker return (-1);
1486*5e7646d2SAndroid Build Coastguard Worker
1487*5e7646d2SAndroid Build Coastguard Worker *(fp->ptr) ++ = (char)c;
1488*5e7646d2SAndroid Build Coastguard Worker }
1489*5e7646d2SAndroid Build Coastguard Worker
1490*5e7646d2SAndroid Build Coastguard Worker fp->pos ++;
1491*5e7646d2SAndroid Build Coastguard Worker
1492*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFilePutChar: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1493*5e7646d2SAndroid Build Coastguard Worker
1494*5e7646d2SAndroid Build Coastguard Worker return (0);
1495*5e7646d2SAndroid Build Coastguard Worker }
1496*5e7646d2SAndroid Build Coastguard Worker
1497*5e7646d2SAndroid Build Coastguard Worker
1498*5e7646d2SAndroid Build Coastguard Worker /*
1499*5e7646d2SAndroid Build Coastguard Worker * 'cupsFilePutConf()' - Write a configuration line.
1500*5e7646d2SAndroid Build Coastguard Worker *
1501*5e7646d2SAndroid Build Coastguard Worker * This function handles any comment escaping of the value.
1502*5e7646d2SAndroid Build Coastguard Worker *
1503*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.4/macOS 10.6@
1504*5e7646d2SAndroid Build Coastguard Worker */
1505*5e7646d2SAndroid Build Coastguard Worker
1506*5e7646d2SAndroid Build Coastguard Worker ssize_t /* O - Number of bytes written or -1 on error */
cupsFilePutConf(cups_file_t * fp,const char * directive,const char * value)1507*5e7646d2SAndroid Build Coastguard Worker cupsFilePutConf(cups_file_t *fp, /* I - CUPS file */
1508*5e7646d2SAndroid Build Coastguard Worker const char *directive, /* I - Directive */
1509*5e7646d2SAndroid Build Coastguard Worker const char *value) /* I - Value */
1510*5e7646d2SAndroid Build Coastguard Worker {
1511*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes, /* Number of bytes written */
1512*5e7646d2SAndroid Build Coastguard Worker temp; /* Temporary byte count */
1513*5e7646d2SAndroid Build Coastguard Worker const char *ptr; /* Pointer into value */
1514*5e7646d2SAndroid Build Coastguard Worker
1515*5e7646d2SAndroid Build Coastguard Worker
1516*5e7646d2SAndroid Build Coastguard Worker if (!fp || !directive || !*directive)
1517*5e7646d2SAndroid Build Coastguard Worker return (-1);
1518*5e7646d2SAndroid Build Coastguard Worker
1519*5e7646d2SAndroid Build Coastguard Worker if ((bytes = cupsFilePuts(fp, directive)) < 0)
1520*5e7646d2SAndroid Build Coastguard Worker return (-1);
1521*5e7646d2SAndroid Build Coastguard Worker
1522*5e7646d2SAndroid Build Coastguard Worker if (cupsFilePutChar(fp, ' ') < 0)
1523*5e7646d2SAndroid Build Coastguard Worker return (-1);
1524*5e7646d2SAndroid Build Coastguard Worker bytes ++;
1525*5e7646d2SAndroid Build Coastguard Worker
1526*5e7646d2SAndroid Build Coastguard Worker if (value && *value)
1527*5e7646d2SAndroid Build Coastguard Worker {
1528*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strchr(value, '#')) != NULL)
1529*5e7646d2SAndroid Build Coastguard Worker {
1530*5e7646d2SAndroid Build Coastguard Worker /*
1531*5e7646d2SAndroid Build Coastguard Worker * Need to quote the first # in the info string...
1532*5e7646d2SAndroid Build Coastguard Worker */
1533*5e7646d2SAndroid Build Coastguard Worker
1534*5e7646d2SAndroid Build Coastguard Worker if ((temp = cupsFileWrite(fp, value, (size_t)(ptr - value))) < 0)
1535*5e7646d2SAndroid Build Coastguard Worker return (-1);
1536*5e7646d2SAndroid Build Coastguard Worker bytes += temp;
1537*5e7646d2SAndroid Build Coastguard Worker
1538*5e7646d2SAndroid Build Coastguard Worker if (cupsFilePutChar(fp, '\\') < 0)
1539*5e7646d2SAndroid Build Coastguard Worker return (-1);
1540*5e7646d2SAndroid Build Coastguard Worker bytes ++;
1541*5e7646d2SAndroid Build Coastguard Worker
1542*5e7646d2SAndroid Build Coastguard Worker if ((temp = cupsFilePuts(fp, ptr)) < 0)
1543*5e7646d2SAndroid Build Coastguard Worker return (-1);
1544*5e7646d2SAndroid Build Coastguard Worker bytes += temp;
1545*5e7646d2SAndroid Build Coastguard Worker }
1546*5e7646d2SAndroid Build Coastguard Worker else if ((temp = cupsFilePuts(fp, value)) < 0)
1547*5e7646d2SAndroid Build Coastguard Worker return (-1);
1548*5e7646d2SAndroid Build Coastguard Worker else
1549*5e7646d2SAndroid Build Coastguard Worker bytes += temp;
1550*5e7646d2SAndroid Build Coastguard Worker }
1551*5e7646d2SAndroid Build Coastguard Worker
1552*5e7646d2SAndroid Build Coastguard Worker if (cupsFilePutChar(fp, '\n') < 0)
1553*5e7646d2SAndroid Build Coastguard Worker return (-1);
1554*5e7646d2SAndroid Build Coastguard Worker else
1555*5e7646d2SAndroid Build Coastguard Worker return (bytes + 1);
1556*5e7646d2SAndroid Build Coastguard Worker }
1557*5e7646d2SAndroid Build Coastguard Worker
1558*5e7646d2SAndroid Build Coastguard Worker
1559*5e7646d2SAndroid Build Coastguard Worker /*
1560*5e7646d2SAndroid Build Coastguard Worker * 'cupsFilePuts()' - Write a string.
1561*5e7646d2SAndroid Build Coastguard Worker *
1562*5e7646d2SAndroid Build Coastguard Worker * Like the @code fputs@ function, no newline is appended to the string.
1563*5e7646d2SAndroid Build Coastguard Worker *
1564*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1565*5e7646d2SAndroid Build Coastguard Worker */
1566*5e7646d2SAndroid Build Coastguard Worker
1567*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of bytes written or -1 on error */
cupsFilePuts(cups_file_t * fp,const char * s)1568*5e7646d2SAndroid Build Coastguard Worker cupsFilePuts(cups_file_t *fp, /* I - CUPS file */
1569*5e7646d2SAndroid Build Coastguard Worker const char *s) /* I - String to write */
1570*5e7646d2SAndroid Build Coastguard Worker {
1571*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Bytes to write */
1572*5e7646d2SAndroid Build Coastguard Worker
1573*5e7646d2SAndroid Build Coastguard Worker
1574*5e7646d2SAndroid Build Coastguard Worker /*
1575*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1576*5e7646d2SAndroid Build Coastguard Worker */
1577*5e7646d2SAndroid Build Coastguard Worker
1578*5e7646d2SAndroid Build Coastguard Worker if (!fp || !s || (fp->mode != 'w' && fp->mode != 's'))
1579*5e7646d2SAndroid Build Coastguard Worker return (-1);
1580*5e7646d2SAndroid Build Coastguard Worker
1581*5e7646d2SAndroid Build Coastguard Worker /*
1582*5e7646d2SAndroid Build Coastguard Worker * Write the string...
1583*5e7646d2SAndroid Build Coastguard Worker */
1584*5e7646d2SAndroid Build Coastguard Worker
1585*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)strlen(s);
1586*5e7646d2SAndroid Build Coastguard Worker
1587*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
1588*5e7646d2SAndroid Build Coastguard Worker {
1589*5e7646d2SAndroid Build Coastguard Worker if (cups_write(fp, s, (size_t)bytes) < 0)
1590*5e7646d2SAndroid Build Coastguard Worker return (-1);
1591*5e7646d2SAndroid Build Coastguard Worker
1592*5e7646d2SAndroid Build Coastguard Worker fp->pos += bytes;
1593*5e7646d2SAndroid Build Coastguard Worker
1594*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFilePuts: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1595*5e7646d2SAndroid Build Coastguard Worker
1596*5e7646d2SAndroid Build Coastguard Worker return ((int)bytes);
1597*5e7646d2SAndroid Build Coastguard Worker }
1598*5e7646d2SAndroid Build Coastguard Worker
1599*5e7646d2SAndroid Build Coastguard Worker if ((fp->ptr + bytes) > fp->end)
1600*5e7646d2SAndroid Build Coastguard Worker if (cupsFileFlush(fp))
1601*5e7646d2SAndroid Build Coastguard Worker return (-1);
1602*5e7646d2SAndroid Build Coastguard Worker
1603*5e7646d2SAndroid Build Coastguard Worker fp->pos += bytes;
1604*5e7646d2SAndroid Build Coastguard Worker
1605*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFilePuts: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1606*5e7646d2SAndroid Build Coastguard Worker
1607*5e7646d2SAndroid Build Coastguard Worker if ((size_t)bytes > sizeof(fp->buf))
1608*5e7646d2SAndroid Build Coastguard Worker {
1609*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1610*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
1611*5e7646d2SAndroid Build Coastguard Worker return ((int)cups_compress(fp, s, (size_t)bytes));
1612*5e7646d2SAndroid Build Coastguard Worker else
1613*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1614*5e7646d2SAndroid Build Coastguard Worker return ((int)cups_write(fp, s, (size_t)bytes));
1615*5e7646d2SAndroid Build Coastguard Worker }
1616*5e7646d2SAndroid Build Coastguard Worker else
1617*5e7646d2SAndroid Build Coastguard Worker {
1618*5e7646d2SAndroid Build Coastguard Worker memcpy(fp->ptr, s, (size_t)bytes);
1619*5e7646d2SAndroid Build Coastguard Worker fp->ptr += bytes;
1620*5e7646d2SAndroid Build Coastguard Worker
1621*5e7646d2SAndroid Build Coastguard Worker if (fp->is_stdio && cupsFileFlush(fp))
1622*5e7646d2SAndroid Build Coastguard Worker return (-1);
1623*5e7646d2SAndroid Build Coastguard Worker else
1624*5e7646d2SAndroid Build Coastguard Worker return ((int)bytes);
1625*5e7646d2SAndroid Build Coastguard Worker }
1626*5e7646d2SAndroid Build Coastguard Worker }
1627*5e7646d2SAndroid Build Coastguard Worker
1628*5e7646d2SAndroid Build Coastguard Worker
1629*5e7646d2SAndroid Build Coastguard Worker /*
1630*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileRead()' - Read from a file.
1631*5e7646d2SAndroid Build Coastguard Worker *
1632*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1633*5e7646d2SAndroid Build Coastguard Worker */
1634*5e7646d2SAndroid Build Coastguard Worker
1635*5e7646d2SAndroid Build Coastguard Worker ssize_t /* O - Number of bytes read or -1 on error */
cupsFileRead(cups_file_t * fp,char * buf,size_t bytes)1636*5e7646d2SAndroid Build Coastguard Worker cupsFileRead(cups_file_t *fp, /* I - CUPS file */
1637*5e7646d2SAndroid Build Coastguard Worker char *buf, /* O - Buffer */
1638*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number of bytes to read */
1639*5e7646d2SAndroid Build Coastguard Worker {
1640*5e7646d2SAndroid Build Coastguard Worker size_t total; /* Total bytes read */
1641*5e7646d2SAndroid Build Coastguard Worker ssize_t count; /* Bytes read */
1642*5e7646d2SAndroid Build Coastguard Worker
1643*5e7646d2SAndroid Build Coastguard Worker
1644*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileRead(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST bytes));
1645*5e7646d2SAndroid Build Coastguard Worker
1646*5e7646d2SAndroid Build Coastguard Worker /*
1647*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1648*5e7646d2SAndroid Build Coastguard Worker */
1649*5e7646d2SAndroid Build Coastguard Worker
1650*5e7646d2SAndroid Build Coastguard Worker if (!fp || !buf || (fp->mode != 'r' && fp->mode != 's'))
1651*5e7646d2SAndroid Build Coastguard Worker return (-1);
1652*5e7646d2SAndroid Build Coastguard Worker
1653*5e7646d2SAndroid Build Coastguard Worker if (bytes == 0)
1654*5e7646d2SAndroid Build Coastguard Worker return (0);
1655*5e7646d2SAndroid Build Coastguard Worker
1656*5e7646d2SAndroid Build Coastguard Worker if (fp->eof)
1657*5e7646d2SAndroid Build Coastguard Worker {
1658*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("5cupsFileRead: End-of-file!");
1659*5e7646d2SAndroid Build Coastguard Worker return (-1);
1660*5e7646d2SAndroid Build Coastguard Worker }
1661*5e7646d2SAndroid Build Coastguard Worker
1662*5e7646d2SAndroid Build Coastguard Worker /*
1663*5e7646d2SAndroid Build Coastguard Worker * Loop until all bytes are read...
1664*5e7646d2SAndroid Build Coastguard Worker */
1665*5e7646d2SAndroid Build Coastguard Worker
1666*5e7646d2SAndroid Build Coastguard Worker total = 0;
1667*5e7646d2SAndroid Build Coastguard Worker while (bytes > 0)
1668*5e7646d2SAndroid Build Coastguard Worker {
1669*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr >= fp->end)
1670*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
1671*5e7646d2SAndroid Build Coastguard Worker {
1672*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileRead: cups_fill() returned -1, total="
1673*5e7646d2SAndroid Build Coastguard Worker CUPS_LLFMT, CUPS_LLCAST total));
1674*5e7646d2SAndroid Build Coastguard Worker
1675*5e7646d2SAndroid Build Coastguard Worker if (total > 0)
1676*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)total);
1677*5e7646d2SAndroid Build Coastguard Worker else
1678*5e7646d2SAndroid Build Coastguard Worker return (-1);
1679*5e7646d2SAndroid Build Coastguard Worker }
1680*5e7646d2SAndroid Build Coastguard Worker
1681*5e7646d2SAndroid Build Coastguard Worker count = (ssize_t)(fp->end - fp->ptr);
1682*5e7646d2SAndroid Build Coastguard Worker if (count > (ssize_t)bytes)
1683*5e7646d2SAndroid Build Coastguard Worker count = (ssize_t)bytes;
1684*5e7646d2SAndroid Build Coastguard Worker
1685*5e7646d2SAndroid Build Coastguard Worker memcpy(buf, fp->ptr,(size_t) count);
1686*5e7646d2SAndroid Build Coastguard Worker fp->ptr += count;
1687*5e7646d2SAndroid Build Coastguard Worker fp->pos += count;
1688*5e7646d2SAndroid Build Coastguard Worker
1689*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileRead: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1690*5e7646d2SAndroid Build Coastguard Worker
1691*5e7646d2SAndroid Build Coastguard Worker /*
1692*5e7646d2SAndroid Build Coastguard Worker * Update the counts for the last read...
1693*5e7646d2SAndroid Build Coastguard Worker */
1694*5e7646d2SAndroid Build Coastguard Worker
1695*5e7646d2SAndroid Build Coastguard Worker bytes -= (size_t)count;
1696*5e7646d2SAndroid Build Coastguard Worker total += (size_t)count;
1697*5e7646d2SAndroid Build Coastguard Worker buf += count;
1698*5e7646d2SAndroid Build Coastguard Worker }
1699*5e7646d2SAndroid Build Coastguard Worker
1700*5e7646d2SAndroid Build Coastguard Worker /*
1701*5e7646d2SAndroid Build Coastguard Worker * Return the total number of bytes read...
1702*5e7646d2SAndroid Build Coastguard Worker */
1703*5e7646d2SAndroid Build Coastguard Worker
1704*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3cupsFileRead: total=" CUPS_LLFMT, CUPS_LLCAST total));
1705*5e7646d2SAndroid Build Coastguard Worker
1706*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)total);
1707*5e7646d2SAndroid Build Coastguard Worker }
1708*5e7646d2SAndroid Build Coastguard Worker
1709*5e7646d2SAndroid Build Coastguard Worker
1710*5e7646d2SAndroid Build Coastguard Worker /*
1711*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileRewind()' - Set the current file position to the beginning of the
1712*5e7646d2SAndroid Build Coastguard Worker * file.
1713*5e7646d2SAndroid Build Coastguard Worker *
1714*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1715*5e7646d2SAndroid Build Coastguard Worker */
1716*5e7646d2SAndroid Build Coastguard Worker
1717*5e7646d2SAndroid Build Coastguard Worker off_t /* O - New file position or -1 on error */
cupsFileRewind(cups_file_t * fp)1718*5e7646d2SAndroid Build Coastguard Worker cupsFileRewind(cups_file_t *fp) /* I - CUPS file */
1719*5e7646d2SAndroid Build Coastguard Worker {
1720*5e7646d2SAndroid Build Coastguard Worker /*
1721*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1722*5e7646d2SAndroid Build Coastguard Worker */
1723*5e7646d2SAndroid Build Coastguard Worker
1724*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileRewind(fp=%p)", (void *)fp));
1725*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileRewind: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1726*5e7646d2SAndroid Build Coastguard Worker
1727*5e7646d2SAndroid Build Coastguard Worker if (!fp || fp->mode != 'r')
1728*5e7646d2SAndroid Build Coastguard Worker return (-1);
1729*5e7646d2SAndroid Build Coastguard Worker
1730*5e7646d2SAndroid Build Coastguard Worker /*
1731*5e7646d2SAndroid Build Coastguard Worker * Handle special cases...
1732*5e7646d2SAndroid Build Coastguard Worker */
1733*5e7646d2SAndroid Build Coastguard Worker
1734*5e7646d2SAndroid Build Coastguard Worker if (fp->bufpos == 0)
1735*5e7646d2SAndroid Build Coastguard Worker {
1736*5e7646d2SAndroid Build Coastguard Worker /*
1737*5e7646d2SAndroid Build Coastguard Worker * No seeking necessary...
1738*5e7646d2SAndroid Build Coastguard Worker */
1739*5e7646d2SAndroid Build Coastguard Worker
1740*5e7646d2SAndroid Build Coastguard Worker fp->pos = 0;
1741*5e7646d2SAndroid Build Coastguard Worker
1742*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr)
1743*5e7646d2SAndroid Build Coastguard Worker {
1744*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
1745*5e7646d2SAndroid Build Coastguard Worker fp->eof = 0;
1746*5e7646d2SAndroid Build Coastguard Worker }
1747*5e7646d2SAndroid Build Coastguard Worker
1748*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileRewind: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1749*5e7646d2SAndroid Build Coastguard Worker
1750*5e7646d2SAndroid Build Coastguard Worker return (0);
1751*5e7646d2SAndroid Build Coastguard Worker }
1752*5e7646d2SAndroid Build Coastguard Worker
1753*5e7646d2SAndroid Build Coastguard Worker /*
1754*5e7646d2SAndroid Build Coastguard Worker * Otherwise, seek in the file and cleanup any compression buffers...
1755*5e7646d2SAndroid Build Coastguard Worker */
1756*5e7646d2SAndroid Build Coastguard Worker
1757*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1758*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
1759*5e7646d2SAndroid Build Coastguard Worker {
1760*5e7646d2SAndroid Build Coastguard Worker inflateEnd(&fp->stream);
1761*5e7646d2SAndroid Build Coastguard Worker fp->compressed = 0;
1762*5e7646d2SAndroid Build Coastguard Worker }
1763*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1764*5e7646d2SAndroid Build Coastguard Worker
1765*5e7646d2SAndroid Build Coastguard Worker if (lseek(fp->fd, 0, SEEK_SET))
1766*5e7646d2SAndroid Build Coastguard Worker {
1767*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("1cupsFileRewind: lseek failed: %s", strerror(errno)));
1768*5e7646d2SAndroid Build Coastguard Worker return (-1);
1769*5e7646d2SAndroid Build Coastguard Worker }
1770*5e7646d2SAndroid Build Coastguard Worker
1771*5e7646d2SAndroid Build Coastguard Worker fp->bufpos = 0;
1772*5e7646d2SAndroid Build Coastguard Worker fp->pos = 0;
1773*5e7646d2SAndroid Build Coastguard Worker fp->ptr = NULL;
1774*5e7646d2SAndroid Build Coastguard Worker fp->end = NULL;
1775*5e7646d2SAndroid Build Coastguard Worker fp->eof = 0;
1776*5e7646d2SAndroid Build Coastguard Worker
1777*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileRewind: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1778*5e7646d2SAndroid Build Coastguard Worker
1779*5e7646d2SAndroid Build Coastguard Worker return (0);
1780*5e7646d2SAndroid Build Coastguard Worker }
1781*5e7646d2SAndroid Build Coastguard Worker
1782*5e7646d2SAndroid Build Coastguard Worker
1783*5e7646d2SAndroid Build Coastguard Worker /*
1784*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileSeek()' - Seek in a file.
1785*5e7646d2SAndroid Build Coastguard Worker *
1786*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1787*5e7646d2SAndroid Build Coastguard Worker */
1788*5e7646d2SAndroid Build Coastguard Worker
1789*5e7646d2SAndroid Build Coastguard Worker off_t /* O - New file position or -1 on error */
cupsFileSeek(cups_file_t * fp,off_t pos)1790*5e7646d2SAndroid Build Coastguard Worker cupsFileSeek(cups_file_t *fp, /* I - CUPS file */
1791*5e7646d2SAndroid Build Coastguard Worker off_t pos) /* I - Position in file */
1792*5e7646d2SAndroid Build Coastguard Worker {
1793*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Number bytes in buffer */
1794*5e7646d2SAndroid Build Coastguard Worker
1795*5e7646d2SAndroid Build Coastguard Worker
1796*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileSeek(fp=%p, pos=" CUPS_LLFMT ")", (void *)fp, CUPS_LLCAST pos));
1797*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileSeek: fp->pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1798*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileSeek: fp->ptr=%p, fp->end=%p", (void *)fp->ptr, (void *)fp->end));
1799*5e7646d2SAndroid Build Coastguard Worker
1800*5e7646d2SAndroid Build Coastguard Worker /*
1801*5e7646d2SAndroid Build Coastguard Worker * Range check input...
1802*5e7646d2SAndroid Build Coastguard Worker */
1803*5e7646d2SAndroid Build Coastguard Worker
1804*5e7646d2SAndroid Build Coastguard Worker if (!fp || pos < 0 || fp->mode != 'r')
1805*5e7646d2SAndroid Build Coastguard Worker return (-1);
1806*5e7646d2SAndroid Build Coastguard Worker
1807*5e7646d2SAndroid Build Coastguard Worker /*
1808*5e7646d2SAndroid Build Coastguard Worker * Handle special cases...
1809*5e7646d2SAndroid Build Coastguard Worker */
1810*5e7646d2SAndroid Build Coastguard Worker
1811*5e7646d2SAndroid Build Coastguard Worker if (pos == 0)
1812*5e7646d2SAndroid Build Coastguard Worker return (cupsFileRewind(fp));
1813*5e7646d2SAndroid Build Coastguard Worker
1814*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr)
1815*5e7646d2SAndroid Build Coastguard Worker {
1816*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)(fp->end - fp->buf);
1817*5e7646d2SAndroid Build Coastguard Worker
1818*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileSeek: bytes=" CUPS_LLFMT, CUPS_LLCAST bytes));
1819*5e7646d2SAndroid Build Coastguard Worker
1820*5e7646d2SAndroid Build Coastguard Worker if (pos >= fp->bufpos && pos < (fp->bufpos + bytes))
1821*5e7646d2SAndroid Build Coastguard Worker {
1822*5e7646d2SAndroid Build Coastguard Worker /*
1823*5e7646d2SAndroid Build Coastguard Worker * No seeking necessary...
1824*5e7646d2SAndroid Build Coastguard Worker */
1825*5e7646d2SAndroid Build Coastguard Worker
1826*5e7646d2SAndroid Build Coastguard Worker fp->pos = pos;
1827*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf + pos - fp->bufpos;
1828*5e7646d2SAndroid Build Coastguard Worker fp->eof = 0;
1829*5e7646d2SAndroid Build Coastguard Worker
1830*5e7646d2SAndroid Build Coastguard Worker return (pos);
1831*5e7646d2SAndroid Build Coastguard Worker }
1832*5e7646d2SAndroid Build Coastguard Worker }
1833*5e7646d2SAndroid Build Coastguard Worker
1834*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1835*5e7646d2SAndroid Build Coastguard Worker if (!fp->compressed && !fp->ptr)
1836*5e7646d2SAndroid Build Coastguard Worker {
1837*5e7646d2SAndroid Build Coastguard Worker /*
1838*5e7646d2SAndroid Build Coastguard Worker * Preload a buffer to determine whether the file is compressed...
1839*5e7646d2SAndroid Build Coastguard Worker */
1840*5e7646d2SAndroid Build Coastguard Worker
1841*5e7646d2SAndroid Build Coastguard Worker if (cups_fill(fp) <= 0)
1842*5e7646d2SAndroid Build Coastguard Worker return (-1);
1843*5e7646d2SAndroid Build Coastguard Worker }
1844*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1845*5e7646d2SAndroid Build Coastguard Worker
1846*5e7646d2SAndroid Build Coastguard Worker /*
1847*5e7646d2SAndroid Build Coastguard Worker * Seek forwards or backwards...
1848*5e7646d2SAndroid Build Coastguard Worker */
1849*5e7646d2SAndroid Build Coastguard Worker
1850*5e7646d2SAndroid Build Coastguard Worker fp->eof = 0;
1851*5e7646d2SAndroid Build Coastguard Worker
1852*5e7646d2SAndroid Build Coastguard Worker if (pos < fp->bufpos)
1853*5e7646d2SAndroid Build Coastguard Worker {
1854*5e7646d2SAndroid Build Coastguard Worker /*
1855*5e7646d2SAndroid Build Coastguard Worker * Need to seek backwards...
1856*5e7646d2SAndroid Build Coastguard Worker */
1857*5e7646d2SAndroid Build Coastguard Worker
1858*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("2cupsFileSeek: SEEK BACKWARDS");
1859*5e7646d2SAndroid Build Coastguard Worker
1860*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1861*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
1862*5e7646d2SAndroid Build Coastguard Worker {
1863*5e7646d2SAndroid Build Coastguard Worker inflateEnd(&fp->stream);
1864*5e7646d2SAndroid Build Coastguard Worker
1865*5e7646d2SAndroid Build Coastguard Worker lseek(fp->fd, 0, SEEK_SET);
1866*5e7646d2SAndroid Build Coastguard Worker fp->bufpos = 0;
1867*5e7646d2SAndroid Build Coastguard Worker fp->pos = 0;
1868*5e7646d2SAndroid Build Coastguard Worker fp->ptr = NULL;
1869*5e7646d2SAndroid Build Coastguard Worker fp->end = NULL;
1870*5e7646d2SAndroid Build Coastguard Worker
1871*5e7646d2SAndroid Build Coastguard Worker while ((bytes = cups_fill(fp)) > 0)
1872*5e7646d2SAndroid Build Coastguard Worker if (pos >= fp->bufpos && pos < (fp->bufpos + bytes))
1873*5e7646d2SAndroid Build Coastguard Worker break;
1874*5e7646d2SAndroid Build Coastguard Worker
1875*5e7646d2SAndroid Build Coastguard Worker if (bytes <= 0)
1876*5e7646d2SAndroid Build Coastguard Worker return (-1);
1877*5e7646d2SAndroid Build Coastguard Worker
1878*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf + pos - fp->bufpos;
1879*5e7646d2SAndroid Build Coastguard Worker fp->pos = pos;
1880*5e7646d2SAndroid Build Coastguard Worker }
1881*5e7646d2SAndroid Build Coastguard Worker else
1882*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1883*5e7646d2SAndroid Build Coastguard Worker {
1884*5e7646d2SAndroid Build Coastguard Worker fp->bufpos = lseek(fp->fd, pos, SEEK_SET);
1885*5e7646d2SAndroid Build Coastguard Worker fp->pos = fp->bufpos;
1886*5e7646d2SAndroid Build Coastguard Worker fp->ptr = NULL;
1887*5e7646d2SAndroid Build Coastguard Worker fp->end = NULL;
1888*5e7646d2SAndroid Build Coastguard Worker
1889*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileSeek: lseek() returned " CUPS_LLFMT,
1890*5e7646d2SAndroid Build Coastguard Worker CUPS_LLCAST fp->pos));
1891*5e7646d2SAndroid Build Coastguard Worker }
1892*5e7646d2SAndroid Build Coastguard Worker }
1893*5e7646d2SAndroid Build Coastguard Worker else
1894*5e7646d2SAndroid Build Coastguard Worker {
1895*5e7646d2SAndroid Build Coastguard Worker /*
1896*5e7646d2SAndroid Build Coastguard Worker * Need to seek forwards...
1897*5e7646d2SAndroid Build Coastguard Worker */
1898*5e7646d2SAndroid Build Coastguard Worker
1899*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("2cupsFileSeek: SEEK FORWARDS");
1900*5e7646d2SAndroid Build Coastguard Worker
1901*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
1902*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
1903*5e7646d2SAndroid Build Coastguard Worker {
1904*5e7646d2SAndroid Build Coastguard Worker while ((bytes = cups_fill(fp)) > 0)
1905*5e7646d2SAndroid Build Coastguard Worker {
1906*5e7646d2SAndroid Build Coastguard Worker if (pos >= fp->bufpos && pos < (fp->bufpos + bytes))
1907*5e7646d2SAndroid Build Coastguard Worker break;
1908*5e7646d2SAndroid Build Coastguard Worker }
1909*5e7646d2SAndroid Build Coastguard Worker
1910*5e7646d2SAndroid Build Coastguard Worker if (bytes <= 0)
1911*5e7646d2SAndroid Build Coastguard Worker return (-1);
1912*5e7646d2SAndroid Build Coastguard Worker
1913*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf + pos - fp->bufpos;
1914*5e7646d2SAndroid Build Coastguard Worker fp->pos = pos;
1915*5e7646d2SAndroid Build Coastguard Worker }
1916*5e7646d2SAndroid Build Coastguard Worker else
1917*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
1918*5e7646d2SAndroid Build Coastguard Worker {
1919*5e7646d2SAndroid Build Coastguard Worker fp->bufpos = lseek(fp->fd, pos, SEEK_SET);
1920*5e7646d2SAndroid Build Coastguard Worker fp->pos = fp->bufpos;
1921*5e7646d2SAndroid Build Coastguard Worker fp->ptr = NULL;
1922*5e7646d2SAndroid Build Coastguard Worker fp->end = NULL;
1923*5e7646d2SAndroid Build Coastguard Worker
1924*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileSeek: lseek() returned " CUPS_LLFMT,
1925*5e7646d2SAndroid Build Coastguard Worker CUPS_LLCAST fp->pos));
1926*5e7646d2SAndroid Build Coastguard Worker }
1927*5e7646d2SAndroid Build Coastguard Worker }
1928*5e7646d2SAndroid Build Coastguard Worker
1929*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileSeek: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
1930*5e7646d2SAndroid Build Coastguard Worker
1931*5e7646d2SAndroid Build Coastguard Worker return (fp->pos);
1932*5e7646d2SAndroid Build Coastguard Worker }
1933*5e7646d2SAndroid Build Coastguard Worker
1934*5e7646d2SAndroid Build Coastguard Worker
1935*5e7646d2SAndroid Build Coastguard Worker /*
1936*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileStderr()' - Return a CUPS file associated with stderr.
1937*5e7646d2SAndroid Build Coastguard Worker *
1938*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1939*5e7646d2SAndroid Build Coastguard Worker */
1940*5e7646d2SAndroid Build Coastguard Worker
1941*5e7646d2SAndroid Build Coastguard Worker cups_file_t * /* O - CUPS file */
cupsFileStderr(void)1942*5e7646d2SAndroid Build Coastguard Worker cupsFileStderr(void)
1943*5e7646d2SAndroid Build Coastguard Worker {
1944*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */
1945*5e7646d2SAndroid Build Coastguard Worker
1946*5e7646d2SAndroid Build Coastguard Worker
1947*5e7646d2SAndroid Build Coastguard Worker /*
1948*5e7646d2SAndroid Build Coastguard Worker * Open file descriptor 2 as needed...
1949*5e7646d2SAndroid Build Coastguard Worker */
1950*5e7646d2SAndroid Build Coastguard Worker
1951*5e7646d2SAndroid Build Coastguard Worker if (!cg->stdio_files[2])
1952*5e7646d2SAndroid Build Coastguard Worker {
1953*5e7646d2SAndroid Build Coastguard Worker /*
1954*5e7646d2SAndroid Build Coastguard Worker * Flush any pending output on the stdio file...
1955*5e7646d2SAndroid Build Coastguard Worker */
1956*5e7646d2SAndroid Build Coastguard Worker
1957*5e7646d2SAndroid Build Coastguard Worker fflush(stderr);
1958*5e7646d2SAndroid Build Coastguard Worker
1959*5e7646d2SAndroid Build Coastguard Worker /*
1960*5e7646d2SAndroid Build Coastguard Worker * Open file descriptor 2...
1961*5e7646d2SAndroid Build Coastguard Worker */
1962*5e7646d2SAndroid Build Coastguard Worker
1963*5e7646d2SAndroid Build Coastguard Worker if ((cg->stdio_files[2] = cupsFileOpenFd(2, "w")) != NULL)
1964*5e7646d2SAndroid Build Coastguard Worker cg->stdio_files[2]->is_stdio = 1;
1965*5e7646d2SAndroid Build Coastguard Worker }
1966*5e7646d2SAndroid Build Coastguard Worker
1967*5e7646d2SAndroid Build Coastguard Worker return (cg->stdio_files[2]);
1968*5e7646d2SAndroid Build Coastguard Worker }
1969*5e7646d2SAndroid Build Coastguard Worker
1970*5e7646d2SAndroid Build Coastguard Worker
1971*5e7646d2SAndroid Build Coastguard Worker /*
1972*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileStdin()' - Return a CUPS file associated with stdin.
1973*5e7646d2SAndroid Build Coastguard Worker *
1974*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
1975*5e7646d2SAndroid Build Coastguard Worker */
1976*5e7646d2SAndroid Build Coastguard Worker
1977*5e7646d2SAndroid Build Coastguard Worker cups_file_t * /* O - CUPS file */
cupsFileStdin(void)1978*5e7646d2SAndroid Build Coastguard Worker cupsFileStdin(void)
1979*5e7646d2SAndroid Build Coastguard Worker {
1980*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */
1981*5e7646d2SAndroid Build Coastguard Worker
1982*5e7646d2SAndroid Build Coastguard Worker
1983*5e7646d2SAndroid Build Coastguard Worker /*
1984*5e7646d2SAndroid Build Coastguard Worker * Open file descriptor 0 as needed...
1985*5e7646d2SAndroid Build Coastguard Worker */
1986*5e7646d2SAndroid Build Coastguard Worker
1987*5e7646d2SAndroid Build Coastguard Worker if (!cg->stdio_files[0])
1988*5e7646d2SAndroid Build Coastguard Worker {
1989*5e7646d2SAndroid Build Coastguard Worker /*
1990*5e7646d2SAndroid Build Coastguard Worker * Open file descriptor 0...
1991*5e7646d2SAndroid Build Coastguard Worker */
1992*5e7646d2SAndroid Build Coastguard Worker
1993*5e7646d2SAndroid Build Coastguard Worker if ((cg->stdio_files[0] = cupsFileOpenFd(0, "r")) != NULL)
1994*5e7646d2SAndroid Build Coastguard Worker cg->stdio_files[0]->is_stdio = 1;
1995*5e7646d2SAndroid Build Coastguard Worker }
1996*5e7646d2SAndroid Build Coastguard Worker
1997*5e7646d2SAndroid Build Coastguard Worker return (cg->stdio_files[0]);
1998*5e7646d2SAndroid Build Coastguard Worker }
1999*5e7646d2SAndroid Build Coastguard Worker
2000*5e7646d2SAndroid Build Coastguard Worker
2001*5e7646d2SAndroid Build Coastguard Worker /*
2002*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileStdout()' - Return a CUPS file associated with stdout.
2003*5e7646d2SAndroid Build Coastguard Worker *
2004*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
2005*5e7646d2SAndroid Build Coastguard Worker */
2006*5e7646d2SAndroid Build Coastguard Worker
2007*5e7646d2SAndroid Build Coastguard Worker cups_file_t * /* O - CUPS file */
cupsFileStdout(void)2008*5e7646d2SAndroid Build Coastguard Worker cupsFileStdout(void)
2009*5e7646d2SAndroid Build Coastguard Worker {
2010*5e7646d2SAndroid Build Coastguard Worker _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals... */
2011*5e7646d2SAndroid Build Coastguard Worker
2012*5e7646d2SAndroid Build Coastguard Worker
2013*5e7646d2SAndroid Build Coastguard Worker /*
2014*5e7646d2SAndroid Build Coastguard Worker * Open file descriptor 1 as needed...
2015*5e7646d2SAndroid Build Coastguard Worker */
2016*5e7646d2SAndroid Build Coastguard Worker
2017*5e7646d2SAndroid Build Coastguard Worker if (!cg->stdio_files[1])
2018*5e7646d2SAndroid Build Coastguard Worker {
2019*5e7646d2SAndroid Build Coastguard Worker /*
2020*5e7646d2SAndroid Build Coastguard Worker * Flush any pending output on the stdio file...
2021*5e7646d2SAndroid Build Coastguard Worker */
2022*5e7646d2SAndroid Build Coastguard Worker
2023*5e7646d2SAndroid Build Coastguard Worker fflush(stdout);
2024*5e7646d2SAndroid Build Coastguard Worker
2025*5e7646d2SAndroid Build Coastguard Worker /*
2026*5e7646d2SAndroid Build Coastguard Worker * Open file descriptor 1...
2027*5e7646d2SAndroid Build Coastguard Worker */
2028*5e7646d2SAndroid Build Coastguard Worker
2029*5e7646d2SAndroid Build Coastguard Worker if ((cg->stdio_files[1] = cupsFileOpenFd(1, "w")) != NULL)
2030*5e7646d2SAndroid Build Coastguard Worker cg->stdio_files[1]->is_stdio = 1;
2031*5e7646d2SAndroid Build Coastguard Worker }
2032*5e7646d2SAndroid Build Coastguard Worker
2033*5e7646d2SAndroid Build Coastguard Worker return (cg->stdio_files[1]);
2034*5e7646d2SAndroid Build Coastguard Worker }
2035*5e7646d2SAndroid Build Coastguard Worker
2036*5e7646d2SAndroid Build Coastguard Worker
2037*5e7646d2SAndroid Build Coastguard Worker /*
2038*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileTell()' - Return the current file position.
2039*5e7646d2SAndroid Build Coastguard Worker *
2040*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
2041*5e7646d2SAndroid Build Coastguard Worker */
2042*5e7646d2SAndroid Build Coastguard Worker
2043*5e7646d2SAndroid Build Coastguard Worker off_t /* O - File position */
cupsFileTell(cups_file_t * fp)2044*5e7646d2SAndroid Build Coastguard Worker cupsFileTell(cups_file_t *fp) /* I - CUPS file */
2045*5e7646d2SAndroid Build Coastguard Worker {
2046*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileTell(fp=%p)", (void *)fp));
2047*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("3cupsFileTell: pos=" CUPS_LLFMT, CUPS_LLCAST (fp ? fp->pos : -1)));
2048*5e7646d2SAndroid Build Coastguard Worker
2049*5e7646d2SAndroid Build Coastguard Worker return (fp ? fp->pos : 0);
2050*5e7646d2SAndroid Build Coastguard Worker }
2051*5e7646d2SAndroid Build Coastguard Worker
2052*5e7646d2SAndroid Build Coastguard Worker
2053*5e7646d2SAndroid Build Coastguard Worker /*
2054*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileUnlock()' - Unlock access to a file.
2055*5e7646d2SAndroid Build Coastguard Worker *
2056*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
2057*5e7646d2SAndroid Build Coastguard Worker */
2058*5e7646d2SAndroid Build Coastguard Worker
2059*5e7646d2SAndroid Build Coastguard Worker int /* O - 0 on success, -1 on error */
cupsFileUnlock(cups_file_t * fp)2060*5e7646d2SAndroid Build Coastguard Worker cupsFileUnlock(cups_file_t *fp) /* I - CUPS file */
2061*5e7646d2SAndroid Build Coastguard Worker {
2062*5e7646d2SAndroid Build Coastguard Worker /*
2063*5e7646d2SAndroid Build Coastguard Worker * Range check...
2064*5e7646d2SAndroid Build Coastguard Worker */
2065*5e7646d2SAndroid Build Coastguard Worker
2066*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("cupsFileUnlock(fp=%p)", (void *)fp));
2067*5e7646d2SAndroid Build Coastguard Worker
2068*5e7646d2SAndroid Build Coastguard Worker if (!fp || fp->mode == 's')
2069*5e7646d2SAndroid Build Coastguard Worker return (-1);
2070*5e7646d2SAndroid Build Coastguard Worker
2071*5e7646d2SAndroid Build Coastguard Worker /*
2072*5e7646d2SAndroid Build Coastguard Worker * Unlock...
2073*5e7646d2SAndroid Build Coastguard Worker */
2074*5e7646d2SAndroid Build Coastguard Worker
2075*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
2076*5e7646d2SAndroid Build Coastguard Worker return (_locking(fp->fd, _LK_UNLCK, 0));
2077*5e7646d2SAndroid Build Coastguard Worker #else
2078*5e7646d2SAndroid Build Coastguard Worker return (lockf(fp->fd, F_ULOCK, 0));
2079*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
2080*5e7646d2SAndroid Build Coastguard Worker }
2081*5e7646d2SAndroid Build Coastguard Worker
2082*5e7646d2SAndroid Build Coastguard Worker
2083*5e7646d2SAndroid Build Coastguard Worker /*
2084*5e7646d2SAndroid Build Coastguard Worker * 'cupsFileWrite()' - Write to a file.
2085*5e7646d2SAndroid Build Coastguard Worker *
2086*5e7646d2SAndroid Build Coastguard Worker * @since CUPS 1.2/macOS 10.5@
2087*5e7646d2SAndroid Build Coastguard Worker */
2088*5e7646d2SAndroid Build Coastguard Worker
2089*5e7646d2SAndroid Build Coastguard Worker ssize_t /* O - Number of bytes written or -1 on error */
cupsFileWrite(cups_file_t * fp,const char * buf,size_t bytes)2090*5e7646d2SAndroid Build Coastguard Worker cupsFileWrite(cups_file_t *fp, /* I - CUPS file */
2091*5e7646d2SAndroid Build Coastguard Worker const char *buf, /* I - Buffer */
2092*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number of bytes to write */
2093*5e7646d2SAndroid Build Coastguard Worker {
2094*5e7646d2SAndroid Build Coastguard Worker /*
2095*5e7646d2SAndroid Build Coastguard Worker * Range check input...
2096*5e7646d2SAndroid Build Coastguard Worker */
2097*5e7646d2SAndroid Build Coastguard Worker
2098*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("2cupsFileWrite(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST bytes));
2099*5e7646d2SAndroid Build Coastguard Worker
2100*5e7646d2SAndroid Build Coastguard Worker if (!fp || !buf || (fp->mode != 'w' && fp->mode != 's'))
2101*5e7646d2SAndroid Build Coastguard Worker return (-1);
2102*5e7646d2SAndroid Build Coastguard Worker
2103*5e7646d2SAndroid Build Coastguard Worker if (bytes == 0)
2104*5e7646d2SAndroid Build Coastguard Worker return (0);
2105*5e7646d2SAndroid Build Coastguard Worker
2106*5e7646d2SAndroid Build Coastguard Worker /*
2107*5e7646d2SAndroid Build Coastguard Worker * Write the buffer...
2108*5e7646d2SAndroid Build Coastguard Worker */
2109*5e7646d2SAndroid Build Coastguard Worker
2110*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
2111*5e7646d2SAndroid Build Coastguard Worker {
2112*5e7646d2SAndroid Build Coastguard Worker if (cups_write(fp, buf, bytes) < 0)
2113*5e7646d2SAndroid Build Coastguard Worker return (-1);
2114*5e7646d2SAndroid Build Coastguard Worker
2115*5e7646d2SAndroid Build Coastguard Worker fp->pos += (off_t)bytes;
2116*5e7646d2SAndroid Build Coastguard Worker
2117*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileWrite: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
2118*5e7646d2SAndroid Build Coastguard Worker
2119*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)bytes);
2120*5e7646d2SAndroid Build Coastguard Worker }
2121*5e7646d2SAndroid Build Coastguard Worker
2122*5e7646d2SAndroid Build Coastguard Worker if ((fp->ptr + bytes) > fp->end)
2123*5e7646d2SAndroid Build Coastguard Worker if (cupsFileFlush(fp))
2124*5e7646d2SAndroid Build Coastguard Worker return (-1);
2125*5e7646d2SAndroid Build Coastguard Worker
2126*5e7646d2SAndroid Build Coastguard Worker fp->pos += (off_t)bytes;
2127*5e7646d2SAndroid Build Coastguard Worker
2128*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("4cupsFileWrite: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos));
2129*5e7646d2SAndroid Build Coastguard Worker
2130*5e7646d2SAndroid Build Coastguard Worker if (bytes > sizeof(fp->buf))
2131*5e7646d2SAndroid Build Coastguard Worker {
2132*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
2133*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
2134*5e7646d2SAndroid Build Coastguard Worker return (cups_compress(fp, buf, bytes));
2135*5e7646d2SAndroid Build Coastguard Worker else
2136*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
2137*5e7646d2SAndroid Build Coastguard Worker return (cups_write(fp, buf, bytes));
2138*5e7646d2SAndroid Build Coastguard Worker }
2139*5e7646d2SAndroid Build Coastguard Worker else
2140*5e7646d2SAndroid Build Coastguard Worker {
2141*5e7646d2SAndroid Build Coastguard Worker memcpy(fp->ptr, buf, bytes);
2142*5e7646d2SAndroid Build Coastguard Worker fp->ptr += bytes;
2143*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)bytes);
2144*5e7646d2SAndroid Build Coastguard Worker }
2145*5e7646d2SAndroid Build Coastguard Worker }
2146*5e7646d2SAndroid Build Coastguard Worker
2147*5e7646d2SAndroid Build Coastguard Worker
2148*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
2149*5e7646d2SAndroid Build Coastguard Worker /*
2150*5e7646d2SAndroid Build Coastguard Worker * 'cups_compress()' - Compress a buffer of data.
2151*5e7646d2SAndroid Build Coastguard Worker */
2152*5e7646d2SAndroid Build Coastguard Worker
2153*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes written or -1 */
cups_compress(cups_file_t * fp,const char * buf,size_t bytes)2154*5e7646d2SAndroid Build Coastguard Worker cups_compress(cups_file_t *fp, /* I - CUPS file */
2155*5e7646d2SAndroid Build Coastguard Worker const char *buf, /* I - Buffer */
2156*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number bytes */
2157*5e7646d2SAndroid Build Coastguard Worker {
2158*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7cups_compress(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST bytes));
2159*5e7646d2SAndroid Build Coastguard Worker
2160*5e7646d2SAndroid Build Coastguard Worker /*
2161*5e7646d2SAndroid Build Coastguard Worker * Update the CRC...
2162*5e7646d2SAndroid Build Coastguard Worker */
2163*5e7646d2SAndroid Build Coastguard Worker
2164*5e7646d2SAndroid Build Coastguard Worker fp->crc = crc32(fp->crc, (const Bytef *)buf, (uInt)bytes);
2165*5e7646d2SAndroid Build Coastguard Worker
2166*5e7646d2SAndroid Build Coastguard Worker /*
2167*5e7646d2SAndroid Build Coastguard Worker * Deflate the bytes...
2168*5e7646d2SAndroid Build Coastguard Worker */
2169*5e7646d2SAndroid Build Coastguard Worker
2170*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_in = (Bytef *)buf;
2171*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_in = (uInt)bytes;
2172*5e7646d2SAndroid Build Coastguard Worker
2173*5e7646d2SAndroid Build Coastguard Worker while (fp->stream.avail_in > 0)
2174*5e7646d2SAndroid Build Coastguard Worker {
2175*5e7646d2SAndroid Build Coastguard Worker /*
2176*5e7646d2SAndroid Build Coastguard Worker * Flush the current buffer...
2177*5e7646d2SAndroid Build Coastguard Worker */
2178*5e7646d2SAndroid Build Coastguard Worker
2179*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_compress: avail_in=%d, avail_out=%d",
2180*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_in, fp->stream.avail_out));
2181*5e7646d2SAndroid Build Coastguard Worker
2182*5e7646d2SAndroid Build Coastguard Worker if (fp->stream.avail_out < (uInt)(sizeof(fp->cbuf) / 8))
2183*5e7646d2SAndroid Build Coastguard Worker {
2184*5e7646d2SAndroid Build Coastguard Worker if (cups_write(fp, (char *)fp->cbuf, (size_t)(fp->stream.next_out - fp->cbuf)) < 0)
2185*5e7646d2SAndroid Build Coastguard Worker return (-1);
2186*5e7646d2SAndroid Build Coastguard Worker
2187*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_out = fp->cbuf;
2188*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_out = sizeof(fp->cbuf);
2189*5e7646d2SAndroid Build Coastguard Worker }
2190*5e7646d2SAndroid Build Coastguard Worker
2191*5e7646d2SAndroid Build Coastguard Worker deflate(&(fp->stream), Z_NO_FLUSH);
2192*5e7646d2SAndroid Build Coastguard Worker }
2193*5e7646d2SAndroid Build Coastguard Worker
2194*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)bytes);
2195*5e7646d2SAndroid Build Coastguard Worker }
2196*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
2197*5e7646d2SAndroid Build Coastguard Worker
2198*5e7646d2SAndroid Build Coastguard Worker
2199*5e7646d2SAndroid Build Coastguard Worker /*
2200*5e7646d2SAndroid Build Coastguard Worker * 'cups_fill()' - Fill the input buffer.
2201*5e7646d2SAndroid Build Coastguard Worker */
2202*5e7646d2SAndroid Build Coastguard Worker
2203*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes or -1 */
cups_fill(cups_file_t * fp)2204*5e7646d2SAndroid Build Coastguard Worker cups_fill(cups_file_t *fp) /* I - CUPS file */
2205*5e7646d2SAndroid Build Coastguard Worker {
2206*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Number of bytes read */
2207*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
2208*5e7646d2SAndroid Build Coastguard Worker int status; /* Decompression status */
2209*5e7646d2SAndroid Build Coastguard Worker const unsigned char *ptr, /* Pointer into buffer */
2210*5e7646d2SAndroid Build Coastguard Worker *end; /* End of buffer */
2211*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
2212*5e7646d2SAndroid Build Coastguard Worker
2213*5e7646d2SAndroid Build Coastguard Worker
2214*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7cups_fill(fp=%p)", (void *)fp));
2215*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: fp->ptr=%p, fp->end=%p, fp->buf=%p, fp->bufpos=" CUPS_LLFMT ", fp->eof=%d", (void *)fp->ptr, (void *)fp->end, (void *)fp->buf, CUPS_LLCAST fp->bufpos, fp->eof));
2216*5e7646d2SAndroid Build Coastguard Worker
2217*5e7646d2SAndroid Build Coastguard Worker if (fp->ptr && fp->end)
2218*5e7646d2SAndroid Build Coastguard Worker fp->bufpos += fp->end - fp->buf;
2219*5e7646d2SAndroid Build Coastguard Worker
2220*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
2221*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: fp->compressed=%d", fp->compressed));
2222*5e7646d2SAndroid Build Coastguard Worker
2223*5e7646d2SAndroid Build Coastguard Worker while (!fp->ptr || fp->compressed)
2224*5e7646d2SAndroid Build Coastguard Worker {
2225*5e7646d2SAndroid Build Coastguard Worker /*
2226*5e7646d2SAndroid Build Coastguard Worker * Check to see if we have read any data yet; if not, see if we have a
2227*5e7646d2SAndroid Build Coastguard Worker * compressed file...
2228*5e7646d2SAndroid Build Coastguard Worker */
2229*5e7646d2SAndroid Build Coastguard Worker
2230*5e7646d2SAndroid Build Coastguard Worker if (!fp->ptr)
2231*5e7646d2SAndroid Build Coastguard Worker {
2232*5e7646d2SAndroid Build Coastguard Worker /*
2233*5e7646d2SAndroid Build Coastguard Worker * Reset the file position in case we are seeking...
2234*5e7646d2SAndroid Build Coastguard Worker */
2235*5e7646d2SAndroid Build Coastguard Worker
2236*5e7646d2SAndroid Build Coastguard Worker fp->compressed = 0;
2237*5e7646d2SAndroid Build Coastguard Worker
2238*5e7646d2SAndroid Build Coastguard Worker /*
2239*5e7646d2SAndroid Build Coastguard Worker * Read the first bytes in the file to determine if we have a gzip'd
2240*5e7646d2SAndroid Build Coastguard Worker * file...
2241*5e7646d2SAndroid Build Coastguard Worker */
2242*5e7646d2SAndroid Build Coastguard Worker
2243*5e7646d2SAndroid Build Coastguard Worker if ((bytes = cups_read(fp, (char *)fp->buf, sizeof(fp->buf))) < 0)
2244*5e7646d2SAndroid Build Coastguard Worker {
2245*5e7646d2SAndroid Build Coastguard Worker /*
2246*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2247*5e7646d2SAndroid Build Coastguard Worker */
2248*5e7646d2SAndroid Build Coastguard Worker
2249*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: cups_read() returned " CUPS_LLFMT,
2250*5e7646d2SAndroid Build Coastguard Worker CUPS_LLCAST bytes));
2251*5e7646d2SAndroid Build Coastguard Worker
2252*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2253*5e7646d2SAndroid Build Coastguard Worker
2254*5e7646d2SAndroid Build Coastguard Worker return (-1);
2255*5e7646d2SAndroid Build Coastguard Worker }
2256*5e7646d2SAndroid Build Coastguard Worker
2257*5e7646d2SAndroid Build Coastguard Worker if (bytes < 10 || fp->buf[0] != 0x1f ||
2258*5e7646d2SAndroid Build Coastguard Worker (fp->buf[1] & 255) != 0x8b ||
2259*5e7646d2SAndroid Build Coastguard Worker fp->buf[2] != 8 || (fp->buf[3] & 0xe0) != 0)
2260*5e7646d2SAndroid Build Coastguard Worker {
2261*5e7646d2SAndroid Build Coastguard Worker /*
2262*5e7646d2SAndroid Build Coastguard Worker * Not a gzip'd file!
2263*5e7646d2SAndroid Build Coastguard Worker */
2264*5e7646d2SAndroid Build Coastguard Worker
2265*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
2266*5e7646d2SAndroid Build Coastguard Worker fp->end = fp->buf + bytes;
2267*5e7646d2SAndroid Build Coastguard Worker
2268*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: Returning " CUPS_LLFMT,
2269*5e7646d2SAndroid Build Coastguard Worker CUPS_LLCAST bytes));
2270*5e7646d2SAndroid Build Coastguard Worker
2271*5e7646d2SAndroid Build Coastguard Worker return (bytes);
2272*5e7646d2SAndroid Build Coastguard Worker }
2273*5e7646d2SAndroid Build Coastguard Worker
2274*5e7646d2SAndroid Build Coastguard Worker /*
2275*5e7646d2SAndroid Build Coastguard Worker * Parse header junk: extra data, original name, and comment...
2276*5e7646d2SAndroid Build Coastguard Worker */
2277*5e7646d2SAndroid Build Coastguard Worker
2278*5e7646d2SAndroid Build Coastguard Worker ptr = (unsigned char *)fp->buf + 10;
2279*5e7646d2SAndroid Build Coastguard Worker end = (unsigned char *)fp->buf + bytes;
2280*5e7646d2SAndroid Build Coastguard Worker
2281*5e7646d2SAndroid Build Coastguard Worker if (fp->buf[3] & 0x04)
2282*5e7646d2SAndroid Build Coastguard Worker {
2283*5e7646d2SAndroid Build Coastguard Worker /*
2284*5e7646d2SAndroid Build Coastguard Worker * Skip extra data...
2285*5e7646d2SAndroid Build Coastguard Worker */
2286*5e7646d2SAndroid Build Coastguard Worker
2287*5e7646d2SAndroid Build Coastguard Worker if ((ptr + 2) > end)
2288*5e7646d2SAndroid Build Coastguard Worker {
2289*5e7646d2SAndroid Build Coastguard Worker /*
2290*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2291*5e7646d2SAndroid Build Coastguard Worker */
2292*5e7646d2SAndroid Build Coastguard Worker
2293*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: Extra gzip header data missing, returning -1.");
2294*5e7646d2SAndroid Build Coastguard Worker
2295*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2296*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2297*5e7646d2SAndroid Build Coastguard Worker
2298*5e7646d2SAndroid Build Coastguard Worker return (-1);
2299*5e7646d2SAndroid Build Coastguard Worker }
2300*5e7646d2SAndroid Build Coastguard Worker
2301*5e7646d2SAndroid Build Coastguard Worker bytes = ((unsigned char)ptr[1] << 8) | (unsigned char)ptr[0];
2302*5e7646d2SAndroid Build Coastguard Worker ptr += 2 + bytes;
2303*5e7646d2SAndroid Build Coastguard Worker
2304*5e7646d2SAndroid Build Coastguard Worker if (ptr > end)
2305*5e7646d2SAndroid Build Coastguard Worker {
2306*5e7646d2SAndroid Build Coastguard Worker /*
2307*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2308*5e7646d2SAndroid Build Coastguard Worker */
2309*5e7646d2SAndroid Build Coastguard Worker
2310*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: Extra gzip header data does not fit in initial buffer, returning -1.");
2311*5e7646d2SAndroid Build Coastguard Worker
2312*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2313*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2314*5e7646d2SAndroid Build Coastguard Worker
2315*5e7646d2SAndroid Build Coastguard Worker return (-1);
2316*5e7646d2SAndroid Build Coastguard Worker }
2317*5e7646d2SAndroid Build Coastguard Worker }
2318*5e7646d2SAndroid Build Coastguard Worker
2319*5e7646d2SAndroid Build Coastguard Worker if (fp->buf[3] & 0x08)
2320*5e7646d2SAndroid Build Coastguard Worker {
2321*5e7646d2SAndroid Build Coastguard Worker /*
2322*5e7646d2SAndroid Build Coastguard Worker * Skip original name data...
2323*5e7646d2SAndroid Build Coastguard Worker */
2324*5e7646d2SAndroid Build Coastguard Worker
2325*5e7646d2SAndroid Build Coastguard Worker while (ptr < end && *ptr)
2326*5e7646d2SAndroid Build Coastguard Worker ptr ++;
2327*5e7646d2SAndroid Build Coastguard Worker
2328*5e7646d2SAndroid Build Coastguard Worker if (ptr < end)
2329*5e7646d2SAndroid Build Coastguard Worker ptr ++;
2330*5e7646d2SAndroid Build Coastguard Worker else
2331*5e7646d2SAndroid Build Coastguard Worker {
2332*5e7646d2SAndroid Build Coastguard Worker /*
2333*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2334*5e7646d2SAndroid Build Coastguard Worker */
2335*5e7646d2SAndroid Build Coastguard Worker
2336*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: Original filename in gzip header data does not fit in initial buffer, returning -1.");
2337*5e7646d2SAndroid Build Coastguard Worker
2338*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2339*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2340*5e7646d2SAndroid Build Coastguard Worker
2341*5e7646d2SAndroid Build Coastguard Worker return (-1);
2342*5e7646d2SAndroid Build Coastguard Worker }
2343*5e7646d2SAndroid Build Coastguard Worker }
2344*5e7646d2SAndroid Build Coastguard Worker
2345*5e7646d2SAndroid Build Coastguard Worker if (fp->buf[3] & 0x10)
2346*5e7646d2SAndroid Build Coastguard Worker {
2347*5e7646d2SAndroid Build Coastguard Worker /*
2348*5e7646d2SAndroid Build Coastguard Worker * Skip comment data...
2349*5e7646d2SAndroid Build Coastguard Worker */
2350*5e7646d2SAndroid Build Coastguard Worker
2351*5e7646d2SAndroid Build Coastguard Worker while (ptr < end && *ptr)
2352*5e7646d2SAndroid Build Coastguard Worker ptr ++;
2353*5e7646d2SAndroid Build Coastguard Worker
2354*5e7646d2SAndroid Build Coastguard Worker if (ptr < end)
2355*5e7646d2SAndroid Build Coastguard Worker ptr ++;
2356*5e7646d2SAndroid Build Coastguard Worker else
2357*5e7646d2SAndroid Build Coastguard Worker {
2358*5e7646d2SAndroid Build Coastguard Worker /*
2359*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2360*5e7646d2SAndroid Build Coastguard Worker */
2361*5e7646d2SAndroid Build Coastguard Worker
2362*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: Comment in gzip header data does not fit in initial buffer, returning -1.");
2363*5e7646d2SAndroid Build Coastguard Worker
2364*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2365*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2366*5e7646d2SAndroid Build Coastguard Worker
2367*5e7646d2SAndroid Build Coastguard Worker return (-1);
2368*5e7646d2SAndroid Build Coastguard Worker }
2369*5e7646d2SAndroid Build Coastguard Worker }
2370*5e7646d2SAndroid Build Coastguard Worker
2371*5e7646d2SAndroid Build Coastguard Worker if (fp->buf[3] & 0x02)
2372*5e7646d2SAndroid Build Coastguard Worker {
2373*5e7646d2SAndroid Build Coastguard Worker /*
2374*5e7646d2SAndroid Build Coastguard Worker * Skip header CRC data...
2375*5e7646d2SAndroid Build Coastguard Worker */
2376*5e7646d2SAndroid Build Coastguard Worker
2377*5e7646d2SAndroid Build Coastguard Worker ptr += 2;
2378*5e7646d2SAndroid Build Coastguard Worker
2379*5e7646d2SAndroid Build Coastguard Worker if (ptr > end)
2380*5e7646d2SAndroid Build Coastguard Worker {
2381*5e7646d2SAndroid Build Coastguard Worker /*
2382*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2383*5e7646d2SAndroid Build Coastguard Worker */
2384*5e7646d2SAndroid Build Coastguard Worker
2385*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: Header CRC in gzip header data does not fit in initial buffer, returning -1.");
2386*5e7646d2SAndroid Build Coastguard Worker
2387*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2388*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2389*5e7646d2SAndroid Build Coastguard Worker
2390*5e7646d2SAndroid Build Coastguard Worker return (-1);
2391*5e7646d2SAndroid Build Coastguard Worker }
2392*5e7646d2SAndroid Build Coastguard Worker }
2393*5e7646d2SAndroid Build Coastguard Worker
2394*5e7646d2SAndroid Build Coastguard Worker /*
2395*5e7646d2SAndroid Build Coastguard Worker * Copy the flate-compressed data to the compression buffer...
2396*5e7646d2SAndroid Build Coastguard Worker */
2397*5e7646d2SAndroid Build Coastguard Worker
2398*5e7646d2SAndroid Build Coastguard Worker if ((bytes = end - ptr) > 0)
2399*5e7646d2SAndroid Build Coastguard Worker memcpy(fp->cbuf, ptr, (size_t)bytes);
2400*5e7646d2SAndroid Build Coastguard Worker
2401*5e7646d2SAndroid Build Coastguard Worker /*
2402*5e7646d2SAndroid Build Coastguard Worker * Setup the decompressor data...
2403*5e7646d2SAndroid Build Coastguard Worker */
2404*5e7646d2SAndroid Build Coastguard Worker
2405*5e7646d2SAndroid Build Coastguard Worker fp->stream.zalloc = (alloc_func)0;
2406*5e7646d2SAndroid Build Coastguard Worker fp->stream.zfree = (free_func)0;
2407*5e7646d2SAndroid Build Coastguard Worker fp->stream.opaque = (voidpf)0;
2408*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_in = (Bytef *)fp->cbuf;
2409*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_out = NULL;
2410*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_in = (uInt)bytes;
2411*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_out = 0;
2412*5e7646d2SAndroid Build Coastguard Worker fp->crc = crc32(0L, Z_NULL, 0);
2413*5e7646d2SAndroid Build Coastguard Worker
2414*5e7646d2SAndroid Build Coastguard Worker if ((status = inflateInit2(&(fp->stream), -15)) != Z_OK)
2415*5e7646d2SAndroid Build Coastguard Worker {
2416*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: inflateInit2 returned %d, returning -1.", status));
2417*5e7646d2SAndroid Build Coastguard Worker
2418*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2419*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2420*5e7646d2SAndroid Build Coastguard Worker
2421*5e7646d2SAndroid Build Coastguard Worker return (-1);
2422*5e7646d2SAndroid Build Coastguard Worker }
2423*5e7646d2SAndroid Build Coastguard Worker
2424*5e7646d2SAndroid Build Coastguard Worker fp->compressed = 1;
2425*5e7646d2SAndroid Build Coastguard Worker }
2426*5e7646d2SAndroid Build Coastguard Worker
2427*5e7646d2SAndroid Build Coastguard Worker if (fp->compressed)
2428*5e7646d2SAndroid Build Coastguard Worker {
2429*5e7646d2SAndroid Build Coastguard Worker /*
2430*5e7646d2SAndroid Build Coastguard Worker * If we have reached end-of-file, return immediately...
2431*5e7646d2SAndroid Build Coastguard Worker */
2432*5e7646d2SAndroid Build Coastguard Worker
2433*5e7646d2SAndroid Build Coastguard Worker if (fp->eof)
2434*5e7646d2SAndroid Build Coastguard Worker {
2435*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: EOF, returning 0.");
2436*5e7646d2SAndroid Build Coastguard Worker
2437*5e7646d2SAndroid Build Coastguard Worker return (0);
2438*5e7646d2SAndroid Build Coastguard Worker }
2439*5e7646d2SAndroid Build Coastguard Worker
2440*5e7646d2SAndroid Build Coastguard Worker /*
2441*5e7646d2SAndroid Build Coastguard Worker * Fill the decompression buffer as needed...
2442*5e7646d2SAndroid Build Coastguard Worker */
2443*5e7646d2SAndroid Build Coastguard Worker
2444*5e7646d2SAndroid Build Coastguard Worker if (fp->stream.avail_in == 0)
2445*5e7646d2SAndroid Build Coastguard Worker {
2446*5e7646d2SAndroid Build Coastguard Worker if ((bytes = cups_read(fp, (char *)fp->cbuf, sizeof(fp->cbuf))) <= 0)
2447*5e7646d2SAndroid Build Coastguard Worker {
2448*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: cups_read error, returning %d.", (int)bytes));
2449*5e7646d2SAndroid Build Coastguard Worker
2450*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2451*5e7646d2SAndroid Build Coastguard Worker
2452*5e7646d2SAndroid Build Coastguard Worker return (bytes);
2453*5e7646d2SAndroid Build Coastguard Worker }
2454*5e7646d2SAndroid Build Coastguard Worker
2455*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_in = fp->cbuf;
2456*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_in = (uInt)bytes;
2457*5e7646d2SAndroid Build Coastguard Worker }
2458*5e7646d2SAndroid Build Coastguard Worker
2459*5e7646d2SAndroid Build Coastguard Worker /*
2460*5e7646d2SAndroid Build Coastguard Worker * Decompress data from the buffer...
2461*5e7646d2SAndroid Build Coastguard Worker */
2462*5e7646d2SAndroid Build Coastguard Worker
2463*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_out = (Bytef *)fp->buf;
2464*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_out = sizeof(fp->buf);
2465*5e7646d2SAndroid Build Coastguard Worker
2466*5e7646d2SAndroid Build Coastguard Worker status = inflate(&(fp->stream), Z_NO_FLUSH);
2467*5e7646d2SAndroid Build Coastguard Worker
2468*5e7646d2SAndroid Build Coastguard Worker if (fp->stream.next_out > (Bytef *)fp->buf)
2469*5e7646d2SAndroid Build Coastguard Worker fp->crc = crc32(fp->crc, (Bytef *)fp->buf,
2470*5e7646d2SAndroid Build Coastguard Worker (uInt)(fp->stream.next_out - (Bytef *)fp->buf));
2471*5e7646d2SAndroid Build Coastguard Worker
2472*5e7646d2SAndroid Build Coastguard Worker if (status == Z_STREAM_END)
2473*5e7646d2SAndroid Build Coastguard Worker {
2474*5e7646d2SAndroid Build Coastguard Worker /*
2475*5e7646d2SAndroid Build Coastguard Worker * Read the CRC and length...
2476*5e7646d2SAndroid Build Coastguard Worker */
2477*5e7646d2SAndroid Build Coastguard Worker
2478*5e7646d2SAndroid Build Coastguard Worker unsigned char trailer[8]; /* Trailer bytes */
2479*5e7646d2SAndroid Build Coastguard Worker uLong tcrc; /* Trailer CRC */
2480*5e7646d2SAndroid Build Coastguard Worker ssize_t tbytes = 0; /* Number of bytes */
2481*5e7646d2SAndroid Build Coastguard Worker
2482*5e7646d2SAndroid Build Coastguard Worker if (fp->stream.avail_in > 0)
2483*5e7646d2SAndroid Build Coastguard Worker {
2484*5e7646d2SAndroid Build Coastguard Worker if (fp->stream.avail_in > sizeof(trailer))
2485*5e7646d2SAndroid Build Coastguard Worker tbytes = (ssize_t)sizeof(trailer);
2486*5e7646d2SAndroid Build Coastguard Worker else
2487*5e7646d2SAndroid Build Coastguard Worker tbytes = (ssize_t)fp->stream.avail_in;
2488*5e7646d2SAndroid Build Coastguard Worker
2489*5e7646d2SAndroid Build Coastguard Worker memcpy(trailer, fp->stream.next_in, (size_t)tbytes);
2490*5e7646d2SAndroid Build Coastguard Worker fp->stream.next_in += tbytes;
2491*5e7646d2SAndroid Build Coastguard Worker fp->stream.avail_in -= (size_t)tbytes;
2492*5e7646d2SAndroid Build Coastguard Worker }
2493*5e7646d2SAndroid Build Coastguard Worker
2494*5e7646d2SAndroid Build Coastguard Worker if (tbytes < (ssize_t)sizeof(trailer))
2495*5e7646d2SAndroid Build Coastguard Worker {
2496*5e7646d2SAndroid Build Coastguard Worker if (read(fp->fd, trailer + tbytes, sizeof(trailer) - (size_t)tbytes) < ((ssize_t)sizeof(trailer) - tbytes))
2497*5e7646d2SAndroid Build Coastguard Worker {
2498*5e7646d2SAndroid Build Coastguard Worker /*
2499*5e7646d2SAndroid Build Coastguard Worker * Can't get it, so mark end-of-file...
2500*5e7646d2SAndroid Build Coastguard Worker */
2501*5e7646d2SAndroid Build Coastguard Worker
2502*5e7646d2SAndroid Build Coastguard Worker DEBUG_puts("9cups_fill: Unable to read gzip CRC trailer, returning -1.");
2503*5e7646d2SAndroid Build Coastguard Worker
2504*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2505*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2506*5e7646d2SAndroid Build Coastguard Worker
2507*5e7646d2SAndroid Build Coastguard Worker return (-1);
2508*5e7646d2SAndroid Build Coastguard Worker }
2509*5e7646d2SAndroid Build Coastguard Worker }
2510*5e7646d2SAndroid Build Coastguard Worker
2511*5e7646d2SAndroid Build Coastguard Worker tcrc = ((((((uLong)trailer[3] << 8) | (uLong)trailer[2]) << 8) |
2512*5e7646d2SAndroid Build Coastguard Worker (uLong)trailer[1]) << 8) | (uLong)trailer[0];
2513*5e7646d2SAndroid Build Coastguard Worker
2514*5e7646d2SAndroid Build Coastguard Worker if (tcrc != fp->crc)
2515*5e7646d2SAndroid Build Coastguard Worker {
2516*5e7646d2SAndroid Build Coastguard Worker /*
2517*5e7646d2SAndroid Build Coastguard Worker * Bad CRC, mark end-of-file...
2518*5e7646d2SAndroid Build Coastguard Worker */
2519*5e7646d2SAndroid Build Coastguard Worker
2520*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: tcrc=%08x != fp->crc=%08x, returning -1.", (unsigned int)tcrc, (unsigned int)fp->crc));
2521*5e7646d2SAndroid Build Coastguard Worker
2522*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2523*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2524*5e7646d2SAndroid Build Coastguard Worker
2525*5e7646d2SAndroid Build Coastguard Worker return (-1);
2526*5e7646d2SAndroid Build Coastguard Worker }
2527*5e7646d2SAndroid Build Coastguard Worker
2528*5e7646d2SAndroid Build Coastguard Worker /*
2529*5e7646d2SAndroid Build Coastguard Worker * Otherwise, reset the compressed flag so that we re-read the
2530*5e7646d2SAndroid Build Coastguard Worker * file header...
2531*5e7646d2SAndroid Build Coastguard Worker */
2532*5e7646d2SAndroid Build Coastguard Worker
2533*5e7646d2SAndroid Build Coastguard Worker inflateEnd(&fp->stream);
2534*5e7646d2SAndroid Build Coastguard Worker
2535*5e7646d2SAndroid Build Coastguard Worker fp->compressed = 0;
2536*5e7646d2SAndroid Build Coastguard Worker }
2537*5e7646d2SAndroid Build Coastguard Worker else if (status < Z_OK)
2538*5e7646d2SAndroid Build Coastguard Worker {
2539*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: inflate returned %d, returning -1.", status));
2540*5e7646d2SAndroid Build Coastguard Worker
2541*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2542*5e7646d2SAndroid Build Coastguard Worker errno = EIO;
2543*5e7646d2SAndroid Build Coastguard Worker
2544*5e7646d2SAndroid Build Coastguard Worker return (-1);
2545*5e7646d2SAndroid Build Coastguard Worker }
2546*5e7646d2SAndroid Build Coastguard Worker
2547*5e7646d2SAndroid Build Coastguard Worker bytes = (ssize_t)sizeof(fp->buf) - (ssize_t)fp->stream.avail_out;
2548*5e7646d2SAndroid Build Coastguard Worker
2549*5e7646d2SAndroid Build Coastguard Worker /*
2550*5e7646d2SAndroid Build Coastguard Worker * Return the decompressed data...
2551*5e7646d2SAndroid Build Coastguard Worker */
2552*5e7646d2SAndroid Build Coastguard Worker
2553*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
2554*5e7646d2SAndroid Build Coastguard Worker fp->end = fp->buf + bytes;
2555*5e7646d2SAndroid Build Coastguard Worker
2556*5e7646d2SAndroid Build Coastguard Worker if (bytes)
2557*5e7646d2SAndroid Build Coastguard Worker {
2558*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: Returning %d.", (int)bytes));
2559*5e7646d2SAndroid Build Coastguard Worker return (bytes);
2560*5e7646d2SAndroid Build Coastguard Worker }
2561*5e7646d2SAndroid Build Coastguard Worker }
2562*5e7646d2SAndroid Build Coastguard Worker }
2563*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
2564*5e7646d2SAndroid Build Coastguard Worker
2565*5e7646d2SAndroid Build Coastguard Worker /*
2566*5e7646d2SAndroid Build Coastguard Worker * Read a buffer's full of data...
2567*5e7646d2SAndroid Build Coastguard Worker */
2568*5e7646d2SAndroid Build Coastguard Worker
2569*5e7646d2SAndroid Build Coastguard Worker if ((bytes = cups_read(fp, fp->buf, sizeof(fp->buf))) <= 0)
2570*5e7646d2SAndroid Build Coastguard Worker {
2571*5e7646d2SAndroid Build Coastguard Worker /*
2572*5e7646d2SAndroid Build Coastguard Worker * Can't read from file!
2573*5e7646d2SAndroid Build Coastguard Worker */
2574*5e7646d2SAndroid Build Coastguard Worker
2575*5e7646d2SAndroid Build Coastguard Worker fp->eof = 1;
2576*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
2577*5e7646d2SAndroid Build Coastguard Worker fp->end = fp->buf;
2578*5e7646d2SAndroid Build Coastguard Worker }
2579*5e7646d2SAndroid Build Coastguard Worker else
2580*5e7646d2SAndroid Build Coastguard Worker {
2581*5e7646d2SAndroid Build Coastguard Worker /*
2582*5e7646d2SAndroid Build Coastguard Worker * Return the bytes we read...
2583*5e7646d2SAndroid Build Coastguard Worker */
2584*5e7646d2SAndroid Build Coastguard Worker
2585*5e7646d2SAndroid Build Coastguard Worker fp->eof = 0;
2586*5e7646d2SAndroid Build Coastguard Worker fp->ptr = fp->buf;
2587*5e7646d2SAndroid Build Coastguard Worker fp->end = fp->buf + bytes;
2588*5e7646d2SAndroid Build Coastguard Worker }
2589*5e7646d2SAndroid Build Coastguard Worker
2590*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_fill: Not gzip, returning %d.", (int)bytes));
2591*5e7646d2SAndroid Build Coastguard Worker
2592*5e7646d2SAndroid Build Coastguard Worker return (bytes);
2593*5e7646d2SAndroid Build Coastguard Worker }
2594*5e7646d2SAndroid Build Coastguard Worker
2595*5e7646d2SAndroid Build Coastguard Worker
2596*5e7646d2SAndroid Build Coastguard Worker /*
2597*5e7646d2SAndroid Build Coastguard Worker * 'cups_open()' - Safely open a file for writing.
2598*5e7646d2SAndroid Build Coastguard Worker *
2599*5e7646d2SAndroid Build Coastguard Worker * We don't allow appending to directories or files that are hard-linked or
2600*5e7646d2SAndroid Build Coastguard Worker * symlinked.
2601*5e7646d2SAndroid Build Coastguard Worker */
2602*5e7646d2SAndroid Build Coastguard Worker
2603*5e7646d2SAndroid Build Coastguard Worker static int /* O - File descriptor or -1 otherwise */
cups_open(const char * filename,int mode)2604*5e7646d2SAndroid Build Coastguard Worker cups_open(const char *filename, /* I - Filename */
2605*5e7646d2SAndroid Build Coastguard Worker int mode) /* I - Open mode */
2606*5e7646d2SAndroid Build Coastguard Worker {
2607*5e7646d2SAndroid Build Coastguard Worker int fd; /* File descriptor */
2608*5e7646d2SAndroid Build Coastguard Worker struct stat fileinfo; /* File information */
2609*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
2610*5e7646d2SAndroid Build Coastguard Worker struct stat linkinfo; /* Link information */
2611*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
2612*5e7646d2SAndroid Build Coastguard Worker
2613*5e7646d2SAndroid Build Coastguard Worker
2614*5e7646d2SAndroid Build Coastguard Worker /*
2615*5e7646d2SAndroid Build Coastguard Worker * Open the file...
2616*5e7646d2SAndroid Build Coastguard Worker */
2617*5e7646d2SAndroid Build Coastguard Worker
2618*5e7646d2SAndroid Build Coastguard Worker if ((fd = open(filename, mode, 0666)) < 0)
2619*5e7646d2SAndroid Build Coastguard Worker return (-1);
2620*5e7646d2SAndroid Build Coastguard Worker
2621*5e7646d2SAndroid Build Coastguard Worker /*
2622*5e7646d2SAndroid Build Coastguard Worker * Then verify that the file descriptor doesn't point to a directory or hard-
2623*5e7646d2SAndroid Build Coastguard Worker * linked file.
2624*5e7646d2SAndroid Build Coastguard Worker */
2625*5e7646d2SAndroid Build Coastguard Worker
2626*5e7646d2SAndroid Build Coastguard Worker if (fstat(fd, &fileinfo))
2627*5e7646d2SAndroid Build Coastguard Worker {
2628*5e7646d2SAndroid Build Coastguard Worker close(fd);
2629*5e7646d2SAndroid Build Coastguard Worker return (-1);
2630*5e7646d2SAndroid Build Coastguard Worker }
2631*5e7646d2SAndroid Build Coastguard Worker
2632*5e7646d2SAndroid Build Coastguard Worker if (fileinfo.st_nlink != 1)
2633*5e7646d2SAndroid Build Coastguard Worker {
2634*5e7646d2SAndroid Build Coastguard Worker close(fd);
2635*5e7646d2SAndroid Build Coastguard Worker errno = EPERM;
2636*5e7646d2SAndroid Build Coastguard Worker return (-1);
2637*5e7646d2SAndroid Build Coastguard Worker }
2638*5e7646d2SAndroid Build Coastguard Worker
2639*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
2640*5e7646d2SAndroid Build Coastguard Worker if (fileinfo.st_mode & _S_IFDIR)
2641*5e7646d2SAndroid Build Coastguard Worker #else
2642*5e7646d2SAndroid Build Coastguard Worker if (S_ISDIR(fileinfo.st_mode))
2643*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
2644*5e7646d2SAndroid Build Coastguard Worker {
2645*5e7646d2SAndroid Build Coastguard Worker close(fd);
2646*5e7646d2SAndroid Build Coastguard Worker errno = EISDIR;
2647*5e7646d2SAndroid Build Coastguard Worker return (-1);
2648*5e7646d2SAndroid Build Coastguard Worker }
2649*5e7646d2SAndroid Build Coastguard Worker
2650*5e7646d2SAndroid Build Coastguard Worker #ifndef _WIN32
2651*5e7646d2SAndroid Build Coastguard Worker /*
2652*5e7646d2SAndroid Build Coastguard Worker * Then use lstat to determine whether the filename is a symlink...
2653*5e7646d2SAndroid Build Coastguard Worker */
2654*5e7646d2SAndroid Build Coastguard Worker
2655*5e7646d2SAndroid Build Coastguard Worker if (lstat(filename, &linkinfo))
2656*5e7646d2SAndroid Build Coastguard Worker {
2657*5e7646d2SAndroid Build Coastguard Worker close(fd);
2658*5e7646d2SAndroid Build Coastguard Worker return (-1);
2659*5e7646d2SAndroid Build Coastguard Worker }
2660*5e7646d2SAndroid Build Coastguard Worker
2661*5e7646d2SAndroid Build Coastguard Worker if (S_ISLNK(linkinfo.st_mode) ||
2662*5e7646d2SAndroid Build Coastguard Worker fileinfo.st_dev != linkinfo.st_dev ||
2663*5e7646d2SAndroid Build Coastguard Worker fileinfo.st_ino != linkinfo.st_ino ||
2664*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_ST_GEN
2665*5e7646d2SAndroid Build Coastguard Worker fileinfo.st_gen != linkinfo.st_gen ||
2666*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_ST_GEN */
2667*5e7646d2SAndroid Build Coastguard Worker fileinfo.st_nlink != linkinfo.st_nlink ||
2668*5e7646d2SAndroid Build Coastguard Worker fileinfo.st_mode != linkinfo.st_mode)
2669*5e7646d2SAndroid Build Coastguard Worker {
2670*5e7646d2SAndroid Build Coastguard Worker /*
2671*5e7646d2SAndroid Build Coastguard Worker * Yes, don't allow!
2672*5e7646d2SAndroid Build Coastguard Worker */
2673*5e7646d2SAndroid Build Coastguard Worker
2674*5e7646d2SAndroid Build Coastguard Worker close(fd);
2675*5e7646d2SAndroid Build Coastguard Worker errno = EPERM;
2676*5e7646d2SAndroid Build Coastguard Worker return (-1);
2677*5e7646d2SAndroid Build Coastguard Worker }
2678*5e7646d2SAndroid Build Coastguard Worker #endif /* !_WIN32 */
2679*5e7646d2SAndroid Build Coastguard Worker
2680*5e7646d2SAndroid Build Coastguard Worker return (fd);
2681*5e7646d2SAndroid Build Coastguard Worker }
2682*5e7646d2SAndroid Build Coastguard Worker
2683*5e7646d2SAndroid Build Coastguard Worker
2684*5e7646d2SAndroid Build Coastguard Worker /*
2685*5e7646d2SAndroid Build Coastguard Worker * 'cups_read()' - Read from a file descriptor.
2686*5e7646d2SAndroid Build Coastguard Worker */
2687*5e7646d2SAndroid Build Coastguard Worker
2688*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes read or -1 */
cups_read(cups_file_t * fp,char * buf,size_t bytes)2689*5e7646d2SAndroid Build Coastguard Worker cups_read(cups_file_t *fp, /* I - CUPS file */
2690*5e7646d2SAndroid Build Coastguard Worker char *buf, /* I - Buffer */
2691*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number bytes */
2692*5e7646d2SAndroid Build Coastguard Worker {
2693*5e7646d2SAndroid Build Coastguard Worker ssize_t total; /* Total bytes read */
2694*5e7646d2SAndroid Build Coastguard Worker
2695*5e7646d2SAndroid Build Coastguard Worker
2696*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7cups_read(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST bytes));
2697*5e7646d2SAndroid Build Coastguard Worker
2698*5e7646d2SAndroid Build Coastguard Worker /*
2699*5e7646d2SAndroid Build Coastguard Worker * Loop until we read at least 0 bytes...
2700*5e7646d2SAndroid Build Coastguard Worker */
2701*5e7646d2SAndroid Build Coastguard Worker
2702*5e7646d2SAndroid Build Coastguard Worker for (;;)
2703*5e7646d2SAndroid Build Coastguard Worker {
2704*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
2705*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
2706*5e7646d2SAndroid Build Coastguard Worker total = (ssize_t)recv(fp->fd, buf, (unsigned)bytes, 0);
2707*5e7646d2SAndroid Build Coastguard Worker else
2708*5e7646d2SAndroid Build Coastguard Worker total = (ssize_t)read(fp->fd, buf, (unsigned)bytes);
2709*5e7646d2SAndroid Build Coastguard Worker #else
2710*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
2711*5e7646d2SAndroid Build Coastguard Worker total = recv(fp->fd, buf, bytes, 0);
2712*5e7646d2SAndroid Build Coastguard Worker else
2713*5e7646d2SAndroid Build Coastguard Worker total = read(fp->fd, buf, bytes);
2714*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
2715*5e7646d2SAndroid Build Coastguard Worker
2716*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_read: total=" CUPS_LLFMT, CUPS_LLCAST total));
2717*5e7646d2SAndroid Build Coastguard Worker
2718*5e7646d2SAndroid Build Coastguard Worker if (total >= 0)
2719*5e7646d2SAndroid Build Coastguard Worker break;
2720*5e7646d2SAndroid Build Coastguard Worker
2721*5e7646d2SAndroid Build Coastguard Worker /*
2722*5e7646d2SAndroid Build Coastguard Worker * Reads can be interrupted by signals and unavailable resources...
2723*5e7646d2SAndroid Build Coastguard Worker */
2724*5e7646d2SAndroid Build Coastguard Worker
2725*5e7646d2SAndroid Build Coastguard Worker if (errno == EAGAIN || errno == EINTR)
2726*5e7646d2SAndroid Build Coastguard Worker continue;
2727*5e7646d2SAndroid Build Coastguard Worker else
2728*5e7646d2SAndroid Build Coastguard Worker return (-1);
2729*5e7646d2SAndroid Build Coastguard Worker }
2730*5e7646d2SAndroid Build Coastguard Worker
2731*5e7646d2SAndroid Build Coastguard Worker /*
2732*5e7646d2SAndroid Build Coastguard Worker * Return the total number of bytes read...
2733*5e7646d2SAndroid Build Coastguard Worker */
2734*5e7646d2SAndroid Build Coastguard Worker
2735*5e7646d2SAndroid Build Coastguard Worker return (total);
2736*5e7646d2SAndroid Build Coastguard Worker }
2737*5e7646d2SAndroid Build Coastguard Worker
2738*5e7646d2SAndroid Build Coastguard Worker
2739*5e7646d2SAndroid Build Coastguard Worker /*
2740*5e7646d2SAndroid Build Coastguard Worker * 'cups_write()' - Write to a file descriptor.
2741*5e7646d2SAndroid Build Coastguard Worker */
2742*5e7646d2SAndroid Build Coastguard Worker
2743*5e7646d2SAndroid Build Coastguard Worker static ssize_t /* O - Number of bytes written or -1 */
cups_write(cups_file_t * fp,const char * buf,size_t bytes)2744*5e7646d2SAndroid Build Coastguard Worker cups_write(cups_file_t *fp, /* I - CUPS file */
2745*5e7646d2SAndroid Build Coastguard Worker const char *buf, /* I - Buffer */
2746*5e7646d2SAndroid Build Coastguard Worker size_t bytes) /* I - Number bytes */
2747*5e7646d2SAndroid Build Coastguard Worker {
2748*5e7646d2SAndroid Build Coastguard Worker size_t total; /* Total bytes written */
2749*5e7646d2SAndroid Build Coastguard Worker ssize_t count; /* Count this time */
2750*5e7646d2SAndroid Build Coastguard Worker
2751*5e7646d2SAndroid Build Coastguard Worker
2752*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("7cups_write(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST bytes));
2753*5e7646d2SAndroid Build Coastguard Worker
2754*5e7646d2SAndroid Build Coastguard Worker /*
2755*5e7646d2SAndroid Build Coastguard Worker * Loop until all bytes are written...
2756*5e7646d2SAndroid Build Coastguard Worker */
2757*5e7646d2SAndroid Build Coastguard Worker
2758*5e7646d2SAndroid Build Coastguard Worker total = 0;
2759*5e7646d2SAndroid Build Coastguard Worker while (bytes > 0)
2760*5e7646d2SAndroid Build Coastguard Worker {
2761*5e7646d2SAndroid Build Coastguard Worker #ifdef _WIN32
2762*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
2763*5e7646d2SAndroid Build Coastguard Worker count = (ssize_t)send(fp->fd, buf, (unsigned)bytes, 0);
2764*5e7646d2SAndroid Build Coastguard Worker else
2765*5e7646d2SAndroid Build Coastguard Worker count = (ssize_t)write(fp->fd, buf, (unsigned)bytes);
2766*5e7646d2SAndroid Build Coastguard Worker #else
2767*5e7646d2SAndroid Build Coastguard Worker if (fp->mode == 's')
2768*5e7646d2SAndroid Build Coastguard Worker count = send(fp->fd, buf, bytes, 0);
2769*5e7646d2SAndroid Build Coastguard Worker else
2770*5e7646d2SAndroid Build Coastguard Worker count = write(fp->fd, buf, bytes);
2771*5e7646d2SAndroid Build Coastguard Worker #endif /* _WIN32 */
2772*5e7646d2SAndroid Build Coastguard Worker
2773*5e7646d2SAndroid Build Coastguard Worker DEBUG_printf(("9cups_write: count=" CUPS_LLFMT, CUPS_LLCAST count));
2774*5e7646d2SAndroid Build Coastguard Worker
2775*5e7646d2SAndroid Build Coastguard Worker if (count < 0)
2776*5e7646d2SAndroid Build Coastguard Worker {
2777*5e7646d2SAndroid Build Coastguard Worker /*
2778*5e7646d2SAndroid Build Coastguard Worker * Writes can be interrupted by signals and unavailable resources...
2779*5e7646d2SAndroid Build Coastguard Worker */
2780*5e7646d2SAndroid Build Coastguard Worker
2781*5e7646d2SAndroid Build Coastguard Worker if (errno == EAGAIN || errno == EINTR)
2782*5e7646d2SAndroid Build Coastguard Worker continue;
2783*5e7646d2SAndroid Build Coastguard Worker else
2784*5e7646d2SAndroid Build Coastguard Worker return (-1);
2785*5e7646d2SAndroid Build Coastguard Worker }
2786*5e7646d2SAndroid Build Coastguard Worker
2787*5e7646d2SAndroid Build Coastguard Worker /*
2788*5e7646d2SAndroid Build Coastguard Worker * Update the counts for the last write call...
2789*5e7646d2SAndroid Build Coastguard Worker */
2790*5e7646d2SAndroid Build Coastguard Worker
2791*5e7646d2SAndroid Build Coastguard Worker bytes -= (size_t)count;
2792*5e7646d2SAndroid Build Coastguard Worker total += (size_t)count;
2793*5e7646d2SAndroid Build Coastguard Worker buf += count;
2794*5e7646d2SAndroid Build Coastguard Worker }
2795*5e7646d2SAndroid Build Coastguard Worker
2796*5e7646d2SAndroid Build Coastguard Worker /*
2797*5e7646d2SAndroid Build Coastguard Worker * Return the total number of bytes written...
2798*5e7646d2SAndroid Build Coastguard Worker */
2799*5e7646d2SAndroid Build Coastguard Worker
2800*5e7646d2SAndroid Build Coastguard Worker return ((ssize_t)total);
2801*5e7646d2SAndroid Build Coastguard Worker }
2802