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 *
fdgets(char * buf,size_t len,int fd)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 *
queue_name_from_uri(uri_t * uri)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
recvfd(int sockfd)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
lpd_open(service_t * svc,char type,char ** args,int timeout)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