Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cupsFileTell() returns invalid results for append mode (log files) #2810

Closed
michaelrsweet opened this issue Apr 23, 2008 · 2 comments
Closed
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 1.3-current
CUPS.org User: mike

cupsFileTell() returns for the current file position when appending to an existing file. It should return the current file size.

This is most noticeable with the log file rotation in the scheduler - if the scheduler is restarted (very common on Mac OS X since launchd runs cupsd on demand), we lose track of the log file size and do not rotate the old access_log or error_log files.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

"str2810.patch":

Index: file.c

--- file.c (revision 7489)
+++ file.c (working copy)
@@ -111,7 +111,8 @@
buf[4096], /* Buffer /
*ptr, /
Pointer into buffer /
*end; /
End of buffer data */

  • off_t pos; /* File position for start of buffer */

  • off_t pos, /* Position in file */

  •   bufpos;         /* File position for start of buffer */
    

    #ifdef HAVE_LIBZ
    z_stream stream; /* (De)compression stream */
    @@ -413,13 +414,14 @@

    if (!fp || fp->mode != 'w')
    {

  • DEBUG_puts(" Attempt to flush a read-only file...");

  • DEBUG_puts("cupsFileFlush: Attempt to flush a read-only file...");
    return (-1);
    }

bytes = (ssize_t)(fp->ptr - fp->buf);

  • DEBUG_printf((" Flushing %ld bytes...\n", (long)bytes));

  • DEBUG_printf(("cupsFileFlush: Flushing " CUPS_LLFMT " bytes...\n",

  •            CUPS_LLCAST bytes));
    

    if (bytes > 0)
    {
    @@ -453,6 +455,8 @@

    • Range check input...
      */
  • DEBUG_printf(("cupsFileGetChar(fp=%p)\n", fp));

if (!fp || (fp->mode != 'r' && fp->mode != 's'))
{
DEBUG_puts("cupsFileGetChar: Bad arguments!");
@@ -476,6 +480,10 @@

DEBUG_printf(("cupsFileGetChar: Returning %d...\n", *(fp->ptr) & 255));

  • fp->pos ++;
  • DEBUG_printf(("cupsFileGetChar: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (*(fp->ptr)++ & 255);
}

@@ -500,6 +508,10 @@

  • Range check input...
    */

  • DEBUG_printf(("cupsFileGetConf(fp=%p, buf=%p, buflen=" CUPS_LLFMT

  •            ", value=%p, linenum=%p)\n", fp, buf, CUPS_LLCAST buflen,
    
  •   value, linenum));
    

    if (!fp || (fp->mode != 'r' && fp->mode != 's') ||
    !buf || buflen < 2 || !value)
    {
    @@ -640,6 +652,9 @@

    • Range check input...
      */
  • DEBUG_printf(("cupsFileGetLine(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")\n",

  •            fp, buf, CUPS_LLCAST buflen));
    

    if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 3)
    return (0);

@@ -654,6 +669,7 @@
break;

 *ptr++ = ch = *(fp->ptr)++;
  • fp->pos ++;

if (ch == '\r')
{
@@ -666,7 +682,10 @@
break;

 if (*(fp->ptr) == '\n')
  •  {
     *ptr++ = *(fp->ptr)++;
    
  • fp->pos ++;

  •  }
    

    break;
    }
    @@ -682,6 +701,8 @@

    *ptr = '\0';

  • DEBUG_printf(("cupsFileGetLine: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (ptr - buf);
}

@@ -706,6 +727,9 @@

  • Range check input...
    */
  • DEBUG_printf(("cupsFileGets(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")\n", fp, buf,
  •            CUPS_LLCAST buflen));
    
    if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 2)
    return (NULL);

@@ -725,6 +749,7 @@
}

 ch = *(fp->ptr)++;
  • fp->pos ++;

