]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_input.c
Status cleanup and cancelling FD
[bacula/bacula] / bacula / src / dird / ua_input.c
1 /*
2  *
3  *   Bacula Director -- User Agent Input and scanning code
4  *
5  *     Kern Sibbald, October 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 #include "ua.h"
33
34
35 /* Imported variables */
36
37
38 /* Exported functions */
39
40 int get_cmd(UAContext *ua, char *prompt)
41 {
42    BSOCK *sock = ua->UA_sock;
43    int stat;
44
45    ua->cmd[0] = 0;
46    if (!sock) {                       /* No UA */
47       return 0;
48    }
49    bnet_fsend(sock, "%s", prompt);
50    bnet_sig(sock, BNET_PROMPT);       /* request more input */
51    for ( ;; ) {
52       stat = bnet_recv(sock);
53       if (stat == BNET_SIGNAL) {
54          continue;                    /* ignore signals */
55       }
56       if (is_bnet_stop(sock)) {
57          return 0;                    /* error or terminate */
58       }
59       ua->cmd = check_pool_memory_size(ua->cmd, sock->msglen+1);
60       bstrncpy(ua->cmd, sock->msg, sock->msglen+1);
61       strip_trailing_junk(ua->cmd);
62       if (strcmp(ua->cmd, ".messages") == 0) {
63          qmessagescmd(ua, ua->cmd);
64       }
65       /* ****FIXME**** if .command, go off and do it. For now ignore it. */
66       if (ua->cmd[0] == '.' && ua->cmd[1] != 0) {
67          continue;                    /* dot command */
68       }
69       /* Lone dot => break or actual response */
70       break;
71    }
72    return 1;
73 }
74
75 /* 
76  * Return next argument from command line.  Note, this
77  * routine is destructive.
78  */
79 char *next_arg(char **s)
80 {
81    char *p, *q, *n;
82    int in_quote = 0;
83
84    /* skip past spaces to next arg */
85    for (p=*s; *p && *p == ' '; ) {
86       p++;
87    }    
88    Dmsg1(400, "Next arg=%s\n", p);
89    for (n = q = p; *p ; ) {
90       if (*p == '\\') {
91          p++;
92          if (*p) {
93             *q++ = *p++;
94          } else {
95             *q++ = *p;
96          }
97          continue;
98       }
99       if (*p == '"') {                  /* start or end of quote */
100          if (in_quote) {
101             p++;                        /* skip quote */
102             in_quote = 0;
103             continue;
104          }
105          in_quote = 1;
106          p++;
107          continue;
108       }
109       if (!in_quote && *p == ' ') {     /* end of field */
110          p++;
111          break;
112       }
113       *q++ = *p++;
114    }
115    *q = 0;
116    *s = p;
117    Dmsg2(400, "End arg=%s next=%s\n", n, p);
118    return n;
119 }   
120
121 /*
122  * This routine parses the input command line.
123  * It makes a copy in args, then builds an
124  *  argc, argv like list where
125  *    
126  *  argc = count of arguments
127  *  argk[i] = argument keyword (part preceding =)
128  *  argv[i] = argument value (part after =)
129  *
130  *  example:  arg1 arg2=abc arg3=
131  *
132  *  argc = c
133  *  argk[0] = arg1
134  *  argv[0] = NULL
135  *  argk[1] = arg2
136  *  argv[1] = abc
137  *  argk[2] = arg3
138  *  argv[2] = 
139  */
140
141 void parse_command_args(UAContext *ua)
142 {
143    char *p, *q, *n;
144    int i, len;
145
146    len = strlen(ua->cmd) + 1;
147    ua->args = check_pool_memory_size(ua->args, len);
148    bstrncpy(ua->args, ua->cmd, len);
149    strip_trailing_junk(ua->args);
150    ua->argc = 0;
151    p = ua->args;
152    /* Pick up all arguments */
153    while (ua->argc < MAX_ARGS) {
154       n = next_arg(&p);   
155       if (*n) {
156          ua->argk[ua->argc++] = n;
157       } else {
158          break;
159       }
160    }
161    /* Separate keyword and value */
162    for (i=0; i<ua->argc; i++) {
163       p = strchr(ua->argk[i], '=');
164       if (p) {
165          *p++ = 0;                    /* terminate keyword and point to value */
166          /* Unquote quoted values */
167          if (*p == '"') {
168             for (n = q = ++p; *p && *p != '"'; ) {
169                if (*p == '\\') {
170                   p++;
171                }
172                *q++ = *p++;
173             }
174             *q = 0;                   /* terminate string */
175             p = n;                    /* point to string */
176          }
177          if (strlen(p) > MAX_NAME_LENGTH-1) {
178             p[MAX_NAME_LENGTH-1] = 0; /* truncate to max len */
179          }
180       }
181       ua->argv[i] = p;                /* save ptr to value or NULL */
182    }
183 #ifdef xxxx
184    for (i=0; i<ua->argc; i++) {
185       Dmsg3(000, "Arg %d: kw=%s val=%s\n", i, 
186          ua->argk[i], ua->argv[i]?ua->argv[i]:"NULL");
187    }
188 #endif
189 }