"Fossies" - the Fresh Open Source Software Archive

Member "sarg-2.4.0/longline.c" (30 Jan 2017, 5261 Bytes) of package /linux/privat/sarg-2.4.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "longline.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.3.11_vs_2.4.0.

    1 /*
    2  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
    3  *                                                            1998, 2015
    4  *
    5  * SARG donations:
    6  *      please look at http://sarg.sourceforge.net/donations.php
    7  * Support:
    8  *     http://sourceforge.net/projects/sarg/forums/forum/363374
    9  * ---------------------------------------------------------------------
   10  *
   11  *  This program is free software; you can redistribute it and/or modify
   12  *  it under the terms of the GNU General Public License as published by
   13  *  the Free Software Foundation; either version 2 of the License, or
   14  *  (at your option) any later version.
   15  *
   16  *  This program is distributed in the hope that it will be useful,
   17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19  *  GNU General Public License for more details.
   20  *
   21  *  You should have received a copy of the GNU General Public License
   22  *  along with this program; if not, write to the Free Software
   23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   24  *
   25  */
   26 
   27 #include "include/conf.h"
   28 #include "include/defs.h"
   29 
   30 //! The size, in bytes, to allocate from the start.
   31 #define INITIAL_LINE_BUFFER_SIZE 32768
   32 /*!
   33 The amount by which the line buffer size is increased when it turns out to be too small to accomodate
   34 the line to read.
   35 */
   36 #define LINE_BUFFER_SIZE_INCREMENT 8192
   37 /*!
   38 Maximum size of the line buffer.
   39 
   40 A text line read from the file must be smaller than this value or the functions fails
   41 and aborts the program.
   42 
   43 10MB should not be a problem as most of the line is filled with the URL and squid 3
   44 limits the URL to 4096 bytes (see MAX_URL). Squid has reportedly been tested with
   45 MAX_URL set up to 32KB so I'm not expecting URL much longer than that.
   46 
   47 Other proxies might handle longer URLs but certainly not longer than 10MB.
   48 
   49 Now, why put a limit? Sarg version 2.3 originaly had no limits until sarg 2.3.3. At
   50 that point a user with a defective network mount point reported that sarg was eating
   51 up 8GB of memory available on the server triggering the OOM killer. So the limit is
   52 here to prevent sarg from choking on an invalid file.
   53 */
   54 #define MAX_LINE_BUFFER_SIZE (10*1024*1024)
   55 
   56 struct longlinestruct
   57 {
   58     //! The buffer to store the data read from the log file.
   59     char *buffer;
   60     //! The size of the buffer.
   61     size_t size;
   62     //! The number of bytes stored in the buffer.
   63     size_t length;
   64     //! The position of the beginning of the current string.
   65     size_t start;
   66     //! The position of the end of the current string.
   67     size_t end;
   68 };
   69 
   70 longline longline_create(void)
   71 {
   72     longline line;
   73 
   74     line=malloc(sizeof(*line));
   75     if (line==NULL) return(NULL);
   76     line->size=INITIAL_LINE_BUFFER_SIZE;
   77     line->buffer=malloc(line->size);
   78     if (line->buffer==NULL) {
   79         free(line);
   80         return(NULL);
   81     }
   82     line->start=0;
   83     line->end=0;
   84     line->length=0;
   85     return(line);
   86 }
   87 
   88 void longline_reset(longline line)
   89 {
   90     if (line!=NULL) {
   91         line->start=0;
   92         line->end=0;
   93         line->length=0;
   94     }
   95 }
   96 
   97 char *longline_read(FileObject *fp_in,longline line)
   98 {
   99     int i;
  100     char *newbuf;
  101     int nread;
  102 
  103     if (line==NULL || line->buffer==NULL) return(NULL);
  104 
  105     while (true) {
  106         for (i=line->end ; i<line->length && (line->buffer[i]=='\n' || line->buffer[i]=='\r') ; i++);
  107         if (i<line->length) {
  108             line->end=i;
  109             break;
  110         }
  111         nread=(FileObject_Eof(fp_in)!=0) ? 0 : FileObject_Read(fp_in,line->buffer,line->size);
  112         if (nread<=0) return(NULL);
  113         line->length=nread;
  114         line->end=0;
  115     }
  116 
  117     line->start=line->end;
  118     while (true) {
  119         for (i=line->end ; i<line->length ; i++) {
  120             if ((unsigned char)line->buffer[i]>=' ') continue;
  121             if (line->buffer[i]=='\n' || line->buffer[i]=='\r') break;
  122         }
  123 
  124         line->end=i;
  125         if (line->end<line->length) break;
  126 
  127         if (line->start>0) {
  128             for (i=line->start ; i<line->length ; i++) line->buffer[i-line->start]=line->buffer[i];
  129             line->length-=line->start;
  130             line->end-=line->start;
  131             line->start=0;
  132         }
  133         if (line->length>=line->size) {
  134             line->size+=LINE_BUFFER_SIZE_INCREMENT;
  135             if (line->size>=MAX_LINE_BUFFER_SIZE) {
  136                 debuga(__FILE__,__LINE__,_("A text line is more than %d bytes long denoting a corrupted file\n"),MAX_LINE_BUFFER_SIZE);
  137                 exit(EXIT_FAILURE);
  138             }
  139             newbuf=realloc(line->buffer,line->size);
  140             if (!newbuf) {
  141                 debuga(__FILE__,__LINE__,_("Not enough memory to read one more line from the file\n"));
  142                 exit(EXIT_FAILURE);
  143             }
  144             line->buffer=newbuf;
  145         }
  146         nread=(FileObject_Eof(fp_in)!=0) ? 0 : FileObject_Read(fp_in,line->buffer+line->length,line->size-line->length);
  147         if (nread<=0) {
  148             if (line->end<=line->start) return(NULL);
  149             if (line->end>=line->size) {
  150                 line->end=line->size;
  151                 line->size++;
  152                 newbuf=realloc(line->buffer,line->size);
  153                 if (!newbuf) {
  154                     debuga(__FILE__,__LINE__,_("Not enough memory to read one more line from the file\n"));
  155                     exit(EXIT_FAILURE);
  156                 }
  157                 line->buffer=newbuf;
  158             }
  159             line->buffer[line->end]='\0';
  160             return(line->buffer+line->start);
  161         }
  162         line->length+=nread;
  163     }
  164     line->buffer[line->end++]='\0';
  165     return(line->buffer+line->start);
  166 }
  167 
  168 void longline_destroy(longline *line_ptr)
  169 {
  170     longline line;
  171 
  172     if (line_ptr==NULL || *line_ptr==NULL) return;
  173     line=*line_ptr;
  174     *line_ptr=NULL;
  175     if (line->buffer!=NULL) free(line->buffer);
  176     free(line);
  177 }