]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_query.c
kes Add code in catreq.c to reject volumes not marked Enabled.
[bacula/bacula] / bacula / src / dird / ua_query.c
1 /*
2  *
3  *   Bacula Director -- User Agent Database Query Commands
4  *
5  *     Kern Sibbald, December MMI
6  *
7  *   Version $Id$
8  */
9 /*
10    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
13
14    The main author of Bacula is Kern Sibbald, with contributions from
15    many others, a complete list can be found in the file AUTHORS.
16    This program is Free Software; you can redistribute it and/or
17    modify it under the terms of version two of the GNU General Public
18    License as published by the Free Software Foundation plus additions
19    that are listed in the file LICENSE.
20
21    This program is distributed in the hope that it will be useful, but
22    WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24    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, write to the Free Software
28    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.
30
31    Bacula® is a registered trademark of John Walker.
32    The licensor of Bacula is the Free Software Foundation Europe
33    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34    Switzerland, email:ftf@fsfeurope.org.
35 */
36
37 #include "bacula.h"
38 #include "dird.h"
39
40 extern DIRRES *director;
41
42 static POOLMEM *substitute_prompts(UAContext *ua,
43                        POOLMEM *query, char **prompt, int nprompt);
44
45 /*
46  * Read a file containing SQL queries and prompt
47  *  the user to select which one.
48  *
49  *   File format:
50  *   #  => comment
51  *   :prompt for query
52  *   *prompt for subst %1
53  *   *prompt for subst %2
54  *   ...
55  *   SQL statement possibly terminated by ;
56  *   :next query prompt
57  */
58 int querycmd(UAContext *ua, const char *cmd)
59 {
60    FILE *fd = NULL;
61    POOLMEM *query = get_pool_memory(PM_MESSAGE);
62    char line[1000];
63    int i, item, len;
64    char *prompt[9];
65    int nprompt = 0;;
66    char *query_file = director->query_file;
67
68    if (!open_client_db(ua)) {
69       goto bail_out;
70    }
71    if ((fd=fopen(query_file, "rb")) == NULL) {
72       bsendmsg(ua, _("Could not open %s: ERR=%s\n"), query_file,
73          strerror(errno));
74       goto bail_out;
75    }
76
77    start_prompt(ua, _("Available queries:\n"));
78    while (fgets(line, sizeof(line), fd) != NULL) {
79       if (line[0] == ':') {
80          strip_trailing_junk(line);
81          add_prompt(ua, line+1);
82       }
83    }
84    if ((item=do_prompt(ua, "", _("Choose a query"), NULL, 0)) < 0) {
85       goto bail_out;
86    }
87    rewind(fd);
88    i = -1;
89    while (fgets(line, sizeof(line), fd) != NULL) {
90       if (line[0] == ':') {
91          i++;
92       }
93       if (i == item) {
94          break;
95       }
96    }
97    if (i != item) {
98       bsendmsg(ua, _("Could not find query.\n"));
99       goto bail_out;
100    }
101    query[0] = 0;
102    for (i=0; i<9; i++) {
103       prompt[i] = NULL;
104    }
105    while (fgets(line, sizeof(line), fd) != NULL) {
106       if (line[0] == '#') {
107          continue;
108       }
109       if (line[0] == ':') {
110          break;
111       }
112       strip_trailing_junk(line);
113       len = strlen(line);
114       if (line[0] == '*') {            /* prompt */
115          if (nprompt >= 9) {
116             bsendmsg(ua, _("Too many prompts in query, max is 9.\n"));
117          } else {
118             line[len++] = ' ';
119             line[len] = 0;
120             prompt[nprompt++] = bstrdup(line+1);
121             continue;
122          }
123       }
124       if (*query != 0) {
125          pm_strcat(query, " ");
126       }
127       pm_strcat(query, line);
128       if (line[len-1] != ';') {
129          continue;
130       }
131       line[len-1] = 0;             /* zap ; */
132       if (query[0] != 0) {
133          query = substitute_prompts(ua, query, prompt, nprompt);
134          Dmsg1(100, "Query2=%s\n", query);
135          if (query[0] == '!') {
136             db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
137          } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
138             bsendmsg(ua, "%s\n", query);
139          }
140          query[0] = 0;
141       }
142    } /* end while */
143
144    if (query[0] != 0) {
145       query = substitute_prompts(ua, query, prompt, nprompt);
146       Dmsg1(100, "Query2=%s\n", query);
147          if (query[0] == '!') {
148             db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
149          } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
150             bsendmsg(ua, "%s\n", query);
151          }
152    }
153
154 bail_out:
155    if (fd) {
156       fclose(fd);
157    }
158    free_pool_memory(query);
159    for (i=0; i<nprompt; i++) {
160       free(prompt[i]);
161    }
162    return 1;
163 }
164
165 static POOLMEM *substitute_prompts(UAContext *ua,
166                        POOLMEM *query, char **prompt, int nprompt)
167 {
168    char *p, *q, *o;
169    POOLMEM *new_query;
170    int i, n, len, olen;
171    char *subst[9];
172
173    if (nprompt == 0) {
174       return query;
175    }
176    for (i=0; i<9; i++) {
177       subst[i] = NULL;
178    }
179    new_query = get_pool_memory(PM_FNAME);
180    o = new_query;
181    for (q=query; (p=strchr(q, '%')); ) {
182       if (p) {
183         olen = o - new_query;
184         new_query = check_pool_memory_size(new_query, olen + p - q + 10);
185         o = new_query + olen;
186          while (q < p) {              /* copy up to % */
187             *o++ = *q++;
188          }
189          p++;
190          switch (*p) {
191          case '1':
192          case '2':
193          case '3':
194          case '4':
195          case '5':
196          case '6':
197          case '7':
198          case '8':
199          case '9':
200             n = (int)(*p) - (int)'1';
201             if (prompt[n]) {
202                if (!subst[n]) {
203                   if (!get_cmd(ua, prompt[n])) {
204                      q += 2;
205                      break;
206                   }
207                }
208                len = strlen(ua->cmd);
209                p = (char *)malloc(len * 2 + 1);
210                db_escape_string(p, ua->cmd, len);
211                subst[n] = p;
212                olen = o - new_query;
213                new_query = check_pool_memory_size(new_query, olen + strlen(p) + 10);
214                o = new_query + olen;
215                while (*p) {
216                   *o++ = *p++;
217                }
218             } else {
219                bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
220             }
221             q += 2;
222             break;
223          case '%':
224             *o++ = '%';
225             q += 2;
226             break;
227          default:
228             *o++ = '%';
229             q++;
230             break;
231          }
232       }
233    }
234    olen = o - new_query;
235    new_query = check_pool_memory_size(new_query, olen + strlen(q) + 10);
236    o = new_query + olen;
237    while (*q) {
238       *o++ = *q++;
239    }
240    *o = 0;
241    for (i=0; i<9; i++) {
242       if (subst[i]) {
243          free(subst[i]);
244       }
245    }
246    free_pool_memory(query);
247    return new_query;
248 }
249
250 /*
251  * Get general SQL query for Catalog
252  */
253 int sqlquerycmd(UAContext *ua, const char *cmd)
254 {
255    POOLMEM *query = get_pool_memory(PM_MESSAGE);
256    int len;
257    const char *msg;
258
259    if (!open_client_db(ua)) {
260       free_pool_memory(query);
261       return 1;
262    }
263    *query = 0;
264
265    bsendmsg(ua, _("Entering SQL query mode.\n"
266 "Terminate each query with a semicolon.\n"
267 "Terminate query mode with a blank line.\n"));
268    msg = _("Enter SQL query: ");
269    while (get_cmd(ua, msg)) {
270       len = strlen(ua->cmd);
271       Dmsg2(400, "len=%d cmd=%s:\n", len, ua->cmd);
272       if (len == 0) {
273          break;
274       }
275       query = check_pool_memory_size(query, len + 1);
276       if (*query != 0) {
277          pm_strcat(query, " ");
278       }
279       pm_strcat(query, ua->cmd);
280       if (ua->cmd[len-1] == ';') {
281          ua->cmd[len-1] = 0;          /* zap ; */
282          /* Submit query */
283          db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
284          *query = 0;                  /* start new query */
285          msg = _("Enter SQL query: ");
286       } else {
287          msg = _("Add to SQL query: ");
288       }
289    }
290    free_pool_memory(query);
291    bsendmsg(ua, _("End query mode.\n"));
292    return 1;
293 }