LCOV - code coverage report
Current view: top level - src - fzp.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 160 245 65.3 %
Date: 2015-10-31 Functions: 27 31 87.1 %

          Line data    Source code
       1             : #include "burp.h"
       2             : #include "alloc.h"
       3             : #include "cmd.h"
       4             : #include "fsops.h"
       5             : #include "fzp.h"
       6             : #include "log.h"
       7             : #include "prepend.h"
       8             : #ifndef HAVE_WIN32
       9             : #include "server/compress.h"
      10             : #include "server/protocol1/zlibio.h"
      11             : #endif
      12             : 
      13        2768 : static struct fzp *fzp_alloc(void)
      14             : {
      15        2768 :         return (struct fzp *)calloc_w(1, sizeof(struct fzp), __func__);
      16             : }
      17             : 
      18        2767 : static void fzp_free(struct fzp **fzp)
      19             : {
      20        5534 :         if(!fzp || !*fzp) return;
      21        2767 :         free_v((void **)fzp);
      22             : }
      23             : 
      24        2170 : FILE *open_fp(const char *fname, const char *mode)
      25             : {
      26        2170 :         FILE *fp=NULL;
      27        2170 :         if(!(fp=fopen(fname, mode)))
      28          21 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      29        2170 :         return fp;
      30             : }
      31             : 
      32         598 : gzFile open_zp(const char *fname, const char *mode)
      33             : {
      34         598 :         gzFile zp=NULL;
      35             : 
      36         598 :         if(!(zp=gzopen(fname, mode)))
      37           0 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      38         598 :         return zp;
      39             : }
      40             : 
      41        2169 : static int close_fp(FILE **fp)
      42             : {
      43        2169 :         int ret=0;
      44        2169 :         if(!*fp) return ret;
      45        2148 :         if(fclose(*fp))
      46             :         {
      47           0 :                 logp("fclose failed: %s\n", strerror(errno));
      48           0 :                 ret=-1;
      49             :         }
      50        2148 :         *fp=NULL;
      51        2148 :         return ret;
      52             : }
      53             : 
      54         598 : static int close_zp(gzFile *zp)
      55             : {
      56             :         int e;
      57         598 :         int ret=0;
      58         598 :         if(!*zp) return ret;
      59         598 :         if((e=gzclose(*zp)))
      60             :         {
      61           0 :                 const char *str=NULL;
      62           0 :                 if(e==Z_ERRNO) str=strerror(errno);
      63           0 :                 else str=gzerror(*zp, &e);
      64           0 :                 logp("gzclose failed: %d (%s)\n", e, str?:"");
      65           0 :                 ret=-1;
      66             :         }
      67         598 :         return ret;
      68             : }
      69             : 
      70           0 : static void unknown_type(enum fzp_type type, const char *func)
      71             : {
      72           0 :         logp("unknown type in %s: %d\n", func, type);
      73           0 : }
      74             : 
      75          11 : static void not_open(const char *func)
      76             : {
      77          11 :         logp("File pointer not open in %s\n", func);
      78          11 : }
      79             : 
      80        2768 : static struct fzp *fzp_do_open(const char *path, const char *mode,
      81             :         enum fzp_type type)
      82             : {
      83        2768 :         struct fzp *fzp=NULL;
      84             : 
      85        2768 :         if(!(fzp=fzp_alloc())) goto error;
      86        2768 :         fzp->type=type;
      87        2768 :         switch(type)
      88             :         {
      89             :                 case FZP_FILE:
      90        2170 :                         if(!(fzp->fp=open_fp(path, mode)))
      91          21 :                                 goto error;
      92        2149 :                         return fzp;
      93             :                 case FZP_COMPRESSED:
      94         598 :                         if(!(fzp->zp=open_zp(path, mode)))
      95           0 :                                 goto error;
      96         598 :                         return fzp;
      97             :                 default:
      98           0 :                         unknown_type(fzp->type, __func__);
      99           0 :                         goto error;
     100             :         }
     101             : error:
     102          21 :         fzp_close(&fzp);
     103          21 :         return NULL;
     104             : }
     105             : 
     106        2170 : struct fzp *fzp_open(const char *path, const char *mode)
     107             : {
     108        2170 :         return fzp_do_open(path, mode, FZP_FILE);
     109             : }
     110             : 
     111         598 : struct fzp *fzp_gzopen(const char *path, const char *mode)
     112             : {
     113         598 :         return fzp_do_open(path, mode, FZP_COMPRESSED);
     114             : }
     115             : 
     116      119786 : int fzp_close(struct fzp **fzp)
     117             : {
     118      119786 :         int ret=-1;
     119      119786 :         if(!fzp || !*fzp) return 0;
     120        2767 :         switch((*fzp)->type)
     121             :         {
     122             :                 case FZP_FILE:
     123        2169 :                         ret=close_fp(&((*fzp)->fp));
     124        2169 :                         break;
     125             :                 case FZP_COMPRESSED:
     126         598 :                         ret=close_zp(&((*fzp)->zp));
     127         598 :                         break;
     128             :                 default:
     129           0 :                         unknown_type((*fzp)->type, __func__);
     130           0 :                         break;
     131             :         }
     132        2767 :         fzp_free(fzp);
     133        2767 :         return ret;
     134             : }
     135             : 
     136      585357 : size_t fzp_read(struct fzp *fzp, void *ptr, size_t nmemb)
     137             : {
     138      585357 :         if(fzp) switch(fzp->type)
     139             :         {
     140             :                 case FZP_FILE:
     141      455320 :                         return fread(ptr, 1, nmemb, fzp->fp);
     142             :                 case FZP_COMPRESSED:
     143      130036 :                         return gzread(fzp->zp, ptr, (unsigned)nmemb);
     144             :                 default:
     145           0 :                         unknown_type(fzp->type, __func__);
     146           0 :                         goto error;
     147             :         }
     148           1 :         not_open(__func__);
     149             : error:
     150           1 :         return 0;
     151             : }
     152             : 
     153      279236 : size_t fzp_write(struct fzp *fzp, const void *ptr, size_t nmemb)
     154             : {
     155      279236 :         if(fzp) switch(fzp->type)
     156             :         {
     157             :                 case FZP_FILE:
     158      177763 :                         return fwrite(ptr, 1, nmemb, fzp->fp);
     159             :                 case FZP_COMPRESSED:
     160      101472 :                         return gzwrite(fzp->zp, ptr, (unsigned)nmemb);
     161             :                 default:
     162           0 :                         unknown_type(fzp->type, __func__);
     163           0 :                         goto error;
     164             :         }
     165           1 :         not_open(__func__);
     166             : error:
     167           1 :         return 0;
     168             : }
     169             : 
     170         410 : int fzp_eof(struct fzp *fzp)
     171             : {
     172         410 :         if(fzp) switch(fzp->type)
     173             :         {
     174             :                 case FZP_FILE:
     175         280 :                         return feof(fzp->fp);
     176             :                 case FZP_COMPRESSED:
     177         129 :                         return gzeof(fzp->zp);
     178             :                 default:
     179           0 :                         unknown_type(fzp->type, __func__);
     180           0 :                         goto error;
     181             :         }
     182           1 :         not_open(__func__);
     183             : error:
     184             :         // Non-zero means end of file. Should be OK to use -1 here.
     185           1 :         return -1;
     186             : }
     187             : 
     188          13 : int fzp_flush(struct fzp *fzp)
     189             : {
     190          13 :         if(fzp) switch(fzp->type)
     191             :         {
     192             :                 case FZP_FILE:
     193           6 :                         return fflush(fzp->fp);
     194             :                 case FZP_COMPRESSED:
     195           6 :                         return gzflush(fzp->zp, Z_FINISH);
     196             :                 default:
     197           0 :                         unknown_type(fzp->type, __func__);
     198           0 :                         goto error;
     199             :         }
     200           1 :         not_open(__func__);
     201             : error:
     202           1 :         return EOF;
     203             : }
     204             : 
     205         257 : int fzp_seek(struct fzp *fzp, off_t offset, int whence)
     206             : {
     207         257 :         if(fzp) switch(fzp->type)
     208             :         {
     209             :                 case FZP_FILE:
     210           5 :                         return fseeko(fzp->fp, offset, whence);
     211             :                 case FZP_COMPRESSED:
     212             :                         // Notice that gzseek returns the new offset.
     213         251 :                         if(gzseek(fzp->zp, offset, whence)==offset)
     214         251 :                                 return 0;
     215           0 :                         goto error;
     216             :                 default:
     217           0 :                         unknown_type(fzp->type, __func__);
     218           0 :                         goto error;
     219             :         }
     220           1 :         not_open(__func__);
     221             : error:
     222           1 :         return -1;
     223             : }
     224             : 
     225       13001 : off_t fzp_tell(struct fzp *fzp)
     226             : {
     227       13001 :         if(fzp) switch(fzp->type)
     228             :         {
     229             :                 case FZP_FILE:
     230       12895 :                         return ftello(fzp->fp);
     231             :                 case FZP_COMPRESSED:
     232         105 :                         return gztell(fzp->zp);
     233             :                 default:
     234           0 :                         unknown_type(fzp->type, __func__);
     235           0 :                         goto error;
     236             :         }
     237           1 :         not_open(__func__);
     238             : error:
     239           1 :         return -1;
     240             : }
     241             : 
     242             : #ifndef HAVE_WIN32
     243             : // There is no zlib gztruncate. Inflate it, truncate it, recompress it.
     244           4 : static int gztruncate(const char *path, off_t length, int compression)
     245             : {
     246           4 :         int ret=1;
     247             :         char tmp[16];
     248           4 :         char *dest=NULL;
     249           4 :         char *dest2=NULL;
     250           4 :         snprintf(tmp, sizeof(tmp), ".%d", getpid());
     251          12 :         if(!(dest=prepend(path, tmp))
     252           4 :           || !(dest2=prepend(dest, "-2"))
     253          12 :           || zlib_inflate(NULL, path, dest, NULL))
     254           0 :                 goto end;
     255           4 :         if(truncate(dest, length))
     256             :         {
     257           0 :                 logp("truncate of %s failed in %s\n", dest, __func__);
     258           0 :                 goto end;
     259             :         }
     260           4 :         if(compress_file(dest, dest2, compression))
     261           0 :                 goto end;
     262           4 :         unlink(dest);
     263           4 :         ret=do_rename(dest2, path);
     264             : end:
     265           4 :         if(dest) unlink(dest);
     266           4 :         if(dest2) unlink(dest2);
     267           4 :         free_w(&dest);
     268           4 :         free_w(&dest2);
     269           4 :         return ret;
     270             : }
     271             : 
     272         209 : int fzp_truncate(const char *path, enum fzp_type type, off_t length,
     273             :         int compression)
     274             : {
     275         209 :         switch(type)
     276             :         {
     277             :                 case FZP_FILE:
     278         205 :                         return truncate(path, length);
     279             :                 case FZP_COMPRESSED:
     280           4 :                         return gztruncate(path, length, compression);
     281             :                 default:
     282           0 :                         unknown_type(type, __func__);
     283           0 :                         goto error;
     284             :         }
     285             : error:
     286           0 :         return -1;
     287             : }
     288             : #endif
     289             : 
     290      550849 : int fzp_printf(struct fzp *fzp, const char *format, ...)
     291             : {
     292             :         static char buf[4096];
     293      550849 :         int ret=-1;
     294             :         va_list ap;
     295      550849 :         va_start(ap, format);
     296      550849 :         vsnprintf(buf, sizeof(buf), format, ap);
     297             : 
     298      550849 :         if(fzp) switch(fzp->type)
     299             :         {
     300             :                 case FZP_FILE:
     301      347907 :                         ret=fprintf(fzp->fp, "%s", buf);
     302      347907 :                         break;
     303             :                 case FZP_COMPRESSED:
     304      202941 :                         ret=gzprintf(fzp->zp, "%s", buf);
     305      202941 :                         break;
     306             :                 default:
     307           0 :                         unknown_type(fzp->type, __func__);
     308           0 :                         break;
     309             :         }
     310             :         else
     311           1 :                 not_open(__func__);
     312      550849 :         va_end(ap);
     313      550849 :         return ret;
     314             : }
     315             : 
     316           1 : void fzp_setlinebuf(struct fzp *fzp)
     317             : {
     318             : #ifndef HAVE_WIN32
     319           1 :         if(fzp) switch(fzp->type)
     320             :         {
     321             :                 case FZP_FILE:
     322           0 :                         setlinebuf(fzp->fp);
     323           0 :                         return;
     324             :                 case FZP_COMPRESSED:
     325           0 :                         logp("gzsetlinebuf() does not exist in %s\n", __func__);
     326           0 :                         return;
     327             :                 default:
     328           0 :                         unknown_type(fzp->type, __func__);
     329           0 :                         return;
     330             :         }
     331           1 :         not_open(__func__);
     332             : #endif
     333             : }
     334             : 
     335         944 : char *fzp_gets(struct fzp *fzp, char *s, int size)
     336             : {
     337         944 :         if(fzp) switch(fzp->type)
     338             :         {
     339             :                 case FZP_FILE:
     340         943 :                         return fgets(s, size, fzp->fp);
     341             :                 case FZP_COMPRESSED:
     342           0 :                         return gzgets(fzp->zp, s, size);
     343             :                 default:
     344           0 :                         unknown_type(fzp->type, __func__);
     345           0 :                         goto error;
     346             :         }
     347           1 :         not_open(__func__);
     348             : error:
     349           1 :         return NULL;
     350             : }
     351             : 
     352           1 : extern int fzp_fileno(struct fzp *fzp)
     353             : {
     354           1 :         if(fzp) switch(fzp->type)
     355             :         {
     356             :                 case FZP_FILE:
     357           0 :                         return fileno(fzp->fp);
     358             :                 case FZP_COMPRESSED:
     359           0 :                         logp("gzfileno() does not exist in %s\n", __func__);
     360           0 :                         goto error;
     361             :                 default:
     362           0 :                         unknown_type(fzp->type, __func__);
     363           0 :                         goto error;
     364             :         }
     365           1 :         not_open(__func__);
     366             : error:
     367           1 :         return -1;
     368             : }
     369             : 
     370           0 : static struct fzp *fzp_do_dopen(int fd, const char *mode,
     371             :         enum fzp_type type)
     372             : {
     373           0 :         struct fzp *fzp=NULL;
     374             : 
     375           0 :         if(!(fzp=fzp_alloc())) goto error;
     376           0 :         fzp->type=type;
     377           0 :         switch(type)
     378             :         {
     379             :                 case FZP_FILE:
     380           0 :                         if(!(fzp->fp=fdopen(fd, mode)))
     381           0 :                                 goto error;
     382           0 :                         return fzp;
     383             :                 case FZP_COMPRESSED:
     384           0 :                         if(!(fzp->zp=gzdopen(fd, mode)))
     385           0 :                                 goto error;
     386           0 :                         return fzp;
     387             :                 default:
     388           0 :                         unknown_type(fzp->type, __func__);
     389           0 :                         goto error;
     390             :         }
     391             : error:
     392           0 :         fzp_close(&fzp);
     393           0 :         return NULL;
     394             : }
     395             : 
     396           0 : struct fzp *fzp_dopen(int fd, const char *mode)
     397             : {
     398           0 :         return fzp_do_dopen(fd, mode, FZP_FILE);
     399             : }
     400             : 
     401           0 : struct fzp *fzp_gzdopen(int fd, const char *mode)
     402             : {
     403           0 :         return fzp_do_dopen(fd, mode, FZP_COMPRESSED);
     404             : }
     405             : 
     406           1 : void fzp_ERR_print_errors_fp(struct fzp *fzp)
     407             : {
     408           1 :         if(fzp) switch(fzp->type)
     409             :         {
     410             :                 case FZP_FILE:
     411           0 :                         ERR_print_errors_fp(fzp->fp);
     412           0 :                         break;
     413             :                 case FZP_COMPRESSED:
     414             :                         logp("ERR_print_errors_zp() does not exist in %s\n",
     415           0 :                                 __func__);
     416           0 :                         break;
     417             :                 default:
     418           0 :                         unknown_type(fzp->type, __func__);
     419           0 :                         break;
     420             :         }
     421           1 : }
     422             : 
     423           1 : X509 *fzp_PEM_read_X509(struct fzp *fzp)
     424             : {
     425           1 :         if(fzp) switch(fzp->type)
     426             :         {
     427             :                 case FZP_FILE:
     428           0 :                         return PEM_read_X509(fzp->fp, NULL, NULL, NULL);
     429             :                 case FZP_COMPRESSED:
     430             :                         logp("PEM_read_X509() does not exist in %s\n",
     431           0 :                                 __func__);
     432           0 :                         goto error;
     433             :                 default:
     434           0 :                         unknown_type(fzp->type, __func__);
     435           0 :                         goto error;
     436             :         }
     437           1 :         not_open(__func__);
     438             : error:
     439           1 :         return NULL;
     440             : }
     441             : 
     442          59 : static void pass_msg(size_t nmemb, size_t got, int pass)
     443             : {
     444             :         logp("Tried to read %u bytes, got %u by pass %d\n",
     445          59 :                 nmemb, got, pass);
     446          59 : }
     447             : 
     448      585266 : int fzp_read_ensure(struct fzp *fzp, void *ptr, size_t nmemb, const char *func)
     449             : {
     450             :         static int f;
     451             :         static size_t r;
     452             :         static size_t got;
     453             :         static int pass;
     454     1170212 :         for(r=0, got=0, pass=0; got!=nmemb; pass++)
     455             :         {
     456      585325 :                 r=fzp_read(fzp, ((char *)ptr)+got, nmemb-got);
     457      585325 :                 if(r>0)
     458             :                 {
     459      584946 :                         got+=r;
     460      584946 :                         continue;
     461             :                 }
     462             :                 if(r<0)
     463             :                 {
     464             :                         pass_msg(nmemb, got, pass);
     465             :                         logp("Error in %s, called from %s: %s\n",
     466             :                                 __func__, func, strerror(errno));
     467             :                         return -1;
     468             :                 }
     469         379 :                 f=fzp_eof(fzp);
     470         379 :                 if(!f) continue; // Not yet end of file, keep trying.
     471         379 :                 if(f>0)
     472             :                 {
     473             :                         // End of file.
     474         379 :                         if(!got) return 1;
     475          59 :                         pass_msg(nmemb, got, pass);
     476             :                         logp("Error in %s, called from %s: %u bytes, eof\n",
     477          59 :                                 __func__, func, got);
     478          59 :                         return -1;
     479             :                 }
     480             :                 else
     481             :                 {
     482           0 :                         pass_msg(nmemb, got, pass);
     483             :                         logp("Error in %s by fzp_feof, called from %s: %s\n",
     484           0 :                                 __func__, func, strerror(errno));
     485           0 :                         return -1;
     486             :                 }
     487             :         }
     488      584887 :         return 0;
     489             : }

Generated by: LCOV version 1.10