Logo Search packages:      
Sourcecode: maxdb-7.5.00 version File versions

ven05.c

Go to the documentation of this file.
/*!
  @file           ven05.c
  @author         JoergM
  @brief          Client RunTime: Virtual Printer (using standard spooler "lp")
  @see            

\if EMIT_LICENCE

    ========== licence begin  GPL
    Copyright (c) 2001-2004 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end


\endif
*/

#define MOD__ "ven05.c:"

#include "gen00.h"
#include "heo00.h"
#include "heo46.h"
#include "hen50.h"
#include "hen40.h"

#if SVR4
#include    <wait.h>
#endif
#if SCO
#include    <sys/wait.h>
#endif

#ifdef  DEBUG_RTE
#define ERRTEXT(v,t)    { DBG1 (( MF__,"ERR %s\n", t));\
                    eo46CtoP(v,t,MAXERRORTEXT); }
#else
#define ERRTEXT(v,t)    { eo46CtoP(v,t,MAXERRORTEXT); }
#endif  


#define LP                             "lp"

#define DEST                           "-d"
#define STD_IN                         0
#define STD_OUT                        1
#define STD_ERR                        2
#define MAX_PID                        8
#define MAX_DR_ANZ                     3
#define SPL_NAME                       "/tmp/spl"

static struct
    {
    char                               dest[2];
    PRINTERNAMEC                       printer;
    } destination = { 0 };

static  pid_t                   sql05_apc_pid = (pid_t)0;
static  tsp00_Bool              sql05_vp_initial_printer = (tsp00_Bool)TRUE ;
static  tsp00_VFilenamec        sql05_spl_filename ;
static  tsp00_VFilenamec        sql05_pr_file ;
static  tsp00_VFilenamec        sql05_lp ;
static  tsp00_Int4              sql05_pr_number = 0;
static  char                    sql05_pr_lf = 0;
static  char                    sql05_pr_ff = 0;
static  char                    sql05_pr_cr = 0;
static  int                     sql05_spool_fd ;
static  char                    * sql05_pr_argv [ 3 ] = { NULL, NULL, NULL };
static  tsp00_Bool                 has_printed = 0;
static  int                     fildes [ 2 ] = { 0, 0 };

/*  IST unused * /
/ * IST * / static      char              blankprinter [] =
/ * IST * /     "                                                                ";
/ * IST */

#ifdef  REL30
void                        sqlpon ( tsp00_PrtName  printer,
tsp00_Bool                                *vpok);
void                        sqlprint ( tsp00_PrtLine line,
tsp00_Int2                               length,
tsp00_VpLinefeeds                       lfeeds,
tsp00_ErrText                              errtext,
tsp00_Bool                                *vpok);
void                        sqlpoff ( tsp00_Bool print,
tsp00_ErrText                            errtext,
tsp00_Bool                                *printok);
#else
void                        vpon ( tsp00_PrtName  printer,
tsp00_Bool                                *vpok);
void                                      vprint ( tsp00_PrtLine line,
tsp00_Int2                               length,
tsp00_VpLinefeeds                       lfeeds,
tsp00_ErrText                            errtext,
tsp00_Bool                                *vpok);
void                              vpoff ( tsp00_Bool print);
#endif

static      void              newdest ();
static      void              init_printer ();
static      void              spoolname ();
static      void              dup_in ();
static      void              dup_stdout ();
static      void              dup_stderr ();

/*==========================================================================*/

static                  void newdest ()
{
int             len ;

DBG1 (( MF__,"newdest: called \n" ));

/*  FST * / if ( strncmp ( destination.printer, blankprinter, sizeof (tsp00_PrtName) ) )
/ * FST **/
len = strlen ( destination.printer ) ;
DBG1 (( MF__,"newdest         : len                            = %d\n", len ))
if ( len )
  {
  /* destination is not blank, use it      */
  (void) strncpy (destination.dest, DEST, 2);
  sql05_pr_argv [ 1 ] = (char *) & destination ;
  sql05_pr_argv [ 2 ] = (char *) NULL ;
  }
else
  {
  /* destination is blank, use default */
  sql05_pr_argv [ 1 ] = (char *) NULL ;
  }

DBG1 (( MF__,"newdest: returning \n" ));
}


