Coverage Report

Created: 2026-01-17 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/common/status.c
Line
Count
Source
1
/* status.c - status code helper functions
2
 *  Copyright (C) 2007 Free Software Foundation, Inc.
3
 *
4
 * This file is part of GnuPG.
5
 *
6
 * This file is free software; you can redistribute it and/or modify
7
 * it under the terms of either
8
 *
9
 *   - the GNU Lesser General Public License as published by the Free
10
 *     Software Foundation; either version 3 of the License, or (at
11
 *     your option) any later version.
12
 *
13
 * or
14
 *
15
 *   - the GNU General Public License as published by the Free
16
 *     Software Foundation; either version 2 of the License, or (at
17
 *     your option) any later version.
18
 *
19
 * or both in parallel, as here.
20
 *
21
 * This file is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
28
 */
29
30
#include <config.h>
31
#include <stdlib.h>
32
33
#include "util.h"
34
#include "status.h"
35
#include "status-codes.h"
36
37
/* The stream to output the status information.  Output is disabled if
38
 * this is NULL.  */
39
static estream_t statusfp;
40
41
42
/* Return the status string for code NO. */
43
const char *
44
get_status_string ( int no )
45
0
{
46
0
  int idx = statusstr_msgidxof (no);
47
0
  if (idx == -1)
48
0
    return "?";
49
0
  else
50
0
    return statusstr_msgstr + statusstr_msgidx[idx];
51
0
}
52
53
54
/* Set a global status FD.  */
55
void
56
gnupg_set_status_fd (int fd)
57
0
{
58
0
  static int last_fd = -1;
59
60
0
  if (fd != -1 && last_fd == fd)
61
0
    return;
62
63
0
  if (statusfp && statusfp != es_stdout && statusfp != es_stderr)
64
0
    es_fclose (statusfp);
65
0
  statusfp = NULL;
66
0
  if (fd == -1)
67
0
    return;
68
69
0
  if (fd == 1)
70
0
    statusfp = es_stdout;
71
0
  else if (fd == 2)
72
0
    statusfp = es_stderr;
73
0
  else
74
0
    statusfp = es_fdopen (fd, "w");
75
0
  if (!statusfp)
76
0
    {
77
0
      log_fatal ("can't open fd %d for status output: %s\n",
78
0
                 fd, gpg_strerror (gpg_error_from_syserror ()));
79
0
    }
80
0
  last_fd = fd;
81
0
}
82
83
84
/* Write a status line with code NO followed by the output of the
85
 * printf style FORMAT.  The caller needs to make sure that LFs and
86
 * CRs are not printed.  */
87
void
88
gnupg_status_printf (int no, const char *format, ...)
89
0
{
90
0
  va_list arg_ptr;
91
92
0
  if (!statusfp)
93
0
    return;  /* Not enabled.  */
94
95
0
  es_fputs ("[GNUPG:] ", statusfp);
96
0
  es_fputs (get_status_string (no), statusfp);
97
0
  if (format)
98
0
    {
99
0
      es_putc (' ', statusfp);
100
0
      va_start (arg_ptr, format);
101
0
      es_vfprintf (statusfp, format, arg_ptr);
102
0
      va_end (arg_ptr);
103
0
    }
104
0
  es_putc ('\n', statusfp);
105
0
}
106
107
108
/* Write a status line with code NO followed by the remaining
109
 * arguments which must be a list of strings terminated by a NULL.
110
 * Embedded CR and LFs in the strings are C-style escaped.  All
111
 * strings are printed with a space as delimiter.  */
112
gpg_error_t
113
gnupg_status_strings (ctrl_t dummy, int no, ...)
114
0
{
115
0
  va_list arg_ptr;
116
0
  const char *s;
117
118
0
  (void)dummy;
119
120
0
  if (!statusfp)
121
0
    return 0;  /* Not enabled. */
122
123
0
  va_start (arg_ptr, no);
124
125
0
  es_fputs ("[GNUPG:] ", statusfp);
126
0
  es_fputs (get_status_string (no), statusfp);
127
0
  while ((s = va_arg (arg_ptr, const char*)))
128
0
    {
129
0
      if (*s)
130
0
        es_putc (' ', statusfp);
131
0
      for (; *s; s++)
132
0
        {
133
0
          if (*s == '\n')
134
0
            es_fputs ("\\n", statusfp);
135
0
          else if (*s == '\r')
136
0
            es_fputs ("\\r", statusfp);
137
0
          else
138
0
            es_fputc (*(const byte *)s, statusfp);
139
0
        }
140
0
    }
141
0
  es_putc ('\n', statusfp);
142
0
  es_fflush (statusfp);
143
144
0
  va_end (arg_ptr);
145
0
  return 0;
146
0
}
147
148
149
const char *
150
get_inv_recpsgnr_code (gpg_error_t err)
151
0
{
152
0
  const char *errstr;
153
154
0
  switch (gpg_err_code (err))
155
0
    {
156
0
    case GPG_ERR_NO_PUBKEY:       errstr = "1"; break;
157
0
    case GPG_ERR_AMBIGUOUS_NAME:  errstr = "2"; break;
158
0
    case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break;
159
0
    case GPG_ERR_CERT_REVOKED:    errstr = "4"; break;
160
0
    case GPG_ERR_CERT_EXPIRED:    errstr = "5"; break;
161
0
    case GPG_ERR_NO_CRL_KNOWN:
162
0
    case GPG_ERR_INV_CRL_OBJ:     errstr = "6"; break;
163
0
    case GPG_ERR_CRL_TOO_OLD:     errstr = "7"; break;
164
0
    case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break;
165
166
0
    case GPG_ERR_UNUSABLE_SECKEY:
167
0
    case GPG_ERR_NO_SECKEY:       errstr = "9"; break;
168
169
0
    case GPG_ERR_NOT_TRUSTED:     errstr = "10"; break;
170
0
    case GPG_ERR_MISSING_CERT:    errstr = "11"; break;
171
0
    case GPG_ERR_MISSING_ISSUER_CERT: errstr = "12"; break;
172
0
    default:                      errstr = "0"; break;
173
0
    }
174
175
0
  return errstr;
176
0
}