Skip to content

Commit

Permalink
Merge pull request #59 from chu11/hostlist
Browse files Browse the repository at this point in the history
hostlist: update to copy in pdsh
  • Loading branch information
chu11 authored Aug 29, 2023
2 parents d83e702 + 2536205 commit 843d518
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 65 deletions.
160 changes: 96 additions & 64 deletions src/libcommon/hostlist.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*****************************************************************************\
* $Id: hostlist.c,v 1.4 2008-07-11 22:37:28 chu11 Exp $
* $LSDId: hostlist.c 11882 2012-10-03 17:31:41Z grondo $
*****************************************************************************
* Copyright (C) 2002 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
Expand Down Expand Up @@ -350,21 +350,6 @@ static void _error(char *file, int line, char *msg, ...)
return;
}

static int _advance_past_brackets (char *tok, char **str)
{
/* if _single_ opening bracket exists b/w tok and str, push str
* past first closing bracket to next seperator */
if ( memchr(tok, '[', *str - tok) != NULL
&& memchr(tok, ']', *str - tok) == NULL ) {
char *q = strchr(*str, ']');
if (q && memchr(*str, '[', q - *str) == NULL) {
*str = q + 1;
return (1);
}
}

return 0;
}

/*
* Helper function for host list string parsing routines
Expand All @@ -375,13 +360,16 @@ static int _advance_past_brackets (char *tok, char **str)
* (with modifications to support bracketed hostlists, i.e.:
* xxx[xx,xx,xx] is a single token)
*
* _next_tok now handles multiple brackets within the same token,
* e.g. node[01-30]-[1-2,6].
*/
static char * _next_tok(char *sep, char **str)
{
char *tok;
int level = 0;

/* push str past any leading separators */
while (**str != '\0' && strchr(sep, **str) != '\0')
while (**str != '\0' && strchr(sep, **str))
(*str)++;

if (**str == '\0')
Expand All @@ -390,19 +378,15 @@ static char * _next_tok(char *sep, char **str)
/* assign token ptr */
tok = *str;

/*
* Advance str past any separators, but if a separator occurs between
* brackets, e.g. foo[0-3,5], then advance str past closing brackets and
* try again.
*/
do {
/* push str past token and leave pointing to first separator */
while (**str != '\0' && strchr(sep, **str) == '\0')
(*str)++;
} while (_advance_past_brackets (tok, str));
while ( **str != '\0' &&
(level != 0 || strchr(sep, **str) == NULL) ) {
if ( **str == '[' ) level++;
else if ( **str == ']' ) level--;
(*str)++;
}

/* nullify consecutive separators and push str beyond them */
while (**str != '\0' && strchr(sep, **str) != '\0')
while (**str != '\0' && strchr(sep, **str) != NULL)
*(*str)++ = '\0';

return tok;
Expand Down Expand Up @@ -479,22 +463,16 @@ static int host_prefix_end(const char *hostname)
return idx;
}

/*
* create a hostname_t object from a string hostname
*/
static hostname_t hostname_create(const char *hostname)
static hostname_t hostname_create_with_suffix (const char *hostname, int idx)
{
hostname_t hn = NULL;
char *p = '\0';
int idx = 0;
char *p = "\0";

assert(hostname != NULL);

if (!(hn = (hostname_t) malloc(sizeof(*hn))))
out_of_memory("hostname create");

idx = host_prefix_end(hostname);

if (!(hn->hostname = strdup(hostname))) {
free(hn);
out_of_memory("hostname create");
Expand Down Expand Up @@ -531,6 +509,17 @@ static hostname_t hostname_create(const char *hostname)
}

return hn;

}


/*
* create a hostname_t object from a string hostname
*/
static hostname_t hostname_create(const char *hostname)
{
int idx = host_prefix_end (hostname);
return hostname_create_with_suffix (hostname, idx);
}

