1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23/*	  All Rights Reserved  	*/
24
25
26#ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.6	*/
27/* LINTLIBRARY */
28
29
30#include <errno.h>
31#include <fcntl.h>
32#include <string.h>
33#include <stropts.h>
34
35#include "lp.h"
36#include "msgs.h"
37
38extern int	Lp_prio_msg;
39
40/*
41**	Function:	int mread( MESG *, char *, int)
42**	Args:		message descriptor
43**			message buffer (var)
44**			buffer size
45**	Return:		The size of the message in message buffer.
46**			or -1 on error.  Possible errnos are:
47**		EINVAL	Bad value for md or msgbuf.
48**		E2BIG	Not enough space for message.
49**		EPIPE	Far end dropped the connection.
50**		ENOMSG	No valid message available on fifo.
51**
52**	mread examines message descriptor and either calls read3_2
53**	to read 3.2 HPI messages or getmsg(2) to read 4.0 HPI messages.
54**	If a message is read, it is returned in message buffer.
55*/
56
57#if	defined(__STDC__)
58int mread ( MESG * md, char * msgbuf, int size )
59#else
60int mread ( md, msgbuf, size )
61MESG	*md;
62char	*msgbuf;
63int	size;
64#endif
65{
66    int			flag = 0;
67    char		buff [MSGMAX];
68    struct strbuf	dat;
69    struct strbuf	ctl;
70
71    if (md == NULL || msgbuf == NULL)
72    {
73	errno = EINVAL;
74	return(-1);
75    }
76
77    switch(md->type)
78    {
79      case MD_CHILD:
80      case MD_STREAM:
81      case MD_BOUND:
82	if (size <= 0)
83	{
84	    errno = E2BIG;
85	    return(-1);
86	}
87	dat.buf = msgbuf;
88	dat.maxlen = size;
89	dat.len = 0;
90	ctl.buf = buff;
91	ctl.maxlen = sizeof (buff);
92	ctl.len = 0;
93	flag = Lp_prio_msg;
94	Lp_prio_msg = 0;	/* clean this up so there are no surprises */
95
96	if (Getmsg(md, &ctl, &dat, &flag) < 0)
97	{
98	    if (errno == EBADF)
99		errno = EPIPE;
100	    return(-1);
101	}
102
103	if (dat.len == 0)
104	{
105	    (void) Close(md->readfd);
106	    return(0);
107	}
108	break;
109
110      case MD_USR_FIFO:
111      case MD_SYS_FIFO:
112	if (size < CONTROL_LEN)
113	{
114	    errno = E2BIG;
115	    return(-1);
116	}
117
118	if (read3_2(md, msgbuf, size) < 0)
119	    return(-1);
120	break;
121    }
122
123    return((int)msize(msgbuf));
124}
125