From: Lennart Poettering Date: Fri, 15 Apr 2011 23:57:23 +0000 (+0200) Subject: hostname: split out hostname validation into util.c X-Git-Tag: v25~33 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9beb3f4d5c527f995e0e44308d7372fa4ea5470f;p=systemd hostname: split out hostname validation into util.c --- diff --git a/src/hostname-setup.c b/src/hostname-setup.c index e9869bb4..ab497670 100644 --- a/src/hostname-setup.c +++ b/src/hostname-setup.c @@ -40,25 +40,8 @@ #define FILENAME "/etc/conf.d/hostname" #endif -static char* strip_bad_chars(char *s) { - char *p, *d; - - for (p = s, d = s; *p; p++) - if ((*p >= 'a' && *p <= 'z') || - (*p >= 'A' && *p <= 'Z') || - (*p >= '0' && *p <= '9') || - *p == '-' || - *p == '_' || - *p == '.') - *(d++) = *p; - - *d = 0; - - return s; -} - static int read_and_strip_hostname(const char *path, char **hn) { - char *s, *k; + char *s; int r; assert(path); @@ -67,20 +50,14 @@ static int read_and_strip_hostname(const char *path, char **hn) { if ((r = read_one_line_file(path, &s)) < 0) return r; - k = strdup(strstrip(s)); - free(s); - - if (!k) - return -ENOMEM; - - strip_bad_chars(k); + hostname_cleanup(s); - if (k[0] == 0) { - free(k); + if (isempty(s)) { + free(s); return -ENOENT; } - *hn = k; + *hn = s; return 0; } @@ -118,9 +95,9 @@ static int read_distro_hostname(char **hn) { goto finish; } - strip_bad_chars(k); + hostname_cleanup(k); - if (k[0] == 0) { + if (isempty(k)) { free(k); r = -ENOENT; goto finish; diff --git a/src/util.c b/src/util.c index fb8df84e..bec6e0c8 100644 --- a/src/util.c +++ b/src/util.c @@ -4248,6 +4248,59 @@ int have_effective_cap(int value) { return r; } +char* strshorten(char *s, size_t l) { + assert(s); + + if (l < strlen(s)) + s[l] = 0; + + return s; +} + +static bool hostname_valid_char(char c) { + return + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '-' || + c == '_' || + c == '.'; +} + +bool hostname_is_valid(const char *s) { + const char *p; + + if (isempty(s)) + return false; + + for (p = s; *p; p++) + if (!hostname_valid_char(*p)) + return false; + + if (p-s > HOST_NAME_MAX) + return false; + + return true; +} + +char* hostname_cleanup(char *s) { + char *p, *d; + + for (p = s, d = s; *p; p++) + if ((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9') || + *p == '-' || + *p == '_' || + *p == '.') + *(d++) = *p; + + *d = 0; + + strshorten(s, HOST_NAME_MAX); + return s; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/src/util.h b/src/util.h index 72ddd36e..946179a9 100644 --- a/src/util.h +++ b/src/util.h @@ -117,6 +117,10 @@ static inline bool is_path_absolute(const char *p) { return *p == '/'; } +static inline bool isempty(const char *p) { + return !p || !p[0]; +} + bool endswith(const char *s, const char *postfix); bool startswith(const char *s, const char *prefix); bool startswith_no_case(const char *s, const char *prefix); @@ -398,6 +402,11 @@ void parse_syslog_priority(char **p, int *priority); int have_effective_cap(int value); +bool hostname_is_valid(const char *s); +char* hostname_cleanup(char *s); + +char* strshorten(char *s, size_t l); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)