#include "config.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdarg.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include "mpl.h"
#include "pmi.h"
#include "simple_pmiutil.h"
#define MAXVALLEN 1024
#define MAXKEYLEN 32
struct PMIU_keyval_pairs {
char key[MAXKEYLEN];
char value[MAXVALLEN];
};
static struct PMIU_keyval_pairs PMIU_keyval_tab[64] = { { {0}, {0} } };
static int PMIU_keyval_tab_idx = 0;
static char PMIU_print_id[PMIU_IDSIZE] = "unset";
void PMIU_Set_rank( int PMI_rank )
{
MPL_snprintf( PMIU_print_id, PMIU_IDSIZE, "cli_%d", PMI_rank );
}
void PMIU_SetServer( void )
{
MPL_strncpy( PMIU_print_id, "server", PMIU_IDSIZE );
}
void PMIU_printf( int print_flag, const char *fmt, ... )
{
va_list ap;
static FILE *logfile= 0;
if (!logfile) {
char *p;
p = getenv("PMI_USE_LOGFILE");
if (p) {
char filename[1024];
p = getenv("PMI_ID");
if (p) {
MPL_snprintf( filename, sizeof(filename),
"testclient-%s.out", p );
logfile = fopen( filename, "w" );
}
else {
logfile = fopen( "testserver.out", "w" );
}
}
else
logfile = stderr;
}
if ( print_flag ) {
fprintf( logfile, "[%s]: ", PMIU_print_id );
va_start( ap, fmt );
vfprintf( logfile, fmt, ap );
va_end( ap );
fflush( logfile );
}
}
#define MAX_READLINE 1024
int PMIU_readline( int fd, char *buf, int maxlen )
{
static char readbuf[MAX_READLINE];
static char *nextChar = 0, *lastChar = 0;
static int lastfd = -1;
ssize_t n;
int curlen;
char *p, ch;
if (nextChar != lastChar && fd != lastfd) {
MPL_internal_error_printf( "Panic - buffer inconsistent\n" );
return PMI_FAIL;
}
p = buf;
curlen = 1;
while (curlen < maxlen) {
if (nextChar == lastChar) {
lastfd = fd;
do {
n = read( fd, readbuf, sizeof(readbuf)-1 );
} while (n == -1 && errno == EINTR);
if (n == 0) {
break;
}
else if (n < 0) {
if (curlen == 1) {
curlen = 0;
}
break;
}
nextChar = readbuf;
lastChar = readbuf + n;
readbuf[n] = 0;
}
ch = *nextChar++;
*p++ = ch;
curlen++;
if (ch == '\n') break;
}
*p = 0;
return curlen-1;
}
int PMIU_writeline( int fd, char *buf )
{
ssize_t size, n;
size = strlen( buf );
if ( size > PMIU_MAXLINE ) {
buf[PMIU_MAXLINE-1] = '\0';
PMIU_printf( 1, "write_line: message string too big: :%s:\n", buf );
}
else if ( buf[strlen( buf ) - 1] != '\n' )
PMIU_printf( 1, "write_line: message string doesn't end in newline: :%s:\n",
buf );
else {
do {
n = write( fd, buf, size );
} while (n == -1 && errno == EINTR);
if ( n < 0 ) {
PMIU_printf( 1, "write_line error; fd=%d buf=:%s:\n", fd, buf );
perror("system msg for write_line failure ");
return PMI_FAIL;
}
if ( n < size)
PMIU_printf( 1, "write_line failed to write entire message\n" );
}
return PMI_SUCCESS;
}
int PMIU_parse_keyvals( char *st )
{
char *p, *keystart, *valstart;
int offset;
if ( !st )
return PMI_FAIL;
PMIU_keyval_tab_idx = 0;
p = st;
while ( 1 ) {
while ( *p == ' ' )
p++;
if ( *p == '=' ) {
PMIU_printf( 1, "PMIU_parse_keyvals: unexpected = at character %d in %s\n",
p - st, st );
return PMI_FAIL;
}
if ( *p == '\n' || *p == '\0' )
return PMI_SUCCESS;
keystart = p;
while ( *p != ' ' && *p != '=' && *p != '\n' && *p != '\0' )
p++;
if ( *p == ' ' || *p == '\n' || *p == '\0' ) {
PMIU_printf( 1,
"PMIU_parse_keyvals: unexpected key delimiter at character %d in %s\n",
p - st, st );
return PMI_FAIL;
}
*p = 0;
MPL_strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].key, keystart,
MAXKEYLEN );
valstart = ++p;
while ( *p != ' ' && *p != '\n' && *p != '\0' )
p++;
MPL_strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].value, valstart,
MAXVALLEN );
offset = (int)(p - valstart);
PMIU_keyval_tab[PMIU_keyval_tab_idx].value[offset] = '\0';
PMIU_keyval_tab_idx++;
if ( *p == ' ' )
continue;
if ( *p == '\n' || *p == '\0' )
return PMI_SUCCESS;
}
}
void PMIU_dump_keyvals( void )
{
int i;
for (i=0; i < PMIU_keyval_tab_idx; i++)
PMIU_printf(1, " %s=%s\n",PMIU_keyval_tab[i].key, PMIU_keyval_tab[i].value);
}
char *PMIU_getval( const char *keystr, char *valstr, int vallen )
{
int i, rc;
for (i = 0; i < PMIU_keyval_tab_idx; i++) {
if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) {
rc = MPL_strncpy( valstr, PMIU_keyval_tab[i].value, vallen );
if (rc != 0) {
PMIU_printf( 1, "MPL_strncpy failed in PMIU_getval\n" );
return NULL;
}
return valstr;
}
}
valstr[0] = '\0';
return NULL;
}
void PMIU_chgval( const char *keystr, char *valstr )
{
int i;
for ( i = 0; i < PMIU_keyval_tab_idx; i++ ) {
if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) {
MPL_strncpy( PMIU_keyval_tab[i].value, valstr, MAXVALLEN - 1 );
PMIU_keyval_tab[i].value[MAXVALLEN - 1] = '\0';
}
}
}