/*------------------------------*/


static void init_printer ()
{

DBG1 (( MF__,"init_prin: called \n" ));

sql05_apc_pid   = getpid ();
sql05_pr_number = 1;
sql05_pr_lf     = '\n';
sql05_pr_ff     = '\f';
sql05_pr_cr     = '\r';
(void) strcpy ( sql05_lp , LP);
(void) strcpy ( sql05_pr_file , LP );
sql05_pr_argv [ 0 ] = sql05_lp ;
sql05_pr_argv [ 1 ] = (char *) NULL ;
sql05_pr_argv [ 2 ] = (char *) NULL ;

DBG1 (( MF__,"init_prin: returning \n" ));
}


/*------------------------------*/


/*
 * spoolname
 *
 * ermittelt aus Prozess_id und Anzahl der Druckjobs den Namen fuer die
 * Druckausgabedatei.
 */

static void spoolname (
pid_t             pid ,
tsp00_Int4        dr_anz )
{
char                                   pid_str[MAX_PID+1];
char                                   dr_str[MAX_DR_ANZ+1];
char                                   *cp;

DBG1 (( MF__,"spoolname: called \n" ));

for (*((cp = pid_str + MAX_PID)) = '\0', cp--; cp >= pid_str; cp--)
    {
    *cp     = pid % 10 + '0';
    pid    /= 10;
    }

for (*((cp = dr_str + MAX_DR_ANZ)) = '\0', cp--; cp >= dr_str; cp--)
    {
    *cp     = dr_anz % 10 + '0';
    dr_anz /= 10;
    }

(void) strcpy ( sql05_spl_filename , SPL_NAME);
(void) strcat ( sql05_spl_filename , pid_str);
(void) strcat ( sql05_spl_filename , dr_str);

DBG1 (( MF__,"spoolname: returning \n" ));
}


/*------------------------------*/


static void dup_in (
tsp00_Bool                                *notok)
{

DBG1 (( MF__,"dup_in: called \n" ));

*notok = TRUE;
if ( lseek ( sql05_spool_fd , 0 , 0 ) == ( long ) UNDEF )
    {
    MSGD (( -11301 , ERR_TYPE, "VPRINTER", "lseek error, %s\n", sqlerrs() ));
    }
else
    {
    if (close (STD_IN) == UNDEF)
      {
      MSGD (( -11302 , ERR_TYPE, "VPRINTER", "close stdin error, %s\n", sqlerrs() ));
      }
    else
      {
      if (dup ( sql05_spool_fd ) != STD_IN)
          {
          MSGD (( -11300 , ERR_TYPE, "VPRINTER", "error, %s\n", sqlerrs() ));
          }
        else
          {
          if (close ( sql05_spool_fd ) == UNDEF)
            {
            MSGD (( -11303 , ERR_TYPE, "VPRINTER", "close error, %s\n", sqlerrs() ));
            }
          else
            {
            *notok = FALSE;
            }
          }
      }
    }

DBG1 (( MF__,"dup_in: returning \n" ));
}


/*==========================================================================*/


