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 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 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 */ 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 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