1355b4669Sjacobs /* 2355b4669Sjacobs * CDDL HEADER START 3355b4669Sjacobs * 4355b4669Sjacobs * The contents of this file are subject to the terms of the 5355b4669Sjacobs * Common Development and Distribution License (the "License"). 6355b4669Sjacobs * You may not use this file except in compliance with the License. 7355b4669Sjacobs * 8355b4669Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9355b4669Sjacobs * or http://www.opensolaris.org/os/licensing. 10355b4669Sjacobs * See the License for the specific language governing permissions 11355b4669Sjacobs * and limitations under the License. 12355b4669Sjacobs * 13355b4669Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14355b4669Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15355b4669Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16355b4669Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17355b4669Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18355b4669Sjacobs * 19355b4669Sjacobs * CDDL HEADER END 20355b4669Sjacobs */ 21355b4669Sjacobs 22355b4669Sjacobs /* 23*e059026eSKeerthi Kondaka * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24355b4669Sjacobs * Use is subject to license terms. 25355b4669Sjacobs * 26355b4669Sjacobs */ 27355b4669Sjacobs 28355b4669Sjacobs /* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */ 29355b4669Sjacobs 30355b4669Sjacobs #define __EXTENSIONS__ /* for strtok_r() */ 31355b4669Sjacobs #include <stdio.h> 32355b4669Sjacobs #include <stdlib.h> 33355b4669Sjacobs #include <unistd.h> 34355b4669Sjacobs #include <sys/types.h> 35355b4669Sjacobs #include <fcntl.h> 36355b4669Sjacobs #include <stdarg.h> 37355b4669Sjacobs #include <string.h> 38355b4669Sjacobs #include <signal.h> 39355b4669Sjacobs #include <sys/socket.h> 40355b4669Sjacobs #include <errno.h> 41355b4669Sjacobs #include <wait.h> 42355b4669Sjacobs #include <stropts.h> 43355b4669Sjacobs #include <papi_impl.h> 44355b4669Sjacobs 45355b4669Sjacobs #include <config-site.h> 46355b4669Sjacobs 47355b4669Sjacobs char * 48355b4669Sjacobs fdgets(char *buf, size_t len, int fd) 49355b4669Sjacobs { 50355b4669Sjacobs char tmp; 51355b4669Sjacobs int count = 0; 52355b4669Sjacobs 53355b4669Sjacobs memset(buf, 0, len); 54355b4669Sjacobs while ((count < len) && (read(fd, &tmp, 1) > 0)) 55355b4669Sjacobs if ((buf[count++] = tmp) == '\n') break; 56355b4669Sjacobs 57355b4669Sjacobs if (count != 0) 58355b4669Sjacobs return (buf); 59355b4669Sjacobs return (NULL); 60355b4669Sjacobs } 61355b4669Sjacobs 62355b4669Sjacobs char * 63355b4669Sjacobs queue_name_from_uri(uri_t *uri) 64355b4669Sjacobs { 65355b4669Sjacobs char *result = NULL; 66355b4669Sjacobs 67355b4669Sjacobs if ((uri != NULL) && (uri->path != NULL)) { 68355b4669Sjacobs char *ptr = strrchr(uri->path, '/'); 69355b4669Sjacobs 70355b4669Sjacobs if (ptr == NULL) 71355b4669Sjacobs result = uri->path; 72355b4669Sjacobs else 73355b4669Sjacobs result = ++ptr; 74355b4669Sjacobs } 75355b4669Sjacobs 76355b4669Sjacobs return (result); 77355b4669Sjacobs } 78355b4669Sjacobs 79355b4669Sjacobs static int 80355b4669Sjacobs recvfd(int sockfd) 81355b4669Sjacobs { 82355b4669Sjacobs int fd = -1; 83355b4669Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 84355b4669Sjacobs struct strrecvfd recv_fd; 85355b4669Sjacobs 86355b4669Sjacobs memset(&recv_fd, NULL, sizeof (recv_fd)); 87355b4669Sjacobs if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0) 88355b4669Sjacobs fd = recv_fd.fd; 89355b4669Sjacobs #else 90355b4669Sjacobs struct iovec iov[1]; 91355b4669Sjacobs struct msghdr msg; 92355b4669Sjacobs 93355b4669Sjacobs #ifdef CMSG_DATA 94355b4669Sjacobs struct cmsghdr cmp[1]; 95355b4669Sjacobs char buf[24]; /* send/recv 2 byte protocol */ 96355b4669Sjacobs 97355b4669Sjacobs memset(buf, 0, sizeof (buf)); 98355b4669Sjacobs 99355b4669Sjacobs iov[0].iov_base = buf; 100355b4669Sjacobs iov[0].iov_len = sizeof (buf); 101355b4669Sjacobs 102355b4669Sjacobs msg.msg_control = cmp; 103355b4669Sjacobs msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); 104355b4669Sjacobs #else 105355b4669Sjacobs iov[0].iov_base = NULL; 106355b4669Sjacobs iov[0].iov_len = 0; 107355b4669Sjacobs msg.msg_accrights = (caddr_t)&fd; 108355b4669Sjacobs msg.msg_accrights = sizeof (fd); 109355b4669Sjacobs #endif 110355b4669Sjacobs msg.msg_iov = iov; 111355b4669Sjacobs msg.msg_iovlen = 1; 112355b4669Sjacobs msg.msg_name = NULL; 113355b4669Sjacobs msg.msg_namelen = 0; 114355b4669Sjacobs 115355b4669Sjacobs if (recvmsg(sockfd, &msg, 0) < 0) 116355b4669Sjacobs fd = -1; 117355b4669Sjacobs #ifdef CMSG_DATA 118355b4669Sjacobs else 119355b4669Sjacobs fd = * (int *)CMSG_DATA(cmp); 120355b4669Sjacobs #endif 121355b4669Sjacobs #endif 122355b4669Sjacobs return (fd); 123355b4669Sjacobs } 124355b4669Sjacobs 125355b4669Sjacobs int 126355b4669Sjacobs lpd_open(service_t *svc, char type, char **args, int timeout) 127355b4669Sjacobs { 128355b4669Sjacobs int ac, rc = -1, fds[2]; 129355b4669Sjacobs pid_t pid; 13010144ea8Sjacobs char *av[64], *tmp, buf[BUFSIZ]; 131355b4669Sjacobs 132355b4669Sjacobs if ((svc == NULL) || (svc->uri == NULL)) 133355b4669Sjacobs return (-1); 134355b4669Sjacobs 135355b4669Sjacobs #ifndef SUID_LPD_PORT 136355b4669Sjacobs #define SUID_LPD_PORT "/usr/lib/print/lpd-port" 137355b4669Sjacobs #endif 138355b4669Sjacobs 139355b4669Sjacobs av[0] = SUID_LPD_PORT; ac = 1; 140355b4669Sjacobs 14110144ea8Sjacobs /* server */ 14210144ea8Sjacobs av[ac++] = "-H"; 14310144ea8Sjacobs av[ac++] = svc->uri->host; 14410144ea8Sjacobs 14510144ea8Sjacobs /* timeout */ 146355b4669Sjacobs if (timeout > 0) { 147355b4669Sjacobs snprintf(buf, sizeof (buf), "%d", timeout); 148355b4669Sjacobs av[ac++] = "-t"; 149355b4669Sjacobs av[ac++] = strdup(buf); 150355b4669Sjacobs } 15110144ea8Sjacobs 15210144ea8Sjacobs /* operation */ 153355b4669Sjacobs snprintf(buf, sizeof (buf), "-%c", type); 154355b4669Sjacobs av[ac++] = buf; 155355b4669Sjacobs 15610144ea8Sjacobs /* queue */ 157*e059026eSKeerthi Kondaka if (svc->uri->path == NULL) { 158*e059026eSKeerthi Kondaka tmp = ""; 159*e059026eSKeerthi Kondaka } else { 16010144ea8Sjacobs if ((tmp = strrchr(svc->uri->path, '/')) == NULL) 16110144ea8Sjacobs tmp = svc->uri->path; 16210144ea8Sjacobs else 16310144ea8Sjacobs tmp++; 164*e059026eSKeerthi Kondaka } 16510144ea8Sjacobs av[ac++] = tmp; 16610144ea8Sjacobs 16710144ea8Sjacobs /* args */ 168355b4669Sjacobs if (args != NULL) 169355b4669Sjacobs while ((*args != NULL) && (ac < 62)) 170355b4669Sjacobs av[ac++] = *args++; 171355b4669Sjacobs 172355b4669Sjacobs av[ac++] = NULL; 173355b4669Sjacobs 174355b4669Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 175355b4669Sjacobs pipe(fds); 176355b4669Sjacobs #else 177355b4669Sjacobs socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 178355b4669Sjacobs #endif 179355b4669Sjacobs 180355b4669Sjacobs switch (pid = fork()) { 181355b4669Sjacobs case -1: /* failed */ 182355b4669Sjacobs break; 183355b4669Sjacobs case 0: /* child */ 184355b4669Sjacobs dup2(fds[1], 1); 185355b4669Sjacobs execv(av[0], &av[0]); 186355b4669Sjacobs perror("exec"); 187355b4669Sjacobs exit(1); 188355b4669Sjacobs break; 189355b4669Sjacobs default: { /* parent */ 190355b4669Sjacobs int err, status = 0; 191355b4669Sjacobs 192355b4669Sjacobs while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR)); 193355b4669Sjacobs errno = WEXITSTATUS(status); 194355b4669Sjacobs 195355b4669Sjacobs if (errno == 0) 196355b4669Sjacobs rc = recvfd(fds[0]); 197355b4669Sjacobs 198355b4669Sjacobs err = errno; 199355b4669Sjacobs close(fds[0]); 200355b4669Sjacobs close(fds[1]); 201355b4669Sjacobs errno = err; 202355b4669Sjacobs } 203355b4669Sjacobs } 204355b4669Sjacobs 205355b4669Sjacobs return (rc); 206355b4669Sjacobs } 207