]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/scan.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / lib / scan.c
1 /*
2  *   scan.c -- scanning routines for Bacula
3  * 
4  *    Kern Sibbald, MM  separated from util.c MMIII
5  *
6  *   Version $Id$
7  */
8
9 /*
10    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of
15    the License, or (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20    General Public License for more details.
21
22    You should have received a copy of the GNU General Public
23    License along with this program; if not, write to the Free
24    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25    MA 02111-1307, USA.
26
27  */
28
29 #include "bacula.h"
30 #include "jcr.h"
31 #include "findlib/find.h"
32
33
34 /* Strip any trailing junk from the command */
35 void strip_trailing_junk(char *cmd)
36 {
37    char *p;
38    p = cmd + strlen(cmd) - 1;
39
40    /* strip trailing junk from command */
41    while ((p >= cmd) && (*p == '\n' || *p == '\r' || *p == ' '))
42       *p-- = 0;
43 }
44
45 /* Strip any trailing slashes from a directory path */
46 void strip_trailing_slashes(char *dir)
47 {
48    char *p;
49    p = dir + strlen(dir) - 1;
50
51    /* strip trailing slashes */
52    while ((p >= dir) && (*p == '/'))
53       *p-- = 0;
54 }
55
56 /*
57  * Skip spaces
58  *  Returns: 0 on failure (EOF)             
59  *           1 on success
60  *           new address in passed parameter 
61  */
62 bool skip_spaces(char **msg)
63 {
64    char *p = *msg;
65    if (!p) {
66       return false;
67    }
68    while (*p && B_ISSPACE(*p)) {
69       p++;
70    }
71    *msg = p;
72    return *p ? true : false;
73 }
74
75 /*
76  * Skip nonspaces
77  *  Returns: 0 on failure (EOF)             
78  *           1 on success
79  *           new address in passed parameter 
80  */
81 bool skip_nonspaces(char **msg)
82 {
83    char *p = *msg;
84
85    if (!p) {
86       return false;
87    }
88    while (*p && !B_ISSPACE(*p)) {
89       p++;
90    }
91    *msg = p;
92    return *p ? true : false;
93 }
94
95 /* folded search for string - case insensitive */
96 int
97 fstrsch(char *a, char *b)   /* folded case search */
98 {
99    register char *s1,*s2;
100    register char c1, c2;
101
102    s1=a;
103    s2=b;
104    while (*s1) {                      /* do it the fast way */
105       if ((*s1++ | 0x20) != (*s2++ | 0x20))
106          return 0;                    /* failed */
107    }
108    while (*a) {                       /* do it over the correct slow way */
109       if (B_ISUPPER(c1 = *a)) {
110          c1 = tolower((int)c1);
111       }
112       if (B_ISUPPER(c2 = *b)) {
113          c2 = tolower((int)c2);
114       }
115       if (c1 != c2) {
116          return 0;
117       }
118       a++;
119       b++;
120    }
121    return 1;
122 }
123
124
125 /* 
126  * Return next argument from command line.  Note, this
127  * routine is destructive.
128  */
129 char *next_arg(char **s)
130 {
131    char *p, *q, *n;
132    bool in_quote = false;
133
134    /* skip past spaces to next arg */
135    for (p=*s; *p && B_ISSPACE(*p); ) {
136       p++;
137    }    
138    Dmsg1(400, "Next arg=%s\n", p);
139    for (n = q = p; *p ; ) {
140       if (*p == '\\') {
141          p++;
142          if (*p) {
143             *q++ = *p++;
144          } else {
145             *q++ = *p;
146          }
147          continue;
148       }
149       if (*p == '"') {                  /* start or end of quote */
150          if (in_quote) {
151             p++;                        /* skip quote */
152             in_quote = false;
153             continue;
154          }
155          in_quote = true;
156          p++;
157          continue;
158       }
159       if (!in_quote && B_ISSPACE(*p)) {     /* end of field */
160          p++;
161          break;
162       }
163       *q++ = *p++;
164    }
165    *q = 0;
166    *s = p;
167    Dmsg2(400, "End arg=%s next=%s\n", n, p);
168    return n;
169 }   
170
171 /*
172  * This routine parses the input command line.
173  * It makes a copy in args, then builds an
174  *  argc, argv like list where
175  *    
176  *  argc = count of arguments
177  *  argk[i] = argument keyword (part preceding =)
178  *  argv[i] = argument value (part after =)
179  *
180  *  example:  arg1 arg2=abc arg3=
181  *
182  *  argc = c
183  *  argk[0] = arg1
184  *  argv[0] = NULL
185  *  argk[1] = arg2
186  *  argv[1] = abc
187  *  argk[2] = arg3
188  *  argv[2] = 
189  */
190
191 int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, 
192                char **argk, char **argv, int max_args) 
193 {
194    char *p, *q, *n;
195
196    pm_strcpy(args, cmd);
197    strip_trailing_junk(*args);
198    p = *args;
199    *argc = 0;
200    /* Pick up all arguments */
201    while (*argc < max_args) {
202       n = next_arg(&p);   
203       if (*n) {
204          argk[*argc] = n;
205          argv[(*argc)++] = NULL;
206       } else {
207          break;
208       }
209    }
210    /* Separate keyword and value */
211    for (int i=0; i < *argc; i++) {
212       p = strchr(argk[i], '=');
213       if (p) {
214          *p++ = 0;                    /* terminate keyword and point to value */
215          /* Unquote quoted values */
216          if (*p == '"') {
217             for (n = q = ++p; *p && *p != '"'; ) {
218                if (*p == '\\') {
219                   p++;
220                }
221                *q++ = *p++;
222             }
223             *q = 0;                   /* terminate string */
224             p = n;                    /* point to string */
225          }
226          if (strlen(p) > MAX_NAME_LENGTH-1) {
227             p[MAX_NAME_LENGTH-1] = 0; /* truncate to max len */
228          }
229       }
230       argv[i] = p;                    /* save ptr to value or NULL */
231    }
232 #ifdef xxxx
233    for (int i=0; i < *argc; i++) {
234       Pmsg3(000, "Arg %d: kw=%s val=%s\n", i, argk[i], argv[i]?argv[i]:"NULL");
235    }
236 #endif
237    return 1;
238 }