Net2/usr/src/contrib/isode/dsap/common/picture.c

Compare this file to the similar file:
Show the results in this format:

/* picture.c - exec printing of external attributes */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/dsap/common/RCS/picture.c,v 7.3 91/03/09 11:53:31 mrose Exp $";
#endif

/* 
 * $Header: /f/osi/dsap/common/RCS/picture.c,v 7.3 91/03/09 11:53:31 mrose Exp $
 *
 *
 * $Log:	picture.c,v $
 * Revision 7.3  91/03/09  11:53:31  mrose
 * update
 * 
 * Revision 7.2  91/02/22  09:19:57  mrose
 * Interim 6.8
 * 
 * Revision 7.1  90/11/20  15:29:20  mrose
 * cjr
 * 
 * Revision 7.0  89/11/23  21:44:21  mrose
 * Release 6.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include <signal.h>
#include "quipu/util.h"
#include "quipu/photo.h"
#include "quipu/attr.h"
#include "psap.h"
#include <errno.h>
#ifdef	BSD42
#include <sys/wait.h>
#endif
#include "quipu/syntaxes.h"

typedef struct childList {
	struct childList *next;
	int childpid;
} ChildList;

static ChildList *rootChildList = NULL;

char * show_picture (picture,picture_process,len)
char    *picture;
char    *picture_process;
int 	len;
{
int     ret;
int     pd[2];
int     pd2[2];
static char * buffer = NULLCP;
char    * cp;
char	* argv[NVEC];
SFP	pstat;
ChildList *cl;

	if (buffer == NULLCP)
		 buffer = smalloc (BUFLEN);

	/* hide_picture (); */

	if (*picture == '\0')
		return ("(No data to pass !)");
	if (picture_process == NULLCP) 
		return ("(No external process defined !)");

	(void) sstr2arg (picture_process, NVEC, argv, " \t");

	/* get next two file descriptors  used for data xfer */
	ret = pipe(pd);
	if (ret == -1)
		return ("ERROR: could not create pipe");

	ret = pipe(pd2);
	if (ret == -1) {
		(void) close (pd[1]);
		(void) close (pd[0]);
		return ("ERROR: could not create 2nd pipe");
	}


	pstat = signal (SIGPIPE, SIG_IGN);

	cl = (ChildList *) malloc(sizeof(ChildList));
	/* generate one parent and one child process */
	if ((cl->childpid = fork()) == -1) {
		(void) free ((char *) cl);
		(void) close (pd[1]);
		(void) close (pd[0]);
		(void) close (pd2[1]);
		(void) close (pd2[0]);
		(void) signal (SIGPIPE, pstat);
		return ("ERROR: could not fork");
	}
	if (rootChildList == NULL)
		cl->next = NULL;
	else
		cl->next = rootChildList;
	rootChildList = cl;

	if (cl->childpid != 0) {

		/* in parent process */
		(void) close (pd[0]);
		(void) close (pd2[1]);

		if (write (pd[1], picture, len) != len) {
			(void) close (pd[1]);
			(void) close (pd2[0]);
			(void) signal (SIGPIPE, pstat);
			return("ERROR: length error");
		}

		(void) close (pd[1]);

		for (cp = buffer, len = BUFLEN - 1; len > 0;) {
			if ((ret = read (pd2[0], cp, len)) <= 0)
				break;
			cp += ret;
			len -= ret;
		}
		if (cp > buffer) {
		    if (*--cp != '\n')
			cp++;
		    *cp = NULL;
		}
		else
		    (void) sprintf (buffer, "%s invoked", argv[0]);
		
		(void) close (pd2[0]);

		(void) signal (SIGPIPE, pstat);

		if ( ret < 0 )
			return ("ERROR: read error");

		return (buffer);

	} 

		/* you're in child process */
		(void) signal (SIGPIPE, pstat);

		if (dup2(pd[0], 0) == -1)
			_exit (-1);
		(void) close (pd[0]);
		(void) close (pd[1]);

		if (dup2(pd2[1], 1) == -1)
			_exit (-1);
		(void) close (pd2[0]);
		(void) close (pd2[1]);

		(void) execv (argv[0],argv);

		while (read (0, buffer, sizeof buffer) > 0)
		    continue;
		(void) printf ("ERROR: can't execute '%s'",argv[0]);

		(void) fflush (stdout);
		/* safety catch */
		_exit (-1);
		/* NOTREACHED */
}


exec_print (ps,av,proc)
PS ps;
AttributeValue av;
char * proc;
{
char * ptr;
PS sps;
PE pe, grab_pe();

	(void) ps_flush (ps);

	if ((sps = ps_alloc (str_open)) == NULLPS)
		return;
	if (str_setup (sps,NULLCP,LINESIZE,0) == NOTOK) {
	        ps_free (sps);
		return;
	}

	pe = grab_pe (av);
	(void) pe2ps (sps,pe);

	ptr = show_picture (sps->ps_base,proc,ps_get_abs(pe));
	ps_print (ps,ptr);
	
	pe_free (pe);
	ps_free (sps);

}


hide_picture ()
{
    int	    pid;
#ifndef	BSD42
    int	status;
#else
    union wait status;
#endif
    ChildList *cl, *cl1;

	cl = rootChildList;
	while (cl != NULL) {
	    (void) kill (cl->childpid, SIGTERM);
	    while ((pid = wait (&status)) != NOTOK && cl->childpid != pid)
		continue;

	    cl1 = cl;
	    cl = cl->next;
	    (void) free((char *) cl1);
	}
	rootChildList = NULL;
}

picture_print (ps,pe,format)
PS ps;
PE pe;
int format;
{
	if (format != READOUT)
		pe_print (ps,pe,format);
	else
		ps_print (ps,"(No display process defined)");
}

quipu_pe_cmp();

photo_syntax ()
{
	(void) add_attribute_syntax ("photo",
		(IFP)pe_cpy,	NULLIFP,
		NULLIFP,	picture_print,
		(IFP)pe_cpy,	quipu_pe_cmp,
		pe_free,	NULLCP,
		NULLIFP,	TRUE );

}