/*
 *
 * Copyright 1998-1999, University of Notre Dame.
 * Authors: Jeffrey M. Squyres, Kinis L. Meyer with M. D. McNally 
 *          and Andrew Lumsdaine
 *
 * This file is part of the Notre Dame LAM implementation of MPI.
 *
 * You should have received a copy of the License Agreement for the
 * Notre Dame LAM implementation of MPI along with the software; see
 * the file LICENSE.  If not, contact Office of Research, University
 * of Notre Dame, Notre Dame, IN 46556.
 *
 * Permission to modify the code and to distribute modified code is
 * granted, provided the text of this NOTICE is retained, a notice that
 * the code was modified is included with the above COPYRIGHT NOTICE and
 * with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE
 * file is distributed with the modified code.
 *
 * LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.
 * By way of example, but not limitation, Licensor MAKES NO
 * REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY
 * PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS
 * OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS
 * OR OTHER RIGHTS.  
 *
 * Additional copyrights may follow.
 *
 *	Ohio Trollius
 *	Copyright 1995 The Ohio State University
 *	RBD/GDB
 *
 *	$Log: bhostparse.c,v $
 *	Revision 6.3  1999/08/26 22:17:43  jsquyres
 *	Cast args of isspace to (int) per -Wall
 *	
 *	Revision 6.2  1999/05/23 19:28:24  kmeyer1
 *	added copyrights
 *	
 *	Revision 6.1  1996/11/24 00:44:50  nevin
 *	Ohio Release
 *	
 * Revision 6.0  96/02/29  13:40:55  gdburns
 * Ohio Release
 * 
 * Revision 5.2.1.3  96/02/28  18:31:18  gdburns
 * major overhaul
 * 
 * Revision 5.2.1.2  94/10/18  02:14:44  raja
 * Upgrade to new network description.
 * 
 * Revision 5.2.1.1  94/08/31  10:19:40  gdburns
 * Remove printing.
 * 
 * Revision 5.2  94/08/22  13:55:28  gdburns
 * Ohio Release
 * 
 * Revision 5.1  94/05/18  10:45:03  gdburns
 * Ohio Release
 * 
 * Revision 2.3  94/04/22  12:32:32  gdburns
 * Ohio Release
 * 
 *	Function:	- boot schema parser
 *			- host file syntax version
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <lamnet.h>
#include <net.h>
#include <typical.h>

/*
 * constants
 */
#define MAXLINE		256		/* input line size */
#define LNDBLOCK	10		/* array allocation block */

/*
 * static variables
 */
static char		linebuf[MAXLINE];

/*
 * static functions
 */
static void		parseline();

/*
 *	parse_host
 *
 *	Function:	- parse a host file
 *			- fill the network description
 *			- node IDs are [0, N-1]
 *	Accepts:	- input file stream
 *			- node description array (value returned)
 *			- array size (value returned)
 */
int
bhostparse(fp, plamnet, pnlamnet)

FILE			*fp;
struct lamnode		**plamnet;
int			*pnlamnet;

{
	char		*host;		/* host machine name */
	char		*user;		/* user name */
	int		nlndalloc;	/* current allocation size */
	int		node;		/* current node ID */
	struct lamnode	*lamnet;	/* current node desc. array */
/*
 * Loop till EOF reading and parsing line-by-line.
 */
	lamnet = 0;
	nlndalloc = 0;
	node = 0;

	while (! feof(fp)) {

		if (fgets(linebuf, MAXLINE, fp) == 0) break;
/*
 * Parse the line for hostname and username.
 */
		parseline(&host, &user);
/*
 * If a machine name is found, add the node to the network.
 */
		if (!host) {
			continue;
		}
/*
 * Allocate initial node description array.
 */
		if (lamnet == 0) {
			lamnet = (struct lamnode *) malloc((unsigned)
					LNDBLOCK * sizeof(struct lamnode));
			if (lamnet == 0) return(LAMERROR);
			nlndalloc = LNDBLOCK;
		}
/*
 * Extend node description array.
 */
		if (nlndalloc <= node) {
			nlndalloc += LNDBLOCK;
			lamnet = (struct lamnode *) realloc((char *) lamnet,
					(unsigned) nlndalloc *
					sizeof(struct lamnode));
			if (lamnet == 0) return(LAMERROR);
		}

		lamnet[node].lnd_nodeid = node;
		lamnet[node].lnd_type = NT_BOOT;
/*
 * Set host name.
 */
		lamnet[node].lnd_hname = malloc((unsigned) strlen(host) + 1);
		if (lamnet[node].lnd_hname == 0) return(LAMERROR);
		strcpy(lamnet[node].lnd_hname, host);
/*
 * Set optional user name.
 */
		lamnet[node].lnd_uname = 0;

		if (user) {
			lamnet[node].lnd_uname = malloc((unsigned)
					strlen(user) + 1);
			if (lamnet[node].lnd_uname == 0) return(LAMERROR);
			strcpy(lamnet[node].lnd_uname, user);
		}

		node++;
	}

	*pnlamnet = node;
	*plamnet = lamnet;
	return(0);
}

/*
 *	parseline
 *
 *	Function:	- parses the line buffer for hostname and username
 *			- Format: hostname [username]
 *			- skip comments: everything after a # character
 *			- fills hostname/username or NULL
 *	Accepts:	- host name (returned value)
 *			- user name (returned value)
 */
static void
parseline(phost, puser)

char			**phost;
char			**puser;

{
	char		*p;		/* favourite pointer */

	*phost = 0;
	*puser = 0;
	linebuf[MAXLINE - 1] = '\0';
/*
 * Skip comments by replacing the first '#' with a NULL.
 */
	for (p = linebuf; *p; ++p) {

		if (*p == '#') {
			*p = '\0';
			break;
		}
	}
/*
 * Find beginning and end of hostname and null-terminate it.
 */
	for (p = linebuf; *p; ++p) {

		if ( ! isspace((int) *p)) {
			*phost = p;
			break;
		}
	}

	for ( ; *p; ++p) {

		if (isspace((int) *p)) {
			*p++ = '\0';
			break;
		}
	}
/*
 * Find beginning and end of username and null-terminate it.
 */
	for ( ; *p; ++p) {

		if ( ! isspace((int) *p)) {
			*puser = p;
			break;
		}
	}

	for ( ; *p; ++p) {

		if (isspace((int) *p)) {
			*p++ = '\0';
			break;
		}
	}
}
