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

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../action.h"
       3             : #include "../asfd.h"
       4             : #include "../async.h"
       5             : #include "../attribs.h"
       6             : #include "../cmd.h"
       7             : #include "../log.h"
       8             : #include "../yajl_gen_w.h"
       9             : 
      10             : static int items_open=0;
      11             : 
      12           0 : static void json_write_all(void)
      13             : {
      14             :         size_t len;  
      15             :         const unsigned char *buf;  
      16           0 :         yajl_gen_get_buf(yajl, &buf, &len);  
      17           0 :         fwrite(buf, 1, len, stdout);  
      18           0 :         yajl_gen_clear(yajl);  
      19           0 : }
      20             : 
      21             : /* Note: The chars in this function are not the same as in the CMD_ set.
      22             :    These are for printing to the screen only. */
      23           0 : static char *encode_mode(mode_t mode, char *buf)
      24             : {
      25           0 :         char *cp=buf;
      26           0 :         *cp++=S_ISDIR(mode)?'d':S_ISBLK(mode)?'b':S_ISCHR(mode)?'c':
      27           0 :               S_ISLNK(mode)?'l':S_ISFIFO(mode)?'p':S_ISSOCK(mode)?'s':'-';
      28           0 :         *cp++=mode&S_IRUSR?'r':'-';
      29           0 :         *cp++=mode&S_IWUSR?'w':'-';
      30           0 :         *cp++=(mode&S_ISUID?(mode&S_IXUSR?'s':'S'):(mode&S_IXUSR?'x':'-'));
      31           0 :         *cp++=mode&S_IRGRP?'r':'-';
      32           0 :         *cp++=mode&S_IWGRP?'w':'-';
      33           0 :         *cp++=(mode&S_ISGID?(mode&S_IXGRP?'s':'S'):(mode&S_IXGRP?'x':'-'));
      34           0 :         *cp++=mode&S_IROTH?'r':'-';
      35           0 :         *cp++=mode&S_IWOTH?'w':'-';
      36           0 :         *cp++=(mode&S_ISVTX?(mode&S_IXOTH?'t':'T'):(mode&S_IXOTH?'x':'-'));
      37           0 :         *cp='\0';
      38           0 :         return cp;
      39             : }
      40             : 
      41           0 : static char *encode_time(uint64_t utime, char *buf)
      42             : {
      43             :         const struct tm *tm;
      44           0 :         int n=0;
      45           0 :         time_t time=utime;
      46             : 
      47             : #ifdef HAVE_WIN32
      48             :         /* Avoid a seg fault in Microsoft's CRT localtime_r(),
      49             :          *  which incorrectly references a NULL returned from gmtime() if
      50             :          *  time is negative before or after the timezone adjustment. */
      51             :         struct tm *gtm;
      52             : 
      53             :         if(!(gtm=gmtime(&time))) return buf;
      54             : 
      55             :         if(gtm->tm_year==1970 && gtm->tm_mon==1 && gtm->tm_mday<3) return buf;
      56             : #endif
      57             : 
      58           0 :         if((tm=localtime(&time)))
      59             :                 n=sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
      60             :                         tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
      61           0 :                         tm->tm_hour, tm->tm_min, tm->tm_sec);
      62           0 :         return buf+n;
      63             : }
      64             : 
      65           0 : void ls_to_buf(char *lsbuf, struct sbuf *sb)
      66             : {
      67             :         int n;
      68             :         char *p;
      69             :         time_t time;
      70             :         const char *f;
      71           0 :         struct stat *statp=&sb->statp;
      72           0 :         *lsbuf='\0';
      73             : 
      74           0 :         p=encode_mode(statp->st_mode, lsbuf);
      75           0 :         n=sprintf(p, " %2d ", (uint32_t)statp->st_nlink);
      76           0 :         p+=n;
      77             :         n=sprintf(p, "%5d %5d", (uint32_t)statp->st_uid,
      78           0 :                 (uint32_t)statp->st_gid);
      79           0 :         p+=n;
      80           0 :         n=sprintf(p, " %7lu ", (unsigned long)statp->st_size);
      81           0 :         p+=n;
      82           0 :         if(statp->st_ctime>statp->st_mtime) time=statp->st_ctime;
      83           0 :         else time=statp->st_mtime;
      84             : 
      85             :         // Display most recent time.
      86           0 :         p=encode_time(time, p);
      87           0 :         *p++=' ';
      88           0 :         for(f=sb->path.buf; *f; ) *p++=*f++;
      89           0 :         *p=0;
      90           0 : }
      91             : 
      92           0 : static void ls_long_output(struct sbuf *sb)
      93             : {
      94             :         static char lsbuf[2048];
      95           0 :         ls_to_buf(lsbuf, sb);
      96           0 :         printf("%s", lsbuf);
      97           0 :         if(sb->link.buf) printf(" -> %s", sb->link.buf);
      98           0 :         printf("\n");
      99           0 : }
     100             : 
     101           0 : static void ls_long_output_json(struct sbuf *sb)
     102             : {
     103           0 :         struct stat *statp=&sb->statp;
     104             : 
     105           0 :         yajl_map_open_w();
     106           0 :         yajl_gen_str_pair_w("name", sb->path.buf?sb->path.buf:"");
     107           0 :         yajl_gen_str_pair_w("link", sb->link.buf?sb->link.buf:"");
     108           0 :         yajl_gen_int_pair_w("st_dev", (long long)statp->st_dev);
     109           0 :         yajl_gen_int_pair_w("st_ino", (long long)statp->st_ino);
     110           0 :         yajl_gen_int_pair_w("st_mode", (long long)statp->st_mode);
     111           0 :         yajl_gen_int_pair_w("st_nlink", (long long)statp->st_nlink);
     112           0 :         yajl_gen_int_pair_w("st_uid", (long long)statp->st_uid);
     113           0 :         yajl_gen_int_pair_w("st_gid", (long long)statp->st_gid);
     114           0 :         yajl_gen_int_pair_w("st_rdev", (long long)statp->st_rdev);
     115           0 :         yajl_gen_int_pair_w("st_size", (long long)statp->st_size);
     116           0 :         yajl_gen_int_pair_w("st_atime", (long long)statp->st_atime);
     117           0 :         yajl_gen_int_pair_w("st_mtime", (long long)statp->st_mtime);
     118           0 :         yajl_gen_int_pair_w("st_ctime", (long long)statp->st_ctime);
     119           0 :         yajl_map_close_w();
     120           0 : }
     121             : 
     122           0 : static void json_backup(char *statbuf, struct conf **confs)
     123             : {
     124           0 :         char *cp=NULL;
     125           0 :         if((cp=strstr(statbuf, " (deletable)")))
     126             :         {
     127           0 :                 *cp='\0';
     128           0 :                 cp++;
     129             :         }
     130             : 
     131           0 :         if(items_open)
     132             :         {
     133           0 :                 yajl_array_close_w();
     134           0 :                 yajl_map_close_w();
     135           0 :                 items_open=0;
     136             :         }
     137             : 
     138           0 :         yajl_map_open_w();
     139           0 :         yajl_gen_str_pair_w("timestamp", statbuf);
     140           0 :         yajl_gen_int_pair_w("deletable", cp?(long long)1:(long long)0);
     141             : 
     142           0 :         if(get_string(confs[OPT_BACKUP]))
     143             :         {
     144           0 :                 const char *browsedir=get_string(confs[OPT_BROWSEDIR]);
     145           0 :                 const char *regex=get_string(confs[OPT_REGEX]);
     146             :                 yajl_gen_str_pair_w("directory", 
     147           0 :                         browsedir?browsedir:"");
     148             :                 yajl_gen_str_pair_w("regex", 
     149           0 :                         regex?regex:"");
     150           0 :                 yajl_gen_str_w("items");
     151           0 :                 yajl_array_open_w();
     152           0 :                 items_open=1;
     153             :         }
     154             :         else
     155           0 :                 yajl_map_close_w();
     156           0 :         json_write_all();
     157           0 : }
     158             : 
     159           0 : static void ls_short_output(struct sbuf *sb)
     160             : {
     161           0 :         printf("%s\n", sb->path.buf);
     162           0 : }
     163             : 
     164           0 : static void ls_short_output_json(struct sbuf *sb)
     165             : {
     166           0 :         yajl_map_open_w();
     167           0 :         yajl_gen_str_pair_w("name",  sb->path.buf);
     168           0 :         yajl_map_close_w();
     169           0 : }
     170             : 
     171           0 : static void list_item(int json, enum action act, struct sbuf *sb)
     172             : {
     173           0 :         if(act==ACTION_LIST_LONG)
     174             :         {
     175           0 :                 if(json) ls_long_output_json(sb);
     176           0 :                 else ls_long_output(sb);
     177             :         }
     178             :         else
     179             :         {
     180           0 :                 if(json) ls_short_output_json(sb);
     181           0 :                 else ls_short_output(sb);
     182             :         }
     183           0 :         if(json) json_write_all();
     184           0 : }
     185             : 
     186           0 : int do_list_client(struct asfd *asfd,
     187             :         enum action act, int json, struct conf **confs)
     188             : {
     189           0 :         int ret=-1;
     190           0 :         char msg[512]="";
     191           0 :         char *dpth=NULL;
     192           0 :         struct sbuf *sb=NULL;
     193           0 :         struct iobuf *rbuf=asfd->rbuf;
     194           0 :         const char *backup=get_string(confs[OPT_BACKUP]);
     195           0 :         const char *browsedir=get_string(confs[OPT_BROWSEDIR]);
     196           0 :         const char *regex=get_string(confs[OPT_REGEX]);
     197             : //logp("in do_list\n");
     198             : 
     199           0 :         if(browsedir)
     200             :           snprintf(msg, sizeof(msg), "listb %s:%s",
     201           0 :                 backup?backup:"", browsedir);
     202             :         else
     203             :           snprintf(msg, sizeof(msg), "list %s:%s",
     204           0 :                 backup?backup:"", regex?regex:"");
     205           0 :         if(asfd->write_str(asfd, CMD_GEN, msg)
     206           0 :           || asfd->read_expect(asfd, CMD_GEN, "ok"))
     207           0 :                 goto end;
     208             : 
     209           0 :         if(!(sb=sbuf_alloc(get_protocol(confs)))) goto end;
     210           0 :         iobuf_init(&sb->path);
     211           0 :         iobuf_init(&sb->link);
     212           0 :         iobuf_init(&sb->attr);
     213             : 
     214           0 :         if(json)
     215             :         {
     216           0 :                 if(!(yajl=yajl_gen_alloc(NULL)))
     217           0 :                         goto end;
     218           0 :                 yajl_gen_config(yajl, yajl_gen_beautify, 1);
     219           0 :                 if(yajl_map_open_w()
     220           0 :                   || yajl_gen_str_w("backups")
     221           0 :                   || yajl_array_open_w())
     222           0 :                         goto end;
     223             :         }
     224             : 
     225             :         // This should probably should use the sbuf stuff.
     226             :         while(1)
     227             :         {
     228           0 :                 sbuf_free_content(sb);
     229             : 
     230           0 :                 iobuf_free_content(rbuf);
     231           0 :                 if(asfd->read(asfd)) break;
     232           0 :                 if(rbuf->cmd==CMD_TIMESTAMP)
     233             :                 {
     234             :                         // A backup timestamp, just print it.
     235           0 :                         if(json) json_backup(rbuf->buf, confs);
     236             :                         else
     237             :                         {
     238           0 :                                 printf("Backup: %s\n", rbuf->buf);
     239           0 :                                 if(browsedir)
     240             :                                         printf("Listing directory: %s\n",
     241           0 :                                                browsedir);
     242           0 :                                 if(regex)
     243             :                                         printf("With regex: %s\n",
     244           0 :                                                regex);
     245             :                         }
     246           0 :                         continue;
     247             :                 }
     248           0 :                 else if(rbuf->cmd!=CMD_ATTRIBS)
     249             :                 {
     250           0 :                         iobuf_log_unexpected(rbuf, __func__);
     251           0 :                         goto end;
     252             :                 }
     253           0 :                 iobuf_copy(&sb->attr, rbuf);
     254           0 :                 iobuf_init(rbuf);
     255             : 
     256           0 :                 attribs_decode(sb);
     257             : 
     258           0 :                 if(asfd->read(asfd))
     259             :                 {
     260           0 :                         logp("got stat without an object\n");
     261           0 :                         goto end;
     262             :                 }
     263           0 :                 iobuf_copy(&sb->path, rbuf);
     264           0 :                 iobuf_init(rbuf);
     265             : 
     266           0 :                 if(sb->path.cmd==CMD_DIRECTORY
     267           0 :                         || sb->path.cmd==CMD_FILE
     268           0 :                         || sb->path.cmd==CMD_ENC_FILE
     269           0 :                         || sb->path.cmd==CMD_EFS_FILE
     270           0 :                         || sb->path.cmd==CMD_SPECIAL)
     271             :                 {
     272           0 :                         list_item(json, act, sb);
     273             :                 }
     274           0 :                 else if(cmd_is_link(sb->path.cmd)) // symlink or hardlink
     275             :                 {
     276           0 :                         if(asfd->read(asfd)
     277           0 :                           || rbuf->cmd!=sb->path.cmd)
     278             :                         {
     279             :                                 logp("could not get link %c:%s\n",
     280           0 :                                         sb->path.cmd, sb->path.buf);
     281           0 :                                 goto end;
     282             :                         }
     283           0 :                         iobuf_copy(&sb->link, rbuf);
     284           0 :                         iobuf_init(rbuf);
     285           0 :                         list_item(json, act, sb);
     286             :                 }
     287             :                 else
     288             :                 {
     289             :                         fprintf(stderr, "unlistable %c:%s\n",
     290           0 :                                 sb->path.cmd, sb->path.buf?sb->path.buf:"");
     291             :                 }
     292             :         }
     293             : 
     294           0 :         ret=0;
     295             : end:
     296           0 :         if(json && yajl)
     297             :         {
     298           0 :                 if(items_open)
     299             :                 {
     300           0 :                         yajl_array_close_w();
     301           0 :                         yajl_map_close_w();
     302           0 :                         items_open=0;
     303             :                 }
     304           0 :                 yajl_array_close_w();
     305           0 :                 yajl_map_close_w();
     306           0 :                 json_write_all();
     307           0 :                 yajl_gen_free(yajl);
     308           0 :                 yajl=NULL;
     309             :         }
     310             : 
     311           0 :         if(sb)
     312             :         {
     313           0 :                 iobuf_free_content(&sb->path);
     314           0 :                 iobuf_free_content(&sb->link);
     315           0 :                 iobuf_free_content(&sb->attr);
     316           0 :                 sbuf_free(&sb);
     317             :         }
     318           0 :         if(dpth) free(dpth);
     319           0 :         if(!ret) logp("List finished ok\n");
     320           0 :         return ret;
     321             : }

Generated by: LCOV version 1.10