X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=cups%2Ffile.c;h=e6e1f5b826f9d91d130891ab30c5036b45db3a75;hb=ffbf1e61ffbb56b95018ef4301e4ddb230b88468;hp=8cdf0368ce5ae422b4696455eac32895b9caf779;hpb=5c476bf970766279bfba6b5535968e9b233c0ba0;p=thirdparty%2Fcups.git diff --git a/cups/file.c b/cups/file.c index 8cdf0368c..e6e1f5b82 100644 --- a/cups/file.c +++ b/cups/file.c @@ -6,16 +6,11 @@ * our own file functions allows us to provide transparent support of * different line endings, gzip'd print files, PPD files, etc. * - * Copyright 2007-2017 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -23,9 +18,43 @@ */ #include "file-private.h" +#include "debug-internal.h" #include #include +# ifdef HAVE_LIBZ +# include +# endif /* HAVE_LIBZ */ + + +/* + * Internal structures... + */ + +struct _cups_file_s /**** CUPS file structure... ****/ + +{ + int fd; /* File descriptor */ + char mode, /* Mode ('r' or 'w') */ + compressed, /* Compression used? */ + is_stdio, /* stdin/out/err? */ + eof, /* End of file? */ + buf[4096], /* Buffer */ + *ptr, /* Pointer into buffer */ + *end; /* End of buffer data */ + off_t pos, /* Position in file */ + bufpos; /* File position for start of buffer */ + +#ifdef HAVE_LIBZ + z_stream stream; /* (De)compression stream */ + Bytef cbuf[4096]; /* (De)compression buffer */ + uLong crc; /* (De)compression CRC */ +#endif /* HAVE_LIBZ */ + + char *printf_buffer; /* cupsFilePrintf buffer */ + size_t printf_size; /* Size of cupsFilePrintf buffer */ +}; + /* * Local functions... @@ -40,7 +69,7 @@ static ssize_t cups_read(cups_file_t *fp, char *buf, size_t bytes); static ssize_t cups_write(cups_file_t *fp, const char *buf, size_t bytes); -#ifndef WIN32 +#ifndef _WIN32 /* * '_cupsFileCheck()' - Check the permissions of the given filename. */ @@ -306,7 +335,7 @@ _cupsFileCheckFilter( fprintf(stderr, "%s: %s\n", prefix, message); } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* @@ -526,22 +555,22 @@ cupsFileFind(const char *filename, /* I - File to find */ while (*path) { -#ifdef WIN32 +#ifdef _WIN32 if (*path == ';' || (*path == ':' && ((bufptr - buffer) > 1 || !isalpha(buffer[0] & 255)))) #else if (*path == ';' || *path == ':') -#endif /* WIN32 */ +#endif /* _WIN32 */ { if (bufptr > buffer && bufptr[-1] != '/' && bufptr < bufend) *bufptr++ = '/'; strlcpy(bufptr, filename, (size_t)(bufend - bufptr)); -#ifdef WIN32 +#ifdef _WIN32 if (!access(buffer, 0)) #else if (!access(buffer, executable ? X_OK : 0)) -#endif /* WIN32 */ +#endif /* _WIN32 */ { DEBUG_printf(("1cupsFileFind: Returning \"%s\"", buffer)); return (buffer); @@ -646,6 +675,12 @@ cupsFileGetChar(cups_file_t *fp) /* I - CUPS file */ return (-1); } + if (fp->eof) + { + DEBUG_puts("5cupsFileGetChar: End-of-file!"); + return (-1); + } + /* * If the input buffer is empty, try to read more data... */ @@ -992,11 +1027,11 @@ cupsFileLock(cups_file_t *fp, /* I - CUPS file */ * Try the lock... */ -#ifdef WIN32 +#ifdef _WIN32 return (_locking(fp->fd, block ? _LK_LOCK : _LK_NBLCK, 0)); #else return (lockf(fp->fd, block ? F_LOCK : F_TLOCK, 0)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -1084,11 +1119,11 @@ cupsFileOpen(const char *filename, /* I - Name of file */ } if (fd >= 0) -#ifdef WIN32 +#ifdef _WIN32 _chsize(fd, 0); #else ftruncate(fd, 0); -#endif /* WIN32 */ +#endif /* _WIN32 */ break; case 's' : /* Read/write socket */ @@ -1255,14 +1290,26 @@ cupsFileOpenFd(int fd, /* I - File descriptor */ * Don't pass this file to child processes... */ -#ifndef WIN32 +#ifndef _WIN32 fcntl(fp->fd, F_SETFD, fcntl(fp->fd, F_GETFD) | FD_CLOEXEC); -#endif /* !WIN32 */ +#endif /* !_WIN32 */ return (fp); } +/* + * '_cupsFilePeekAhead()' - See if the requested character is buffered up. + */ + +int /* O - 1 if present, 0 otherwise */ +_cupsFilePeekAhead(cups_file_t *fp, /* I - CUPS file */ + int ch) /* I - Character */ +{ + return (fp && fp->ptr && memchr(fp->ptr, ch, (size_t)(fp->end - fp->ptr))); +} + + /* * 'cupsFilePeekChar()' - Peek at the next character from a file. * @@ -1606,6 +1653,12 @@ cupsFileRead(cups_file_t *fp, /* I - CUPS file */ if (bytes == 0) return (0); + if (fp->eof) + { + DEBUG_puts("5cupsFileRead: End-of-file!"); + return (-1); + } + /* * Loop until all bytes are read... */ @@ -2019,11 +2072,11 @@ cupsFileUnlock(cups_file_t *fp) /* I - CUPS file */ * Unlock... */ -#ifdef WIN32 +#ifdef _WIN32 return (_locking(fp->fd, _LK_UNLCK, 0)); #else return (lockf(fp->fd, F_ULOCK, 0)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -2477,6 +2530,8 @@ cups_fill(cups_file_t *fp) /* I - CUPS file */ * file header... */ + inflateEnd(&fp->stream); + fp->compressed = 0; } else if (status < Z_OK) @@ -2551,9 +2606,9 @@ cups_open(const char *filename, /* I - Filename */ { int fd; /* File descriptor */ struct stat fileinfo; /* File information */ -#ifndef WIN32 +#ifndef _WIN32 struct stat linkinfo; /* Link information */ -#endif /* !WIN32 */ +#endif /* !_WIN32 */ /* @@ -2581,18 +2636,18 @@ cups_open(const char *filename, /* I - Filename */ return (-1); } -#ifdef WIN32 +#ifdef _WIN32 if (fileinfo.st_mode & _S_IFDIR) #else if (S_ISDIR(fileinfo.st_mode)) -#endif /* WIN32 */ +#endif /* _WIN32 */ { close(fd); errno = EISDIR; return (-1); } -#ifndef WIN32 +#ifndef _WIN32 /* * Then use lstat to determine whether the filename is a symlink... */ @@ -2620,7 +2675,7 @@ cups_open(const char *filename, /* I - Filename */ errno = EPERM; return (-1); } -#endif /* !WIN32 */ +#endif /* !_WIN32 */ return (fd); } @@ -2646,7 +2701,7 @@ cups_read(cups_file_t *fp, /* I - CUPS file */ for (;;) { -#ifdef WIN32 +#ifdef _WIN32 if (fp->mode == 's') total = (ssize_t)recv(fp->fd, buf, (unsigned)bytes, 0); else @@ -2656,7 +2711,7 @@ cups_read(cups_file_t *fp, /* I - CUPS file */ total = recv(fp->fd, buf, bytes, 0); else total = read(fp->fd, buf, bytes); -#endif /* WIN32 */ +#endif /* _WIN32 */ DEBUG_printf(("9cups_read: total=" CUPS_LLFMT, CUPS_LLCAST total)); @@ -2703,7 +2758,7 @@ cups_write(cups_file_t *fp, /* I - CUPS file */ total = 0; while (bytes > 0) { -#ifdef WIN32 +#ifdef _WIN32 if (fp->mode == 's') count = (ssize_t)send(fp->fd, buf, (unsigned)bytes, 0); else @@ -2713,7 +2768,7 @@ cups_write(cups_file_t *fp, /* I - CUPS file */ count = send(fp->fd, buf, bytes, 0); else count = write(fp->fd, buf, bytes); -#endif /* WIN32 */ +#endif /* _WIN32 */ DEBUG_printf(("9cups_write: count=" CUPS_LLFMT, CUPS_LLCAST count));