X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Flib%2Fscan.c;h=d8dfab383562fc8ad7b989abe46776f4a42d6524;hb=840ed7767c6fda33fab5f305645af6714d429409;hp=cfb5751300de698e97bd015f0090bebdd4a42bf5;hpb=5acf2fea2740c922a094c4e67c575686844f7e71;p=bacula%2Fbacula diff --git a/bacula/src/lib/scan.c b/bacula/src/lib/scan.c index cfb5751300..d8dfab3835 100644 --- a/bacula/src/lib/scan.c +++ b/bacula/src/lib/scan.c @@ -1,34 +1,48 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2000-2011 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version three of the GNU Affero General Public + License as published by the Free Software Foundation and included + in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of Kern Sibbald. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ /* * scan.c -- scanning routines for Bacula * * Kern Sibbald, MM separated from util.c MMIII * - * Version $Id$ */ -/* - Copyright (C) 2000-2005 Kern Sibbald - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as amended with additional clauses defined in the - file LICENSE in the main source directory. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - the file LICENSE for additional details. - - */ - #include "bacula.h" #include "jcr.h" #include "findlib/find.h" -/* Strip leading space from command line arguments */ +/* + * Strip leading space from command line arguments + */ void strip_leading_space(char *str) { char *p = str; + while (B_ISSPACE(*p)) { p++; } @@ -37,27 +51,49 @@ void strip_leading_space(char *str) } } - -/* Strip any trailing junk from the command */ +/* + * Strip any trailing junk from the command + */ void strip_trailing_junk(char *cmd) { char *p; + + /* + * Strip trailing junk from command + */ p = cmd + strlen(cmd) - 1; + while ((p >= cmd) && (*p == '\n' || *p == '\r' || *p == ' ')) { + *p-- = 0; + } +} + +/* + * Strip any trailing newline characters from the string + */ +void strip_trailing_newline(char *cmd) +{ + char *p; - /* strip trailing junk from command */ - while ((p >= cmd) && (*p == '\n' || *p == '\r' || *p == ' ')) + p = cmd + strlen(cmd) - 1; + while ((p >= cmd) && (*p == '\n' || *p == '\r')) { *p-- = 0; + } } -/* Strip any trailing slashes from a directory path */ +/* + * Strip any trailing slashes from a directory path + */ void strip_trailing_slashes(char *dir) { char *p; - p = dir + strlen(dir) - 1; - /* strip trailing slashes */ - while ((p >= dir) && (*p == '/')) + /* + * Strip trailing slashes + */ + p = dir + strlen(dir) - 1; + while (p >= dir && IsPathSeparator(*p)) { *p-- = 0; + } } /* @@ -99,9 +135,10 @@ bool skip_nonspaces(char **msg) return *p ? true : false; } -/* folded search for string - case insensitive */ -int -fstrsch(const char *a, const char *b) /* folded case search */ +/* + * Folded search for string - case insensitive + */ +int fstrsch(const char *a, const char *b) /* folded case search */ { const char *s1,*s2; char c1, c2; @@ -128,10 +165,20 @@ fstrsch(const char *a, const char *b) /* folded case search */ return 1; } - /* * Return next argument from command line. Note, this - * routine is destructive. + * routine is destructive because it stored 0 at the end + * of each argument. + * Called with pointer to pointer to command line. This + * pointer is updated to point to the remainder of the + * command line. + * + * Returns pointer to next argument -- don't store the result + * in the pointer you passed as an argument ... + * The next argument is terminated by a space unless within + * quotes. Double quote characters (unless preceded by a \) are + * stripped. + * */ char *next_arg(char **s) { @@ -144,8 +191,8 @@ char *next_arg(char **s) } Dmsg1(900, "Next arg=%s\n", p); for (n = q = p; *p ; ) { - if (*p == '\\') { - p++; + if (*p == '\\') { /* slash? */ + p++; /* yes, skip it */ if (*p) { *q++ = *p++; } else { @@ -154,16 +201,11 @@ char *next_arg(char **s) continue; } if (*p == '"') { /* start or end of quote */ - if (in_quote) { - p++; /* skip quote */ - in_quote = false; - continue; - } - in_quote = true; p++; + in_quote = !in_quote; /* change state */ continue; } - if (!in_quote && B_ISSPACE(*p)) { /* end of field */ + if (!in_quote && B_ISSPACE(*p)) { /* end of field */ p++; break; } @@ -178,7 +220,7 @@ char *next_arg(char **s) /* * This routine parses the input command line. * It makes a copy in args, then builds an - * argc, argv like list where + * argc, argk, argv list where: * * argc = count of arguments * argk[i] = argument keyword (part preceding =) @@ -194,17 +236,65 @@ char *next_arg(char **s) * argk[2] = arg3 * argv[2] = */ - int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, char **argk, char **argv, int max_args) { - char *p, *q, *n; + char *p; + + parse_args_only(cmd, args, argc, argk, argv, max_args); + + /* Separate keyword and value */ + for (int i=0; i < *argc; i++) { + p = strchr(argk[i], '='); + if (p) { + *p++ = 0; /* terminate keyword and point to value */ + } + argv[i] = p; /* save ptr to value or NULL */ + } +#ifdef xxx_debug + for (int i=0; i < *argc; i++) { + Pmsg3(000, "Arg %d: kw=%s val=%s\n", i, argk[i], argv[i]?argv[i]:"NULL"); + } +#endif + return 1; +} + + +/* + * This routine parses the input command line. + * It makes a copy in args, then builds an + * argc, argk, but no argv (values). + * This routine is useful for scanning command lines where the data + * is a filename and no keywords are expected. If we scan a filename + * for keywords, any = in the filename will be interpreted as the + * end of a keyword, and this is not good. + * + * argc = count of arguments + * argk[i] = argument keyword (part preceding =) + * argv[i] = NULL + * + * example: arg1 arg2=abc arg3= + * + * argc = c + * argk[0] = arg1 + * argv[0] = NULL + * argk[1] = arg2=abc + * argv[1] = NULL + * argk[2] = arg3 + * argv[2] = + */ +int parse_args_only(POOLMEM *cmd, POOLMEM **args, int *argc, + char **argk, char **argv, int max_args) +{ + char *p, *n; pm_strcpy(args, cmd); strip_trailing_junk(*args); p = *args; *argc = 0; - /* Pick up all arguments */ + /* + * Pick up all arguments + */ while (*argc < max_args) { n = next_arg(&p); if (*n) { @@ -214,33 +304,6 @@ int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, break; } } - /* Separate keyword and value */ - for (int i=0; i < *argc; i++) { - p = strchr(argk[i], '='); - if (p) { - *p++ = 0; /* terminate keyword and point to value */ - /* Unquote quoted values */ - if (*p == '"') { - for (n = q = ++p; *p && *p != '"'; ) { - if (*p == '\\') { - p++; - } - *q++ = *p++; - } - *q = 0; /* terminate string */ - p = n; /* point to string */ - } - if (strlen(p) > MAX_NAME_LENGTH-1) { - p[MAX_NAME_LENGTH-1] = 0; /* truncate to max len */ - } - } - argv[i] = p; /* save ptr to value or NULL */ - } -#ifdef xxxx - for (int i=0; i < *argc; i++) { - Pmsg3(000, "Arg %d: kw=%s val=%s\n", i, argk[i], argv[i]?argv[i]:"NULL"); - } -#endif return 1; } @@ -250,7 +313,7 @@ int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc, * in the arguments provided. */ void split_path_and_filename(const char *fname, POOLMEM **path, int *pnl, - POOLMEM **file, int *fnl) + POOLMEM **file, int *fnl) { const char *f; int slen; @@ -265,16 +328,16 @@ void split_path_and_filename(const char *fname, POOLMEM **path, int *pnl, */ f = fname + len - 1; /* "strip" any trailing slashes */ - while (slen > 1 && *f == '/') { + while (slen > 1 && IsPathSeparator(*f)) { slen--; f--; } /* Walk back to last slash -- begin of filename */ - while (slen > 0 && *f != '/') { + while (slen > 0 && !IsPathSeparator(*f)) { slen--; f--; } - if (*f == '/') { /* did we find a slash? */ + if (IsPathSeparator(*f)) { /* did we find a slash? */ f++; /* yes, point to filename */ } else { /* no, whole thing must be path name */ f = fname; @@ -312,6 +375,7 @@ int bsscanf(const char *buf, const char *fmt, ...) int max_len = BIG; uint64_t value; bool error = false; + bool negative; va_start(ap, fmt); while (*fmt && !error) { @@ -322,18 +386,47 @@ int bsscanf(const char *buf, const char *fmt, ...) switch_top: switch (*fmt++) { case 'u': - case 'd': value = 0; while (B_ISDIGIT(*buf)) { value = B_TIMES10(value) + *buf++ - '0'; } vp = (void *)va_arg(ap, void *); // Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp); - if (l < 2) { + if (l == 0) { + *((int *)vp) = (int)value; + } else if (l == 1) { *((uint32_t *)vp) = (uint32_t)value; // Dmsg0(000, "Store 32 bit int\n"); } else { *((uint64_t *)vp) = (uint64_t)value; +// Dmsg0(000, "Store 64 bit int\n"); + } + count++; + l = 0; + break; + case 'd': + value = 0; + if (*buf == '-') { + negative = true; + buf++; + } else { + negative = false; + } + while (B_ISDIGIT(*buf)) { + value = B_TIMES10(value) + *buf++ - '0'; + } + if (negative) { + value = -value; + } + vp = (void *)va_arg(ap, void *); +// Dmsg2(000, "val=%lld at 0x%lx\n", value, (long unsigned)vp); + if (l == 0) { + *((int *)vp) = (int)value; + } else if (l == 1) { + *((int32_t *)vp) = (int32_t)value; +// Dmsg0(000, "Store 32 bit int\n"); + } else { + *((int64_t *)vp) = (int64_t)value; // Dmsg0(000, "Store 64 bit int\n"); } count++;