/* ======================================================= *
* Copyright 1998-2005 Stephen C. Grubb *
* http://ploticus.sourceforge.net *
* Covered by GPL; see the file ./Copyright for details. *
* ======================================================= */
/* PL - ploticus main module */
#include "pl.h"
#include <unistd.h>
#ifdef WIN32
#include <fcntl.h> /* for _O_BINARY */
#endif
extern int PLGG_setimfmt();
/* ============================================= */
int
PL_version_msg( longmsg )
int longmsg;
{
char outputformats[80];
PL_devstring( outputformats );
fprintf( PLS.diagfp, "\n\
Usage: pl -prefab prefabname [parameters] ..or.. pl scriptfile [options] \n\
%s\n\n", outputformats );
#ifdef WIN32
fprintf( PLS.diagfp, "ploticus %s (win32) ", PLVERSION );
#else
fprintf( PLS.diagfp, "ploticus %s (unix) ", PLVERSION );
#endif
fprintf( PLS.diagfp, " Copyright 1998-2006 Steve Grubb, http://ploticus.sourceforge.net\n" );
if( longmsg ) fprintf( PLS.diagfp, "\n\
Please see the Copyright file or web site for additional credits and information.\n\
\n\
This program is free software; you can redistribute it and/or modify it\n\
under the terms of the GNU General Public License as published by the\n\
Free Software Foundation; either version 2 of the License, or (at your\n\
option) any later version.\n\
\n\
This program is distributed in the hope that it will be useful, but \n\
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY \n\
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n\
for more details.\n" );
exit( 1 );
}
/* ============================================= */
/* MAIN */
/* ============================================= */
int
main( argc, argv )
int argc;
char **argv;
{
int i, argi, use_stdin, stat, found, valused, stoparg, ci, cii;
char buf[256];
char scriptfile[MAXPATH];
char prefabname[80];
char *arg, *nextarg, *getenv();
char *outnamebase;
/* check to see if we are operating as a direct CGI program.. */
PLS.cgiargs = NULL;
if( argc == 1 ) {
PLS.cgiargs = getenv( "QUERY_STRING" );
if( getenv( "SCRIPT_FILENAME" )==NULL ) { /* some web servers don't set SCRIPT_FILENAME.. scg 8/27/02 */
sprintf( buf, "SCRIPT_FILENAME=%s", argv[0] );
putenv( buf );
}
}
/* set hard defaults and process config file if any.. */
stat = PL_do_preliminaries();
if( stat ) exit( 1 );
use_stdin = 0;
/* if in direct cgi mode, initialize and set some useful defaults.. */
if( PLS.cgiargs != NULL ) {
/* begin parsing QUERY_STRING.. */
stoparg = 80;
ci = 0;
strcpy( PLS.outfile, "stdout" );
#ifdef WIN32
/* must set stdin and stdout to binary mode */
_setmode( _fileno( stdin ), _O_BINARY );
_setmode( _fileno( stdout ), _O_BINARY );
#endif /* WIN32 */
PLS.device = 's';
#ifndef NOGD
PLS.device = 'g';
/* try to be smart about picking default output format.. */
if( devavail( "gif" )) PLGG_setimfmt( "gif" );
else if( devavail( "jpeg" )) PLGG_setimfmt( "jpeg" );
else if( devavail( "png" )) PLGG_setimfmt( "png" );
#endif
}
else stoparg = argc;
strcpy( scriptfile, "" );
strcpy( prefabname, "" );
/* process command line arguments.. (if direct CGI, arguments are parsed from URL).. */
for( argi = 1; argi < stoparg; argi++ ) {
if( PLS.cgiargs != NULL ) {
/* parse next 2 args from QUERY_STRING.. */
GL_getcgiarg( PL_bigbuf, PLS.cgiargs, &ci, 252 );
if( PL_bigbuf[0] == '\0' ) break;
arg = PL_bigbuf;
cii = ci;
GL_getcgiarg( &PL_bigbuf[500], PLS.cgiargs, &cii, 252 ); /* share PL_bigbuf */
nextarg = &PL_bigbuf[500];
}
else {
arg = argv[ argi ];
if( argi+1 < argc ) nextarg = argv[argi+1];
else nextarg = "";
}
if( strcmp( arg, "-stdin" )==0 && PLS.cgiargs == NULL ) use_stdin = 1;
else if( strcmp( arg, "-png" )==0 && !devavail( "png" ) && PLS.cgiargs == NULL ) {
char *p[100];
if( strlen( argv[0] ) >= 5 ) {
if( strcmp( &argv[0][strlen(argv[0])-5], "plpng" )==0 ) {
Eerr( 5279, "png not available in plpng", "" );
PL_version_msg( 0 ); exit(1);
}
}
p[0] = "plpng";
for( i = 1; i < argc; i++ ) p[i] = argv[i];
p[argc] = NULL;
execvp( "plpng", argv );
fprintf( PLS.errfp, "PNG not supported in this build (plpng not found).\n" );
PL_version_msg( 0 ); exit(1);
}
else if( strcmp( arg, "-f" )==0 ) {
if( strlen( nextarg ) > MAXPATH-10 ) { /* allow extra for output file suffix add */
fprintf( PLS.errfp, "pl: script file name too long" );
PL_version_msg( 0 ); exit( 1 );
}
strcpy( scriptfile, nextarg );
argi++;
}
else if( strcmp( arg, "-prefab" )==0 ) {
if( PLS.cgiargs != NULL ) {
Eerr( 4916, "-prefab not available in direct cgi mode", "" ); PL_version_msg( 0 ); exit( 1 );
}
if( PLS.prefabsdir == NULL ) {
Eerr( 4899, "PLOTICUS_PREFABS environment var not found (pathname of dir where prefab files reside)", "" );
PL_version_msg( 0 ); exit( 1 );
}
sprintf( prefabname, "%s.pl", nextarg );
sprintf( scriptfile, "%s%c%s", PLS.prefabsdir, PATH_SLASH, prefabname );
if( PLS.debug ) fprintf( PLS.diagfp, "Prefabs dir is: %s\nScript file is %s\n", PLS.prefabsdir, scriptfile );
argi++;
}
else if( GL_smember( arg, "-? -help -ver -version" ) ) { PL_version_msg( 1 ); exit(0); }
else {
stat = PL_process_arg( arg, nextarg, &valused, &found );
if( stat != 0 ) exit( 1 );
if( !found && arg[0] == '-' ) Eerr( 4892, "warning, unrecognized argument", arg );
else if( !found && scriptfile[0] == '\0' ) {
if( strlen( arg ) > MAXPATH-10 ) { /* allow extra for output file suffix add */
fprintf( PLS.errfp, "pl: script file name too long" );
PL_version_msg( 0 ); exit( 1 );
}
strcpy( scriptfile, arg );
}
argi += valused;
if( PLS.cgiargs != NULL && valused ) ci = cii; /* jump ahead */
}
}
/* CGI header stuff.. */
if( PLS.cgiargs != NULL ) {
char imagetype[20];
strcpy( PLS.outfile, "stdout" );
/* check for loopy script file names.. */
if( scriptfile[0] == '/' && prefabname[0] == '\0' ) { /* changed scg 2/6/02 */
Eerr( 2740, "cgi mode: script file name may not begin with '/'", scriptfile );
PL_version_msg( 0 ); exit(1);
}
if( GL_slmember( scriptfile, "*..* .*" ) ) {
Eerr( 2740, "cgi mode: script file name may not begin with '.' or contain '..'", scriptfile );
PL_version_msg( 0 ); exit(1);
}
/* output the HTTP content-type header.. */
devnamemap( &(PLS.device), imagetype, 2 );
if( PLS.device == 's' ) printf( "Content-type: image/%s-xml\n\n", imagetype );
else printf( "Content-type: image/%s\n\n", imagetype );
/* be sure clickmap is off - incompatible with direct cgi mode.. */
PLS.clickmap = 0;
}
/* if script coming from stdin, copy stdin to a tmp file.. */
if( use_stdin ) {
FILE *tfp;
sprintf( scriptfile, "%s_I", PLS.tmpname );
tfp = fopen( scriptfile, "w" ); /* temp file, unlinked below */
if( tfp == NULL ) { Eerr( 102, "Cannot open tmp file for stdin script\n", scriptfile ); PL_version_msg( 0 ); exit(1); }
while( fgets( PL_bigbuf, MAXBIGBUF-1, stdin ) != NULL ) fprintf( tfp, "%s", PL_bigbuf ); /* was 255 scg 5/20/03 */
fclose( tfp );
}
if( scriptfile[0] == '\0' ) {
Eerr( 20, "No -prefab or scriptfile specified on command line", "" );
PL_version_msg( 0 );
}
/* DEVICE variable.. */
if( TDH_getvar( "DEVICE", buf ) != 0 ) { /* DEVICE not given on command line, set DEVICE */
stat = devnamemap( &(PLS.device), buf, 2 );
if( stat != 0 ) { PL_version_msg( 0 ); exit( 1 ); }
TDH_setvar( "DEVICE", buf );
}
else { /* DEVICE given on command line, set PLS.device from DEVICE */
TDH_getvar( "DEVICE", buf );
stat = devnamemap( &(PLS.device), buf, 1 );
if( stat != 0 ) { PL_version_msg( 0 ); exit( 1 ); }
}
if( PLS.debug ) fprintf( PLS.diagfp, "Device code is %c\n", PLS.device );
/* build output file names.. */
if( prefabname[0] != '\0' ) outnamebase = prefabname;
else outnamebase = scriptfile;
if( PLS.outfile[0] == '\0' && GL_member( PLS.device, "egsf" ) ) makeoutfilename( outnamebase, PLS.outfile, PLS.device, 1);
/* if a viewcommand is specified and an outfile has not been and the device
is paginated postscript, we need to set the output file to out.ps */
if( PLS.viewer[0] != '\0' && PLS.outfile[0] == '\0' && GL_member( PLS.device, "cp")) strcpy( PLS.outfile, "out.ps" );
if( PLS.outfile[0] != '\0' &&
strcmp( PLS.outfile, "-" )!= 0 ) {
if( PLS.debug ) fprintf( PLS.diagfp, "Setting output file name to %s\n", PLS.outfile );
Esetoutfilename( PLS.outfile );
}
PL_begin(); /* various other initializations that must be done after config & args processing.. */
/* execute the script file to produce the plot.. */
if( PLS.debug ) fprintf( PLS.diagfp, "Script file is: %s\n", scriptfile );
stat = PL_exec_scriptfile( scriptfile );
if( stat != 0 ) { PL_version_msg( 0 ); exit( 1 ); }
/* finish up (x11: button, etc.) */
if( PLS.eready && PLS.device == 'x' ) PL_do_x_button( "End." );
if( PLS.eready ) Eendoffile();
if( use_stdin ) unlink( scriptfile );
if( PLS.viewer[0] != '\0' && PLS.device != 'x' && PLS.cgiargs == NULL ) {
int len;
strcpy( buf, PLS.viewer );
len = strlen( buf );
strcpy( &buf[len++], " " );
Egetoutfilename( &buf[ len ] );
if( strnicmp( &buf[ len ], "stdout", 6 )==0 ) fprintf( PLS.diagfp, "Cannot use -o stdout with -viewer\n" );
else if( PLS.noshell ) fprintf( PLS.diagfp, "-noshell prohibits -viewer" );
else {
fprintf( PLS.diagfp, "Executing '%s' to view results..\n", buf );
system( buf );
}
}
PL_free();
exit( 0 );
}
/* ======================================================= *
* 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