/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9 */
# include <unistd.h>
# include <stdlib.h>
# include <string.h>
# include <poll.h>
# include <stropts.h>
# include <fcntl.h>
# include <errno.h>
#include <syslog.h>
#include <user_attr.h>
#include <secdb.h>
#include <pwd.h>
# include "lp.h"
# include "msgs.h"
static int NumEvents = 0;
static int NumCons = 0;
static int ConsSize= 0;
static int NumNewCons = 0;
int
{
{
return(-1);
}
if (ConsSize > 0)
{
return(-1);
}
ConsSize = 20;
{
return(-1);
}
Connections[0] = md;
PollFdList[0].revents = 0;
NumCons = 1;
return(0);
}
int
{
int slack;
/*
** See if we have room in the connection table.
** Realloc(3) the table if the number of connections
** changes by more than 20.
*/
if (slack < 0)
{
ConsSize += 20;
{
return(-1);
}
}
if (slack > 20)
{
ConsSize -= 20;
{
return(-1);
}
}
/*
** Now add the entry to the connection table
** NumCons will be updated above.
*/
return(0);
}
MESG *
{
int x;
if (ConsSize == 0)
return(NULL);
ConsSize = 0;
for (x = 1; x < NumCons; x++)
(void) mdisconnect(Connections[x]);
md = Connections[0];
Connections = NULL;
PollFdList = NULL;
NumCons = 0;
NumNewCons = 0;
NumEvents = 0;
return(md);
}
MESG *
mlisten()
{
MQUE * p;
int flag = 0;
int disconacts;
int x;
int y;
#if defined(NOCONNLD)
#endif
#if defined(NOCONNLD)
/*
** Set up buffer for receiving messages.
*/
#endif
/*
** This loop exists to return control to poll after the
** result of poll yeilds no new connections or serviceable
** messages.
*/
for (;;)
{
/*
** If there are no unserviced events pending, call poll(2)
** and wait for a message or connection.
** NumEvents may be -1 in the event of an interrupt, hence
** <= 0
*/
if (NumEvents <= 0)
{
/*
** Add new connections, if any, reset connection counter
*/
NumCons += NumNewCons;
NumNewCons = 0;
if (NumCons <= 0)
{
return(NULL);
}
/*
** Scan the connection table and remove any holes
*/
for (x = 0; x < NumCons; x++)
{
mdp = Connections[x];
/*
** Disconnected, clear the node and compress the
** tables. If the disconnect called any
** on_discon functions (disconacts > 0), return
** because there may be something to clean up.
** Finally, decrement <x> so that the next node
** doesn't get missed.
*/
{
NumCons--;
for (y = x; y < (NumCons + NumNewCons); y++)
{
}
if (disconacts > 0)
{
return(NULL);
}
else
x--;
} else {
/*
* We are in "mlisten", POLLIN is always set. We'll look
* at POLLOUT possibility when mque is non-NULL.
*/
}
}
/*
** Wait for a message or a connection.
** This call may be interrupted by alarms used
** elsewhere, so if poll fails, return NULL and
** set errno to EAGAIN.
*/
{
return(NULL);
}
}
for (x = 0; x < NumCons; x++)
{
mdp = Connections[x];
fdp = PollFdList + x;
continue;
case MD_MASTER:
/*
** Only valid revent is: POLLIN
*/
{
return(NULL);
}
/*
** Retrieve the file descriptor
*/
{
{
return(NULL);
}
{
NumEvents--;
continue;
}
#if defined(NOCONNLD)
#endif
return(NULL);
}
/*
** Now, create the message descriptor
** and populate it with what we know.
*/
{
return(NULL);
}
/*
* Determine if a print administrator is contacting lpsched.
* currently, root, lp and users with the "solaris.print.admin"
* privilege are print administrators
*/
}
return(NULL);
/*
** Reset fdp because mlistenadd may have
** realloc()ed PollFdList and changed its
** physical location.
*/
fdp = PollFdList + x;
/*
** Clear the event that brought us here,
** decrement the event counter, and get the
** next event.
*/
NumEvents--;
break;
case MD_CHILD:
/*
** If this connection is a child process, just
** save the event and return the message descriptor
*/
"MD_CHILD mflush failed");
}
}
}
NumEvents--;
return (mdp); /* we are in listening mode */
}
NumEvents--;
break;
default:
/*
** POLLNVAL means this client disconnected and
** all messages have been processed.
*/
{
}
NumEvents--;
continue;
}
/*
** POLLERR means an error message is on the
** stream. Since this is totally unexpected,
** the assumption is made that this stream will
** be flagged POLLNVAL next time through poll
** and will be removed at that time.
*/
{
}
NumEvents--;
continue;
}
/*
** POLLHUP means the client aborted the call.
** The client is not removed, because there may
** still be messages on the stream.
*/
{
NumEvents--;
/*
* MORE: This is odd. Why are we closing the
* stream if there ``may still be messages''???
*/
}
continue;
/*
* MORE: Why is this here??
*
if (mdp->type == MD_SYS_FIFO)
(void) Close(mdp->writefd);
mdp->writefd = -1;
if (fdp->revents == POLLHUP)
{
NumEvents--;
fdp->revents = 0;
(void) Close(mdp->readfd);
mdp->readfd = -1;
continue;
}
*
*/
}
/*
** POLLOUT means that the client had a full
** stream and messages became backlogged and
** now the stream is empty. So the queued msgs
** are sent with putmsg(2)
*/
{
{
NumEvents--;
continue;
}
break; /* failed for some reason */
Free(p);
}
NumEvents--;
continue;
}
/*
** POLLIN means that there is a message on the
** stream.
** Return the message descriptor to the caller
** so that the message may be received and
** processed.
*/
{
NumEvents--;
return(mdp);
}
break;
}
}
}
}
# define VOID_FUNC_PTR void (*)()
# define PTR_TO_VOID_FUNC_PTR void (**)()
int
{
void (**fnp) ();
{
size++;
if ((md->on_discon = (PTR_TO_VOID_FUNC_PTR) Realloc (md->on_discon, size * sizeof(VOID_FUNC_PTR))) == NULL)
{
return(-1);
}
}
else
{
return(-1);
}
size--;
size--;
return(0);
}