#include "xbcomm.h"
int inPipe[ 2 ], outPipe[ 2 ], errPipe[ 2 ];
FILE *toProc, *fromProc, *errProc;
/* Returns a char* copy. Allocates sufficient space to contain the string */
/* given as argument, copy the argument string, and returns a pointer to */
/* the copy. */
char *copyString( val )
char *val;
{
char *str;
if ( val IS NULL )
str = NULL;
else
{
str = (char *)malloc( strlen( val ) + 1 );
strcpy( str, val );
}
return( str );
}
/* Resets a char* pointer to a new value. Allocates sufficient space to */
/* contain the string given as argument, copy the argument string, and */
/* gives back the new pointer, which now contains the copy. */
VOIDPARM setString( str, val )
char **str;
char *val;
{
/* to be most correct, this should free any space that's already */
/* taken up by str - which it doesn't yet */
if ( val IS NULL )
*str = NULL;
else
{
*str = (char *)malloc( strlen( val ) + 1 );
strcpy( *str, val );
}
}
/* Returns a char* concatenation of str1 (which may be null) with str2. */
/* Iff str1 is not null, str3 is used as a separating string (which may be */
/* null) between str1 and str2. Allocates sufficient space to contain the */
/* string(s) given as arguments, performs the concatenation, and returns a */
/* pointer to the concatenated string. */
char *addString( str1, str2, str3 )
char *str1, *str2, *str3;
{
char *str;
if ( str1 IS NULL )
str = copyString( str2 );
else
{
if ( str3 IS NULL )
{
str = (char *)malloc( strlen( str1 ) + strlen( str2 ) + 1 );
sprintf( str, "%s%s", str1, str2 );
}
else
{
str = (char *)malloc( strlen( str1 ) + strlen( str2 )
+ strlen( str3 ) + 1 );
sprintf( str, "%s%s%s", str1, str3, str2 );
}
}
return( str );
}
/* Determine if b is contained in a, if so return a pointer to the */
/* occurrence of b in a. */
char *stringIn( a, b )
char *a;
char *b;
{
int aLen=strlen( a );
int bLen=strlen( b );
char *ap=a;
if ( aLen < bLen )
return( NULL );
while ( strlen( ap ) >= bLen )
{
if ( NOT strncmp( ap, b, bLen ) )
return( ap );
ap++;
}
return( NULL );
}
char *getAnswer( VOIDPARM )
{
char ans[ 256 ], inpt;
int count;
fflush( stdout );
count = 0;
ans[ count ] = NULLTERM;
while ( read( 0, &inpt, 1 ) > 0 )
{
if ( inpt IS EOL )
{
ans[ count ] = NULLTERM;
break;
}
else
ans[ count ] = inpt;
count++;
}
printf( "\n" );
return( copyString( ans ) );
}
/* Return the "root" part of the filename (max 10 characters)*/
boolean getRootName( VOIDPARM )
{
int nameLen, charPos, scriptPos, tmpChar;
fileName = theFile;
nameLen = strlen( theFile );
charPos = nameLen - 1;
while ( charPos )
{
tmpChar = theFile[ charPos ];
if ( tmpChar IS SLASH )
{
fileName = copyString( theFile + charPos + 1 );
break;
}
charPos--;
}
nameLen = strlen( fileName );
charPos = nameLen - 1;
while ( charPos )
{
tmpChar = fileName[ charPos ];
if ( tmpChar IS DOT )
break;
charPos--;
}
if ( charPos IS 0 )
{
fileRoot = fileName;
scriptPos = nameLen;
}
else
{
fileRoot = (char *)malloc( charPos + 1 );
strncpy( fileRoot, fileName, charPos );
fileRoot[ charPos ] = NULLTERM;
scriptPos = charPos;
}
if ( scriptPos > 8 )
scriptPos = 8;
scriptRoot = (char *)malloc( scriptPos + 1 );
strncpy( scriptRoot, fileName, scriptPos );
scriptRoot[ scriptPos ] = NULLTERM;
partRoot = (char *)malloc( scriptPos + 1 );
strncpy( partRoot, fileName, scriptPos - 1 );
partRoot[ scriptPos - 1 ] = EQUALSIGN;
partRoot[ scriptPos ] = NULLTERM;
return( TRUE );
}
boolean verifyEnvPath( var )
char *var;
{
char *envPath;
envPath = (char *)getenv( var );
return( ( envPath ISNT NULL ) AND ( strlen( envPath ) ISNT 0 ) );
}
char *descPath( VOIDPARM )
{
char testPath[ MAXPATHLEN ];
char *envPath;
sprintf( testPath, "%s.dsc", fileRoot );
if ( fileExists( testPath ) )
return( fileRoot );
envPath = (char *)getenv( "DSCDIR" );
if ( envPath ISNT NULL AND strlen( envPath ) )
{
sprintf( testPath, "%s/%s.dsc", envPath, fileRoot );
if ( noConfirm OR fileExists( testPath ) )
return( addString( envPath, fileRoot, "/" ) );
else
return( addString( tmpDir, fileRoot, "/" ) );
}
else
return( addString( tmpDir, fileRoot, "/" ) );
}
#define fileIsFile( fil ) \
( ( ( fil ).st_mode AND_ S_IFREG ) AND NOT \
( ( fil ).st_mode AND_ ( S_IFREG XOR_ S_IFLNK ) ) )
/* Determine the existance of a file of a specified type. Returns TRUE */
/* iff the file exists and is of the type(s) specified. */
boolean fileExists( name )
char *name;
{
boolean statFailed;
struct stat dirStat;
statFailed = stat( name, &dirStat );
if ( NOT statFailed )
{
if ( fileIsFile( dirStat ) )
return( TRUE );
}
return( FALSE );
}
/* Create a DE - allocates and nulls out a DE structure and returns a */
/* pointer to that structure. */
static DirEntry *cDE( dirName, fileName )
char *dirName, *fileName;
{
DirEntry *newDE;
newDE = (DirEntry *)malloc( sizeof( DirEntry ) );
rDEName( newDE, addString( dirName, fileName, "/" ) );
nDE( newDE ) = NULL;
lDE( newDE ) = NULL;
return( newDE );
}
/* Delete an existing DE. Free up the space it used. */
VOIDPARM kDE( theDE )
DirEntry *theDE;
{
free( gDEName( theDE ) );
nDE( theDE ) = NULL;
lDE( theDE ) = NULL;
free( theDE );
}
/* Add a DE to the end of an existing linked list of varying size. */
static VOIDPARM aDEDE( parentDE, childDE )
DirEntry *parentDE, *childDE;
{
DirEntry *tmpDE;
if ( DEBUG_PROC )
printf( "Adding DE %s to DE %s...\n",
gDEName( childDE ), gDEName( parentDE ) );
if ( ( tmpDE = lDE( parentDE ) ) IS NULL )
nDE( parentDE ) = childDE;
else
nDE( tmpDE ) = childDE;
if ( ( tmpDE = lDE( childDE ) ) IS NULL )
lDE( parentDE ) = childDE;
else
lDE( parentDE ) = tmpDE;
}
/* Return a sorted linked list of "DirEntry" structures, representing the */
/* directory entries of the specified type in the specified directory. */
static int comparator( dl1, dl2 )
DirEntry **dl1, **dl2;
{
if ( gDEName( *dl1 ) IS NULL )
/* dl1 should be BEFORE dl2 */
return( -1 );
else if ( gDEName( *dl2 ) IS NULL )
/* dl1 should be AFTER dl2 */
return( 1 );
else
return( strcmp( gDEName( *dl1 ), gDEName( *dl2 ) ) );
}
static DirEntry *sortDEs( currList )
DirEntry *currList;
{
DirEntry *DETable[ 512 ];
int index, count=0;
char lastEntry[ MAXPATHLEN ];
DirEntry *result=NULL;
if ( currList IS NULL )
return( currList );
/* first, put the current link list into an array for sorting... */
while ( currList ISNT NULL )
{
DETable[ count++ ] = currList;
currList = nDE( currList );
}
DETable[ count ] = NULL;
/* ...sort... */
qsort( (char *)DETable, count, sizeof( DirEntry * ), comparator );
/* ...then put the sorted array back into a linked list */
/* "lastEntry" is used to delete any duplicates... */
lastEntry[ 0 ] = NULLTERM;
if ( DEBUG_PROC )
printf( "Sorted list follows:\n" );
for ( index = 0; index < count; index++ )
{
if ( DEBUG_PROC )
printf( "%s...", gDEName( DETable[ index ] ) );
nDE( DETable[ index ] ) = NULL;
lDE( DETable[ index ] ) = NULL;
if ( ( lastEntry[ 0 ] IS NULLTERM ) OR
( ( gDEName( DETable[ index ] ) ISNT NULL ) AND
( strcmp( lastEntry, gDEName( DETable[ index ] ) ) ) ) )
{
if ( DEBUG_PROC )
printf( "\n" );
if ( result IS NULL )
result = DETable[ index ];
else
aDEDE( result, DETable[ index ] );
}
else if ( DEBUG_PROC )
printf( "ELIMINATED\n" );
if ( gDEName( DETable[ index ] ) IS NULL )
strcpy( lastEntry, "(null)" );
else
strcpy( lastEntry, gDEName( DETable[ index ] ) );
}
if ( DEBUG_PROC )
printf( "End of sorted list.\n" );
topDECnt = count;
return( result );
}
VOIDPARM dirList( searchPatt )
char *searchPatt;
{
char dirName[ MAXPATHLEN + 2 ];
DirEntry *newDE, *currList=NULL;
DIR *theDir;
struct dirent *dirEntry;
struct stat dirStat;
char tmpStr[ 1024 ], filePath[ 1024 ];
char *fname;
/*
if ( NOT strcmp( tmpDir, "." ) )
{
#ifdef SYSV
if ( (char *)getcwd( dirName, MAXPATHLEN ) IS NULL )
{
printf( "ERROR: Couldn't get current working directory\n" );
exit( -1 );
}
#else
if ( (char *)getwd( dirName ) IS NULL )
{
printf(
"ERROR: Couldn't get current working directory because:\n%s\n",
dirName );
exit( -1 );
}
#endif
}
else */
sprintf( dirName, "%s", tmpDir );
theDir = opendir( dirName );
while ( ( dirEntry = readdir( theDir ) ) ISNT NULL )
{
newDE = NULL;
fname = dirEntry->d_name;
if ( DEBUG_PROC )
printf( "This directory entry: '%s'\n", fname );
if ( NOT ( strcmp( fname, "." ) AND
strcmp( fname, ".." ) ) )
continue;
if ( NOT stringIn( fname, searchPatt ) )
continue;
sprintf( filePath, "%s/%s", dirName, fname );
if ( stat( filePath, &dirStat ) )
{
sprintf( tmpStr, "\nERROR: Couldn't find file '%s'",
filePath );
perror( tmpStr );
}
else if ( ( newDE IS NULL ) AND fileIsFile( dirStat ) )
newDE = cDE( dirName, fname );
if ( newDE ISNT NULL )
{
if ( currList IS NULL )
currList = newDE;
else
aDEDE( currList, newDE );
}
}
closedir( theDir );
topDE = sortDEs( currList );
}
#define sendToProc( whatToSend, result ) \
{ \
( result) = fprintf( toProc, "%s;\n", whatToSend ); \
fflush( toProc ); \
if ( ( result ) > 0 ) \
( result ) = 0; \
}
char *shellResult( theCommand, returnVal )
char *theCommand;
int *returnVal;
{
int n;
boolean notDone;
char buf[ BUFSIZ ];
char *realCommand;
char *retPtr, *result;
result = NULL;
/* sprintf( realCommand, "%s; echo \"<xStatx>: $?\"", theCommand ); */
realCommand = (char *)malloc( strlen( "; echo \"<xStatx>: $?\"" ) +
strlen( theCommand ) + 1 );
sprintf( realCommand, "%s; echo \"<xStatx>: $?\"", theCommand );
if ( DEBUG_PROC )
printf( "Slave shell about to execute '%s'\n", realCommand );
sendToProc( realCommand, *returnVal );
/* command completed - get stdout and stderr info */
notDone = TRUE;
while ( notDone )
{
while ( ( n = read( inPipe[ 0 ], buf, BUFSIZ ) ) > 0 )
{
buf[ n ] = NULLTERM;
if ( DEBUG_PROC )
printf( "From shell output '%s'\n", buf );
if ( ( ( retPtr = stringIn( buf, "<xStatx>:" ) ) ISNT NULL ) AND
( sscanf( retPtr, "<xStatx>: %d", returnVal ) IS 1 ) )
{
/* got the return status - command is done */
notDone = FALSE;
retPtr[ 0 ] = NULLTERM;
}
if ( DEBUG_PROC )
printf( "(Modified) shell output '%s' (length %d)\n",
buf, strlen( buf ) );
if ( strlen( buf ) )
{
if ( DEBUG_PROC )
printf( "There WAS output!!\n" );
result = addString( result, buf, " " );
if ( DEBUG_PROC )
printf( "result is '%s'\n", result );
}
}
/* ...still waiting for proper return status... */
}
/* Pass anything from shell's standard error */
/* to our standard error */
while ( ( n = read( errPipe[ 0 ], buf, BUFSIZ ) ) > 0 )
{
buf[ n ] = '\0';
if ( DEBUG_PROC )
printf( "From shell error '%s'\n", buf );
}
return( result );
}
VOIDPARM closePipes( VOIDPARM )
{
if ( toProc ISNT NULL )
fclose( toProc );
if ( fromProc ISNT NULL )
fclose( fromProc );
if ( errProc ISNT NULL )
fclose( errProc );
if ( inPipe[ 0 ] ISNT -1 )
close( inPipe[ 0 ] );
if ( inPipe[ 1 ] ISNT -1 )
close( inPipe[ 1 ] );
if ( outPipe[ 0 ] ISNT -1 )
close( outPipe[ 0 ] );
if ( outPipe[ 1 ] ISNT -1 )
close( outPipe[ 1 ] );
if ( errPipe[ 0 ] ISNT -1 )
close( errPipe[ 0 ] );
if ( errPipe[ 1 ] ISNT -1 )
close( errPipe[ 1 ] );
}
boolean openTopShell( VOIDPARM )
{
if ( DEBUG_PROC )
printf( "Opening top-level shell...\n" );
/* set up pipes to standard in, out, and error */
if ( pipe( inPipe ) IS -1 )
{
if ( DEBUG_PROC )
printf( "Error opening up inPipe...\n" );
printf( "ERROR: cannot open slave shell...\n" );
return( FALSE );
}
if ( pipe( outPipe ) IS -1 )
{
if ( DEBUG_PROC )
printf( "Error opening up outPipe...\n" );
closePipes();
printf( "ERROR: cannot open slave shell...\n" );
return( FALSE );
}
if ( pipe( errPipe ) IS -1 )
{
if ( DEBUG_PROC )
printf( "Error opening up errPipe...\n" );
closePipes();
printf( "ERROR: cannot open slave shell...\n" );
return( FALSE );
}
/* open from file descriptors */
toProc = fdopen( outPipe[ 1 ], "w" );
fromProc = fdopen( inPipe[ 0 ], "r" );
errProc = fdopen( errPipe[ 0 ], "r" );
if ( NOT ( toProc AND fromProc AND errProc ) )
{
if ( DEBUG_PROC )
printf( "Error opening up process pipes...\n" );
closePipes();
printf( "ERROR: cannot open slave shell...\n" );
return( FALSE );
}
/* make parent non-blocking */
fcntl( fileno( toProc ), F_SETFL, O_NDELAY );
fcntl( fileno( fromProc ), F_SETFL, O_NDELAY );
fcntl( fileno( errProc ), F_SETFL, O_NDELAY );
if ( fork() IS 0 )
{
system( "sleep 5" );
/* redirect standard input */
close( outPipe[ 1 ] );
close( fileno( stdin ) );
dup( outPipe[ 0 ] );
close( outPipe[ 0 ] );
/* redirect standard error */
close( errPipe[ 0 ] );
close( fileno( stderr ) );
dup( errPipe[ 1 ] );
close( errPipe[ 1 ] );
/* redirect standard output */
close( inPipe[ 0 ] );
close( fileno( stdout ) );
dup( inPipe[ 1 ] );
close( inPipe[ 1 ] );
/* exec the shell! */
execl( "/bin/sh", "sh", "-s", NULL );
if ( DEBUG_PROC )
/* Will NEVER get here unless the exec fails */
printf( "Couldn't start 'sh -s'\n" );
printf( "ERROR: cannot open slave shell...\n" );
exit( 0 );
}
/* close the stuff we don't need as parent */
close( outPipe[ 0 ] );
close( inPipe[ 1 ] );
close( errPipe[ 1 ] );
return( TRUE );
}
boolean closeTopShell( VOIDPARM )
{
int result;
sendToProc( "exit", result );
system( "sleep 2" ); /* give the shell a chance to respond */
if ( DEBUG_PROC )
printf( "Closing top-level shell...\n" );
closePipes();
return( result IS 0 );
}
/* Read a line from a file - return the line and the last character read. */
int lineRead( src, dst )
FILE *src;
char dst[];
{
char *lPtr;
int c;
dst[ 0 ] = NULLTERM;
lPtr = dst;
while ( ( ( c = getc( src ) ) ISNT EOL ) AND ( c ISNT EOF ) )
*lPtr++ = (char)c;
*lPtr = NULLTERM;
return( c );
}
char *utilInPath( util, shouldBitch )
char *util;
boolean shouldBitch;
{
static char *path;
char *this, *next, *suggestion;
char tmpPath[ MAXPATHLEN ], tmpFile[ MAXPATHLEN ];
if ( path IS NULL )
path = (char *)getenv( "PATH" );
/* Now the fun begins... search through the PATH setting to */
/* find out if the given utility is accessible... */
this = path;
suggestion = NULL;
while ( this )
{
if ( ( next = (char *)strchr( this, ':' ) ) AND
( next > this ) )
{
/* Extract out the current PATH element. */
strncpy( tmpPath, this, next - this );
tmpPath[ next - this ] = '\0';
next += 1;
}
else if ( next IS NULL )
{
/* We are on the last element of the PATH variable. */
strcpy( tmpPath, this );
tmpPath[ strlen( this ) ] = '\0';
}
else
{
/* If a ":" is present without a PATH element, a "." */
/* is implied. */
tmpPath[ 0 ] = '\0';
next += 1;
}
if ( tmpPath[ 0 ] ISNT NULLTERM )
sprintf( tmpFile, "%s/%s", tmpPath, util );
else
sprintf( tmpFile, "%s", util );
/* Is it there? */
if ( fileExists( tmpFile ) )
suggestion = addString( suggestion, tmpFile, " or " );
this = next;
}
if ( ( suggestion == NULL ) AND shouldBitch )
printf(
"ERROR: Can't find '%s' in the current path! Aborting...\n",
util );
return( suggestion );
}
VOIDPARM suggest( util, switches )
char *util, *switches;
{
char *suggestion;
if ( suggestion = utilInPath( util, FALSE ) )
{
if ( switches )
printf( "\t(%s {with %s option(s)} might be a good setting...)\n",
suggestion, switches );
else
printf( "\t(%s might be a good setting...)\n", suggestion );
}
else
{
if ( switches )
printf( "\t(I'd suggest '%s %s' - but it's apparently not available...)\n",
util, switches );
else
printf( "\t(I'd suggest '%s' - but it's apparently not available...)\n", util );
}
}
syntax highlighted by Code2HTML, v. 0.9.1