12264Sjacobs /* 22264Sjacobs * CDDL HEADER START 32264Sjacobs * 42264Sjacobs * The contents of this file are subject to the terms of the 52264Sjacobs * Common Development and Distribution License (the "License"). 62264Sjacobs * You may not use this file except in compliance with the License. 72264Sjacobs * 82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92264Sjacobs * or http://www.opensolaris.org/os/licensing. 102264Sjacobs * See the License for the specific language governing permissions 112264Sjacobs * and limitations under the License. 122264Sjacobs * 132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 182264Sjacobs * 192264Sjacobs * CDDL HEADER END 202264Sjacobs */ 212264Sjacobs 222264Sjacobs /* 23*4275Sjacobs * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 242264Sjacobs * Use is subject to license terms. 252264Sjacobs * 262264Sjacobs */ 272264Sjacobs 282264Sjacobs /* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */ 292264Sjacobs 302264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 312264Sjacobs 322264Sjacobs #define __EXTENSIONS__ /* for strtok_r() */ 332264Sjacobs #include <stdio.h> 342264Sjacobs #include <stdlib.h> 352264Sjacobs #include <unistd.h> 362264Sjacobs #include <sys/types.h> 372264Sjacobs #include <fcntl.h> 382264Sjacobs #include <stdarg.h> 392264Sjacobs #include <string.h> 402264Sjacobs #include <signal.h> 412264Sjacobs #include <sys/socket.h> 422264Sjacobs #include <errno.h> 432264Sjacobs #include <wait.h> 442264Sjacobs #include <stropts.h> 452264Sjacobs #include <papi_impl.h> 462264Sjacobs 472264Sjacobs #include <config-site.h> 482264Sjacobs 492264Sjacobs char * 502264Sjacobs fdgets(char *buf, size_t len, int fd) 512264Sjacobs { 522264Sjacobs char tmp; 532264Sjacobs int count = 0; 542264Sjacobs 552264Sjacobs memset(buf, 0, len); 562264Sjacobs while ((count < len) && (read(fd, &tmp, 1) > 0)) 572264Sjacobs if ((buf[count++] = tmp) == '\n') break; 582264Sjacobs 592264Sjacobs if (count != 0) 602264Sjacobs return (buf); 612264Sjacobs return (NULL); 622264Sjacobs } 632264Sjacobs 642264Sjacobs char * 652264Sjacobs queue_name_from_uri(uri_t *uri) 662264Sjacobs { 672264Sjacobs char *result = NULL; 682264Sjacobs 692264Sjacobs if ((uri != NULL) && (uri->path != NULL)) { 702264Sjacobs char *ptr = strrchr(uri->path, '/'); 712264Sjacobs 722264Sjacobs if (ptr == NULL) 732264Sjacobs result = uri->path; 742264Sjacobs else 752264Sjacobs result = ++ptr; 762264Sjacobs } 772264Sjacobs 782264Sjacobs return (result); 792264Sjacobs } 802264Sjacobs 812264Sjacobs static int 822264Sjacobs recvfd(int sockfd) 832264Sjacobs { 842264Sjacobs int fd = -1; 852264Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 862264Sjacobs struct strrecvfd recv_fd; 872264Sjacobs 882264Sjacobs memset(&recv_fd, NULL, sizeof (recv_fd)); 892264Sjacobs if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0) 902264Sjacobs fd = recv_fd.fd; 912264Sjacobs #else 922264Sjacobs struct iovec iov[1]; 932264Sjacobs struct msghdr msg; 942264Sjacobs 952264Sjacobs #ifdef CMSG_DATA 962264Sjacobs struct cmsghdr cmp[1]; 972264Sjacobs char buf[24]; /* send/recv 2 byte protocol */ 982264Sjacobs 992264Sjacobs memset(buf, 0, sizeof (buf)); 1002264Sjacobs 1012264Sjacobs iov[0].iov_base = buf; 1022264Sjacobs iov[0].iov_len = sizeof (buf); 1032264Sjacobs 1042264Sjacobs msg.msg_control = cmp; 1052264Sjacobs msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); 1062264Sjacobs #else 1072264Sjacobs iov[0].iov_base = NULL; 1082264Sjacobs iov[0].iov_len = 0; 1092264Sjacobs msg.msg_accrights = (caddr_t)&fd; 1102264Sjacobs msg.msg_accrights = sizeof (fd); 1112264Sjacobs #endif 1122264Sjacobs msg.msg_iov = iov; 1132264Sjacobs msg.msg_iovlen = 1; 1142264Sjacobs msg.msg_name = NULL; 1152264Sjacobs msg.msg_namelen = 0; 1162264Sjacobs 1172264Sjacobs if (recvmsg(sockfd, &msg, 0) < 0) 1182264Sjacobs fd = -1; 1192264Sjacobs #ifdef CMSG_DATA 1202264Sjacobs else 1212264Sjacobs fd = * (int *)CMSG_DATA(cmp); 1222264Sjacobs #endif 1232264Sjacobs #endif 1242264Sjacobs return (fd); 1252264Sjacobs } 1262264Sjacobs 1272264Sjacobs int 1282264Sjacobs lpd_open(service_t *svc, char type, char **args, int timeout) 1292264Sjacobs { 1302264Sjacobs int ac, rc = -1, fds[2]; 1312264Sjacobs pid_t pid; 132*4275Sjacobs char *av[64], *tmp, buf[BUFSIZ]; 1332264Sjacobs 1342264Sjacobs if ((svc == NULL) || (svc->uri == NULL)) 1352264Sjacobs return (-1); 1362264Sjacobs 1372264Sjacobs #ifndef SUID_LPD_PORT 1382264Sjacobs #define SUID_LPD_PORT "/usr/lib/print/lpd-port" 1392264Sjacobs #endif 1402264Sjacobs 1412264Sjacobs av[0] = SUID_LPD_PORT; ac = 1; 1422264Sjacobs 143*4275Sjacobs /* server */ 144*4275Sjacobs av[ac++] = "-H"; 145*4275Sjacobs av[ac++] = svc->uri->host; 146*4275Sjacobs 147*4275Sjacobs /* timeout */ 1482264Sjacobs if (timeout > 0) { 1492264Sjacobs snprintf(buf, sizeof (buf), "%d", timeout); 1502264Sjacobs av[ac++] = "-t"; 1512264Sjacobs av[ac++] = strdup(buf); 1522264Sjacobs } 153*4275Sjacobs 154*4275Sjacobs /* operation */ 1552264Sjacobs snprintf(buf, sizeof (buf), "-%c", type); 1562264Sjacobs av[ac++] = buf; 1572264Sjacobs 158*4275Sjacobs /* queue */ 159*4275Sjacobs if ((tmp = strrchr(svc->uri->path, '/')) == NULL) 160*4275Sjacobs tmp = svc->uri->path; 161*4275Sjacobs else 162*4275Sjacobs tmp++; 163*4275Sjacobs av[ac++] = tmp; 164*4275Sjacobs 165*4275Sjacobs /* args */ 1662264Sjacobs if (args != NULL) 1672264Sjacobs while ((*args != NULL) && (ac < 62)) 1682264Sjacobs av[ac++] = *args++; 1692264Sjacobs 1702264Sjacobs av[ac++] = NULL; 1712264Sjacobs 1722264Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 1732264Sjacobs pipe(fds); 1742264Sjacobs #else 1752264Sjacobs socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 1762264Sjacobs #endif 1772264Sjacobs 1782264Sjacobs switch (pid = fork()) { 1792264Sjacobs case -1: /* failed */ 1802264Sjacobs break; 1812264Sjacobs case 0: /* child */ 1822264Sjacobs dup2(fds[1], 1); 1832264Sjacobs execv(av[0], &av[0]); 1842264Sjacobs perror("exec"); 1852264Sjacobs exit(1); 1862264Sjacobs break; 1872264Sjacobs default: { /* parent */ 1882264Sjacobs int err, status = 0; 1892264Sjacobs 1902264Sjacobs while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR)); 1912264Sjacobs errno = WEXITSTATUS(status); 1922264Sjacobs 1932264Sjacobs if (errno == 0) 1942264Sjacobs rc = recvfd(fds[0]); 1952264Sjacobs 1962264Sjacobs err = errno; 1972264Sjacobs close(fds[0]); 1982264Sjacobs close(fds[1]); 1992264Sjacobs errno = err; 2002264Sjacobs } 2012264Sjacobs } 2022264Sjacobs 2032264Sjacobs return (rc); 2042264Sjacobs } 205