[PATCH v2 1/3] Add a new helper file 'tools.c' that provides some useful APIs

Masaki Tachibana mas-tachibana at vf.jp.nec.com
Wed Mar 7 20:45:08 PST 2018


Hi Bhupesh,


> -----Original Message-----
> From: Bhupesh Sharma [mailto:bhsharma at redhat.com]
> Sent: Tuesday, March 06, 2018 7:17 PM
> To: Tachibana Masaki() <mas-tachibana at vf.jp.nec.com>
> Cc: kexec at lists.infradead.org; Hayashi Masahiko() <mas-hayashi at tg.jp.nec.com>
> Subject: Re: [PATCH v2 1/3] Add a new helper file 'tools.c' that provides some useful APIs
> 
> Hello Masaki,
> 
> On Tue, Mar 6, 2018 at 3:33 PM, Masaki Tachibana
> <mas-tachibana at vf.jp.nec.com> wrote:
> > Hi bhupesh,
> >
> > Thank you for your V2 patchset.
> >
> > When you have introduced tools.c from crash utility,
> > you have deleted a part of htol()'s error handling
> > that is unnecessary for makedumpfile as follows;
> >
> > htol_error:
> > -       switch (flags & (FAULT_ON_ERROR|RETURN_ON_ERROR))
> > -       {
> > -       case FAULT_ON_ERROR:
> > -               RESTART();
> > -
> > -       case RETURN_ON_ERROR:
> > -               if (errptr)
> > -                       *errptr = TRUE;
> > -               break;
> > -       }
> > -
> >         return BADADDR;
> > }
> >
> > As a result of this, htol() does not refer to 3rd parameter 'errptr'
> > and RETURN_ON_ERROR.
> > I understand that some codes are not used on makedumpfile's tools.c.
> > They may be used in the future.
> 
> Indeed the 3rd parameter in 'htol()' is not currently needed by
> makedumpfile code, but like you mentioned I earlier thought it might
> be required for future compatibility some some future feature
> addition.
> 
> > However I think 'errptr' should be deleted, so I have tried modifying
> > your patches as follows;
> > $ diff "PATCH v2 13 Add a new helper file 'tools
> > .c' that provides some useful APIs.patch.old" "PATCH v2 13 Add a new helper file
> >  'tools.c' that provides some useful APIs.patch"
> > 100c100
> > < +ulong htol(char *s, int flags, int *errptr);
> > ---
> >> +ulong htol(char *s, int flags);
> > 681c681
> > < +htol(char *s, int flags, int *errptr)
> > ---
> >> +htol(char *s, int flags)
> >
> > $ diff "PATCH v2 23 arm64 Add support to read sy
> > mbols like _stext from 'prockallsyms'.patch.old" "PATCH v2 23 arm64 Add support
> > to read symbols like _stext from 'prockallsyms'.patch"
> > 62c62
> > < @@ -177,6 +181,45 @@ get_phys_base_arm64(void)
> > ---
> >> @@ -177,6 +181,44 @@ get_phys_base_arm64(void)
> > 94,95c94
> > < +                     kallsym = htol(kallsyms[0], RETURN_ON_ERROR,
> > < +                                     NULL);
> > ---
> >> +                     kallsym = htol(kallsyms[0], 0);
> >
> > How about this ?
> > If you agree, I'll merge the modified patchset into V1.6.4.
> 
> Yes. This seems fine to me. We can add the 3rd parameter to 'htol'
> later if its needed in future.
> 
> Please feel free to merge the modified patchset into V1.6.4

OK. I will merge the modified patchset into V1.6.4.


Thanks
Tachibana