static void dup_stdout ( 
tsp00_Bool                         *ok)
{
    int                         fd_devnull;
    tsp00_VFilenamec               dev_null;

    DBG1 (( MF__,"********** dup_stdout called **************************\n" ))

    *ok = FALSE;
    (void) strcpy (dev_null, "/dev/null");
    fd_devnull = open ( dev_null , O_WRONLY , 0 );

    DBG1 (( MF__,"dup_stdout      : fd_devnull                     = %d\n",
                       fd_devnull ))

    if (fd_devnull == UNDEF)
    {
      MSGD (( -11115 , ERR_TYPE, "VPRINTER", "open /dev/null error, %s\n", sqlerrs() ));
    }
    else
    {
      if ( close ( STD_OUT ) == UNDEF )
      {
          MSGD (( -11302 , ERR_TYPE, "VPRINTER", "close stdout error, %s\n", sqlerrs() ));
      }
      else
      {
          if (dup (fd_devnull) == UNDEF)
          {
            MSGD (( -11304 , ERR_TYPE, "VPRINTER", "dup stdout error, %s\n", sqlerrs() ));
          }
          else
          {
            if (close (fd_devnull) == UNDEF)
            {
                MSGD (( -11302 , ERR_TYPE, "VPRINTER", "close /dev/null error, %s\n", sqlerrs() ));
            }
            else
            {
                *ok = TRUE;
            }
          }
      }
    }

    DBG1 (( MF__,"dup_stdout : returning \n" ));
}

/*==========================================================================*/


static void dup_stderr (
tsp00_Bool                         *ok)
{
/* IST unused* /
/ *IST* /    int                         fd_devnull;
/ *IST* /    tsp00_VFilenamec               dev_null;
/ *IST*/

    DBG1 (( MF__,"********** dup_stderr called **************************\n" ))

    *ok = FALSE;

    if ( close ( STD_ERR ) == UNDEF )
    {
      MSGD (( -11302 , ERR_TYPE, "VPRINTER", "close stderr error, %s\n", sqlerrs() ));
    }
    else
    {
      if (dup ( fildes [ 1 ] ) == UNDEF)
      {
          MSGD (( -11305 , ERR_TYPE, "VPRINTER", "dup fildes [1] error, %s\n", sqlerrs() ));
      }
      else
      {
          if (close ( fildes [ 1 ] ) == UNDEF)
          {
            MSGD (( -11306 , ERR_TYPE, "VPRINTER", "close fildes [1] error, %s\n", sqlerrs() ));
          }
          else
          {
            *ok = TRUE;
          }
      }
    }

    DBG1 (( MF__,"dup_stderr : returning \n" ));
}

/*------------------------------*/

