]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_input.c
2b16f507433fc1e260febb4346fe5e8ae18faa66
[bacula/bacula] / bacula / src / dird / ua_input.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2001-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *
30  *   Bacula Director -- User Agent Input and scanning code
31  *
32  *     Kern Sibbald, October MMI
33  *
34  *   Version $Id$
35  */
36
37 #include "bacula.h"
38 #include "dird.h"
39
40
41 /* Imported variables */
42
43
44 /* Exported functions */
45
46 /* 
47  * If subprompt is set, we send a BNET_SUB_PROMPT signal otherwise
48  *   send a BNET_TEXT_INPUT signal.
49  */
50 int get_cmd(UAContext *ua, const char *prompt, bool subprompt)
51 {
52    BSOCK *sock = ua->UA_sock;
53    int stat;
54
55    ua->cmd[0] = 0;
56    if (!sock || ua->batch) {          /* No UA or batch mode */
57       return 0;
58    }
59    if (!subprompt) {
60       sock->signal(BNET_TEXT_INPUT);
61    }
62    sock->fsend("%s", prompt);
63    if (subprompt) {
64       sock->signal(BNET_SUB_PROMPT);
65    }
66    for ( ;; ) {
67       stat = sock->recv();
68       if (stat == BNET_SIGNAL) {
69          continue;                    /* ignore signals */
70       }
71       if (is_bnet_stop(sock)) {
72          return 0;                    /* error or terminate */
73       }
74       pm_strcpy(ua->cmd, sock->msg);
75       strip_trailing_junk(ua->cmd);
76       if (strcmp(ua->cmd, ".messages") == 0) {
77          qmessagescmd(ua, ua->cmd);
78       }
79       /* Lone dot => break */
80       if (ua->cmd[0] == '.' && ua->cmd[1] == 0) {
81          return 0;
82       }
83       break;
84    }
85    return 1;
86 }
87
88 /*
89  * Get a positive integer
90  *  Returns:  false if failure
91  *            true  if success => value in ua->pint32_val
92  */
93 bool get_pint(UAContext *ua, const char *prompt)
94 {
95    double dval;
96    ua->pint32_val = 0;
97    ua->int64_val = 0;
98    for (;;) {
99       ua->cmd[0] = 0;
100       if (!get_cmd(ua, prompt)) {
101          return false;
102       }
103       /* Kludge for slots blank line => 0 */
104       if (ua->cmd[0] == 0 && strncmp(prompt, _("Enter slot"), strlen(_("Enter slot"))) == 0) {
105          return true;
106       }
107       if (!is_a_number(ua->cmd)) {
108          ua->warning_msg(_("Expected a positive integer, got: %s\n"), ua->cmd);
109          continue;
110       }
111       errno = 0;
112       dval = strtod(ua->cmd, NULL);
113       if (errno != 0 || dval < 0) {
114          ua->warning_msg(_("Expected a positive integer, got: %s\n"), ua->cmd);
115          continue;
116       }
117       ua->pint32_val = (uint32_t)dval;
118       ua->int64_val = (int64_t)dval;
119       return true;
120    }
121 }
122
123 /*
124  * Test a yes or no response
125  *  Returns:  false if failure
126  *            true  if success => ret == 1 for yes
127  *                                ret == 0 for no
128  */
129 bool is_yesno(char *val, int *ret)
130 {
131    *ret = 0;
132    if ((strcasecmp(val,   _("yes")) == 0) ||
133        (strcasecmp(val, NT_("yes")) == 0))
134    {
135       *ret = 1;
136    } else if ((strcasecmp(val,   _("no")) == 0) ||
137               (strcasecmp(val, NT_("no")) == 0))
138    {
139       *ret = 0;
140    } else {
141       return false;
142    }
143
144    return true;
145 }
146
147 /*
148  * Gets a yes or no response
149  *  Returns:  false if failure
150  *            true  if success => ua->pint32_val == 1 for yes
151  *                                ua->pint32_val == 0 for no
152  */
153 bool get_yesno(UAContext *ua, const char *prompt)
154 {
155    int len;
156    int ret;
157    ua->pint32_val = 0;
158    for (;;) {
159       if (ua->api) ua->UA_sock->signal(BNET_YESNO);
160       if (!get_cmd(ua, prompt)) {
161          return false;
162       }
163       len = strlen(ua->cmd);
164       if (len < 1 || len > 3) {
165          continue;
166       }
167       if (is_yesno(ua->cmd, &ret)) {
168          ua->pint32_val = ret;
169          return true;
170       }
171       ua->warning_msg(_("Invalid response. You must answer yes or no.\n"));
172    }
173 }
174
175 /* 
176  *  Gets an Enabled value => 0, 1, 2, yes, no, archived
177  *  Returns: 0, 1, 2 if OK
178  *           -1 on error
179  */
180 int get_enabled(UAContext *ua, const char *val) 
181 {
182    int Enabled = -1;
183
184    if (strcasecmp(val, "yes") == 0 || strcasecmp(val, "true") == 0) {
185      Enabled = 1;
186    } else if (strcasecmp(val, "no") == 0 || strcasecmp(val, "false") == 0) {
187       Enabled = 0;
188    } else if (strcasecmp(val, "archived") == 0) { 
189       Enabled = 2;
190    } else {
191       Enabled = atoi(val);
192    }
193    if (Enabled < 0 || Enabled > 2) {
194       ua->error_msg(_("Invalid Enabled value, it must be yes, no, archived, 0, 1, or 2\n"));
195       return -1;     
196    }
197    return Enabled;
198 }
199
200 void parse_ua_args(UAContext *ua)
201 {
202    parse_args(ua->cmd, &ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS);
203 }
204
205 /*
206  * Check if the comment has legal characters
207  * If ua is non-NULL send the message
208  */
209 bool is_comment_legal(UAContext *ua, const char *name)
210 {
211    int len;
212    const char *p;
213    const char *forbid = "'<>&\\\"";
214
215    /* Restrict the characters permitted in the comment */
216    for (p=name; *p; p++) {
217       if (!strchr(forbid, (int)(*p))) {
218          continue;
219       }
220       if (ua) {
221          ua->error_msg(_("Illegal character \"%c\" in a comment.\n"), *p);
222       }
223       return 0;
224    }
225    len = strlen(name);
226    if (len >= MAX_NAME_LENGTH) {
227       if (ua) {
228          ua->error_msg(_("Comment too long.\n"));
229       }
230       return 0;
231    }
232    if (len == 0) {
233       if (ua) {
234          ua->error_msg(_("Comment must be at least one character long.\n"));
235       }
236       return 0;
237    }
238    return 1;
239 }