if (ch == '\r')
{
@@ -737,7 +762,10 @@
break;

 if (*(fp->ptr) == '\n')
  •    fp->ptr ++;  
    
  •  {
    
  •    fp->ptr ++;
    
  • fp->pos ++;

  •  }
    

    break;
    }
    @@ -755,6 +783,8 @@

    *ptr = '\0';

  • DEBUG_printf(("cupsFileGets: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (buf);
}

@@ -811,8 +841,9 @@

  • existing file, "a" to append to an existing file or create a new file,

  • or "s" to open a socket connection.
    *

    • * When opening for writing ("w") or appending ("a"), an optional number from
    • * 1 to 9 can be supplied which enables Flate compression of the file.
    • * When opening for writing ("w"), an optional number from 1 to 9 can be
    • * supplied which enables Flate compression of the file. Compression is
    • * not supported for the "a" (append) mode.
      *
  • When opening a socket connection, the filename is a string of the form

  • "address:port" or "hostname:port". The socket will make an IPv4 or IPv6
    @@ -841,7 +872,8 @@
    */

    if (!filename || !mode ||

    •  (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's'))
      
    •  (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's') ||
      
    •  (*mode == 'a' && isdigit(mode[1] & 255)))
      
      return (NULL);

    /*
    @@ -918,11 +950,12 @@
    /*

  • 'cupsFileOpenFd()' - Open a CUPS file using a file descriptor.
    *

    • * The "mode" parameter can be "r" to read, "a" or "w" to write, or "s"
    • * to treat the file descriptor as a bidirectional socket connection.
    • * The "mode" parameter can be "r" to read, "w" to write, "a" to append,
    • * or "s" to treat the file descriptor as a bidirectional socket connection.
      *
    • * When opening for writing ("w") or appending ("a"), an optional number from
    • * 1 to 9 can be supplied which enables Flate compression of the file.
    • * When opening for writing ("w"), an optional number from 1 to 9 can be
    • * supplied which enables Flate compression of the file. Compression is
    • * not supported for the "a" (append) mode.
      *
  • @SInCE CUPS 1.2@
    */
    @@ -941,7 +974,8 @@
    */

    if (fd < 0 || !mode ||

    •  (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's'))
      
    •  (*mode != 'r' && *mode != 'w' && *mode != 'a' && *mode != 's') ||
      
    •  (*mode == 'a' && isdigit(mode[1] & 255)))
      
      return (NULL);

    /*
    @@ -959,8 +993,10 @@

    switch (*mode)
    {

    • case 'a' :
    •    fp->pos = lseek(fd, 0, SEEK_END);
      
      case 'w' :
    • case 'a' :
      fp->mode = 'w';
      fp->ptr = fp->buf;
      fp->end = fp->buf + sizeof(fp->buf);
      @@ -1091,14 +1127,25 @@
      return (-1);

    if (fp->mode == 's')

    • return (cups_write(fp, buf, bytes));
    • {
    • if (cups_write(fp, buf, bytes) < 0)
    •  return (-1);
      
  • fp->pos += bytes;

  • DEBUG_printf(("cupsFilePrintf: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));
  • return (bytes);
  • }

if ((fp->ptr + bytes) > fp->end)
if (cupsFileFlush(fp))
return (-1);

fp->pos += bytes;

  • DEBUG_printf(("cupsFilePrintf: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

if (bytes > sizeof(fp->buf))
{
#ifdef HAVE_LIBZ
@@ -1163,6 +1210,8 @@

fp->pos ++;

  • DEBUG_printf(("cupsFilePutChar: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (0);
}

@@ -1202,6 +1251,8 @@

 fp->pos += bytes;
  • DEBUG_printf(("cupsFilePuts: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (bytes);
}

@@ -1211,6 +1262,8 @@

fp->pos += bytes;

  • DEBUG_printf(("cupsFilePuts: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

if (bytes > sizeof(fp->buf))
{
#ifdef HAVE_LIBZ
@@ -1244,8 +1297,8 @@
ssize_t count; /* Bytes read */

  • DEBUG_printf(("cupsFileRead(fp=%p, buf=%p, bytes=%ld)\n", fp, buf,

  •            (long)bytes));
    
  • DEBUG_printf(("cupsFileRead(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")\n", fp, buf,

  •            CUPS_LLCAST bytes));
    

    /*

    • Range check input...
      @@ -1267,7 +1320,8 @@
      if (fp->ptr >= fp->end)
      if (cups_fill(fp) <= 0)
      {
  •    DEBUG_printf(("    cups_fill() returned -1, total=%d\n", (int)total));
    
  •    DEBUG_printf(("cupsFileRead: cups_fill() returned -1, total=" CUPS_LLFMT "\n",
    
  •             CUPS_LLCAST total));
    
     if (total > 0)
       return ((ssize_t)total);
    

    @@ -1281,7 +1335,10 @@

    memcpy(buf, fp->ptr, count);
    fp->ptr += count;

  • fp->pos += count;

  • DEBUG_printf(("cupsFileRead: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

/*

  • Update the counts for the last read...
    */
    @@ -1295,7 +1352,7 @@
    • Return the total number of bytes read...
      */
  • DEBUG_printf((" total=%d\n", (int)total));
  • DEBUG_printf(("cupsFileRead: total=%d\n", (int)total));