#ifdef  REL30
void                                   sqlpon (
#else
void                                   vpon (
#endif

tsp00_PrtName                            printer,
tsp00_Bool                                *vpok)
{
    eo46PtoC (destination.printer, printer, sizeof(tsp00_PrtName));

    DBG1 (( MF__,"sqlpon: called,    to print on %s\n", destination.printer ));

    has_printed = FALSE ;
    * vpok = FALSE ;

    if (sql05_vp_initial_printer)
    {
      init_printer ();
      sql05_vp_initial_printer = FALSE;
    }

    spoolname ( sql05_apc_pid , sql05_pr_number );
    DBG1 (( MF__,"sqlpon     : printer        >%s<\n", destination.printer));

    newdest ();

    sql05_spool_fd = open ( sql05_spl_filename ,
                                 O_RDWR | O_CREAT | O_TRUNC , 0666);
    if ( sql05_spool_fd == UNDEF)
    {
      MSGD (( -11307, ERR_TYPE, "VPRINTER", "open spoolfile error, %s\n", sqlerrs()));
    }
    else
    {
      if (unlink ( sql05_spl_filename ) == UNDEF)
      {
          *vpok = FALSE;
          MSGD (( -11308, ERR_TYPE, "VPRINTER", "open unlink error, %s\n", sqlerrs()));
      }
      else
      {
          ++ sql05_pr_number ;
          * vpok = TRUE ;
      }
    }

    DBG1 (( MF__,"sqlpon: returning \n" ));
}


/*------------------------------*/


#ifdef  REL30
void  sqlprint (
tsp00_PrtLine                            line,
tsp00_Int2                               length,
tsp00_VpLinefeeds                       lfeeds,
tsp00_ErrText                              errtext,
tsp00_Bool                                *vpok)
#else
void  vprint (
tsp00_PrtLine                            line,
tsp00_Int2                               length,
tsp00_VpLinefeeds                       lfeeds,
tsp00_ErrText                            errtext,
tsp00_Bool                                *vpok)
#endif
{
char                                   prstring[ MX_PRLINE + 4 ];
tsp00_Int2                               len;
tsp00_Int4                               retvalue;
 
DBG1 (( MF__,"sqlprint: called \n" ));


if ( lfeeds < VP_PAGE)
    {
    FILL ( prstring , sql05_pr_lf , lfeeds );
    len =  lfeeds;
    }
else
    {
    * prstring = sql05_pr_ff ;
    len       = 1;
    }

/* memcpy ((INt4)prstring + len, line, (tsp00_Int4) length); FSt */
COPY (( char * ) ( prstring + len ) , line , length );
len           +=  length;
prstring[len]  = sql05_pr_cr ;

retvalue = write ( sql05_spool_fd , prstring , ( unsigned ) ++ len );
if (retvalue < len)
    {
    * vpok = FALSE;
    ERRTEXT (errtext, "write error");
    DBG1 (( MF__,"sqlprint   : write error, %s\n", sqlerrs() ));
    }
else
    {
    has_printed = TRUE ;
    * vpok = TRUE;
    }

DBG1 (( MF__,"sqlprint: returning \n" ));
}


/*------------------------------*/


#ifdef  REL30
void  sqlpoff (
tsp00_Bool                                print,
tsp00_ErrText                            errtext,
tsp00_Bool                                *printok)
#else
void  vpoff (
tsp00_Bool                                print)
#endif
{
    pid_t                               son_pid;
    pid_t                               wait_pid;
    int                                 status;
    tsp00_Int4                            retvalue;
    tsp00_Bool                             ok;
    tsp00_Bool                             notok;
    int                                 cnt ;
    char                                son_err_buf [ 121 ] ;
    SIGNALFUNCTYPE                      (* sig_old)();
#ifdef  REL24
    tsp00_Bool                             printok_buf, *printok = &printok_buf;
#endif

    DBG1 (( MF__,"sqlpoff: called \n" ));

    * printok = TRUE ;

    if ( print && has_printed )
    {

      /* ***** set signal to SIG_DFL ***** */

      sig_old = signal (SIGCLD, SIG_DFL);


      /* ***** create unnamed pipe for error handling ***** */

      if ( pipe ( fildes ) < 0 )
      {
          * printok = FALSE ;
          MSGD (( -11309, ERR_TYPE, "VPRINTER", "sqlpoff: creating pipe error, %s\n", sqlerrs() ))
          DBG1 (( MF__,"sqlpoff         : * printok (pipe)               = %d\n",
                             * printok ))
          ERRTEXT (errtext, "cannot create pipe to lp");
          return ;
      }


      /* ***** fork your SON ***** */

      son_pid = fork ();

      if (son_pid == 0)
      {
          /*****              S O N                 *****/

          /* ***** close fd for reading ***** */
          /* ***** from pipe            ***** */

          (void ) close ( fildes [ 0 ] ) ;


          /* ***** dup printer file to STDIN ***** */

          dup_in (&notok);
          if (notok)
          {
            * printok = FALSE ;
            MSGD (( -11310 , ERR_TYPE, "VPRINTER", "dup_in error, %s\n", sqlerrs() ));
            ERRTEXT (errtext, "cannot redirect stdin to lp");
          }
          else
          {

            /* ***** dup STDOUT to /dev/null ***** */

            dup_stdout (&ok);
            if (! ok)
            {
                * printok = FALSE ;
                MSGD (( -11310 , ERR_TYPE, "VPRINTER", "dup_stdout error, %s\n", sqlerrs() ));
                ERRTEXT (errtext, "cannot redirect stdout from lp");
            }
            else
            {
            /* ***** dup STDERR to pipe ( to father ) ***** */

                dup_stderr (&ok);
                if (! ok)
                {
                  * printok = FALSE ;
                  MSGD (( -11310 , ERR_TYPE, "VPRINTER", "dup_stderr error, %s\n", sqlerrs() ));
                  ERRTEXT (errtext, "cannot redirect stderr from lp");
                }
                else
                {
                  DBG1 (( MF__,"sqlpoff         : sql05_pr_argv [ 0 ]            = >%s<\n",
                                     sql05_pr_argv [ 0 ] ))
                  DBG1 (( MF__,"sqlpoff         : sql05_pr_argv [ 1 ]            = >%s<\n",
                                     sql05_pr_argv [ 1 ] ))
                  DBG1 (( MF__,"sqlpoff         : sql05_pr_argv [ 1 ]            = %d\n",
                                     sql05_pr_argv [ 1 ] ))
                  DBG1 (( MF__,"sqlpoff         : sql05_pr_argv [ 2 ]            = %d\n",
                                     sql05_pr_argv [ 2 ] ))

                  retvalue = execvp ( sql05_pr_file , sql05_pr_argv );

                  if (retvalue < 0)
                  {
                      (void) fprintf ( stderr ,
                        "cannot execute '%s': ", sql05_pr_file );
                      perror ( "" );
                      exit ( -1 );
                  }
                }
            }
          }
      }
      else
      {
          /*****              F A T H E R           *****/
          if (son_pid < 0)
          {
            * printok = FALSE ;
            MSGD (( -11311 , ERR_TYPE, "VPRINTER", "fork error, %s\n", sqlerrs() ));
            ERRTEXT (errtext, "cannot fork for lp");
          }
          else
          {
            DBG1 (( MF__,"sqlpoff    : Waiting \n" ));
            wait_pid = wait (&status);
            if (wait_pid == UNDEF)
            {
                * printok = FALSE ;
                MSGD (( -11312 , ERR_TYPE, "VPRINTER", "wait error, %s\n", sqlerrs() ));
                ERRTEXT (errtext, "cannot get status from lp");
            }
            else
            {
                if (wait_pid != son_pid)
                {
                  * printok = FALSE ;
                  MSGD (( -11313 , ERR_TYPE, "VPRINTER", "son_pid error, %s\n", sqlerrs() ));
                  ERRTEXT (errtext, "got status from wrong process");
                }
                else if ( status )
                {
                  * printok = FALSE ;
                  MSGD (( -11313 , ERR_TYPE, "VPRINTER", "lp returned 0x%04x \n", status ));
                  ERRTEXT (errtext, "lp returned error status");
                }
            }
          }

          /* ***** install old signal handling ***** */

          (void) signal (SIGCLD, sig_old);


          /* ***** reading from pipe ***** */

          FILL ( son_err_buf , '\0' , 120 ) ;
          ( void ) close ( fildes [ 1 ] ) ;
          cnt = read ( fildes [ 0 ] , son_err_buf , 120 ) ;
          if ( cnt < 0 )
          {
            * printok = FALSE ;
            MSGD (( -11314, ERR_TYPE, "VPRINTER", "sqlpoff: read from pipe error, %s\n",
                                          sqlerrs() ))
            ERRTEXT (errtext, "cannot read error message from lp");
          }
          (void) close ( fildes[0] ); /* IST 26.05.94 */
          (void) close ( sql05_spool_fd ); /* IST 13.06.94 */
          sql05_spool_fd = -1 ; /* IST 13.06.94 */

          if ( cnt > 0 )
          {
            * printok = FALSE ;
            MSGD (( -11315, ERR_TYPE, "VPRINTER", "%s" , son_err_buf ))
            (void) sleep ( 4 ); /* lets the MSG stand on screen */
#               ifdef REL24
            sqle04c_cup ( 2 ) ;
            sqle04c_refresh () ;
            write ( STD_ERR , son_err_buf , (unsigned) cnt ) ;
#               endif
            ERRTEXT (errtext, son_err_buf);
          }
      }
    }
    else
    {
      DBG1 (( MF__,"sqlpoff    : Clear up           \n" ));
    }

    DBG1 (( MF__,"sqlpoff         : * printok ( returning )        = %d\n",
                       * printok ))
}

Generated by  Doxygen 1.6.0   Back to index