/* free a hostname object
Expand Down Expand Up @@ -901,11 +890,15 @@ static hostrange_t hostrange_intersect(hostrange_t h1, hostrange_t h2)
return new;
}

/* return 1 if hostname hn is within the hostrange hr
* 0 if not.
/* return offset of hn if it is in the hostlist or
* -1 if not.
*/
static int hostrange_hn_within(hostrange_t hr, hostname_t hn)
{
int len_hr;
int len_hn;
int width;

if (hr->singlehost) {
/*
* If the current hostrange [hr] is a `singlehost' (no valid
Expand All @@ -917,9 +910,9 @@ static int hostrange_hn_within(hostrange_t hr, hostname_t hn)
* possibility that [hn] matches [hr].
*/
if (strcmp (hn->hostname, hr->prefix) == 0)
return 1;
else
return 0;
else
return -1;
}

/*
Expand All @@ -928,26 +921,67 @@ static int hostrange_hn_within(hostrange_t hr, hostname_t hn)
* way we can match
*/
if (!hostname_suffix_is_valid (hn))
return 0;
return -1;

len_hn = strlen (hn->prefix);

/*
* If hostrange and hostname prefixes don't match, then
* there is way the hostname falls within the range [hr].
* If hostrange and hostname prefixes don't match to at least
* the length of the hostname object (which will have the min
* possible prefix length), then there is no way the hostname
* falls within the range [hr].
*/
if (strcmp(hr->prefix, hn->prefix) != 0)
return 0;
if (strncmp (hr->prefix, hn->prefix, len_hn) != 0)
return -1;

/*
* Now we know hostrange and hostname prefixes match up to the
* length of the hostname prefix. If the hostrange and hostname
* prefix lengths do not match (specifically if the hostname prefix
* length is less than the hostrange prefix length) and the
* hostrange prefix contains trailing digits, then it might be
* the case that the hostrange was created by forcing the prefix
* to contain digits a la f00[1-2]. So we try adjusting the
* hostname with the longer prefix and calling this function
* again with the new hostname. (Yes, this is ugly, sorry)
*/
len_hr = strlen (hr->prefix);
width = hostname_suffix_width (hn);

if ((len_hn < len_hr)
&& (width > 1)
&& (isdigit (hr->prefix [len_hr - 1]))
&& (hr->prefix [len_hn] == hn->suffix[0]) ) {
int rc;
/*
* Create new hostname object with its prefix offset by one
*/
hostname_t h = hostname_create_with_suffix (hn->hostname, len_hn);
/*
* Recursive call :-o
*/
rc = hostrange_hn_within (hr, h);
hostname_destroy (h);
return rc;
}


/*
* Finally, check whether [hn], with a valid numeric suffix,
* falls within the range of [hr].
* falls within the range of [hr] if [hn] and [hr] prefix are
* identical.
*/
if (hn->num <= hr->hi && hn->num >= hr->lo) {
int width = hostname_suffix_width(hn);
int num = hn->num;
return (_width_equiv(hr->lo, &hr->width, num, &width));
if ((len_hr == len_hn)
&& (strcmp (hn->prefix, hr->prefix) == 0)
&& (hn->num <= hr->hi)
&& (hn->num >= hr->lo)) {
int width = hostname_suffix_width (hn);
if (!_width_equiv(hr->lo, &hr->width, hn->num, &width))
return -1;
return (hn->num - hr->lo);
}

return 0;
return -1;
}


Expand Down Expand Up @@ -1384,7 +1418,7 @@ static int _parse_single_range(const char *str, struct _range *range)
goto error;

if (range->hi - range->lo + 1 > MAX_RANGE ) {
/* _error(__FILE__, __LINE__, "Too many hosts in range `%s'", orig); */
_error(__FILE__, __LINE__, "Too many hosts in range `%s'", orig);
free(orig);
seterrno_ret(ERANGE, 0);
}
Expand All @@ -1394,7 +1428,7 @@ static int _parse_single_range(const char *str, struct _range *range)
return 1;

error:
/* _error(__FILE__, __LINE__, "Invalid range: `%s'", orig); */
_error(__FILE__, __LINE__, "Invalid range: `%s'", orig);
free(orig);
seterrno_ret(EINVAL, 0);
}
Expand Down Expand Up @@ -1862,8 +1896,8 @@ int hostlist_delete_nth(hostlist_t hl, int n)
}

done:
UNLOCK_HOSTLIST(hl);
hl->nhosts--;
UNLOCK_HOSTLIST(hl);
return 1;
}

Expand All @@ -1889,17 +1923,15 @@ int hostlist_find(hostlist_t hl, const char *hostname)
LOCK_HOSTLIST(hl);

for (i = 0, count = 0; i < hl->nranges; i++) {
if (hostrange_hn_within(hl->hr[i], hn)) {
if (hostname_suffix_is_valid(hn) && !hl->hr[i]->singlehost)
ret = count + hn->num - hl->hr[i]->lo;
else
ret = count;
goto done;
} else
int offset = hostrange_hn_within(hl->hr[i], hn);
if (offset >= 0) {
ret = count + offset;
break;
}
else
count += hostrange_count(hl->hr[i]);
}

done:
UNLOCK_HOSTLIST(hl);
hostname_destroy(hn);
return ret;
Expand Down Expand Up @@ -2113,7 +2145,7 @@ _get_bracketed_list(hostlist_t hl, int *start, const size_t n, char *buf)
if ((len < 0) || (len > n))
return n; /* truncated, buffer filled */

if (bracket_needed && len < n && len >= 0)
if (bracket_needed && len < n)
buf[len++] = '[';

do {
Expand Down Expand Up @@ -2479,7 +2511,7 @@ static int hostset_find_host(hostset_t set, const char *host)
LOCK_HOSTLIST(set->hl);
hn = hostname_create(host);
for (i = 0; i < set->hl->nranges; i++) {
if (hostrange_hn_within(set->hl->hr[i], hn)) {
if (hostrange_hn_within(set->hl->hr[i], hn) >= 0) {
retval = 1;
goto done;
}
Expand Down
6 changes: 5 additions & 1 deletion src/libcommon/hostlist.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/*****************************************************************************\
* $Id: hostlist.h,v 1.3 2008-01-29 19:09:05 chu11 Exp $
* $Id$
*****************************************************************************
* $LSDId: hostlist.h 7428 2008-05-23 16:08:31Z grondo $
*****************************************************************************
* Copyright (C) 2002 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
Expand Down Expand Up @@ -27,6 +29,8 @@
#ifndef _HOSTLIST_H
#define _HOSTLIST_H

#include <unistd.h>

/* Notes:
*
* If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to
Expand Down

0 comments on commit 843d518

Please sign in to comment.