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*9411SKeerthi.Kondaka@Sun.COM * Copyright 2009 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 #define __EXTENSIONS__ /* for strtok_r() */ 312264Sjacobs #include <stdio.h> 322264Sjacobs #include <stdlib.h> 332264Sjacobs #include <unistd.h> 342264Sjacobs #include <sys/types.h> 352264Sjacobs #include <fcntl.h> 362264Sjacobs #include <stdarg.h> 372264Sjacobs #include <string.h> 382264Sjacobs #include <signal.h> 392264Sjacobs #include <sys/socket.h> 402264Sjacobs #include <errno.h> 412264Sjacobs #include <wait.h> 422264Sjacobs #include <stropts.h> 432264Sjacobs #include <papi_impl.h> 442264Sjacobs 452264Sjacobs #include <config-site.h> 462264Sjacobs 472264Sjacobs char * 482264Sjacobs fdgets(char *buf, size_t len, int fd) 492264Sjacobs { 502264Sjacobs char tmp; 512264Sjacobs int count = 0; 522264Sjacobs 532264Sjacobs memset(buf, 0, len); 542264Sjacobs while ((count < len) && (read(fd, &tmp, 1) > 0)) 552264Sjacobs if ((buf[count++] = tmp) == '\n') break; 562264Sjacobs 572264Sjacobs if (count != 0) 582264Sjacobs return (buf); 592264Sjacobs return (NULL); 602264Sjacobs } 612264Sjacobs 622264Sjacobs char * 632264Sjacobs queue_name_from_uri(uri_t *uri) 642264Sjacobs { 652264Sjacobs char *result = NULL; 662264Sjacobs 672264Sjacobs if ((uri != NULL) && (uri->path != NULL)) { 682264Sjacobs char *ptr = strrchr(uri->path, '/'); 692264Sjacobs 702264Sjacobs if (ptr == NULL) 712264Sjacobs result = uri->path; 722264Sjacobs else 732264Sjacobs result = ++ptr; 742264Sjacobs } 752264Sjacobs 762264Sjacobs return (result); 772264Sjacobs } 782264Sjacobs 792264Sjacobs static int 802264Sjacobs recvfd(int sockfd) 812264Sjacobs { 822264Sjacobs int fd = -1; 832264Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 842264Sjacobs struct strrecvfd recv_fd; 852264Sjacobs 862264Sjacobs memset(&recv_fd, NULL, sizeof (recv_fd)); 872264Sjacobs if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0) 882264Sjacobs fd = recv_fd.fd; 892264Sjacobs #else 902264Sjacobs struct iovec iov[1]; 912264Sjacobs struct msghdr msg; 922264Sjacobs 932264Sjacobs #ifdef CMSG_DATA 942264Sjacobs struct cmsghdr cmp[1]; 952264Sjacobs char buf[24]; /* send/recv 2 byte protocol */ 962264Sjacobs 972264Sjacobs memset(buf, 0, sizeof (buf)); 982264Sjacobs 992264Sjacobs iov[0].iov_base = buf; 1002264Sjacobs iov[0].iov_len = sizeof (buf); 1012264Sjacobs 1022264Sjacobs msg.msg_control = cmp; 1032264Sjacobs msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); 1042264Sjacobs #else 1052264Sjacobs iov[0].iov_base = NULL; 1062264Sjacobs iov[0].iov_len = 0; 1072264Sjacobs msg.msg_accrights = (caddr_t)&fd; 1082264Sjacobs msg.msg_accrights = sizeof (fd); 1092264Sjacobs #endif 1102264Sjacobs msg.msg_iov = iov; 1112264Sjacobs msg.msg_iovlen = 1; 1122264Sjacobs msg.msg_name = NULL; 1132264Sjacobs msg.msg_namelen = 0; 1142264Sjacobs 1152264Sjacobs if (recvmsg(sockfd, &msg, 0) < 0) 1162264Sjacobs fd = -1; 1172264Sjacobs #ifdef CMSG_DATA 1182264Sjacobs else 1192264Sjacobs fd = * (int *)CMSG_DATA(cmp); 1202264Sjacobs #endif 1212264Sjacobs #endif 1222264Sjacobs return (fd); 1232264Sjacobs } 1242264Sjacobs 1252264Sjacobs int 1262264Sjacobs lpd_open(service_t *svc, char type, char **args, int timeout) 1272264Sjacobs { 1282264Sjacobs int ac, rc = -1, fds[2]; 1292264Sjacobs pid_t pid; 1304275Sjacobs char *av[64], *tmp, buf[BUFSIZ]; 1312264Sjacobs 1322264Sjacobs if ((svc == NULL) || (svc->uri == NULL)) 1332264Sjacobs return (-1); 1342264Sjacobs 1352264Sjacobs #ifndef SUID_LPD_PORT 1362264Sjacobs #define SUID_LPD_PORT "/usr/lib/print/lpd-port" 1372264Sjacobs #endif 1382264Sjacobs 1392264Sjacobs av[0] = SUID_LPD_PORT; ac = 1; 1402264Sjacobs 1414275Sjacobs /* server */ 1424275Sjacobs av[ac++] = "-H"; 1434275Sjacobs av[ac++] = svc->uri->host; 1444275Sjacobs 1454275Sjacobs /* timeout */ 1462264Sjacobs if (timeout > 0) { 1472264Sjacobs snprintf(buf, sizeof (buf), "%d", timeout); 1482264Sjacobs av[ac++] = "-t"; 1492264Sjacobs av[ac++] = strdup(buf); 1502264Sjacobs } 1514275Sjacobs 1524275Sjacobs /* operation */ 1532264Sjacobs snprintf(buf, sizeof (buf), "-%c", type); 1542264Sjacobs av[ac++] = buf; 1552264Sjacobs 1564275Sjacobs /* queue */ 157*9411SKeerthi.Kondaka@Sun.COM if (svc->uri->path == NULL) { 158*9411SKeerthi.Kondaka@Sun.COM tmp = ""; 159*9411SKeerthi.Kondaka@Sun.COM } else { 160*9411SKeerthi.Kondaka@Sun.COM if ((tmp = strrchr(svc->uri->path, '/')) == NULL) 161*9411SKeerthi.Kondaka@Sun.COM tmp = svc->uri->path; 162*9411SKeerthi.Kondaka@Sun.COM else 163*9411SKeerthi.Kondaka@Sun.COM tmp++; 164*9411SKeerthi.Kondaka@Sun.COM } 1654275Sjacobs av[ac++] = tmp; 1664275Sjacobs 1674275Sjacobs /* args */ 1682264Sjacobs if (args != NULL) 1692264Sjacobs while ((*args != NULL) && (ac < 62)) 1702264Sjacobs av[ac++] = *args++; 1712264Sjacobs 1722264Sjacobs av[ac++] = NULL; 1732264Sjacobs 1742264Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD) 1752264Sjacobs pipe(fds); 1762264Sjacobs #else 1772264Sjacobs socketpair(AF_UNIX, SOCK_STREAM, 0, fds); 1782264Sjacobs #endif 1792264Sjacobs 1802264Sjacobs switch (pid = fork()) { 1812264Sjacobs case -1: /* failed */ 1822264Sjacobs break; 1832264Sjacobs case 0: /* child */ 1842264Sjacobs dup2(fds[1], 1); 1852264Sjacobs execv(av[0], &av[0]); 1862264Sjacobs perror("exec"); 1872264Sjacobs exit(1); 1882264Sjacobs break; 1892264Sjacobs default: { /* parent */ 1902264Sjacobs int err, status = 0; 1912264Sjacobs 1922264Sjacobs while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR)); 1932264Sjacobs errno = WEXITSTATUS(status); 1942264Sjacobs 1952264Sjacobs if (errno == 0) 1962264Sjacobs rc = recvfd(fds[0]); 1972264Sjacobs 1982264Sjacobs err = errno; 1992264Sjacobs close(fds[0]); 2002264Sjacobs close(fds[1]); 2012264Sjacobs errno = err; 2022264Sjacobs } 2032264Sjacobs } 2042264Sjacobs 2052264Sjacobs return (rc); 2062264Sjacobs } 207