return ((ssize_t)total);
}
@@ -1315,6 +1372,9 @@

  • Range check input...
    */
  • DEBUG_printf(("cupsFileRewind(fp=%p)\n", fp));
  • DEBUG_printf(("cupsFileRewind: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

if (!fp || fp->mode != 'r')
return (-1);

@@ -1322,18 +1382,22 @@

  • Handle special cases...
    */
  • if (fp->pos == 0)
  • if (fp->bufpos == 0)
    {
    /*
  • No seeking necessary...
    */
  • fp->pos = 0;

if (fp->ptr)
{
fp->ptr = fp->buf;
fp->eof = 0;
}

  • DEBUG_printf(("cupsFileRewind: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (0);
}

@@ -1351,11 +1415,14 @@

lseek(fp->fd, 0, SEEK_SET);

  • fp->pos = 0;
  • fp->ptr = NULL;
  • fp->end = NULL;
  • fp->eof = 0;
  • fp->bufpos = 0;
  • fp->pos = 0;
  • fp->ptr = NULL;
  • fp->end = NULL;
  • fp->eof = 0;
  • DEBUG_printf(("cupsFileRewind: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (0);
}

@@ -1373,9 +1440,10 @@
ssize_t bytes; /* Number bytes in buffer */

  • DEBUG_printf(("cupsFileSeek(fp=%p, pos=" CUPS_LLFMT ")\n", fp, pos));
  • DEBUG_printf((" fp->pos=" CUPS_LLFMT "\n", fp->pos));
  • DEBUG_printf((" fp->ptr=%p, fp->end=%p\n", fp->ptr, fp->end));
  • DEBUG_printf(("cupsFileSeek(fp=%p, pos=" CUPS_LLFMT ")\n", fp,
  •            CUPS_LLCAST pos));
    
  • DEBUG_printf(("cupsFileSeek: fp->pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));
  • DEBUG_printf(("cupsFileSeek: fp->ptr=%p, fp->end=%p\n", fp->ptr, fp->end));

/*

  • Range check input...
    @@ -1391,19 +1459,22 @@
    if (pos == 0)
    return (cupsFileRewind(fp));
  • if (fp->pos == pos)
  • if (fp->ptr)
    {
  • /*
  • * No seeking necessary...
  • */
  • bytes = (ssize_t)(fp->end - fp->buf);
  • if (fp->ptr)
  • if (pos >= fp->bufpos && pos < (fp->bufpos + bytes))
    {
  •  fp->ptr = fp->buf;
    
  • /*
    
  •  \* No seeking necessary...
    
  •  */
    
  •  fp->pos = pos;
    
  •  fp->ptr = fp->buf + pos - fp->bufpos;
    
    fp->eof = 0;
    +
  •  return (pos);
    

    }

  • return (pos);
    }

#ifdef HAVE_LIBZ
@@ -1419,26 +1490,20 @@
#endif /* HAVE_LIBZ */

/*

  • * Figure out the number of bytes in the current buffer, and then
  • * see if we are outside of it...
    • Seek forwards or backwards...
      */
  • if (fp->ptr)
  • bytes = (ssize_t)(fp->end - fp->buf);
  • else

- bytes = 0;

fp->eof = 0;

  • DEBUG_printf((" bytes=" CUPS_LLFMT "\n", CUPS_LLCAST bytes));
  • DEBUG_printf(("cupsFileSeek: bytes=" CUPS_LLFMT "\n", CUPS_LLCAST bytes));
  • if (pos < fp->pos)
  • if (pos < fp->bufpos)
    {
    /*
  • Need to seek backwards...
    */
  • DEBUG_puts(" SEEK BACKWARDS");
  • DEBUG_puts("cupsFileSeek: SEEK BACKWARDS");

#ifdef HAVE_LIBZ
if (fp->compressed)
@@ -1446,73 +1511,71 @@
inflateEnd(&fp->stream);

 lseek(fp->fd, 0, SEEK_SET);
  •  fp->pos = 0;
    
  •  fp->ptr = NULL;
    
  •  fp->end = NULL;
    
  •  fp->bufpos = 0;
    
  •  fp->pos    = 0;
    
  •  fp->ptr    = NULL;
    
  •  fp->end    = NULL;
    

    while ((bytes = cups_fill(fp)) > 0)

  •    if (pos >= fp->pos && pos < (fp->pos + bytes))
    
  •    if (pos >= fp->bufpos && pos < (fp->bufpos + bytes))
    

    break;

    if (bytes <= 0)
    return (-1);

  •  fp->ptr = fp->buf + pos - fp->pos;
    
  •  fp->ptr = fp->buf + pos - fp->bufpos;
    
  •  fp->pos = pos;
    

    }
    else
    #endif /* HAVE_LIBZ */
    {

  •  fp->pos = lseek(fp->fd, pos, SEEK_SET);
    
  •  fp->ptr = NULL;
    
  •  fp->end = NULL;
    
  •  fp->bufpos = lseek(fp->fd, pos, SEEK_SET);
    
  •  fp->pos    = fp->bufpos;
    
  •  fp->ptr    = NULL;
    
  •  fp->end    = NULL;
    
  •  DEBUG_printf(("    lseek() returned %ld...\n", (long)fp->pos));
    
  •  DEBUG_printf(("cupsFileSeek: lseek() returned " CUPS_LLFMT "...\n",
    
  •                CUPS_LLCAST fp->pos));
    

    }
    }

  • else if (pos >= (fp->pos + bytes))

  • else
    {
    /*

  • Need to seek forwards...
    */

  • DEBUG_puts(" SEEK FORWARDS");

  • DEBUG_puts("cupsFileSeek: SEEK FORWARDS");

#ifdef HAVE_LIBZ
if (fp->compressed)
{
while ((bytes = cups_fill(fp)) > 0)
{

  •    if (pos >= fp->pos && pos < (fp->pos + bytes))
    
  •    if (pos >= fp->bufpos && pos < (fp->bufpos + bytes))
    

    break;
    }

    if (bytes <= 0)
    return (-1);

  •  fp->ptr = fp->buf + pos - fp->pos;
    
  •  fp->ptr = fp->buf + pos - fp->bufpos;
    
  •  fp->pos = pos;
    

    }
    else
    #endif /* HAVE_LIBZ */
    {

  •  fp->pos = lseek(fp->fd, pos, SEEK_SET);
    
  •  fp->ptr = NULL;
    
  •  fp->end = NULL;
    
  •  fp->bufpos = lseek(fp->fd, pos, SEEK_SET);
    
  •  fp->pos    = fp->bufpos;
    
  •  fp->ptr    = NULL;
    
  •  fp->end    = NULL;
    
  •  DEBUG_printf(("    lseek() returned " CUPS_LLFMT "...\n", fp->pos));
    
  •  DEBUG_printf(("cupsFileSeek: lseek() returned " CUPS_LLFMT "...\n",
    
  •                CUPS_LLCAST fp->pos));
    

    }
    }

  • else

  • {

  • /*

  • * Just reposition the current pointer, since we have the right

  • * range...

  • */

  • DEBUG_puts(" SEEK INSIDE BUFFER");

  • DEBUG_printf(("cupsFileSeek: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

  • fp->ptr = fp->buf + pos - fp->pos;

- }

return (fp->pos);
}

@@ -1628,6 +1691,9 @@
off_t /* O - File position /
cupsFileTell(cups_file_t *fp) /
I - CUPS file */
{

  • DEBUG_printf(("cupsFileTell(fp=%p)\n", fp));
  • DEBUG_printf(("cupsFileTell: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return (fp ? fp->pos : 0);
}

@@ -1645,6 +1711,8 @@

  • Range check...
    */
  • DEBUG_printf(("cupsFileUnlock(fp=%p)\n", fp));

if (!fp || fp->mode == 's')
return (-1);

@@ -1675,6 +1743,9 @@

  • Range check input...
    */
  • DEBUG_printf(("cupsFileWrite(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")\n",
  •            fp, buf, CUPS_LLCAST bytes));
    
    if (!fp || !buf || bytes < 0 || (fp->mode != 'w' && fp->mode != 's'))
    return (-1);

@@ -1692,6 +1763,8 @@

 fp->pos += (off_t)bytes;
  • DEBUG_printf(("cupsFileWrite: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

return ((ssize_t)bytes);
}

@@ -1701,6 +1774,8 @@

fp->pos += (off_t)bytes;

  • DEBUG_printf(("cupsFileWrite: pos=" CUPS_LLFMT "\n", CUPS_LLCAST fp->pos));

if (bytes > sizeof(fp->buf))
{
#ifdef HAVE_LIBZ
@@ -1729,8 +1804,8 @@
const char buf, / I - Buffer /
size_t bytes) /
I - Number bytes */
{

  • DEBUG_printf(("cups_compress(fp=%p, buf=%p, bytes=%ld)\n", fp, buf,

  •            (long)bytes));
    
  • DEBUG_printf(("cups_compress(fp=%p, buf=%p, bytes=" CUPS_LLFMT "\n", fp, buf,

  •            CUPS_LLCAST bytes));
    

    /*

    • Update the CRC...
      @@ -1751,8 +1826,8 @@
      • Flush the current buffer...
        */
  • DEBUG_printf((" avail_in=%d, avail_out=%d\n", fp->stream.avail_in,

  •              fp->stream.avail_out));
    
  • DEBUG_printf(("cups_compress: avail_in=%d, avail_out=%d\n",

  •              fp->stream.avail_in, fp->stream.avail_out));
    

    if (fp->stream.avail_out < (int)(sizeof(fp->cbuf) / 8))
    {
    @@ -1787,19 +1862,15 @@

    DEBUG_printf(("cups_fill(fp=%p)\n", fp));

  • DEBUG_printf((" fp->ptr=%p, fp->end=%p, fp->buf=%p, "

  •            "fp->pos=" CUPS_LLFMT ", fp->eof=%d\n",
    
  •            fp->ptr, fp->end, fp->buf, fp->pos, fp->eof));
    
  • DEBUG_printf(("cups_fill: fp->ptr=%p, fp->end=%p, fp->buf=%p, "

  •            "fp->bufpos=" CUPS_LLFMT ", fp->eof=%d\n",
    
  •            fp->ptr, fp->end, fp->buf, CUPS_LLCAST fp->bufpos, fp->eof));
    
  • /*

  • * Update the "pos" element as needed...

- */

if (fp->ptr && fp->end)

  • fp->pos += (off_t)(fp->end - fp->buf);
  • fp->bufpos += fp->end - fp->ptr;

#ifdef HAVE_LIBZ

  • DEBUG_printf((" fp->compressed=%d\n", fp->compressed));
  • DEBUG_printf(("cups_fill: fp->compressed=%d\n", fp->compressed));

while (!fp->ptr || fp->compressed)
{
@@ -1827,7 +1898,7 @@

  • Can't read from file!
    */

  •    DEBUG_printf(("    cups_read() returned " CUPS_LLFMT "!\n",
    
  •    DEBUG_printf(("cups_fill: cups_read() returned " CUPS_LLFMT "!\n",
              CUPS_LLCAST bytes));
    

    return (-1);
    @@ -2107,6 +2178,9 @@
    ssize_t total; /* Total bytes read */

  • DEBUG_printf(("cups_read(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")\n", fp, buf,

  •            CUPS_LLCAST bytes));
    

    /*

    • Loop until we read at least 0 bytes...
      /
      @@ -2125,6 +2199,8 @@
      total = read(fp->fd, buf, bytes);
      #endif /
      WIN32 */
  • DEBUG_printf(("cups_read: total=" CUPS_LLFMT "\n", CUPS_LLCAST total));

if (total >= 0)
break;

@@ -2159,8 +2235,8 @@
ssize_t count; /* Count this time */

  • DEBUG_printf(("cups_write(fp=%p, buf=%p, bytes=%ld)\n", fp, buf,

  •            (long)bytes));
    
  • DEBUG_printf(("cups_write(fp=%p, buf=%p, bytes=" CUPS_LLFMT ")\n", fp, buf,

  •            CUPS_LLCAST bytes));
    

    /*

    • Loop until all bytes are written...
      @@ -2181,6 +2257,8 @@
      count = write(fp->fd, buf, bytes);
      #endif /* WIN32 */
  • DEBUG_printf(("cups_write: count=" CUPS_LLFMT "\n", CUPS_LLCAST count));

if (count < 0)
{
/*
@@ -2193,8 +2271,6 @@
return (-1);
}

- DEBUG_printf((" count=%ld\n", (long)count));

/*
 * Update the counts for the last write call...
 */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant