Home | History | Annotate | Download | only in lpsched
      1     0  stevel /*
      2     0  stevel  * CDDL HEADER START
      3     0  stevel  *
      4     0  stevel  * The contents of this file are subject to the terms of the
      5  3125  jacobs  * Common Development and Distribution License (the "License").
      6  3125  jacobs  * You may not use this file except in compliance with the License.
      7     0  stevel  *
      8     0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9     0  stevel  * or http://www.opensolaris.org/os/licensing.
     10     0  stevel  * See the License for the specific language governing permissions
     11     0  stevel  * and limitations under the License.
     12     0  stevel  *
     13     0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14     0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15     0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     16     0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17     0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18     0  stevel  *
     19     0  stevel  * CDDL HEADER END
     20     0  stevel  */
     21  3125  jacobs 
     22     0  stevel /*
     23  3125  jacobs  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
     24     0  stevel  * Use is subject to license terms.
     25     0  stevel  */
     26     0  stevel 
     27     0  stevel /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     28     0  stevel /*	  All Rights Reserved  	*/
     29     0  stevel 
     30     0  stevel 
     31  3125  jacobs #pragma ident	"%Z%%M%	%I%	%E% SMI"
     32     0  stevel 
     33     0  stevel # include	<stdarg.h>
     34     0  stevel # include	<limits.h>
     35     0  stevel # include	<sys/types.h>
     36     0  stevel # include	<poll.h>
     37     0  stevel # include	<stropts.h>
     38     0  stevel # include	<unistd.h>
     39     0  stevel #include <syslog.h>
     40     0  stevel 
     41     0  stevel # include	"lpsched.h"
     42     0  stevel 
     43     0  stevel #define TURN_OFF(X,F)	(void)Fcntl(X, F_SETFL, (Fcntl(X, F_GETFL, 0) & ~(F)))
     44     0  stevel 
     45     0  stevel 
     46     0  stevel static void	conn_shutdown();
     47     0  stevel 
     48     0  stevel extern int		Filter_Status;
     49     0  stevel extern void		dispatch();
     50     0  stevel extern int		Waitrequest;
     51     0  stevel void			shutdown_messages();
     52     0  stevel static char		*Message;
     53     0  stevel static int		MaxClients		= 0,
     54     0  stevel 			do_msg();
     55     0  stevel extern int		Reserve_Fds;
     56     0  stevel extern int		Shutdown;
     57     0  stevel 
     58     0  stevel MESG			*Net_md;
     59     0  stevel 
     60     0  stevel /*
     61     0  stevel ** take_message() - WAIT FOR INTERRUPT OR ONE MESSAGE FROM USER PROCESS
     62     0  stevel */
     63     0  stevel 
     64     0  stevel void take_message(void)
     65     0  stevel {
     66     0  stevel     int		bytes;
     67  3125  jacobs     int		i;
     68     0  stevel     MESG *	md;
     69     0  stevel 
     70     0  stevel     for (EVER) {	/* not really forever...returns are in the loop */
     71     0  stevel 	if ((md = mlisten()) == NULL)
     72     0  stevel 	    switch(errno) {
     73     0  stevel 	      case EAGAIN:
     74     0  stevel 	      case EINTR:
     75     0  stevel 		return;
     76     0  stevel 
     77     0  stevel 	      case ENOMEM:
     78     0  stevel 		mallocfail();
     79     0  stevel 		/* NOTREACHED */
     80     0  stevel 
     81     0  stevel 	      default:
     82     0  stevel 		fail ("Unexpected streams error in mlisten (%s).\n" , PERROR);
     83     0  stevel 	    }
     84     0  stevel 
     85     0  stevel 	/*
     86     0  stevel 	 * Check for a dropped connection to a child.
     87     0  stevel 	 * Normally a child should tell us that it is dying
     88     0  stevel 	 * (with S_SHUTDOWN or S_SEND_CHILD), but it may have
     89     0  stevel 	 * died a fast death. We'll simulate the message we
     90     0  stevel 	 * wanted to get so we can use the same code to clean up.
     91     0  stevel 	 */
     92     0  stevel 	if ((md->event & POLLHUP) && !(md->event & POLLIN) ||
     93     0  stevel 	    (md->event & (POLLERR|POLLNVAL))) {
     94     0  stevel 		switch (md->type) {
     95     0  stevel 
     96     0  stevel 		case MD_CHILD:
     97     0  stevel 			/*
     98     0  stevel 			 * If the message descriptor is found in the
     99     0  stevel 			 * exec table, it must be an interface pgm,
    100     0  stevel 			 * notification, etc. Otherwise, it must be
    101     0  stevel 			 * a network child.
    102     0  stevel 			 */
    103  3125  jacobs 			for (i = 0; Exec_Table[i] != NULL; i++)
    104  3125  jacobs 				if (Exec_Table[i]->md == md)
    105     0  stevel 					break;
    106     0  stevel 
    107  3125  jacobs 			if (Exec_Table[i] != NULL) {
    108     0  stevel 				(void) putmessage(Message, S_CHILD_DONE,
    109  3125  jacobs 					Exec_Table[i]->key, 0, 0);
    110     0  stevel 			} else {
    111     0  stevel 				(void) putmessage(Message, S_SHUTDOWN, 1);
    112     0  stevel 			}
    113     0  stevel 			bytes = 1;
    114     0  stevel 			break;
    115     0  stevel 
    116     0  stevel 		default:
    117     0  stevel 			bytes = -1;
    118     0  stevel 			break;
    119     0  stevel 
    120     0  stevel 		}
    121     0  stevel 
    122     0  stevel 	} else {
    123     0  stevel 		if (md->readfd == -1) { /* something happened to the readfd */
    124     0  stevel 			syslog(LOG_DEBUG, "take_message: readfd is -1");
    125     0  stevel 			return;
    126     0  stevel 		}
    127     0  stevel 		bytes = mread(md, Message, MSGMAX);
    128     0  stevel 	}
    129     0  stevel 
    130     0  stevel 	switch (bytes) {
    131     0  stevel 	  case -1:
    132     0  stevel 	    if (errno == EINTR)
    133     0  stevel 		return;
    134     0  stevel 	    else
    135     0  stevel 		fail ("Unexpected streams error (%s).\n" , PERROR);
    136     0  stevel 	    break;
    137     0  stevel 
    138     0  stevel 	  case 0:
    139     0  stevel 	    break;
    140     0  stevel 
    141     0  stevel 	  default:
    142     0  stevel 	    if (do_msg(md))
    143     0  stevel 		return;
    144     0  stevel 	    break;
    145     0  stevel 	}
    146     0  stevel     }
    147     0  stevel }
    148     0  stevel 
    149     0  stevel /*
    150     0  stevel ** do_msg() - HANDLE AN INCOMING MESSAGE
    151     0  stevel */
    152     0  stevel 
    153     0  stevel static int
    154     0  stevel do_msg(MESG *md)
    155     0  stevel {
    156     0  stevel     int			type = mtype(Message);
    157     0  stevel 
    158     0  stevel     if (type != S_GOODBYE) {
    159     0  stevel 	    md->wait = 0;
    160     0  stevel 	    dispatch (type, Message, md);
    161     0  stevel 	    /*
    162     0  stevel 	     * The message may have caused the need to
    163     0  stevel 	     * schedule something, so go back and check.
    164     0  stevel 	     */
    165     0  stevel 	    return(1);
    166     0  stevel     }
    167     0  stevel     return(0);
    168     0  stevel }
    169     0  stevel 
    170     0  stevel /*
    171     0  stevel ** calculate_nopen() - DETERMINE # FILE DESCRIPTORS AVAILABLE FOR QUEUES
    172     0  stevel */
    173     0  stevel 
    174     0  stevel static void
    175     0  stevel calculate_nopen(void)
    176     0  stevel {
    177     0  stevel     int		fd, nopen;
    178     0  stevel 
    179     0  stevel     /*
    180     0  stevel      * How many file descriptorss are currently being used?
    181     0  stevel      */
    182     0  stevel     for (fd = nopen = 0; fd < OpenMax; fd++)
    183     0  stevel 	if (fcntl(fd, F_GETFL, 0) != -1)
    184     0  stevel 	    nopen++;
    185     0  stevel 
    186     0  stevel     /*
    187     0  stevel      * How many file descriptors are available for use
    188     0  stevel      * as open FIFOs? Leave one spare as a way to tell
    189     0  stevel      * clients we don't have any to spare (hmmm....) and
    190     0  stevel      * one for the incoming fifo.
    191     0  stevel      */
    192     0  stevel 
    193     0  stevel     MaxClients = OpenMax;
    194     0  stevel     MaxClients -= nopen;	/* current overhead */
    195     0  stevel     MaxClients -= Reserve_Fds;
    196     0  stevel     MaxClients -= 2;		/* incoming FIFO and spare outgoing */
    197     0  stevel     MaxClients--;		/* the requests log */
    198     0  stevel     MaxClients--;		/* HPI routines and lpsched log */
    199     0  stevel 
    200     0  stevel     return;
    201     0  stevel }
    202     0  stevel 
    203     0  stevel static void conn_shutdown ( )
    204     0  stevel {
    205     0  stevel     if (!Shutdown) {
    206     0  stevel 	note ("The public connection \"%s\", has failed.\n", Lp_FIFO);
    207     0  stevel 	lpshut(1);
    208     0  stevel     }
    209     0  stevel }
    210     0  stevel 
    211     0  stevel /*
    212     0  stevel ** init_messages() - INITIALIZE MAIN MESSAGE QUEUE
    213     0  stevel */
    214     0  stevel 
    215     0  stevel void
    216     0  stevel init_messages(void)
    217     0  stevel {
    218     0  stevel     char	*cmd;
    219     0  stevel     MESG *	md;
    220     0  stevel 
    221     0  stevel     (void) signal(SIGPIPE, SIG_IGN);
    222     0  stevel 
    223     0  stevel     calculate_nopen ();
    224     0  stevel 
    225     0  stevel     Message = (char *)Malloc(MSGMAX);
    226     0  stevel 
    227     0  stevel     (void) Chmod(Lp_Tmp, 0711);
    228     0  stevel 
    229     0  stevel     if ((md = mcreate(Lp_FIFO)) == NULL)
    230     0  stevel 	fail ("Can't create public message device (%s).\n", PERROR);
    231     0  stevel     mon_discon(md, conn_shutdown);
    232     0  stevel 
    233     0  stevel     if (mlisteninit(md) != 0)
    234     0  stevel 	if (errno == ENOMEM)
    235     0  stevel 	    mallocfail();
    236     0  stevel 	else
    237     0  stevel 	    fail ("Unexpected streams error (%s).\n" , PERROR);
    238     0  stevel 
    239     0  stevel     (void) Chmod(Lp_FIFO, 0666);
    240     0  stevel     return;
    241     0  stevel }
    242     0  stevel 
    243     0  stevel 
    244     0  stevel void
    245     0  stevel shutdown_messages(void)
    246     0  stevel {
    247     0  stevel     MESG	*md;
    248     0  stevel 
    249     0  stevel     (void) Chmod(Lp_Tmp, 0700);
    250     0  stevel     (void) Chmod(Lp_FIFO, 0600);
    251     0  stevel     md = mlistenreset();
    252     0  stevel     mdestroy(md);
    253     0  stevel }
    254