> 
> Regards,
> Bhupesh
> 
> >
> >> -----Original Message-----
> >> From: kexec [mailto:kexec-bounces at lists.infradead.org] On Behalf Of Bhupesh Sharma
> >> Sent: Tuesday, March 06, 2018 2:13 AM
> >> To: kexec at lists.infradead.org
> >> Cc: bhsharma at redhat.com; bhupesh.linux at gmail.com
> >> Subject: [PATCH v2 1/3] Add a new helper file 'tools.c' that provides some useful APIs
> >>
> >> This patch borrows the 'tools.c' helper file from the crash utility
> >> project and adds it to the makedumpfile source code, to allow
> >> some basic useful APIs to be present which can be invoked from
> >> other source code files.
> >>
> >> 'tools.c' provides some useful APIs like 'htol' (convert
> >> a string to a hexadecimal long value), etc. which can be
> >> invoked by other functions (a functionality that is exposed
> >> by follow-up patches).
> >>
> >> Signed-off-by: Bhupesh Sharma <bhsharma at redhat.com>
> >> ---
> >>  Makefile       |   2 +-
> >>  common.h       |   8 +
> >>  makedumpfile.h |  14 ++
> >>  tools.c        | 766 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  4 files changed, 789 insertions(+), 1 deletion(-)
> >>  create mode 100644 tools.c
> >>
> >> diff --git a/Makefile b/Makefile
> >> index f4b7c56b6f3d..e870b1362c95 100644
> >> --- a/Makefile
> >> +++ b/Makefile
> >> @@ -46,7 +46,7 @@ CFLAGS_ARCH += -m32
> >>  endif
> >>
> >>  SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h
> >> -SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c
> >> +SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c
> >>  OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART))
> >>  SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c
> >> arch/sparc64.c
> >>  OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH))
> >> diff --git a/common.h b/common.h
> >> index 6ad3ca7b952c..6e2f657a79c7 100644
> >> --- a/common.h
> >> +++ b/common.h
> >> @@ -19,6 +19,8 @@
> >>  #define TRUE         (1)
> >>  #define FALSE                (0)
> >>  #define ERROR                (-1)
> >> +#define UNUSED       (-1)
> >> +#define RETURN_ON_ERROR      (0x2)
> >>
> >>  #ifndef LONG_MAX
> >>  #define LONG_MAX     ((long)(~0UL>>1))
> >> @@ -35,12 +37,18 @@
> >>  #define round(x, y)  (((x) / (y)) * (y))
> >>  #define roundup(x, y)        ((((x) + ((y) - 1)) / (y)) * (y))
> >>
> >> +#define NUM_HEX  (0x1)
> >> +#define NUM_DEC  (0x2)
> >> +#define NUM_EXPR (0x4)
> >> +#define NUM_ANY  (NUM_HEX|NUM_DEC|NUM_EXPR)
> >> +
> >>  /*
> >>   * Incorrect address
> >>   */
> >>  #define NOT_MEMMAP_ADDR      (0x0)
> >>  #define NOT_KV_ADDR  (0x0)
> >>  #define NOT_PADDR    (ULONGLONG_MAX)
> >> +#define BADADDR      ((ulong)(-1))
> >>
> >>  #endif  /* COMMON_H */
> >>
> >> diff --git a/makedumpfile.h b/makedumpfile.h
> >> index 01eece231475..0ce75e29fa7f 100644
> >> --- a/makedumpfile.h
> >> +++ b/makedumpfile.h
> >> @@ -237,6 +237,9 @@ isAnon(unsigned long mapping)
> >>  #define MIN_ELF_HEADER_SIZE \
> >>       MAX(MIN_ELF32_HEADER_SIZE, MIN_ELF64_HEADER_SIZE)
> >>  static inline int string_exists(char *s) { return (s ? TRUE : FALSE); }
> >> +#define STREQ(A, B) (string_exists((char *)A) &&     \
> >> +                  string_exists((char *)B) &&        \
> >> +     (strcmp((char *)(A), (char *)(B)) == 0))
> >>  #define STRNEQ(A, B)(string_exists((char *)(A)) &&   \
> >>                    string_exists((char *)(B)) &&      \
> >>       (strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0))
> >> @@ -2319,4 +2322,15 @@ int prepare_splitblock_table(void);
> >>  int initialize_zlib(z_stream *stream, int level);
> >>  int finalize_zlib(z_stream *stream);
> >>
> >> +int parse_line(char *str, char *argv[]);
> >> +char *shift_string_left(char *s, int cnt);
> >> +char *clean_line(char *line);
> >> +char *strip_linefeeds(char *line);
> >> +char *strip_beginning_whitespace(char *line);
> >> +char *strip_ending_whitespace(char *line);
> >> +ulong htol(char *s, int flags, int *errptr);
> >> +int hexadecimal(char *s, int count);
> >> +int decimal(char *s, int count);
> >> +int file_exists(char *file);
> >> +
> >>  #endif /* MAKEDUMPFILE_H */
> >> diff --git a/tools.c b/tools.c
> >> new file mode 100644
> >> index 000000000000..746ffa104816
> >> --- /dev/null
> >> +++ b/tools.c
> >> @@ -0,0 +1,766 @@
> >> +/* tools.c - Borrowed from crash utility code
> >> + *           (https://github.com/crash-utility/crash)
> >> + *
> >> + * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
> >> + * Copyright (C) 2002-2017 David Anderson
> >> + * Copyright (C) 2002-2018 Red Hat, Inc. All rights reserved.
> >> + *
> >> + * This program is free software; you can redistribute it and/or modify
> >> + * it under the terms of the GNU General Public License as published by
> >> + * the Free Software Foundation; either version 2 of the License, or
> >> + * (at your option) any later version.
> >> + *
> >> + * 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.
> >> + */
> >> +
> >> +#include "common.h"
> >> +#include "makedumpfile.h"
> >> +#include <ctype.h>
> >> +
> >> +#define FAULT_ON_ERROR               (0x1)
> >> +#define RETURN_ON_ERROR              (0x2)
> >> +#define QUIET                        (0x4)
> >> +#define HEX_BIAS             (0x8)
> >> +#define LONG_LONG            (0x10)
> >> +#define RETURN_PARTIAL               (0x20)
> >> +#define NO_DEVMEM_SWITCH     (0x40)
> >> +
> >> +#define MAX_HEXADDR_STRLEN   (16)
> >> +
> >> +#define FIRSTCHAR(s)         (s[0])
> >> +
> >> +/*
> >> + * Determine whether a file exists, using the caller's stat structure if
> >> + * one was passed in.
> >> + */
> >> +int
> >> +file_exists(char *file)
> >> +{
> >> +     struct stat sbuf;
> >> +
> >> +     if (stat(file, &sbuf) == 0)
> >> +             return TRUE;
> >> +
> >> +     return FALSE;
> >> +}
> >> +
> >> +/*
> >> + * Parse a line into tokens, populate the passed-in argv[] array, and
> >> + * return the count of arguments found. This function modifies the
> >> + * passed-string by inserting a NULL character at the end of each token.
> >> + * Expressions encompassed by parentheses, and strings encompassed by
> >> + * apostrophes, are collected into single tokens.
> >> + */
> >> +int
> >> +parse_line(char *str, char *argv[])
> >> +{
> >> +     int i, j, k;
> >> +     int string;
> >> +     int expression;
> >> +
> >> +     for (i = 0; i < MAXARGS; i++)
> >> +             argv[i] = NULL;
> >> +
> >> +     clean_line(str);
> >> +
> >> +     if (str == NULL || strlen(str) == 0)
> >> +             return(0);
> >> +
> >> +     i = j = k = 0;
> >> +     string = expression = FALSE;
> >> +
> >> +     /*
> >> +      * Special handling for when the first character is a '"'.
> >> +      */
> >> +     if (str[0] == '"') {
> >> +next:
> >> +             do {
> >> +                     i++;
> >> +             } while ((str[i] != NULLCHAR) && (str[i] != '"'));
> >> +
> >> +             switch (str[i])
> >> +             {
> >> +             case NULLCHAR:
> >> +                     argv[j] = &str[k];
> >> +                     return j+1;
> >> +             case '"':
> >> +                     argv[j++] = &str[k+1];
> >> +                     str[i++] = NULLCHAR;
> >> +                     if (str[i] == '"') {
> >> +                             k = i;
> >> +                             goto next;
> >> +                     }
> >> +                     break;
> >> +             }
> >> +     } else
> >> +             argv[j++] = str;
> >> +
> >> +     while (TRUE) {
> >> +             if (j == MAXARGS)
> >> +                     ERRMSG("too many arguments in string!\n");
> >> +
> >> +             while (str[i] != ' ' && str[i] != '\t' && str[i] != NULLCHAR) {
> >> +                     i++;
> >> +             }
> >> +
> >> +             switch (str[i])
> >> +             {
> >> +             case ' ':
> >> +             case '\t':
> >> +                     str[i++] = NULLCHAR;
> >> +
> >> +                     while (str[i] == ' ' || str[i] == '\t') {
> >> +                             i++;
> >> +                     }
> >> +
> >> +                     if (str[i] == '"') {
> >> +                             str[i] = ' ';
> >> +                             string = TRUE;
> >> +                             i++;
> >> +                     }
> >> +
> >> +                     if (!string && str[i] == '(') {
> >> +                             expression = TRUE;
> >> +                     }
> >> +
> >> +                     if (str[i] != NULLCHAR && str[i] != '\n') {
> >> +                             argv[j++] = &str[i];
> >> +                             if (string) {
> >> +                                     string = FALSE;
> >> +                                     while (str[i] != '"' && str[i] != NULLCHAR)
> >> +                                             i++;
> >> +                                     if (str[i] == '"')
> >> +                                             str[i] = ' ';
> >> +                             }
> >> +                             if (expression) {
> >> +                                     expression = FALSE;
> >> +                                     while (str[i] != ')' && str[i] != NULLCHAR)
> >> +                                             i++;
> >> +                             }
> >> +                             break;
> >> +                     }
> >> +                     /* else fall through */
> >> +             case '\n':
> >> +                     str[i] = NULLCHAR;
> >> +                     /* keep falling... */
> >> +             case NULLCHAR:
> >> +                     argv[j] = NULLCHAR;
> >> +                     return(j);
> >> +             }
> >> +     }
> >> +}
> >> +
> >> +/*
> >> + * Defuse controversy re: extensions to ctype.h
> >> + */
> >> +int
> >> +whitespace(int c)
> >> +{
> >> +     return ((c == ' ') ||(c == '\t'));
> >> +}
> >> +
> >> +int
> >> +ascii(int c)
> >> +{
> >> +     return ((c >= 0) && (c <= 0x7f));
> >> +}
> >> +
> >> +/*
> >> + * Strip line-ending whitespace and linefeeds.
> >> + */
> >> +char *
> >> +strip_line_end(char *line)
> >> +{
> >> +     strip_linefeeds(line);
> >> +     strip_ending_whitespace(line);
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip line-beginning and line-ending whitespace and linefeeds.
> >> + */
> >> +char *
> >> +clean_line(char *line)
> >> +{
> >> +     strip_beginning_whitespace(line);
> >> +     strip_linefeeds(line);
> >> +     strip_ending_whitespace(line);
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip line-ending linefeeds in a string.
> >> + */
> >> +char *
> >> +strip_linefeeds(char *line)
> >> +{
> >> +     char *p;
> >> +
> >> +     if (line == NULL || strlen(line) == 0)
> >> +             return(line);
> >> +
> >> +     p = &LASTCHAR(line);
> >> +
> >> +     while (*p == '\n') {
> >> +             *p = NULLCHAR;
> >> +             if (--p < line)
> >> +                     break;
> >> +     }
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip a specified line-ending character in a string.
> >> + */
> >> +char *
> >> +strip_ending_char(char *line, char c)
> >> +{
> >> +     char *p;
> >> +
> >> +     if (line == NULL || strlen(line) == 0)
> >> +             return(line);
> >> +
> >> +     p = &LASTCHAR(line);
> >> +
> >> +     if (*p == c)
> >> +             *p = NULLCHAR;
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip a specified line-beginning character in a string.
> >> + */
> >> +char *
> >> +strip_beginning_char(char *line, char c)
> >> +{
> >> +     if (line == NULL || strlen(line) == 0)
> >> +             return(line);
> >> +
> >> +     if (FIRSTCHAR(line) == c)
> >> +             shift_string_left(line, 1);
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip line-ending whitespace.
> >> + */
> >> +char *
> >> +strip_ending_whitespace(char *line)
> >> +{
> >> +     char *p;
> >> +
> >> +     if (line == NULL || strlen(line) == 0)
> >> +             return(line);
> >> +
> >> +     p = &LASTCHAR(line);
> >> +
> >> +     while (*p == ' ' || *p == '\t') {
> >> +             *p = NULLCHAR;
> >> +             if (p == line)
> >> +                     break;
> >> +             p--;
> >> +     }
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip line-beginning whitespace.
> >> + */
> >> +char *
> >> +strip_beginning_whitespace(char *line)
> >> +{
> >> +     char buf[BUFSIZE];
> >> +     char *p;
> >> +
> >> +     if (line == NULL || strlen(line) == 0)
> >> +             return(line);
> >> +
> >> +     strcpy(buf, line);
> >> +     p = &buf[0];
> >> +     while (*p == ' ' || *p == '\t')
> >> +             p++;
> >> +     strcpy(line, p);
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * End line at first comma found.
> >> + */
> >> +char *
> >> +strip_comma(char *line)
> >> +{
> >> +     char *p;
> >> +
> >> +     if ((p = strstr(line, ",")))
> >> +             *p = NULLCHAR;
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Strip the 0x from the beginning of a hexadecimal value string.
> >> + */
> >> +char *
> >> +strip_hex(char *line)
> >> +{
> >> +     if (STRNEQ(line, "0x"))
> >> +             shift_string_left(line, 2);
> >> +
> >> +     return(line);
> >> +}
> >> +
> >> +/*
> >> + * Turn a string into upper-case.
> >> + */
> >> +char *
> >> +upper_case(const char *s, char *buf)
> >> +{
> >> +     const char *p1;
> >> +     char *p2;
> >> +
> >> +     p1 = s;
> >> +     p2 = buf;
> >> +
> >> +     while (*p1) {
> >> +             *p2 = toupper(*p1);
> >> +             p1++, p2++;
> >> +     }
> >> +
> >> +     *p2 = NULLCHAR;
> >> +
> >> +     return(buf);
> >> +}
> >> +
> >> +/*
> >> + * Return pointer to first non-space/tab in a string.
> >> + */
> >> +char *
> >> +first_nonspace(char *s)
> >> +{
> >> +     return(s + strspn(s, " \t"));
> >> +}
> >> +
> >> +/*
> >> + * Return pointer to first space/tab in a string. If none are found,
> >> + * return a pointer to the string terminating NULL.
> >> + */
> >> +char *
> >> +first_space(char *s)
> >> +{
> >> +     return(s + strcspn(s, " \t"));
> >> +}
> >> +
> >> +/*
> >> + * Replace the first space/tab found in a string with a NULL character.
> >> + */
> >> +char *
> >> +null_first_space(char *s)
> >> +{
> >> +     char *p1;
> >> +
> >> +     p1 = first_space(s);
> >> +     if (*p1)
> >> +             *p1 = NULLCHAR;
> >> +
> >> +     return s;
> >> +}
> >> +
> >> +/*
> >> + * Replace any instances of the characters in string c that are found in
> >> + * string s with the character passed in r.
> >> + */
> >> +char *
> >> +replace_string(char *s, char *c, char r)
> >> +{
> >> +     int i, j;
> >> +
> >> +     for (i = 0; s[i]; i++) {
> >> +             for (j = 0; c[j]; j++) {
> >> +                     if (s[i] == c[j])
> >> +                             s[i] = r;
> >> +             }
> >> +     }
> >> +
> >> +     return s;
> >> +}
> >> +
> >> +/*
> >> + * Find the rightmost instance of a substring in a string.
> >> + */
> >> +char *
> >> +strstr_rightmost(char *s, char *lookfor)
> >> +{
> >> +     char *next, *last, *p;
> >> +
> >> +     for (p = s, last = NULL; *p; p++) {
> >> +             if (!(next = strstr(p, lookfor)))
> >> +                     break;
> >> +             last = p = next;
> >> +     }
> >> +
> >> +     return last;
> >> +}
> >> +
> >> +/*
> >> + * Shifts the contents of a string to the left by cnt characters,
> >> + * disposing the leftmost characters.
> >> + */
> >> +char *
> >> +shift_string_left(char *s, int cnt)
> >> +{
> >> +     int origlen;
> >> +
> >> +     if (!cnt)
> >> +             return(s);
> >> +
> >> +     origlen = strlen(s);
> >> +     memmove(s, s+cnt, (origlen-cnt));
> >> +     *(s+(origlen-cnt)) = NULLCHAR;
> >> +     return(s);
> >> +}
> >> +
> >> +/*
> >> + * Prints a string verbatim, allowing strings with % signs to be displayed
> >> + * without printf conversions.
> >> + */
> >> +void
> >> +print_verbatim(FILE *filep, char *line)
> >> +{
> >> +     int i;
> >> +
> >> +     for (i = 0; i < strlen(line); i++) {
> >> +             fputc(line[i], filep);
> >> +             fflush(filep);
> >> +     }
> >> +}
> >> +
> >> +char *
> >> +fixup_percent(char *s)
> >> +{
> >> +     char *p1;
> >> +
> >> +     if ((p1 = strstr(s, "%")) == NULL)
> >> +             return s;
> >> +
> >> +     s[strlen(s)+1] = NULLCHAR;
> >> +     memmove(p1+1, p1, strlen(p1));
> >> +     *p1 = '%';
> >> +
> >> +     return s;
> >> +}
> >> +
> >> +/*
> >> + * Append a two-character string to a number to make 1, 2, 3 and 4 into
> >> + * 1st, 2nd, 3rd, 4th, and so on...
> >> + */
> >> +char *
> >> +ordinal(ulong val, char *buf)
> >> +{
> >> +     char *p1;
> >> +
> >> +     sprintf(buf, "%ld", val);
> >> +     p1 = &buf[strlen(buf)-1];
> >> +
> >> +     switch (*p1)
> >> +     {
> >> +     case '1':
> >> +             strcat(buf, "st");
> >> +             break;
> >> +     case '2':
> >> +             strcat(buf, "nd");
> >> +             break;
> >> +     case '3':
> >> +             strcat(buf, "rd");
> >> +             break;
> >> +     default:
> >> +             strcat(buf, "th");
> >> +             break;
> >> +     }
> >> +
> >> +     return buf;
> >> +}
> >> +
> >> +/*
> >> + * Determine whether a string contains only decimal characters.
> >> + * If count is non-zero, limit the search to count characters.
> >> + */
> >> +int
> >> +decimal(char *s, int count)
> >> +{
> >> +     char *p;
> >> +     int cnt, digits;
> >> +
> >> +     if (!count) {
> >> +             strip_line_end(s);
> >> +             cnt = 0;
> >> +     } else
> >> +             cnt = count;
> >> +
> >> +     for (p = &s[0], digits = 0; *p; p++) {
> >> +             switch(*p)
> >> +             {
> >> +             case '0':
> >> +             case '1':
> >> +             case '2':
> >> +             case '3':
> >> +             case '4':
> >> +             case '5':
> >> +             case '6':
> >> +             case '7':
> >> +             case '8':
> >> +             case '9':
> >> +                     digits++;
> >> +             case ' ':
> >> +                     break;
> >> +             default:
> >> +                     return FALSE;
> >> +             }
> >> +
> >> +             if (count && (--cnt == 0))
> >> +                     break;
> >> +     }
> >> +
> >> +     return (digits ? TRUE : FALSE);
> >> +}
> >> +
> >> +/*
> >> + * Determine whether a string contains only ASCII characters.
> >> + */
> >> +int
> >> +ascii_string(char *s)
> >> +{
> >> +     char *p;
> >> +
> >> +     for (p = &s[0]; *p; p++) {
> >> +             if (!ascii(*p))
> >> +                     return FALSE;
> >> +     }
> >> +
> >> +     return TRUE;
> >> +}
> >> +
> >> +/*
> >> + * Check whether a string contains only printable ASCII characters.
> >> + */
> >> +int
> >> +printable_string(char *s)
> >> +{
> >> +     char *p;
> >> +
> >> +     for (p = &s[0]; *p; p++) {
> >> +             if (!isprint(*p))
> >> +                     return FALSE;
> >> +     }
> >> +
> >> +     return TRUE;
> >> +}
> >> +
> >> +/*
> >> + * Convert a string to a hexadecimal long value.
> >> + */
> >> +ulong
> >> +htol(char *s, int flags, int *errptr)
> >> +{
> >> +     ulong i, j;
> >> +     ulong n;
> >> +
> >> +     if (s == NULL) {
> >> +             if (!(flags & QUIET))
> >> +                     ERRMSG("received NULL string\n");
> >> +             goto htol_error;
> >> +     }
> >> +
> >> +     if (STRNEQ(s, "0x") || STRNEQ(s, "0X"))
> >> +             s += 2;
> >> +
> >> +     if (strlen(s) > MAX_HEXADDR_STRLEN) {
> >> +             if (!(flags & QUIET))
> >> +                     ERRMSG("input string too large: \"%s\" (%d vs %d)\n",
> >> +                                     s, (int)strlen(s), (int)MAX_HEXADDR_STRLEN);
> >> +             goto htol_error;
> >> +     }
> >> +
> >> +     for (n = i = 0; s[i] != 0; i++) {
> >> +             switch (s[i])
> >> +             {
> >> +             case 'a':
> >> +             case 'b':
> >> +             case 'c':
> >> +             case 'd':
> >> +             case 'e':
> >> +             case 'f':
> >> +                     j = (s[i] - 'a') + 10;
> >> +                     break;
> >> +             case 'A':
> >> +             case 'B':
> >> +             case 'C':
> >> +             case 'D':
> >> +             case 'E':
> >> +             case 'F':
> >> +                     j = (s[i] - 'A') + 10;
> >> +                     break;
> >> +             case '1':
> >> +             case '2':
> >> +             case '3':
> >> +             case '4':
> >> +             case '5':
> >> +             case '6':
> >> +             case '7':
> >> +             case '8':
> >> +             case '9':
> >> +             case '0':
> >> +                     j = s[i] - '0';
> >> +                     break;
> >> +             case 'x':
> >> +             case 'X':
> >> +             case 'h':
> >> +                     continue;
> >> +             default:
> >> +                     if (!(flags & QUIET))
> >> +                             ERRMSG("invalid input: \"%s\"\n", s);
> >> +                     goto htol_error;
> >> +             }
> >> +             n = (16 * n) + j;
> >> +     }
> >> +
> >> +     return(n);
> >> +
> >> +htol_error:
> >> +     return BADADDR;
> >> +}
> >> +
> >> +/*
> >> + * Determine whether a string contains only hexadecimal characters.
> >> + * If count is non-zero, limit the search to count characters.
> >> + */
> >> +int
> >> +hexadecimal(char *s, int count)
> >> +{
> >> +     char *p;
> >> +     int cnt, digits;
> >> +
> >> +     if (!count) {
> >> +             strip_line_end(s);
> >> +             cnt = 0;
> >> +     } else
> >> +             cnt = count;
> >> +
> >> +     for (p = &s[0], digits = 0; *p; p++) {
> >> +             switch(*p)
> >> +             {
> >> +             case 'a':
> >> +             case 'b':
> >> +             case 'c':
> >> +             case 'd':
> >> +             case 'e':
> >> +             case 'f':
> >> +             case 'A':
> >> +             case 'B':
> >> +             case 'C':
> >> +             case 'D':
> >> +             case 'E':
> >> +             case 'F':
> >> +             case '1':
> >> +             case '2':
> >> +             case '3':
> >> +             case '4':
> >> +             case '5':
> >> +             case '6':
> >> +             case '7':
> >> +             case '8':
> >> +             case '9':
> >> +             case '0':
> >> +                     digits++;
> >> +             case 'x':
> >> +             case 'X':
> >> +                     break;
> >> +
> >> +             case ' ':
> >> +                     if (*(p+1) == NULLCHAR)
> >> +                             break;
> >> +                     else
> >> +                             return FALSE;
> >> +             default:
> >> +                     return FALSE;
> >> +             }
> >> +
> >> +             if (count && (--cnt == 0))
> >> +                     break;
> >> +     }
> >> +
> >> +     return (digits ? TRUE : FALSE);
> >> +}
> >> +
> >> +/*
> >> + * Determine whether a string contains only hexadecimal characters.
> >> + * and cannot be construed as a decimal number.
> >> + * If count is non-zero, limit the search to count characters.
> >> + */
> >> +int
> >> +hexadecimal_only(char *s, int count)
> >> +{
> >> +     char *p;
> >> +     int cnt, only;
> >> +
> >> +     if (!count) {
> >> +             strip_line_end(s);
> >> +             cnt = 0;
> >> +     } else
> >> +             cnt = count;
> >> +
> >> +     only = 0;
> >> +
> >> +     for (p = &s[0]; *p; p++) {
> >> +             switch(*p)
> >> +             {
> >> +             case 'a':
> >> +             case 'b':
> >> +             case 'c':
> >> +             case 'd':
> >> +             case 'e':
> >> +             case 'f':
> >> +             case 'A':
> >> +             case 'B':
> >> +             case 'C':
> >> +             case 'D':
> >> +             case 'E':
> >> +             case 'F':
> >> +             case 'x':
> >> +             case 'X':
> >> +                     only++;
> >> +                     break;
> >> +             case '1':
> >> +             case '2':
> >> +             case '3':
> >> +             case '4':
> >> +             case '5':
> >> +             case '6':
> >> +             case '7':
> >> +             case '8':
> >> +             case '9':
> >> +             case '0':
> >> +                     break;
> >> +
> >> +             case ' ':
> >> +                     if (*(p+1) == NULLCHAR)
> >> +                             break;
> >> +                     else
> >> +                             return FALSE;
> >> +             default:
> >> +                     return FALSE;
> >> +             }
> >> +
> >> +             if (count && (--cnt == 0))
> >> +                     break;
> >> +     }
> >> +
> >> +     return only;
> >> +}
> >> --
> >> 2.7.4
> >>
> >>
> >> _______________________________________________
> >> kexec mailing list
> >> kexec at lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/kexec
> >
> >



More information about the kexec mailing list