home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rexxtk12.zip / loader.c < prev    next >
Text File  |  2002-08-07  |  7KB  |  267 lines

  1. /*
  2.  * Copyright (C) 1998-1999  Mark Hessling <M.Hessling@qut.edu.au>
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Library General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Library General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Library General Public
  15.  * License along with this library; if not, write to the Free
  16.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  *
  18.  * Mark Hessling  M.Hessling@qut.edu.au  http://www.lightlink.com/hessling/
  19.  */
  20.  
  21. static char RCSid[] = "$Id: loader.c,v 1.1 2000/09/05 05:18:50 mark Exp $";
  22.  
  23. #include "rxpack.h"
  24.  
  25. #ifndef R_OK
  26. # define R_OK 4
  27. #endif
  28.  
  29. /* Debugging flags - owned by rxpackage.c */
  30. extern int RxRunFlags;
  31. extern FILE *RxTraceFilePointer;
  32. extern RxPackageGlobalDataDef *RxPackageGlobalData;
  33.  
  34. #ifdef HAVE_PROTO
  35. # if !defined(HAVE_GETOPT)
  36. int getopt( int argc, char *argv[], char *optstring );
  37. # endif
  38. void usage( void );
  39. #else
  40. # if !defined(HAVE_GETOPT)
  41. int getopt( );
  42. # endif
  43. void usage( );
  44. #endif
  45.  
  46. /* These are required by the getopt() function */
  47. extern char *optarg;
  48. extern int  optind;
  49.  
  50. /*-----------------------------------------------------------------------------
  51.  * Checks to see if supplied filename is readable.
  52.  *----------------------------------------------------------------------------*/
  53. static int file_readable
  54.  
  55. #ifdef HAVE_PROTO
  56.    (char *filename)
  57. #else
  58.    (filename)
  59.    char  *filename;
  60. #endif
  61. {
  62.    if ((access(filename,R_OK)) == (-1))
  63.       return(0);
  64.    else
  65.       return(1);
  66. }
  67.  
  68.  
  69. /*-----------------------------------------------------------------------------
  70.  * Processing starts here for stand-alone rexxsql executable...
  71.  *----------------------------------------------------------------------------*/
  72. int main
  73.  
  74. #if HAVE_PROTO
  75.    (int argc, char *argv[])
  76. #else
  77.    (argc, argv)
  78.    int   argc;
  79.    char  *argv[];
  80. #endif
  81. {
  82.    int c=0;
  83.    char *ProgramName=NULL;
  84.    FILE *fp;
  85.    long i=0, ArgCount=0;
  86.    int interactive = FALSE;
  87.    short rc=0;
  88.    RXSTRING retstr;
  89.    CHAR retbuf[RETBUFLEN];
  90.    RXSTRING ArgList;
  91. #if !defined(DYNAMIC_LIBRARY) && (defined(USE_WINREXX) || defined(USE_QUERCUS))
  92.    RXSYSEXIT ExitList[2];
  93. #endif
  94.    RxPackageGlobalDataDef MyGlob;
  95.  
  96.    memset( (char *)&MyGlob, 0, sizeof( RxPackageGlobalDataDef ) );
  97.  
  98.    strcpy( MyGlob.RxTraceFileName, "stderr" );
  99.    /* 
  100.     * Get any program options. 
  101.     */
  102.    while ((c = getopt(argc, argv, "Dudivh?f:")) != EOF)
  103.    {
  104.       switch (c) 
  105.       {
  106.          case 'f': 
  107.             strcpy( MyGlob.RxTraceFileName, optarg );
  108.             break;
  109.          case 'v': 
  110.             MyGlob.RxRunFlags |= MODE_VERBOSE;
  111.             break;
  112.          case 'd': 
  113.             MyGlob.RxRunFlags |= MODE_DEBUG;
  114.             break;
  115.          case 'D': 
  116.             MyGlob.RxRunFlags |= MODE_INTERNAL;
  117.             break;
  118.          case 'i': 
  119.             interactive = TRUE; 
  120.             break;
  121.          case 'u':
  122.             DeregisterRxFunctions( 1 );
  123.             return(0);
  124.             break;
  125.          case 'h':
  126.          default : usage();
  127.       }
  128.    }
  129.  
  130.    /* 
  131.     * Check if any more arguments are presented    
  132.     */
  133.    if (optind >= argc)
  134.    {
  135.       if (interactive)
  136.       {
  137.          ProgramName = tmpnam(NULL);
  138.          if ((fp = fopen(ProgramName,"w")) == NULL)
  139.          {
  140.             (void)fprintf(stderr, "Could not create temporary file for stdin\n");
  141.             exit(REXX_FAIL);
  142.          }
  143.          while(1)
  144.          {
  145.             if ((i = getc(stdin)) == EOF)
  146.                break;
  147.             putc(i,fp);
  148.          }
  149.          (void)fclose(fp);
  150.       }
  151.       else
  152.          usage();
  153.    }
  154.    else
  155.       {
  156.       /* 
  157.        * Next argument is the name of the Rexx program...
  158.        */
  159.       ProgramName = argv[optind++];
  160.       /* 
  161.        * ... and must be readable.
  162.        */
  163.  
  164.       if (!file_readable(ProgramName))
  165.       {
  166.          (void)fprintf(stderr, "Could not read file: %s\n",ProgramName);
  167.          exit(REXX_FAIL);
  168.       }
  169.    }
  170.  
  171.    /* 
  172.     * Get number of arguments to the Rexx program
  173.     */
  174.    ArgCount = argc - optind;
  175.  
  176.    /* 
  177.     * Build an array of arguments if any. 
  178.     */
  179.    if (ArgCount) 
  180.    {
  181.       int len=0;
  182.  
  183.       for ( i = optind; i < argc; i++ )
  184.       {
  185.          len += strlen( (char *)argv[i] );
  186.       }
  187.       if ( ( ArgList.strptr = (RXSTRING_STRPTR_TYPE)malloc( len + 1 + ArgCount) ) == (RXSTRING_STRPTR_TYPE)NULL )
  188.       {
  189.          (void)fprintf( stderr, "%s: out of memory\n", argv[0] );
  190.          exit( REXX_FAIL );
  191.       }
  192.       strcpy( ArgList.strptr, "" );
  193.       for ( i = optind; i < argc; i++ )
  194.       {
  195.          strcat( ArgList.strptr, (RXSTRING_STRPTR_TYPE)argv[optind++] );
  196.          if ( i != argc )
  197.             strcat( ArgList.strptr, (RXSTRING_STRPTR_TYPE)" " );
  198.       }
  199.       ArgList.strlength = ArgCount + len - 1;
  200.    }
  201.    else
  202.    {
  203.       ArgList.strptr = NULL;
  204.       ArgList.strlength = 0;
  205.    }
  206.  
  207.    /* 
  208.     * Initialise the package interface, but don't set the trace file
  209.     */
  210.    if ( ( rc = InitRxPackage( &MyGlob ) ) )
  211.       return( rc );
  212.    /* 
  213.     * Register all external functions
  214.     */
  215.    if ( ( rc = RegisterRxFunctions( ) ) )
  216.       return( rc );
  217.    FunctionPrologue( RxPackageName, 0L, NULL );
  218.    /*
  219.     * Set up the system exit for the Say and Trace redirection
  220.     */
  221. #if !defined(DYNAMIC_LIBRARY) && (defined(USE_WINREXX) || defined(USE_QUERCUS))
  222.    ExitList[0].sysexit_name = RxPackageName;
  223.    ExitList[0].sysexit_code = RXSIO;
  224.    ExitList[1].sysexit_code = RXENDLST;
  225. #endif
  226.  
  227.    MAKERXSTRING( retstr, retbuf, sizeof( retbuf ) );
  228.    /*
  229.     * Execute the Rexx script. Use RXCOMMAND mode so that the Rexx program
  230.     * expects the same parameter list if called directly via the Rexx
  231.     * interpreter.
  232.     */
  233.    assert(retstr.strptr);
  234.    assert(ProgramName);
  235.    RexxStart( ( RS_ARG0_TYPE )(ArgCount) ? 1 : 0,
  236.               ( RS_ARG1_TYPE )&ArgList,
  237.               ( RS_ARG2_TYPE )ProgramName,
  238.               ( RS_ARG3_TYPE )NULL,
  239.               ( RS_ARG4_TYPE )RxPackageName,
  240.               ( RS_ARG5_TYPE )RXCOMMAND,
  241. #if !defined(DYNAMIC_LIBRARY) && (defined(USE_WINREXX) || defined(USE_QUERCUS))
  242.               ( RS_ARG6_TYPE )ExitList,
  243. #else
  244.               ( RS_ARG6_TYPE )NULL,
  245. #endif
  246.               ( RS_ARG7_TYPE )&rc,
  247.               ( RS_ARG8_TYPE )&retstr);
  248.  
  249.    /* 
  250.     * Terminate the package interface.
  251.     */
  252.    if (RxPackageGlobalData != NULL)
  253.       (void)TermRxPackage( RxPackageName, 0 );
  254.  
  255.    if ( ArgList.strptr )
  256.       free(ArgList.strptr);
  257.    /*
  258.     * Return the exit value from the program. This is useful for UNIX/DOS etc.
  259.     * if the value is kept to 0-success, small positive numbers (say < 100)
  260.     * to indicate errors!
  261.     */
  262.    if ( interactive )
  263.       unlink( ProgramName );
  264.  
  265.    return (int)FunctionEpilogue( RxPackageName, (ULONG)rc );
  266. }
  267.