scd: Error code map fix for older Yubikey.
[gnupg.git] / common / yesno.c
1 /* yesno.c - Yes/No questions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003 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 #include <errno.h>
33
34 #include "i18n.h"
35 #include "util.h"
36
37
38 /* Check the string S for a YES or NO answer and take care of
39    localization.  If no valid string is given the value of DEF_ANSWER
40    is returned.  Returns 1 for yes and 0 for no.  */
41 int
42 answer_is_yes_no_default (const char *s, int def_answer)
43 {
44   /* TRANSLATORS: See doc/TRANSLATE about this string. */
45   const char *long_yes = _("yes");
46   const char *short_yes = _("yY");
47   /* TRANSLATORS: See doc/TRANSLATE about this string. */
48   const char *long_no = _("no");
49   const char *short_no = _("nN");
50
51   /* Note: we have to use the local dependent compare here. */
52   if ( match_multistr(long_yes,s) )
53     return 1;
54   if ( *s && strchr( short_yes, *s ) && !s[1] )
55     return 1;
56   /* Test for "no" strings to catch ambiguities for the next test. */
57   if ( match_multistr(long_no,s) )
58     return 0;
59   if ( *s && strchr( short_no, *s ) && !s[1] )
60     return 0;
61   /* Test for the english version (for those who are used to type yes). */
62   if ( !ascii_strcasecmp(s, "yes" ) )
63     return 1;
64   if ( *s && strchr( "yY", *s ) && !s[1] )
65     return 1;
66   return def_answer;
67 }
68
69 int
70 answer_is_yes ( const char *s )
71 {
72   return answer_is_yes_no_default(s,0);
73 }
74
75 /****************
76  * Return 1 for yes, -1 for quit, or 0 for no
77  */
78 int
79 answer_is_yes_no_quit ( const char *s )
80 {
81   /* TRANSLATORS: See doc/TRANSLATE about this string. */
82   const char *long_yes = _("yes");
83   /* TRANSLATORS: See doc/TRANSLATE about this string. */
84   const char *long_no = _("no");
85   /* TRANSLATORS: See doc/TRANSLATE about this string. */
86   const char *long_quit = _("quit");
87   const char *short_yes = _("yY");
88   const char *short_no = _("nN");
89   const char *short_quit = _("qQ");
90
91   /* Note: we have to use a local dependent compare here. */
92   if ( match_multistr(long_no,s) )
93     return 0;
94   if ( match_multistr(long_yes,s) )
95     return 1;
96   if ( match_multistr(long_quit,s) )
97     return -1;
98   if ( *s && strchr( short_no, *s ) && !s[1] )
99     return 0;
100   if ( *s && strchr( short_yes, *s ) && !s[1] )
101       return 1;
102   if ( *s && strchr( short_quit, *s ) && !s[1] )
103     return -1;
104   /* but not here. */
105   if ( !ascii_strcasecmp(s, "yes" ) )
106     return 1;
107   if ( !ascii_strcasecmp(s, "quit" ) )
108       return -1;
109   if ( *s && strchr( "yY", *s ) && !s[1] )
110     return 1;
111   if ( *s && strchr( "qQ", *s ) && !s[1] )
112     return -1;
113   return 0;
114 }
115
116 /*
117    Return 1 for okay, 0 for cancel or DEF_ANSWER for default.
118  */
119 int
120 answer_is_okay_cancel (const char *s, int def_answer)
121 {
122   /* TRANSLATORS: See doc/TRANSLATE about this string. */
123   const char *long_okay = _("okay|okay");
124   /* TRANSLATORS: See doc/TRANSLATE about this string. */
125   const char *long_cancel = _("cancel|cancel");
126   const char *short_okay = _("oO");
127   const char *short_cancel = _("cC");
128
129   /* Note: We have to use the locale dependent compare. */
130   if ( match_multistr(long_okay,s) )
131     return 1;
132   if ( match_multistr(long_cancel,s) )
133     return 0;
134   if ( *s && strchr( short_okay, *s ) && !s[1] )
135     return 1;
136   if ( *s && strchr( short_cancel, *s ) && !s[1] )
137     return 0;
138   /* Always test for the English values (not locale here). */
139   if ( !ascii_strcasecmp(s, "okay" ) )
140     return 1;
141   if ( !ascii_strcasecmp(s, "ok" ) )
142     return 1;
143   if ( !ascii_strcasecmp(s, "cancel" ) )
144     return 0;
145   if ( *s && strchr( "oO", *s ) && !s[1] )
146     return 1;
147   if ( *s && strchr( "cC", *s ) && !s[1] )
148     return 0;
149   return def_answer;
150 }