2 * scan.c -- scanning routines for Bacula
4 * Kern Sibbald, MM separated from util.c MMIII
10 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
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.
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.
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,
31 #include "findlib/find.h"
34 /* Strip any trailing junk from the command */
35 void strip_trailing_junk(char *cmd)
38 p = cmd + strlen(cmd) - 1;
40 /* strip trailing junk from command */
41 while ((p >= cmd) && (*p == '\n' || *p == '\r' || *p == ' '))
45 /* Strip any trailing slashes from a directory path */
46 void strip_trailing_slashes(char *dir)
49 p = dir + strlen(dir) - 1;
51 /* strip trailing slashes */
52 while ((p >= dir) && (*p == '/'))
58 * Returns: 0 on failure (EOF)
60 * new address in passed parameter
62 int skip_spaces(char **msg)
68 while (*p && *p == ' ') {
77 * Returns: 0 on failure (EOF)
79 * new address in passed parameter
81 int skip_nonspaces(char **msg)
88 while (*p && *p != ' ') {
95 /* folded search for string - case insensitive */
97 fstrsch(char *a, char *b) /* folded case search */
99 register char *s1,*s2;
100 register char c1, c2;
104 while (*s1) { /* do it the fast way */
105 if ((*s1++ | 0x20) != (*s2++ | 0x20))
106 return 0; /* failed */
108 while (*a) { /* do it over the correct slow way */
109 if (B_ISUPPER(c1 = *a)) {
110 c1 = tolower((int)c1);
112 if (B_ISUPPER(c2 = *b)) {
113 c2 = tolower((int)c2);
126 * Return next argument from command line. Note, this
127 * routine is destructive.
129 char *next_arg(char **s)
132 bool in_quote = false;
134 /* skip past spaces to next arg */
135 for (p=*s; *p && B_ISSPACE(*p); ) {
138 Dmsg1(400, "Next arg=%s\n", p);
139 for (n = q = p; *p ; ) {
149 if (*p == '"') { /* start or end of quote */
151 p++; /* skip quote */
159 if (!in_quote && B_ISSPACE(*p)) { /* end of field */
167 Dmsg2(400, "End arg=%s next=%s\n", n, p);
172 * This routine parses the input command line.
173 * It makes a copy in args, then builds an
174 * argc, argv like list where
176 * argc = count of arguments
177 * argk[i] = argument keyword (part preceding =)
178 * argv[i] = argument value (part after =)
180 * example: arg1 arg2=abc arg3=
191 int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
192 char **argk, char **argv, int max_args)
196 pm_strcpy(args, cmd);
197 strip_trailing_junk(*args);
200 /* Pick up all arguments */
201 while (*argc < max_args) {
205 argv[(*argc)++] = NULL;
210 /* Separate keyword and value */
211 for (int i=0; i < *argc; i++) {
212 p = strchr(argk[i], '=');
214 *p++ = 0; /* terminate keyword and point to value */
215 /* Unquote quoted values */
217 for (n = q = ++p; *p && *p != '"'; ) {
223 *q = 0; /* terminate string */
224 p = n; /* point to string */
226 if (strlen(p) > MAX_NAME_LENGTH-1) {
227 p[MAX_NAME_LENGTH-1] = 0; /* truncate to max len */
230 argv[i] = p; /* save ptr to value or NULL */
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");