LCOV - code coverage report
Current view: top level - src - fzp.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 143 196 73.0 %
Date: 2017-01-01 Functions: 25 26 96.2 %

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

Generated by: LCOV version 1.10