Imported Upstream version 2.4.3
[platform/upstream/gpg2.git] / common / status.c
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 {
46   int idx = statusstr_msgidxof (no);
47   if (idx == -1)
48     return "?";
49   else
50     return statusstr_msgstr + statusstr_msgidx[idx];
51 }
52
53
54 /* Set a global status FD.  */
55 void
56 gnupg_set_status_fd (int fd)
57 {
58   static int last_fd = -1;
59
60   if (fd != -1 && last_fd == fd)
61     return;
62
63   if (statusfp && statusfp != es_stdout && statusfp != es_stderr)
64     es_fclose (statusfp);
65   statusfp = NULL;
66   if (fd == -1)
67     return;
68
69   if (fd == 1)
70     statusfp = es_stdout;
71   else if (fd == 2)
72     statusfp = es_stderr;
73   else
74     statusfp = es_fdopen (fd, "w");
75   if (!statusfp)
76     {
77       log_fatal ("can't open fd %d for status output: %s\n",
78                  fd, gpg_strerror (gpg_error_from_syserror ()));
79     }
80   last_fd = fd;
81 }
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 {
90   va_list arg_ptr;
91
92   if (!statusfp)
93     return;  /* Not enabled.  */
94
95   es_fputs ("[GNUPG:] ", statusfp);
96   es_fputs (get_status_string (no), statusfp);
97   if (format)
98     {
99       es_putc (' ', statusfp);
100       va_start (arg_ptr, format);
101       es_vfprintf (statusfp, format, arg_ptr);
102       va_end (arg_ptr);
103     }
104   es_putc ('\n', statusfp);
105 }
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 {
115   va_list arg_ptr;
116   const char *s;
117
118   (void)dummy;
119
120   if (!statusfp)
121     return 0;  /* Not enabled. */
122
123   va_start (arg_ptr, no);
124
125   es_fputs ("[GNUPG:] ", statusfp);
126   es_fputs (get_status_string (no), statusfp);
127   while ((s = va_arg (arg_ptr, const char*)))
128     {
129       if (*s)
130         es_putc (' ', statusfp);
131       for (; *s; s++)
132         {
133           if (*s == '\n')
134             es_fputs ("\\n", statusfp);
135           else if (*s == '\r')
136             es_fputs ("\\r", statusfp);
137           else
138             es_fputc (*(const byte *)s, statusfp);
139         }
140     }
141   es_putc ('\n', statusfp);
142   es_fflush (statusfp);
143
144   va_end (arg_ptr);
145   return 0;
146 }
147
148
149 const char *
150 get_inv_recpsgnr_code (gpg_error_t err)
151 {
152   const char *errstr;
153
154   switch (gpg_err_code (err))
155     {
156     case GPG_ERR_NO_PUBKEY:       errstr = "1"; break;
157     case GPG_ERR_AMBIGUOUS_NAME:  errstr = "2"; break;
158     case GPG_ERR_WRONG_KEY_USAGE: errstr = "3"; break;
159     case GPG_ERR_CERT_REVOKED:    errstr = "4"; break;
160     case GPG_ERR_CERT_EXPIRED:    errstr = "5"; break;
161     case GPG_ERR_NO_CRL_KNOWN:
162     case GPG_ERR_INV_CRL_OBJ:     errstr = "6"; break;
163     case GPG_ERR_CRL_TOO_OLD:     errstr = "7"; break;
164     case GPG_ERR_NO_POLICY_MATCH: errstr = "8"; break;
165
166     case GPG_ERR_UNUSABLE_SECKEY:
167     case GPG_ERR_NO_SECKEY:       errstr = "9"; break;
168
169     case GPG_ERR_NOT_TRUSTED:     errstr = "10"; break;
170     case GPG_ERR_MISSING_CERT:    errstr = "11"; break;
171     case GPG_ERR_MISSING_ISSUER_CERT: errstr = "12"; break;
172     default:                      errstr = "0"; break;
173     }
174
175   return errstr;
176 }