LCOV - code coverage report
Current view: top level - src/server - list.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 0 148 0.0 %
Date: 2015-10-31 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../asfd.h"
       4             : #include "../async.h"
       5             : #include "../attribs.h"
       6             : #include "../bu.h"
       7             : #include "../cmd.h"
       8             : #include "../cntr.h"
       9             : #include "../log.h"
      10             : #include "../prepend.h"
      11             : #include "../regexp.h"
      12             : #include "bu_get.h"
      13             : #include "child.h"
      14             : #include "manio.h"
      15             : 
      16             : // Want to make sure that we are listening for reads too - this will let us
      17             : // exit promptly if the client was killed.
      18             : // FIX THIS: Maybe some of this should go in async.c/asfd.c.
      19           0 : static int read_and_write(struct asfd *asfd)
      20             : {
      21           0 :         if(asfd->as->read_write(asfd->as)) return -1;
      22           0 :         if(!asfd->rbuf->buf) return 0;
      23           0 :         iobuf_log_unexpected(asfd->rbuf, __func__);
      24           0 :         return -1;
      25             : }
      26             : 
      27           0 : static int flush_asio(struct asfd *asfd)
      28             : {
      29           0 :         while(asfd->writebuflen>0)
      30           0 :                 if(read_and_write(asfd)) return -1;
      31           0 :         return 0;
      32             : }
      33             : 
      34           0 : static int write_wrapper(struct asfd *asfd, struct iobuf *wbuf)
      35             : {
      36             :         while(1)
      37             :         {
      38           0 :                 switch(asfd->append_all_to_write_buffer(asfd, wbuf))
      39             :                 {
      40           0 :                         case APPEND_OK: return 0;
      41           0 :                         case APPEND_BLOCKED: break;
      42           0 :                         default: return -1;
      43             :                 }
      44           0 :                 if(read_and_write(asfd)) return -1;
      45             :         }
      46             :         return 0;
      47             : }
      48             : 
      49           0 : static int write_wrapper_str(struct asfd *asfd, enum cmd wcmd, const char *wsrc)
      50             : {
      51             :         static struct iobuf wbuf;
      52           0 :         wbuf.cmd=wcmd;
      53           0 :         wbuf.buf=(char *)wsrc;
      54           0 :         wbuf.len=strlen(wsrc);
      55           0 :         return write_wrapper(asfd, &wbuf);
      56             : }
      57             : 
      58           0 : int check_browsedir(const char *browsedir,
      59             :         struct sbuf *mb, size_t bdlen, char **last_bd_match)
      60             : {
      61           0 :         char *cp=mb->path.buf;
      62           0 :         char *copy=NULL;
      63           0 :         if(bdlen>0)
      64             :         {
      65           0 :                 if(strncmp(browsedir, cp, bdlen))
      66           0 :                         return 0;
      67           0 :                 cp+=bdlen;
      68           0 :                 if(browsedir[bdlen-1]!='/')
      69             :                 {
      70           0 :                         if(*cp!='\0')
      71             :                         {
      72           0 :                                 if(*cp!='/') return 0;
      73           0 :                                 cp++;
      74             :                         }
      75             :                 }
      76             :         }
      77           0 :         if(*cp=='\0') cp=(char *)".";
      78           0 :         if(!(copy=strdup_w(cp, __func__))) goto err;
      79           0 :         if((cp=strchr(copy, '/')))
      80             :         {
      81           0 :                 if(bdlen==0) cp++;
      82           0 :                 *cp='\0';
      83             : 
      84           0 :                 if(!S_ISDIR(mb->statp.st_mode))
      85             :                 {
      86             :                         // We are faking a directory entry.
      87             :                         // Make sure the directory bit is set.
      88           0 :                         mb->statp.st_mode &= ~(S_IFMT);
      89           0 :                         mb->statp.st_mode |= S_IFDIR;
      90           0 :                         attribs_encode(mb);
      91             :                 }
      92             :         }
      93             : 
      94             :         // Strip off possible trailing slash.
      95           0 :         if((cp=strrchr(copy, '/')) && cp>copy) *cp='\0';
      96             : 
      97           0 :         if(*last_bd_match)
      98             :         {
      99           0 :                 if(!strcmp(*last_bd_match, copy))
     100             :                 {
     101             :                         // Got a duplicate match.
     102           0 :                         free(copy);
     103           0 :                         return 0;
     104             :                 }
     105           0 :                 free(*last_bd_match);
     106             :         }
     107           0 :         free(mb->path.buf);
     108           0 :         mb->path.buf=copy;
     109           0 :         if(!(*last_bd_match=strdup_w(copy, __func__)))
     110           0 :                 goto err;
     111           0 :         return 1;
     112             : err:
     113           0 :         if(copy) free(copy);
     114           0 :         log_out_of_memory(__func__);
     115           0 :         return -1;
     116             : }
     117             : 
     118           0 : static int list_manifest(struct asfd *asfd,
     119             :         const char *fullpath, regex_t *regex,
     120             :         const char *browsedir, struct cntr *cntr, enum protocol protocol)
     121             : {
     122           0 :         int ret=0;
     123           0 :         struct sbuf *sb=NULL;
     124           0 :         struct manio *manio=NULL;
     125           0 :         char *manifest_dir=NULL;
     126           0 :         char *last_bd_match=NULL;
     127           0 :         size_t bdlen=0;
     128             : 
     129           0 :         if(!(manifest_dir=prepend_s(fullpath,
     130           0 :                 protocol==PROTO_1?"manifest.gz":"manifest"))
     131           0 :           || !(manio=manio_open(manifest_dir, "rb", protocol))
     132           0 :           || !(sb=sbuf_alloc(protocol)))
     133             :         {
     134           0 :                 log_and_send_oom(asfd, __func__);
     135           0 :                 goto error;
     136             :         }
     137             : 
     138           0 :         if(browsedir) bdlen=strlen(browsedir);
     139             : 
     140             :         while(1)
     141             :         {
     142           0 :                 int show=0;
     143           0 :                 sbuf_free_content(sb);
     144             : 
     145           0 :                 switch(manio_read(manio, sb))
     146             :                 {
     147           0 :                         case 0: break;
     148           0 :                         case 1: if(browsedir && *browsedir && !last_bd_match)
     149             :                                         write_wrapper_str(asfd, CMD_ERROR,
     150           0 :                                                 "directory not found");
     151           0 :                                 goto end; // Finished OK.
     152           0 :                         default: goto error;
     153             :                 }
     154             : 
     155           0 :                 if(protocol==PROTO_2 && sb->endfile.buf)
     156           0 :                         continue;
     157           0 :                 if(sbuf_is_metadata(sb))
     158           0 :                         continue;
     159             : 
     160           0 :                 if(write_status(CNTR_STATUS_LISTING, sb->path.buf, cntr))
     161           0 :                         goto error;
     162             : 
     163           0 :                 if(browsedir)
     164             :                 {
     165             :                         int r;
     166           0 :                         if((r=check_browsedir(browsedir,
     167           0 :                                 sb, bdlen, &last_bd_match))<0)
     168           0 :                                         goto error;
     169           0 :                         if(!r) continue;
     170           0 :                         show++;
     171             :                 }
     172             :                 else
     173             :                 {
     174           0 :                         if(check_regex(regex, sb->path.buf))
     175           0 :                                 show++;
     176             :                 }
     177           0 :                 if(show)
     178             :                 {
     179           0 :                         if(write_wrapper(asfd, &sb->attr)
     180           0 :                           || write_wrapper(asfd, &sb->path))
     181           0 :                                 goto error;
     182           0 :                         if(sbuf_is_link(sb)
     183           0 :                           && write_wrapper(asfd, &sb->link))
     184           0 :                                 goto error;
     185             :                 }
     186             :         }
     187             : 
     188             : error:
     189           0 :         ret=-1;
     190             : end:
     191           0 :         sbuf_free(&sb);
     192           0 :         free_w(&manifest_dir);
     193           0 :         manio_close(&manio);
     194           0 :         free_w(&last_bd_match);
     195           0 :         return ret;
     196             : }
     197             : 
     198           0 : static int send_backup_name_to_client(struct asfd *asfd,
     199             :         struct bu *bu, enum protocol protocol)
     200             : {
     201           0 :         char msg[64]="";
     202             :         snprintf(msg, sizeof(msg), "%s%s",
     203             :                 bu->timestamp,
     204             :                 // Protocol2 backups are all deletable, so do not mention it.
     205             :                 protocol==PROTO_1
     206           0 :                 && (bu->flags & BU_DELETABLE)?" (deletable)":"");
     207           0 :         return write_wrapper_str(asfd, CMD_TIMESTAMP, msg);
     208             : }
     209             : 
     210           0 : int do_list_server(struct asfd *asfd, struct sdirs *sdirs, struct cntr *cntr,
     211             :         enum protocol protocol,
     212             :         const char *backup, const char *listregex, const char *browsedir)
     213             : {
     214           0 :         int ret=-1;
     215           0 :         uint8_t found=0;
     216           0 :         unsigned long bno=0;
     217           0 :         regex_t *regex=NULL;
     218           0 :         struct bu *bu=NULL;
     219           0 :         struct bu *bu_list=NULL;
     220             : 
     221             :         //logp("in do_list_server\n");
     222             : 
     223           0 :         if(compile_regex(&regex, listregex)
     224           0 :           || bu_get_list(sdirs, &bu_list)
     225           0 :           || write_status(CNTR_STATUS_LISTING, NULL, cntr))
     226           0 :                 goto end;
     227             : 
     228           0 :         if(backup && *backup) bno=strtoul(backup, NULL, 10);
     229             : 
     230           0 :         for(bu=bu_list; bu; bu=bu->next)
     231             :         {
     232             :                 // Search all backups for things matching the regex.
     233           0 :                 if(listregex && backup && *backup=='a')
     234             :                 {
     235           0 :                         found=1;
     236           0 :                         if(write_wrapper_str(asfd,
     237           0 :                                 CMD_TIMESTAMP, bu->timestamp)
     238           0 :                           || list_manifest(asfd, bu->path,
     239           0 :                                 regex, browsedir, cntr, protocol)) goto end;
     240             :                 }
     241             :                 // Search or list a particular backup.
     242           0 :                 else if(backup && *backup)
     243             :                 {
     244           0 :                         if(!found
     245           0 :                           && (!strcmp(bu->timestamp, backup)
     246           0 :                                 || bu->bno==bno
     247           0 :                                 || (*backup=='c' && (bu->flags & BU_CURRENT))))
     248             :                         {
     249           0 :                                 found=1;
     250           0 :                                 if(send_backup_name_to_client(asfd,
     251           0 :                                         bu, protocol)
     252           0 :                                   || list_manifest(asfd, bu->path, regex,
     253           0 :                                         browsedir, cntr, protocol)) goto end;
     254             :                         }
     255             :                 }
     256             :                 // List the backups.
     257             :                 else
     258             :                 {
     259           0 :                         found=1;
     260           0 :                         if(send_backup_name_to_client(asfd, bu, protocol))
     261           0 :                                 goto end;
     262             :                 }
     263             :         }
     264             : 
     265           0 :         if(backup && *backup && !found)
     266             :         {
     267           0 :                 write_wrapper_str(asfd, CMD_ERROR, "backup not found");
     268           0 :                 flush_asio(asfd);
     269           0 :                 goto end;
     270             :         }
     271             : 
     272           0 :         if(flush_asio(asfd)) goto end;
     273             :         
     274           0 :         ret=0;
     275             : end:
     276           0 :         if(regex) { regfree(regex); free(regex); }
     277           0 :         bu_list_free(&bu);
     278           0 :         return ret;
     279             : }

Generated by: LCOV version 1.10