]>
Commit | Line | Data |
---|---|---|
4ca814cc FM |
1 | /* |
2 | * SARG Squid Analysis Report Generator http://sarg.sourceforge.net | |
61d965f3 | 3 | * 1998, 2012 |
4ca814cc FM |
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 | ||
cdf22cd3 | 30 | //! The size, in bytes, to allocate from the start. |
4ca814cc | 31 | #define INITIAL_LINE_BUFFER_SIZE 32768 |
cdf22cd3 FM |
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) | |
4ca814cc | 55 | |
afaa3b67 | 56 | struct longlinestruct |
4ca814cc | 57 | { |
9bd92830 FM |
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; | |
afaa3b67 FM |
68 | }; |
69 | ||
70 | longline longline_create(void) | |
71 | { | |
9bd92830 | 72 | longline line; |
afaa3b67 | 73 | |
9bd92830 FM |
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); | |
4ca814cc FM |
86 | } |
87 | ||
afaa3b67 FM |
88 | void longline_reset(longline line) |
89 | { | |
9bd92830 FM |
90 | if (line!=NULL) { |
91 | line->start=0; | |
92 | line->end=0; | |
93 | line->length=0; | |
94 | } | |
afaa3b67 FM |
95 | } |
96 | ||
97 | char *longline_read(FILE *fp_in,longline line) | |
4ca814cc | 98 | { |
9bd92830 FM |
99 | int i; |
100 | char *newbuf; | |
101 | size_t nread; | |
4ca814cc | 102 | |
9bd92830 | 103 | if (line==NULL || line->buffer==NULL) return(NULL); |
4ca814cc | 104 | |
9bd92830 FM |
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=(feof(fp_in)!=0) ? 0 : fread(line->buffer,1,line->size,fp_in); | |
112 | if (nread==0) return(NULL); | |
113 | line->length=nread; | |
114 | line->end=0; | |
115 | } | |
4ca814cc | 116 | |
9bd92830 FM |
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 | } | |
7a0a624b | 123 | |
9bd92830 FM |
124 | line->end=i; |
125 | if (line->end<line->length) break; | |
4ca814cc | 126 | |
9bd92830 FM |
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) { | |
cdf22cd3 FM |
134 | line->size+=LINE_BUFFER_SIZE_INCREMENT; |
135 | if (line->size>=MAX_LINE_BUFFER_SIZE) { | |
136 | debuga(_("A text line is more than %d bytes long denoting a corrupted file\n"),MAX_LINE_BUFFER_SIZE); | |
137 | exit(EXIT_FAILURE); | |
138 | } | |
9bd92830 FM |
139 | newbuf=realloc(line->buffer,line->size); |
140 | if (!newbuf) { | |
110ed1b4 | 141 | debuga(_("Not enough memory to read one more line from the file\n")); |
9bd92830 FM |
142 | exit(EXIT_FAILURE); |
143 | } | |
144 | line->buffer=newbuf; | |
145 | } | |
146 | nread=(feof(fp_in)!=0) ? 0 : fread(line->buffer+line->length,1,line->size-line->length,fp_in); | |
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) { | |
110ed1b4 | 154 | debuga(_("Not enough memory to read one more line from the file\n")); |
9bd92830 FM |
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); | |
4ca814cc FM |
166 | } |
167 | ||
afaa3b67 | 168 | void longline_destroy(longline *line_ptr) |
4ca814cc | 169 | { |
9bd92830 | 170 | longline line; |
afaa3b67 | 171 | |
9bd92830 FM |
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); | |
4ca814cc | 177 | } |