/* ======================================================= *
* Copyright 1998-2005 Stephen C. Grubb *
* http://ploticus.sourceforge.net *
* Covered by GPL; see the file ./Copyright for details. *
* ======================================================= */
/* SHELL.C - script shell command interface */
#include "tdhkit.h"
#include <ctype.h>
extern int TDH_setvarcon(), TDH_setvar(), TDH_getvar(), GL_deletechars();
#define NL 0
#define WS 1
#define TAB 2
static FILE *shellfp = NULL;
static char *fn[MAXITEMS];
static char namebuf[512]; /* was MAXRECORDLEN but seemed like overkill.. */
static int nfn = 0;
static int indelim = NL;
static int nrows = 0;
static int exitcode = 0;
static int fconvertflag = 0; /* added 4/17/03 scg */
static int parsefields(), checkexit();
/* =================================== */
int
TDH_shell_initstatic()
{
shellfp = NULL;
nfn = 0;
indelim = NL;
nrows = 0;
exitcode = 0;
return( 0 );
}
/* =================================== */
int
TDH_shellcommand( command )
char *command;
{
FILE *popen();
nfn = 0;
nrows = 0;
#ifndef WIN32
strcat( command, "\necho \"%-exitcode-% $?\" \n" );
#endif
shellfp = popen( command, "r" );
if( shellfp == NULL ) return( 1 );
return( 0 );
}
/* =================================== */
int
TDH_shellreadheader( )
{
int stat;
char *s;
s = fgets( namebuf, SCRIPTLINELEN-1, shellfp );
stat = checkexit( s, namebuf );
if( stat != 0 ) return( stat );
parsefields( namebuf, fn, &nfn );
return( 0 );
}
/* =================================== */
int
TDH_shellresultrow( buf, fields, nfields, maxlen )
char *buf;
char *fields[MAXITEMS];
int *nfields;
int maxlen;
{
char *s;
int stat;
if( shellfp == NULL ) return( 1 );
s = fgets( buf, maxlen, shellfp );
stat = checkexit( s, buf );
if( stat != 0 ) return( stat );
nrows++;
parsefields( buf, fields, nfields );
return( 0 );
}
/* ===================================== */
int
TDH_shellclose()
{
if( shellfp == NULL ) return( 1 );
pclose( shellfp ); shellfp = NULL;
return( 0 );
}
/* ===================================== */
static int
checkexit( s, buf )
char *s; /* return from an fgets */
char *buf;
{
if( s == NULL ) {
pclose( shellfp ); shellfp = NULL;
return( 1 );
}
if( strncmp( buf, "%-exitcode-% ", 13 )==0 ) {
sscanf( buf, "%*s %d", &exitcode );
pclose( shellfp ); shellfp = NULL;
return( 1 );
}
return( 0 );
}
/* =================================== */
static int
parsefields( buf, f, nf )
char *buf;
char *f[MAXITEMS];
int *nf;
{
int ix, i, j, len, startfld, sp;
ix = 0; i = 0;
len = strlen( buf );
startfld = 1;
for( i = 0, j = 0; i < len; i++ ) {
sp = 0;
if( indelim == TAB && (buf[i] == '\t' || buf[i] == '\n' ) ) sp = 1;
else if( indelim == NL && buf[i] == '\n' ) sp = 1;
else if( indelim == WS ) sp = isspace( (int) buf[i] );
if( !sp && startfld ) {
f[j++] = &buf[i];
startfld = 0;
}
if( sp ) {
buf[i] = '\0';
startfld = 1;
}
}
*nf = j;
return( 0 );
}
/* ========================================== */
/* SHFUNCTIONS - TDH script access to shell commands */
int
TDH_shfunctions( hash, name, arg, nargs, result, typ )
int hash;
char *name;
char *arg[];
int nargs;
char *result;
int *typ;
{
char *f[MAXITEMS];
char fname[50];
char buf[MAXRECORDLEN];
int i, n, len, stat;
*typ = 0; /* numeric */
if( hash == 1006 ) { /* $shellrow() - fetch a row of results.
* Return 0 = normal, 1 = no row fetched and no more results, >1 = error. */
/* get next result row.. */
NEXTROW:
if( nargs > 1 && indelim == NL ) indelim = WS; /* more than one var given.. guess whitespace delim */
stat = TDH_shellresultrow( buf, f, &n, SCRIPTLINELEN );
if( stat == 0 ) {
if( nfn > 0 ) { /* names already defined in a header.. */
for( i = 0; i < nfn; i++ ) TDH_setvarcon( fn[i], f[i], fconvertflag );
}
else if( nargs > 0 && strcmp( arg[0], "#varvaluepair" )==0 ) { /* tag-value pair */
strcpy( fname, f[0] );
len = strlen( fname );
if( len == 0 ) goto NEXTROW; /* blank name.. skip.. */
if( fname[ len -1 ] == ':' ) fname[ len-1] = '\0';
TDH_setvarcon( fname, f[1], fconvertflag );
}
else if( nargs > 0 ) { /* names given as function arguments */
for( i = 0; i < nargs; i++ ) {
if( i >= n ) TDH_setvar( arg[i], "" );
else TDH_setvarcon( arg[i], f[i], fconvertflag );
}
}
else { /* error - no name(s) specified */
strcpy( result, "5690" );
return( 0 );
}
}
else for( i = 0; i < nfn; i++ ) TDH_setvar( fn[i], "" );
/* check return status.. non-zero indicates no more rows.. */
sprintf( result, "%d", stat );
return( 0 );
}
if( hash == 2569 ) { /* shellrowcount() - return number of rows presented or affected by last sql command. */
sprintf( result, "%d", nrows );
return( 0 );
}
if( hash == 3084 ) { /* $shellstripchars( chars, varname1 .. varnamen ) - remove characters that could be dangerous
in shell commands. Chars arg may be omitted to use a standard set of characters. */
/* DEPRECATED - this is now automatically done in value_subst when within #shell/#endshell */
int start;
if( isalpha( (int) arg[0][0] )) start = 0;
else start = 1;
for( i = start; i < nargs; i++ ) {
stat = TDH_getvar( buf, arg[i] );
if( start == 0 ) GL_deletechars( "\"'`$\\;", buf );
else GL_deletechars( arg[0], buf );
stat = TDH_setvar( arg[i], buf );
}
sprintf( result, "0" );
return( 0 );
}
if( hash == 2554 ) { /* $shellreadheader() - load field name header */
if( arg[0][0] == 't' ) indelim = TAB; /* added scg 3/10/06 */
else indelim = WS; /* added scg 3/10/06 */
stat = TDH_shellreadheader();
sprintf( result, "%d", stat );
return( 0 );
}
if( hash == 2686 ) { /* $shellfielddelim() */
if( arg[0][0] == 'w' ) indelim = WS;
else if( arg[0][0] == 't' ) indelim = TAB;
else indelim = NL;
sprintf( result, "0" );
return( 0 );
}
if( hash == 3953 ) { /* $shellfieldconvert() - specify conversions to perform on incoming fields */
if( strcmp( arg[0], "shsql" )==0 ) fconvertflag = 1;
else fconvertflag = 0;
sprintf( result, "0" );
return( 0 );
}
if( hash == 2138 ) { /* $shellexitcode() */
sprintf( result, "%d", exitcode );
return( 0 );
}
return( err( 197, "unrecognized function", name )); /* not found */
}
/* ======================================================= *
* Copyright 1998-2005 Stephen C. Grubb *
* http://ploticus.sourceforge.net *
* Covered by GPL; see the file ./Copyright for details. *
* ======================================================= */
syntax highlighted by Code2HTML, v. 0.9.1