LCOV - code coverage report
Current view: top level - g10 - progress.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 10 60 16.7 %
Date: 2015-11-05 17:10:59 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /* progress.c - emit progress status lines
       2             :  * Copyright (C) 2003, 2006 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <stdio.h>
      22             : #include <assert.h>
      23             : 
      24             : #include "gpg.h"
      25             : #include "iobuf.h"
      26             : #include "filter.h"
      27             : #include "status.h"
      28             : #include "util.h"
      29             : #include "options.h"
      30             : 
      31             : /* Create a new context for use with the progress filter.  We need to
      32             :    allocate such contexts on the heap because there is no guarantee
      33             :    that at the end of a function the filter has already been popped
      34             :    off.  In general this will happen but with malformed packets it is
      35             :    possible that a filter has not yet reached the end-of-stream when
      36             :    the function has done all processing.  Checking in each function
      37             :    that end-of-stream has been reached would be to cumbersome.
      38             : 
      39             :    What we also do is to shortcut the progress handler by having this
      40             :    function return NULL if progress information has not been
      41             :    requested.
      42             : */
      43             : progress_filter_context_t *
      44         594 : new_progress_context (void)
      45             : {
      46             :   progress_filter_context_t *pfx;
      47             : 
      48         594 :   if (!opt.enable_progress_filter)
      49         594 :     return NULL;
      50             : 
      51           0 :   if (!is_status_enabled ())
      52           0 :     return NULL;
      53             : 
      54           0 :   pfx = xcalloc (1, sizeof *pfx);
      55           0 :   pfx->refcount = 1;
      56             : 
      57           0 :   return pfx;
      58             : }
      59             : 
      60             : /* Release a progress filter context.  Passing NULL is explicitly
      61             :    allowed and a no-op.  */
      62             : void
      63         590 : release_progress_context (progress_filter_context_t *pfx)
      64             : {
      65         590 :   if (!pfx)
      66         590 :     return;
      67           0 :   assert (pfx->refcount);
      68           0 :   if ( --pfx->refcount )
      69           0 :     return;
      70           0 :   xfree (pfx->what);
      71           0 :   xfree (pfx);
      72             : }
      73             : 
      74             : 
      75             : /****************
      76             :  * The filter is used to report progress to the user.
      77             :  */
      78             : static int
      79           0 : progress_filter (void *opaque, int control,
      80             :                  IOBUF a, byte *buf, size_t *ret_len)
      81             : {
      82           0 :   int rc = 0;
      83           0 :   progress_filter_context_t *pfx = opaque;
      84             : 
      85           0 :   if (control == IOBUFCTRL_INIT)
      86             :     {
      87             :       char buffer[50];
      88             : 
      89           0 :       pfx->last = 0;
      90           0 :       pfx->offset = 0;
      91           0 :       pfx->last_time = make_timestamp ();
      92             : 
      93           0 :       sprintf (buffer, "%.20s ? %lu %lu",
      94           0 :                pfx->what? pfx->what : "?",
      95             :                pfx->offset,
      96             :                pfx->total);
      97           0 :       write_status_text (STATUS_PROGRESS, buffer);
      98             :     }
      99           0 :   else if (control == IOBUFCTRL_UNDERFLOW)
     100             :     {
     101           0 :       u32 timestamp = make_timestamp ();
     102           0 :       int len = iobuf_read (a, buf, *ret_len);
     103             : 
     104           0 :       if (len >= 0)
     105             :         {
     106           0 :           pfx->offset += len;
     107           0 :           *ret_len = len;
     108             :         }
     109             :       else
     110             :         {
     111           0 :           *ret_len = 0;
     112           0 :           rc = -1;
     113             :         }
     114           0 :       if ((len == -1 && pfx->offset != pfx->last)
     115           0 :           || timestamp - pfx->last_time > 0)
     116             :         {
     117             :           char buffer[50];
     118             : 
     119           0 :           sprintf (buffer, "%.20s ? %lu %lu",
     120           0 :                    pfx->what? pfx->what : "?",
     121             :                    pfx->offset,
     122             :                    pfx->total);
     123           0 :           write_status_text (STATUS_PROGRESS, buffer);
     124             : 
     125           0 :           pfx->last = pfx->offset;
     126           0 :           pfx->last_time = timestamp;
     127             :         }
     128             :     }
     129           0 :   else if (control == IOBUFCTRL_FREE)
     130             :     {
     131           0 :       release_progress_context (pfx);
     132             :     }
     133           0 :   else if (control == IOBUFCTRL_DESC)
     134           0 :     *(char**)buf = "progress_filter";
     135           0 :   return rc;
     136             : }
     137             : 
     138             : void
     139         590 : handle_progress (progress_filter_context_t *pfx, IOBUF inp, const char *name)
     140             : {
     141         590 :   off_t filesize = 0;
     142             : 
     143         590 :   if (!pfx)
     144        1180 :     return;
     145             : 
     146           0 :   assert (opt.enable_progress_filter);
     147           0 :   assert (is_status_enabled ());
     148             : 
     149           0 :   if ( !iobuf_is_pipe_filename (name) && *name )
     150           0 :     filesize = iobuf_get_filelength (inp, NULL);
     151           0 :   else if (opt.set_filesize)
     152           0 :     filesize = opt.set_filesize;
     153             : 
     154             :   /* register the progress filter */
     155           0 :   pfx->what = xstrdup (name ? name : "stdin");
     156           0 :   pfx->total = filesize;
     157           0 :   pfx->refcount++;
     158           0 :   iobuf_push_filter (inp, progress_filter, pfx);
     159             : }

Generated by: LCOV version 1.11