LCOV - code coverage report
Current view: top level - src - fzp.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 163 249 65.5 %
Date: 2015-11-30 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        3234 : static struct fzp *fzp_alloc(void)
      14             : {
      15        3234 :         return (struct fzp *)calloc_w(1, sizeof(struct fzp), __func__);
      16             : }
      17             : 
      18        3233 : static void fzp_free(struct fzp **fzp)
      19             : {
      20        6466 :         if(!fzp || !*fzp) return;
      21        3233 :         free_v((void **)fzp);
      22             : }
      23             : 
      24        2635 : FILE *open_fp(const char *fname, const char *mode)
      25             : {
      26        2635 :         FILE *fp=NULL;
      27        2635 :         if(!(fp=fopen(fname, mode)))
      28          21 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      29        2635 :         return fp;
      30             : }
      31             : 
      32         599 : gzFile open_zp(const char *fname, const char *mode)
      33             : {
      34         599 :         gzFile zp=NULL;
      35             : 
      36         599 :         if(!(zp=gzopen(fname, mode)))
      37           1 :                 logp("could not open %s: %s\n", fname, strerror(errno));
      38         599 :         return zp;
      39             : }
      40             : 
      41        2634 : static int close_fp(FILE **fp)
      42             : {
      43        2634 :         int ret=0;
      44        2634 :         if(!*fp) return ret;
      45        2613 :         if(fclose(*fp))
      46             :         {
      47           0 :                 logp("fclose failed: %s\n", strerror(errno));
      48           0 :                 ret=-1;
      49             :         }
      50        2613 :         *fp=NULL;
      51        2613 :         return ret;
      52             : }
      53             : 
      54         599 : static int close_zp(gzFile *zp)
      55             : {
      56             :         int e;
      57         599 :         int ret=0;
      58         599 :         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        3234 : static struct fzp *fzp_do_open(const char *path, const char *mode,
      81             :         enum fzp_type type)
      82             : {
      83        3234 :         struct fzp *fzp=NULL;
      84             : 
      85        3234 :         if(!(fzp=fzp_alloc())) goto error;
      86        3234 :         fzp->type=type;
      87        3234 :         switch(type)
      88             :         {
      89             :                 case FZP_FILE:
      90        2635 :                         if(!(fzp->fp=open_fp(path, mode)))
      91          21 :                                 goto error;
      92        2614 :                         return fzp;
      93             :                 case FZP_COMPRESSED:
      94         599 :                         if(!(fzp->zp=open_zp(path, mode)))
      95           1 :                                 goto error;
      96         598 :                         return fzp;
      97             :                 default:
      98           0 :                         unknown_type(fzp->type, __func__);
      99           0 :                         goto error;
     100             :         }
     101             : error:
     102          22 :         fzp_close(&fzp);
     103          22 :         return NULL;
     104             : }
     105             : 
     106        2635 : struct fzp *fzp_open(const char *path, const char *mode)
     107             : {
     108        2635 :         return fzp_do_open(path, mode, FZP_FILE);
     109             : }
     110             : 
     111         599 : struct fzp *fzp_gzopen(const char *path, const char *mode)
     112             : {
     113         599 :         return fzp_do_open(path, mode, FZP_COMPRESSED);
     114             : }
     115             : 
     116      120351 : int fzp_close(struct fzp **fzp)
     117             : {
     118      120351 :         int ret=-1;
     119      120351 :         if(!fzp || !*fzp) return 0;
     120        3233 :         switch((*fzp)->type)
     121             :         {
     122             :                 case FZP_FILE:
     123        2634 :                         ret=close_fp(&((*fzp)->fp));
     124        2634 :                         break;
     125             :                 case FZP_COMPRESSED:
     126         599 :                         ret=close_zp(&((*fzp)->zp));
     127         599 :                         break;
     128             :                 default:
     129           0 :                         unknown_type((*fzp)->type, __func__);
     130           0 :                         break;
     131             :         }
     132        3233 :         fzp_free(fzp);
     133        3233 :         return ret;
     134             : }
     135             : 
     136      590356 : int fzp_read(struct fzp *fzp, void *ptr, size_t nmemb)
     137             : {
     138      590356 :         if(fzp) switch(fzp->type)
     139             :         {
     140             :                 case FZP_FILE:
     141      460319 :                         return (int)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      279244 : size_t fzp_write(struct fzp *fzp, const void *ptr, size_t nmemb)
     154             : {
     155      279244 :         if(fzp) switch(fzp->type)
     156             :         {
     157             :                 case FZP_FILE:
     158      177771 :                         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         261 : int fzp_seek(struct fzp *fzp, off_t offset, int whence)
     206             : {
     207         261 :         if(fzp) switch(fzp->type)
     208             :         {
     209             :                 case FZP_FILE:
     210           9 :                         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      551053 : int fzp_printf(struct fzp *fzp, const char *format, ...)
     291             : {
     292             :         static char buf[4096];
     293      551053 :         int ret=-1;
     294             :         va_list ap;
     295      551053 :         va_start(ap, format);
     296      551053 :         vsnprintf(buf, sizeof(buf), format, ap);
     297             : 
     298      551053 :         if(fzp) switch(fzp->type)
     299             :         {
     300             :                 case FZP_FILE:
     301      348111 :                         ret=fprintf(fzp->fp, "%s", buf);
     302      348111 :                         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      551053 :         va_end(ap);
     313      551053 :         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        1137 : char *fzp_gets(struct fzp *fzp, char *s, int size)
     336             : {
     337        1137 :         if(fzp) switch(fzp->type)
     338             :         {
     339             :                 case FZP_FILE:
     340        1136 :                         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 int 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         379 :                 if(r<0)
     463             :                 {
     464           0 :                         pass_msg(nmemb, got, pass);
     465             :                         logp("Error in %s, called from %s: %s\n",
     466           0 :                                 __func__, func, strerror(errno));
     467           0 :                         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