]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_query.c
Final changes
[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 /*
11    Copyright (C) 2000-2003 Kern Sibbald and John Walker
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of
16    the License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public
24    License along with this program; if not, write to the Free
25    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26    MA 02111-1307, USA.
27
28  */
29
30 #include "bacula.h"
31 #include "dird.h"
32
33 extern DIRRES *director;
34
35 static char *substitute_prompts(UAContext *ua, 
36                        char *query, char **prompt, int nprompt);
37
38 /*
39  * Read a file containing SQL queries and prompt
40  *  the user to select which one.
41  *
42  *   File format:
43  *   #  => comment
44  *   :prompt for query
45  *   *prompt for subst %1
46  *   *prompt for subst %2
47  *   ...
48  *   SQL statement possibly terminated by ;
49  *   :next query prompt
50  */
51 int querycmd(UAContext *ua, char *cmd)
52 {
53    FILE *fd;
54    POOLMEM *query = get_pool_memory(PM_MESSAGE);
55    char line[1000];
56    int i, item, len;
57    char *prompt[9];
58    int nprompt;
59    char *query_file = director->query_file;
60    
61    if (!open_db(ua)) {
62       free_pool_memory(query);
63       return 1;
64    }
65    if ((fd=fopen(query_file, "r")) == NULL) {
66       bsendmsg(ua, "Could not open %s: ERR=%s\n", query_file,
67          strerror(errno));
68       free_pool_memory(query);
69       return 1;
70    }
71
72    start_prompt(ua, _("Available queries:\n"));
73    while (fgets(line, sizeof(line), fd) != NULL) {
74       if (line[0] == ':') {
75          strip_trailing_junk(line);
76          add_prompt(ua, line+1);
77       }
78    }
79    if ((item=do_prompt(ua, "", _("Choose a query"), NULL, 0)) < 0) {
80       fclose(fd);
81       free_pool_memory(query);
82       return 1;
83    }
84    rewind(fd);
85    i = -1;
86    while (fgets(line, sizeof(line), fd) != NULL) {
87       if (line[0] == ':') {
88          i++;
89       }
90       if (i == item) {
91          break;
92       }
93    }
94    if (i != item) {
95       bsendmsg(ua, _("Could not find query.\n"));
96       fclose(fd);
97       free_pool_memory(query);
98       return 1;
99    }
100    query[0] = 0;
101    for (i=0; i<9; i++) {
102       prompt[i] = NULL;
103    }
104    nprompt = 0;
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       query = check_pool_memory_size(query, len + 1);
125       if (*query != 0) {
126          strcat(query, " ");
127       }
128       strcat(query, line);
129       if (line[len-1] != ';') {
130          continue;
131       }
132       line[len-1] = 0;             /* zap ; */
133       if (query[0] != 0) {
134          query = substitute_prompts(ua, query, prompt, nprompt);
135          Dmsg1(100, "Query2=%s\n", query);
136          if (query[0] == '!') {
137             db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
138          } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
139             bsendmsg(ua, "%s\n", query);
140          }
141          query[0] = 0;
142       }
143    } /* end while */
144
145    if (query[0] != 0) {
146       query = substitute_prompts(ua, query, prompt, nprompt);
147       Dmsg1(100, "Query2=%s\n", query);
148          if (query[0] == '!') {
149             db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
150          } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
151             bsendmsg(ua, "%s\n", query);
152          }
153    }
154    free_pool_memory(query);
155    for (i=0; i<nprompt; i++) {
156       free(prompt[i]);
157    }
158    return 1;
159 }
160
161 static POOLMEM *substitute_prompts(UAContext *ua, 
162                        char *query, char **prompt, int nprompt)
163 {
164    char *p, *q, *o;
165    POOLMEM *new_query;
166    int i, n, len, olen;
167    char *subst[9];
168
169    if (nprompt == 0) {
170       return query;
171    }
172    for (i=0; i<9; i++) {
173       subst[i] = NULL;
174    }
175    new_query = get_pool_memory(PM_FNAME);
176    o = new_query;
177    for (q=query; (p=strchr(q, '%')); ) {
178       if (p) {
179         olen = o - new_query;
180         new_query = check_pool_memory_size(new_query, olen + p - q + 10);
181         o = new_query + olen;
182          while (q < p) {              /* copy up to % */
183             *o++ = *q++;
184          }
185          p++;
186          switch (*p) {
187          case '1':
188          case '2':
189          case '3':
190          case '4':
191          case '5':
192          case '6':
193          case '7':
194          case '8':
195          case '9':
196             n = (int)(*p) - (int)'1';
197             if (prompt[n]) {
198                if (!subst[n]) {
199                   if (!get_cmd(ua, prompt[n])) {
200                      q += 2;
201                      break;
202                   }
203                }
204                len = strlen(ua->cmd);
205                p = (char *)malloc(len * 2 + 1);
206                db_escape_string(p, ua->cmd, len);
207                subst[n] = p;
208                olen = o - new_query;
209                new_query = check_pool_memory_size(new_query, olen + strlen(p) + 10);
210                o = new_query + olen;
211                while (*p) {
212                   *o++ = *p++;
213                }
214             } else {
215                bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
216             }
217             q += 2;
218             break;
219          case '%':
220             *o++ = '%';
221             q += 2;
222             break;
223          default:
224             *o++ = '%';
225             q++;
226             break;
227          }
228       }
229    }
230    olen = o - new_query;
231    new_query = check_pool_memory_size(new_query, olen + strlen(q) + 10);
232    o = new_query + olen;
233    while (*q) {
234       *o++ = *q++;
235    }
236    *o = 0;
237    for (i=0; i<9; i++) {
238       if (subst[i]) {
239          free(subst[i]);
240       }
241    }
242    free_pool_memory(query);
243    return new_query;
244 }
245
246 /*
247  * Get general SQL query for Catalog
248  */
249 int sqlquerycmd(UAContext *ua, char *cmd)
250 {
251    POOLMEM *query = get_pool_memory(PM_MESSAGE);
252    int len;
253    char *msg;
254
255    if (!open_db(ua)) {
256       free_pool_memory(query);
257       return 1;
258    }
259    *query = 0;
260
261    bsendmsg(ua, _("Entering SQL query mode.\n\
262 Terminate each query with a semicolon.\n\
263 Terminate query mode with a blank line.\n"));
264    msg = "Enter SQL query: ";
265    while (get_cmd(ua, msg)) {
266       len = strlen(ua->cmd);
267       Dmsg2(400, "len=%d cmd=%s:\n", len, ua->cmd);
268       if (len == 0) {
269          break;
270       }
271       query = check_pool_memory_size(query, len + 1);
272       if (*query != 0) {
273          strcat(query, " ");
274       }
275       strcat(query, ua->cmd);
276       if (ua->cmd[len-1] == ';') {
277          ua->cmd[len-1] = 0;          /* zap ; */
278          /* Submit query */
279          db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
280          *query = 0;                  /* start new query */
281          msg = _("Enter SQL query: ");
282       } else {
283          msg = _("Add to SQL query: ");
284       }
285    }
286    free_pool_memory(query);
287    bsendmsg(ua, _("End query mode.\n"));
288    return 1; 
289 }