1*2264Sjacobs /* 2*2264Sjacobs * CDDL HEADER START 3*2264Sjacobs * 4*2264Sjacobs * The contents of this file are subject to the terms of the 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * You may not use this file except in compliance with the License. 7*2264Sjacobs * 8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2264Sjacobs * or http://www.opensolaris.org/os/licensing. 10*2264Sjacobs * See the License for the specific language governing permissions 11*2264Sjacobs * and limitations under the License. 12*2264Sjacobs * 13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18*2264Sjacobs * 19*2264Sjacobs * CDDL HEADER END 20*2264Sjacobs */ 21*2264Sjacobs 22*2264Sjacobs /* 23*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2264Sjacobs * Use is subject to license terms. 25*2264Sjacobs * 26*2264Sjacobs */ 27*2264Sjacobs 28*2264Sjacobs /* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */ 29*2264Sjacobs 30*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31*2264Sjacobs 32*2264Sjacobs #define __EXTENSIONS__ /* for strtok_r() */ 33*2264Sjacobs #include <stdio.h> 34*2264Sjacobs #include <stdlib.h> 35*2264Sjacobs #include <unistd.h> 36*2264Sjacobs #include <sys/types.h> 37*2264Sjacobs #include <fcntl.h> 38*2264Sjacobs #include <stdarg.h> 39*2264Sjacobs #include <string.h> 40*2264Sjacobs #include <signal.h> 41*2264Sjacobs #include <sys/socket.h> 42*2264Sjacobs #include <errno.h> 43*2264Sjacobs #include <wait.h> 44*2264Sjacobs #include <stropts.h> 45*2264Sjacobs #include <papi_impl.h> 46*2264Sjacobs 47*2264Sjacobs #include <config-site.h> 48*2264Sjacobs 49*2264Sjacobs char * 50*2264Sjacobs fdgets(char *buf, size_t len, int fd) 51*2264Sjacobs { 52*2264Sjacobs char tmp; 53*2264Sjacobs int count = 0; 54*2264Sjacobs 55*2264Sjacobs memset(buf, 0, len); 56*2264Sjacobs while ((count < len) && (read(fd, &tmp, 1) > 0)) 57*2264Sjacobs if ((buf[count++] = tmp) == '\n') break; 58*2264Sjacobs 59*2264Sjacobs if (count != 0) 60*2264Sjacobs return (buf); 61*2264Sjacobs return (NULL); 62*2264Sjacobs } 63*2264Sjacobs 64*2264Sjacobs char * 65*2264Sjacobs queue_name_from_uri(uri_t *uri) 66*2264Sjacobs { 67*2264Sjacobs char *result = NULL; 68*2264Sjacobs 69*2264Sjacobs if ((uri != NULL) && (uri->path != NULL)) { 70*2264Sjacobs char *ptr = strrchr(uri->path, '/'); 71*2264Sjacobs 72*2264Sjacobs if (ptr == NULL) 73*2264Sjacobs result = uri->path; 74*2264Sjacobs else 75*2264Sjacobs result = ++ptr; 76*2264Sjacobs } 77*2264Sjacobs 78*2264Sjacobs return (result); 79*2264Sjacobs } 80*2264Sjacobs 81*2264Sjacobs static int 82*2264Sjacobs recvfd(int sockfd) 83*2264Sjacobs { 84*2264Sjacobs int fd = -1; 85*2264Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 86*2264Sjacobs struct strrecvfd recv_fd; 87*2264Sjacobs 88*2264Sjacobs memset(&recv_fd, NULL, sizeof (recv_fd)); 89*2264Sjacobs if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0) 90*2264Sjacobs fd = recv_fd.fd; 91*2264Sjacobs #else 92*2264Sjacobs struct iovec iov[1]; 93*2264Sjacobs struct msghdr msg; 94*2264Sjacobs 95*2264Sjacobs #ifdef CMSG_DATA 96*2264Sjacobs struct cmsghdr cmp[1]; 97*2264Sjacobs char buf[24]; /* send/recv 2 byte protocol */ 98*2264Sjacobs 99*2264Sjacobs memset(buf, 0, sizeof (buf)); 100*2264Sjacobs 101*2264Sjacobs iov[0].iov_base = buf; 102*2264Sjacobs iov[0].iov_len = sizeof (buf); 103*2264Sjacobs 104*2264Sjacobs msg.msg_control = cmp; 105*2264Sjacobs msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); 106*2264Sjacobs #else 107*2264Sjacobs iov[0].iov_base = NULL; 108*2264Sjacobs iov[0].iov_len = 0; 109*2264Sjacobs msg.msg_accrights = (caddr_t)&fd; 110*2264Sjacobs msg.msg_accrights = sizeof (fd); 111*2264Sjacobs #endif 112*2264Sjacobs msg.msg_iov = iov; 113*2264Sjacobs msg.msg_iovlen = 1; 114*2264Sjacobs msg.msg_name = NULL; 115*2264Sjacobs msg.msg_namelen = 0; 116*2264Sjacobs 117*2264Sjacobs if (recvmsg(sockfd, &msg, 0) < 0) 118*2264Sjacobs fd = -1; 119*2264Sjacobs #ifdef CMSG_DATA 120*2264Sjacobs else 121*2264Sjacobs fd = * (int *)CMSG_DATA(cmp); 122*2264Sjacobs #endif 123*2264Sjacobs #endif 124*2264Sjacobs return (fd); 125*2264Sjacobs } 126*2264Sjacobs 127*2264Sjacobs int 128*2264Sjacobs lpd_open(service_t *svc, char type, char **args, int timeout) 129*2264Sjacobs { 130*2264Sjacobs int ac, rc = -1, fds[2]; 131*2264Sjacobs pid_t pid; 132*2264Sjacobs char *av[64], buf[BUFSIZ]; 133*2264Sjacobs 134*2264Sjacobs if ((svc == NULL) || (svc->uri == NULL)) 135*2264Sjacobs return (-1); 136*2264Sjacobs 137*2264Sjacobs #ifndef SUID_LPD_PORT 138*2264Sjacobs #define SUID_LPD_PORT "/usr/lib/print/lpd-port" 139*2264Sjacobs #endif 140*2264Sjacobs 141*2264Sjacobs av[0] = SUID_LPD_PORT; ac = 1; 142*2264Sjacobs uri_to_string(svc->uri, buf, sizeof (buf)); 143*2264Sjacobs av[ac++] = "-u"; 144*2264Sjacobs av[ac++] = strdup(buf); 145*2264Sjacobs 146*2264Sjacobs if (timeout > 0) { 147*2264Sjacobs snprintf(buf, sizeof (buf), "%d", timeout); 148*2264Sjacobs av[ac++] = "-t"; 149*2264Sjacobs av[ac++] = strdup(buf); 150*2264Sjacobs } 151*2264Sjacobs snprintf(buf, sizeof (buf), "-%c", type); 152*2264Sjacobs av[ac++] = buf; 153*2264Sjacobs 154*2264Sjacobs if (args != NULL) 155*2264Sjacobs while ((*args != NULL) && (ac < 62)) 156*2264Sjacobs av[ac++] = *args++; 157*2264Sjacobs 158*2264Sjacobs av[ac++] = NULL; 159*2264Sjacobs 160*2264Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 161*2264Sjacobs pipe(fds); 162*2264Sjacobs #else 163*2264Sjacobs socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 164*2264Sjacobs #endif 165*2264Sjacobs 166*2264Sjacobs switch (pid = fork()) { 167*2264Sjacobs case -1: /* failed */ 168*2264Sjacobs break; 169*2264Sjacobs case 0: /* child */ 170*2264Sjacobs dup2(fds[1], 1); 171*2264Sjacobs execv(av[0], &av[0]); 172*2264Sjacobs perror("exec"); 173*2264Sjacobs exit(1); 174*2264Sjacobs break; 175*2264Sjacobs default: { /* parent */ 176*2264Sjacobs int err, status = 0; 177*2264Sjacobs 178*2264Sjacobs while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR)); 179*2264Sjacobs errno = WEXITSTATUS(status); 180*2264Sjacobs 181*2264Sjacobs if (errno == 0) 182*2264Sjacobs rc = recvfd(fds[0]); 183*2264Sjacobs 184*2264Sjacobs err = errno; 185*2264Sjacobs close(fds[0]); 186*2264Sjacobs close(fds[1]); 187*2264Sjacobs errno = err; 188*2264Sjacobs } 189*2264Sjacobs } 190*2264Sjacobs 191*2264Sjacobs return (rc); 192*2264Sjacobs } 193