xref: /onnv-gate/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c (revision 9411:aa9f143d2a60)
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