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 /*
23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 #include <unistd.h>
31 #include <signal.h>
32 #include <stropts.h>
33 #include <errno.h>
34 #include "lp.h"
35 #include "msgs.h"
36
37 extern int errno;
38
39 /*
40 * Putmsg() function
41 * Return 0: success,
42 * non-zero: return code of the failed putmsg() system call.
43 * plus errno for caller to check.
44 * NOTE: cannot do TRACE* calls if errno is expected to be returned!
45 * TRACE* uses fprintf and destroys the content of errno.
46 * Save errno before the TRACE* calls.
47 */
48
49 int
Putmsg(MESG * mdp,strbuf_t * ctlp,strbuf_t * datap,int flags)50 Putmsg (MESG *mdp, strbuf_t *ctlp, strbuf_t *datap, int flags)
51 {
52 int i;
53 int rtncode;
54 int count;
55 struct pollfd fds;
56
57 fds.fd = mdp->writefd;
58 fds.events = POLLOUT;
59 fds.revents = 0;
60
61 (void) poll(&fds, 1, 1000);
62 if (fds.revents & (POLLHUP | POLLERR | POLLNVAL)) {
63 errno = EBADF;
64 return (-1);
65 }
66
67 if (!(fds.revents & POLLOUT)) {
68 errno = EAGAIN;
69 return (-1);
70 }
71
72 rtncode = putmsg (mdp->writefd, ctlp, datap, flags);
73 return (rtncode);
74 }
75
76 int
Getmsg(MESG * mdp,strbuf_t * ctlp,strbuf_t * datap,int * flagsp)77 Getmsg (MESG *mdp, strbuf_t *ctlp, strbuf_t *datap, int *flagsp)
78 {
79 int rtncode;
80
81 rtncode = getmsg (mdp->readfd, ctlp, datap, flagsp);
82 return (rtncode);
83 }
84
85 char AuthCode[HEAD_AUTHCODE_LEN];
86 static void (*callers_sigpipe_trap)() = SIG_DFL;
87
88
89 /*
90 ** Function: static int read3_2( MESG *, char *, int)
91 ** Args: message descriptor
92 ** message buffer (var)
93 ** buffer size
94 ** Return: 0 for sucess, -1 for failure
95 **
96 ** This performs a 3.2 HPI style read_fifo on the pipe referanced
97 ** in the message descriptor. If a message is found, it is returned
98 ** in message buffer.
99 */
read3_2(MESG * md,char * msgbuf,int size)100 int read3_2 ( MESG * md, char *msgbuf, int size )
101 {
102 short type;
103
104 if (md->type == MD_USR_FIFO)
105 (void) Close (Open(md->file, O_RDONLY, 0));
106
107 do
108 {
109 switch (read_fifo(md->readfd, msgbuf, size))
110 {
111 case -1:
112 return (-1);
113
114 case 0:
115 /*
116 ** The fifo was empty and we have O_NDELAY set,
117 ** or the Spooler closed our FIFO.
118 ** We don't set O_NDELAY in the user process,
119 ** so that should never happen. But be warned
120 ** that we can't tell the difference in some versions
121 ** of the UNIX op. sys.!!
122 **
123 */
124 errno = EPIPE;
125 return (-1);
126 }
127
128 if ((type = stoh(msgbuf + HEAD_TYPE)) < 0 || LAST_MESSAGE < type)
129 {
130 errno = ENOMSG;
131 return (-1);
132 }
133 }
134 while (type == I_QUEUE_CHK);
135
136 (void)memcpy (AuthCode, msgbuf + HEAD_AUTHCODE, HEAD_AUTHCODE_LEN);
137
138 /*
139 ** Get the size from the 3.2 HPI message
140 ** minus the size of the control data
141 ** Copy the actual message
142 ** Reset the message size.
143 */
144 size = stoh(msgbuf + HEAD_SIZE) - EXCESS_3_2_LEN;
145 memmove(msgbuf, msgbuf + HEAD_SIZE, size);
146 (void) htos(msgbuf + MESG_SIZE, size);
147 return(0);
148 }
149
write3_2(MESG * md,char * msgbuf,int size)150 int write3_2 ( MESG * md, char * msgbuf, int size )
151 {
152 char tmpbuf [MSGMAX + EXCESS_3_2_LEN];
153 int rval;
154
155
156 (void) memmove(tmpbuf + HEAD_SIZE, msgbuf, size);
157 (void) htos(tmpbuf + HEAD_SIZE, size + EXCESS_3_2_LEN);
158 (void) memcpy (tmpbuf + HEAD_AUTHCODE, AuthCode, HEAD_AUTHCODE_LEN);
159
160 callers_sigpipe_trap = signal(SIGPIPE, SIG_IGN);
161
162 rval = write_fifo(md->writefd, tmpbuf, size + EXCESS_3_2_LEN);
163
164 (void) signal(SIGPIPE, callers_sigpipe_trap);
165
166
167 return (rval);
168 }
169