]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_query.c
Fix conio.h problem on Solaris
[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) 2001-2004 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 POOLMEM *substitute_prompts(UAContext *ua, 
36                        POOLMEM *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, const char *cmd)
52 {
53    FILE *fd = NULL;
54    POOLMEM *query = get_pool_memory(PM_MESSAGE);
55    char line[1000];
56    int i, item, len;
57    char *prompt[9];
58    int nprompt = 0;;
59    char *query_file = director->query_file;
60    
61    if (!open_db(ua)) {
62       goto bail_out;
63    }
64    if ((fd=fopen(query_file, "r")) == NULL) {
65       bsendmsg(ua, "Could not open %s: ERR=%s\n", query_file,
66          strerror(errno));
67       goto bail_out;
68    }
69
70    start_prompt(ua, _("Available queries:\n"));
71    while (fgets(line, sizeof(line), fd) != NULL) {
72       if (line[0] == ':') {
73          strip_trailing_junk(line);
74          add_prompt(ua, line+1);
75       }
76    }
77    if ((item=do_prompt(ua, "", _("Choose a query"), NULL, 0)) < 0) {
78       goto bail_out;
79    }
80    rewind(fd);
81    i = -1;
82    while (fgets(line, sizeof(line), fd) != NULL) {
83       if (line[0] == ':') {
84          i++;
85       }
86       if (i == item) {
87          break;
88       }
89    }
90    if (i != item) {
91       bsendmsg(ua, _("Could not find query.\n"));
92       goto bail_out;
93    }
94    query[0] = 0;
95    for (i=0; i<9; i++) {
96       prompt[i] = NULL;
97    }
98    while (fgets(line, sizeof(line), fd) != NULL) {
99       if (line[0] == '#') {
100          continue;
101       }
102       if (line[0] == ':') {
103          break;
104       }
105       strip_trailing_junk(line);
106       len = strlen(line);
107       if (line[0] == '*') {            /* prompt */
108          if (nprompt >= 9) {
109             bsendmsg(ua, _("Too many prompts in query, max is 9.\n"));
110          } else {
111             line[len++] = ' ';
112             line[len] = 0;
113             prompt[nprompt++] = bstrdup(line+1);
114             continue;
115          }
116       }  
117       if (*query != 0) {
118          pm_strcat(query, " ");
119       }
120       pm_strcat(query, line);
121       if (line[len-1] != ';') {
122          continue;
123       }
124       line[len-1] = 0;             /* zap ; */
125       if (query[0] != 0) {
126          query = substitute_prompts(ua, query, prompt, nprompt);
127          Dmsg1(100, "Query2=%s\n", query);
128          if (query[0] == '!') {
129             db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
130          } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
131             bsendmsg(ua, "%s\n", query);
132          }
133          query[0] = 0;
134       }
135    } /* end while */
136
137    if (query[0] != 0) {
138       query = substitute_prompts(ua, query, prompt, nprompt);
139       Dmsg1(100, "Query2=%s\n", query);
140          if (query[0] == '!') {
141             db_list_sql_query(ua->jcr, ua->db, query+1, prtit, ua, 0, VERT_LIST);
142          } else if (!db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST)) {
143             bsendmsg(ua, "%s\n", query);
144          }
145    }
146
147 bail_out:
148    if (fd) {
149       fclose(fd);
150    }
151    free_pool_memory(query);
152    for (i=0; i<nprompt; i++) {
153       free(prompt[i]);
154    }
155    return 1;
156 }
157
158 static POOLMEM *substitute_prompts(UAContext *ua, 
159                        POOLMEM *query, char **prompt, int nprompt)
160 {
161    char *p, *q, *o;
162    POOLMEM *new_query;
163    int i, n, len, olen;
164    char *subst[9];
165
166    if (nprompt == 0) {
167       return query;
168    }
169    for (i=0; i<9; i++) {
170       subst[i] = NULL;
171    }
172    new_query = get_pool_memory(PM_FNAME);
173    o = new_query;
174    for (q=query; (p=strchr(q, '%')); ) {
175       if (p) {
176         olen = o - new_query;
177         new_query = check_pool_memory_size(new_query, olen + p - q + 10);
178         o = new_query + olen;
179          while (q < p) {              /* copy up to % */
180             *o++ = *q++;
181          }
182          p++;
183          switch (*p) {
184          case '1':
185          case '2':
186          case '3':
187          case '4':
188          case '5':
189          case '6':
190          case '7':
191          case '8':
192          case '9':
193             n = (int)(*p) - (int)'1';
194             if (prompt[n]) {
195                if (!subst[n]) {
196                   if (!get_cmd(ua, prompt[n])) {
197                      q += 2;
198                      break;
199                   }
200                }
201                len = strlen(ua->cmd);
202                p = (char *)malloc(len * 2 + 1);
203                db_escape_string(p, ua->cmd, len);
204                subst[n] = p;
205                olen = o - new_query;
206                new_query = check_pool_memory_size(new_query, olen + strlen(p) + 10);
207                o = new_query + olen;
208                while (*p) {
209                   *o++ = *p++;
210                }
211             } else {
212                bsendmsg(ua, _("Warning prompt %d missing.\n"), n+1);
213             }
214             q += 2;
215             break;
216          case '%':
217             *o++ = '%';
218             q += 2;
219             break;
220          default:
221             *o++ = '%';
222             q++;
223             break;
224          }
225       }
226    }
227    olen = o - new_query;
228    new_query = check_pool_memory_size(new_query, olen + strlen(q) + 10);
229    o = new_query + olen;
230    while (*q) {
231       *o++ = *q++;
232    }
233    *o = 0;
234    for (i=0; i<9; i++) {
235       if (subst[i]) {
236          free(subst[i]);
237       }
238    }
239    free_pool_memory(query);
240    return new_query;
241 }
242
243 /*
244  * Get general SQL query for Catalog
245  */
246 int sqlquerycmd(UAContext *ua, const char *cmd)
247 {
248    POOLMEM *query = get_pool_memory(PM_MESSAGE);
249    int len;
250    const char *msg;
251
252    if (!open_db(ua)) {
253       free_pool_memory(query);
254       return 1;
255    }
256    *query = 0;
257
258    bsendmsg(ua, _("Entering SQL query mode.\n\
259 Terminate each query with a semicolon.\n\
260 Terminate query mode with a blank line.\n"));
261    msg = "Enter SQL query: ";
262    while (get_cmd(ua, msg)) {
263       len = strlen(ua->cmd);
264       Dmsg2(400, "len=%d cmd=%s:\n", len, ua->cmd);
265       if (len == 0) {
266          break;
267       }
268       query = check_pool_memory_size(query, len + 1);
269       if (*query != 0) {
270          strcat(query, " ");
271       }
272       strcat(query, ua->cmd);
273       if (ua->cmd[len-1] == ';') {
274          ua->cmd[len-1] = 0;          /* zap ; */
275          /* Submit query */
276          db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
277          *query = 0;                  /* start new query */
278          msg = _("Enter SQL query: ");
279       } else {
280          msg = _("Add to SQL query: ");
281       }
282    }
283    free_pool_memory(query);
284    bsendmsg(ua, _("End query mode.\n"));
285    return 1; 
286 }