]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_query.c
This commit was manufactured by cvs2svn to create tag
[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_MESSAGE);
176    new_query = check_pool_memory_size(new_query, strlen(query) +100);
177    o = new_query;
178    olen = 0;
179    for (q=query; (p=strchr(q, '%')); ) {
180       if (p) {
181          while (q < p) {              /* copy up to % */
182             *o++ = *q++;
183             olen++;
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                new_query = check_pool_memory_size(new_query, olen + strlen(p) + 1);
209                while (*p) {
210                   *o++ = *p++;
211                   olen++;
212                }
213             } else {
214                bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
215             }
216             q += 2;
217             break;
218          case '%':
219             *o++ = '%';
220             olen++;
221             q += 2;
222             break;
223          default:
224             *o++ = '%';
225             olen++;
226             q++;
227             break;
228          }
229       }
230    }
231    new_query = check_pool_memory_size(new_query, olen + strlen(q) + 1);
232    while (*q) {
233       *o++ = *q++;
234    }
235    *o = 0;
236    for (i=0; i<9; i++) {
237       if (subst[i]) {
238          free(subst[i]);
239       }
240    }
241    free_pool_memory(query);
242    return new_query;
243 }
244
245 /*
246  * Get general SQL query for Catalog
247  */
248 int sqlquerycmd(UAContext *ua, char *cmd)
249 {
250    POOLMEM *query = get_pool_memory(PM_MESSAGE);
251    int len;
252    char *msg;
253
254    if (!open_db(ua)) {
255       free_pool_memory(query);
256       return 1;
257    }
258    *query = 0;
259
260    bsendmsg(ua, _("Entering SQL query mode.\n\
261 Terminate each query with a semicolon.\n\
262 Terminate query mode with a blank line.\n"));
263    msg = "Enter SQL query: ";
264    while (get_cmd(ua, msg)) {
265       len = strlen(ua->cmd);
266       Dmsg2(400, "len=%d cmd=%s:\n", len, ua->cmd);
267       if (len == 0) {
268          break;
269       }
270       query = check_pool_memory_size(query, len + 1);
271       if (*query != 0) {
272          strcat(query, " ");
273       }
274       strcat(query, ua->cmd);
275       if (ua->cmd[len-1] == ';') {
276          ua->cmd[len-1] = 0;          /* zap ; */
277          /* Submit query */
278          db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
279          *query = 0;                  /* start new query */
280          msg = _("Enter SQL query: ");
281       } else {
282          msg = _("Add to SQL query: ");
283       }
284    }
285    free_pool_memory(query);
286    bsendmsg(ua, _("End query mode.\n"));
287    return 1; 
288 }