]> git.ipfire.org Git - thirdparty/sarg.git/blob - decomp.c
Indent the configure script for more readability.
[thirdparty/sarg.git] / decomp.c
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 #ifdef HAVE_ZLIB_H
30 #include "zlib.h"
31 #endif
32 #ifdef HAVE_BZLIB_H
33 #include "bzlib.h"
34 #endif
35
36 #ifdef HAVE_ZLIB_H
37 /*!
38 * Read from gzip file.
39 *
40 * \param Data The file object.
41 * \param Buffer The boffer to store the data read.
42 * \param Size How many bytes to read.
43 *
44 * \return The number of bytes read.
45 */
46 static int Gzip_Read(void *Data,void *Buffer,int Size)
47 {
48 return(gzread((gzFile)Data,Buffer,Size));
49 }
50
51 /*!
52 * Check if end of file is reached.
53 *
54 * \param Data The file object.
55 *
56 * \return \c True if end of file is reached.
57 */
58 static int Gzip_Eof(void *Data)
59 {
60 return(gzeof((gzFile)Data));
61 }
62
63 /*!
64 * Return to the beginnig of the file.
65 *
66 * \param Data The file object.
67 */
68 static void Gzip_Rewind(void *Data)
69 {
70 gzrewind((gzFile)Data);
71 }
72
73 /*!
74 * Close the file.
75 *
76 * \param Data File to close.
77 *
78 * \return 0 on success or -1 on error.
79 */
80 static int Gzip_Close(void *Data)
81 {
82 int RetCode=-1;
83 int Status;
84
85 Status=gzclose((gzFile)Data);
86 switch (Status)
87 {
88 case Z_OK:
89 RetCode=0;
90 break;
91 case Z_STREAM_ERROR:
92 FileObject_SetLastCloseError(_("Invalid gzip file"));
93 break;
94 case Z_ERRNO:
95 FileObject_SetLastCloseError(_("File operation error"));
96 break;
97 case Z_MEM_ERROR:
98 FileObject_SetLastCloseError(_("Not enough memory"));
99 break;
100 case Z_BUF_ERROR:
101 FileObject_SetLastCloseError(_("Truncated gzip stream"));
102 break;
103 default:
104 FileObject_SetLastCloseError(_("Unknown error returned by zlib"));
105 break;
106 }
107 return(RetCode);
108 }
109
110 /*!
111 * Open a file object to read from a gzip file.
112 *
113 * \return The object to pass to other function in this module.
114 */
115 static FileObject *Gzip_Open(int fd)
116 {
117 FileObject *File;
118
119 FileObject_SetLastOpenError(NULL);
120 File=calloc(1,sizeof(*File));
121 if (!File)
122 {
123 FileObject_SetLastOpenError(_("Not enough memory"));
124 return(NULL);
125 }
126 File->Data=gzdopen(fd,"rb");
127 if (!File->Data)
128 {
129 free(File);
130 FileObject_SetLastOpenError(_("Error opening gzip file"));
131 return(NULL);
132 }
133 File->Read=Gzip_Read;
134 File->Eof=Gzip_Eof;
135 File->Rewind=Gzip_Rewind;
136 File->Close=Gzip_Close;
137 return(File);
138 }
139 #endif
140
141 #ifdef HAVE_BZLIB_H
142
143 struct BzlibInternalFile
144 {
145 //! Bzlib object.
146 BZFILE *BzFile;
147 //! \c True if end of file is reached.
148 bool Eof;
149 //! Copy of the original file handle.
150 int fd;
151 }
152
153 /*!
154 * Read from bzip file.
155 *
156 * \param Data The file object.
157 * \param Buffer The boffer to store the data read.
158 * \param Size How many bytes to read.
159 *
160 * \return The number of bytes read.
161 */
162 static int Bzip_Read(void *Data,void *Buffer,int Size)
163 {
164 struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data;
165 int nread;
166
167 nread=BZ2_bzread(BData->BzFile,Buffer,Size);
168 if (nread==0) BData->Eof=true;
169 return(nread);
170 }
171
172 /*!
173 * Check if end of file is reached.
174 *
175 * \param Data The file object.
176 *
177 * \return \c True if end of file is reached.
178 */
179 static int Bzip_Eof(void *Data)
180 {
181 struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data;
182 return(BData->Eof);
183 }
184
185 /*!
186 * Return to the beginnig of the file.
187 *
188 * \param Data The file object.
189 */
190 static void Bzip_Rewind(void *Data)
191 {
192 struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data;
193 int fd;
194
195 BZ2_bzclose(BData->BzFile);
196 fd=dup(BData->fd);
197 if (fd==-1)
198 {
199 debuga(__FILE__,__LINE__,_("Cannot rewind bzip file\n"));
200 exit(EXIT_FAILURE);
201 }
202 BData->BzFile=BZ2_bzdopen(fd,"rb");
203 if (!BData->BzFile)
204 {
205 debuga(__FILE__,__LINE__,_("Cannot rewind bzip file\n"));
206 exit(EXIT_FAILURE);
207 }
208 }
209
210 /*!
211 * Close the file.
212 *
213 * \param Data File to close.
214 *
215 * \return 0 on success or -1 on error.
216 */
217 static int Bzip_Close(void *Data)
218 {
219 struct BzlibInternalFile *BData=(struct BzlibInternalFile *)Data;
220
221 BZ2_bzclose(BData->BzFile);
222 close(BData->fd);
223 free(BData);
224 return(0);
225 }
226
227 /*!
228 * Open a file object to read from a bzip file.
229 *
230 * \return The object to pass to other function in this module.
231 */
232 static FileObject *Bzip_Open(int fd)
233 {
234 FileObject *File;
235 struct BzlibInternalFile *BData;
236
237 FileObject_SetLastOpenError(NULL);
238 File=calloc(1,sizeof(*File));
239 if (!File)
240 {
241 FileObject_SetLastOpenError(_("Not enough memory"));
242 return(NULL);
243 }
244 BData=calloc(1,sizeof(*BData));
245 if (!BData)
246 {
247 free(File);
248 FileObject_SetLastOpenError(_("Not enough memory"));
249 return(NULL);
250 }
251 BData->fd=dup(fd);
252 if (BData->fd==-1)
253 {
254 free(BData);
255 free(File);
256 FileObject_SetLastOpenError(_("Error duplicating file descriptor"));
257 return(NULL);
258 }
259 File=Data=BData;
260 BData->BzFile=BZ2_bzdopen(fd,"rb");
261 if (!BData->BzFile)
262 {
263 close(BData->fd);
264 free(BData);
265 free(File);
266 FileObject_SetLastOpenError(_("Error opening bzip file"));
267 return(NULL);
268 }
269 File->Read=Bzip_Read;
270 File->Eof=Bzip_Eof;
271 File->Rewind=Bzip_Rewind;
272 File->Close=Bzip_Close;
273 return(File);
274 }
275 #endif
276
277
278 /*!
279 Open the log file. If it is compressed, uncompress it through a pipe.
280
281 Log files compressed with gzip, bzip2 or compress are uncompressed with zcat or bzcat.
282
283 If the log file does not exist, the process terminates with an error message.
284
285 \param arq The log file to process.
286 \param pipe A variable set to \c true if the log file is opened through a pipe or set to \c false if the file is open directly.
287
288 \date 2009-09-24 - F Marchal\n This function used to uncompress .Z files in
289 place using uncompress but that required a write access to the log directory,
290 could conflict with logrotate and could leave the log file uncompressed if sarg
291 crashed. According to the documentation, zcat is capable of uncompressing .Z
292 files so it is now used.
293
294 \date 2010-05-10 - F Marchal\n
295 The function doesn't use a temporary file any more and read the compressed file through a pipe.
296 */
297 FileObject *decomp(const char *arq)
298 {
299 int fd;
300 FileObject *fi;
301 unsigned char buf[3];
302 ssize_t nread;
303
304 // guess file type
305 fd=open(arq,O_RDONLY | O_LARGEFILE);
306 if (fd==-1) {
307 debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),arq,strerror(errno));
308 exit(EXIT_FAILURE);
309 }
310 nread=read(fd,buf,sizeof(buf));
311 if (nread==-1) {
312 debuga(__FILE__,__LINE__,_("Error while reading \"%s\" to guess its type: %s\n"),arq,strerror(errno));
313 exit(EXIT_FAILURE);
314 }
315 if (nread<3) {
316 debuga(__FILE__,__LINE__,_("File \"%s\" is too small to guess its type\n"),arq);
317 exit(EXIT_FAILURE);
318 }
319 if (lseek(fd,0,SEEK_SET)==-1) {
320 debuga(__FILE__,__LINE__,_("Cannot return to the beginning of file \"%s\": %s"),arq,strerror(errno));
321 exit(EXIT_FAILURE);
322 }
323
324 if (buf[0]==0x1F && buf[1]==0x8B && buf[2]==0x08)//gzip file
325 {
326 #ifdef HAVE_ZLIB_H
327 fi=Gzip_Open(fd);
328 #else
329 debuga(__FILE__,__LINE__,_("Sarg was not compiled with gzip support to read file \"%s\"\n"),arq);
330 exit(EXIT_FAILURE);
331 #endif
332 }
333 else if (buf[0]==0x42 && buf[1]==0x5A && buf[2]==0x68)//bzip2 file
334 {
335 #ifdef HAVE_BZLIB_H
336 fi=Bzip_Open(fd);
337 #else
338 debuga(__FILE__,__LINE__,_("Sarg was not compiled with bzip support to read file \"%s\"\n"),arq);
339 exit(EXIT_FAILURE);
340 #endif
341 }
342 else if (buf[0]==0x1F && (buf[1]==0x9D || buf[1]==0xA0))//LZW and LZH compressed file
343 {
344 debuga(__FILE__,__LINE__,_("Support for LZW and LZH compressed files was removed in sarg 2.4.\n"
345 "You can still read such a file with a command like this:\n"
346 " zcat \"%s\" | sarg - [your usual options here]\n"
347 "If you think it is important for sarg to read those files, open a bug ticket at <http://sourceforge.net/p/sarg/bugs/>.\n"),
348 arq);
349 exit(EXIT_FAILURE);
350 }
351 else //normal file
352 {
353 fi=FileObject_FdOpen(fd);
354 }
355 return(fi);
356 }