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