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 /*
23e059026eSKeerthi 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 *
fdgets(char * buf,size_t len,int fd)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 *
queue_name_from_uri(uri_t * uri)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
recvfd(int sockfd)80355b4669Sjacobs recvfd(int sockfd)
81355b4669Sjacobs {
82355b4669Sjacobs 	int fd = -1;
83355b4669Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD)
84355b4669Sjacobs 	struct strrecvfd recv_fd;
85355b4669Sjacobs 
86*f4593de7SToomas Soome 	memset(&recv_fd, 0, 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
lpd_open(service_t * svc,char type,char ** args,int timeout)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 
139*f4593de7SToomas Soome 	av[0] = SUID_LPD_PORT;
140*f4593de7SToomas Soome 	ac = 1;
141355b4669Sjacobs 
14210144ea8Sjacobs 	/* server */
14310144ea8Sjacobs 	av[ac++] = "-H";
14410144ea8Sjacobs 	av[ac++] = svc->uri->host;
14510144ea8Sjacobs 
14610144ea8Sjacobs 	/* timeout */
147355b4669Sjacobs 	if (timeout > 0) {
148355b4669Sjacobs 		snprintf(buf, sizeof (buf), "%d", timeout);
149355b4669Sjacobs 		av[ac++] = "-t";
150355b4669Sjacobs 		av[ac++] = strdup(buf);
151355b4669Sjacobs 	}
15210144ea8Sjacobs 
15310144ea8Sjacobs 	/* operation */
154355b4669Sjacobs 	snprintf(buf, sizeof (buf), "-%c", type);
155355b4669Sjacobs 	av[ac++] = buf;
156355b4669Sjacobs 
15710144ea8Sjacobs 	/* queue */
158e059026eSKeerthi Kondaka 	if (svc->uri->path == NULL) {
159e059026eSKeerthi Kondaka 		tmp = "";
160e059026eSKeerthi Kondaka 	} else {
161e059026eSKeerthi Kondaka 		if ((tmp = strrchr(svc->uri->path, '/')) == NULL)
162e059026eSKeerthi Kondaka 			tmp = svc->uri->path;
163e059026eSKeerthi Kondaka 		else
164e059026eSKeerthi Kondaka 			tmp++;
165e059026eSKeerthi Kondaka 	}
16610144ea8Sjacobs 	av[ac++] = tmp;
16710144ea8Sjacobs 
16810144ea8Sjacobs 	/* args */
169355b4669Sjacobs 	if (args != NULL)
170355b4669Sjacobs 		while ((*args != NULL) && (ac < 62))
171355b4669Sjacobs 			av[ac++] = *args++;
172355b4669Sjacobs 
173355b4669Sjacobs 	av[ac++] = NULL;
174355b4669Sjacobs 
175355b4669Sjacobs #if defined(sun) && defined(unix) && defined(I_RECVFD)
176355b4669Sjacobs 	pipe(fds);
177355b4669Sjacobs #else
178355b4669Sjacobs 	socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
179355b4669Sjacobs #endif
180355b4669Sjacobs 
181355b4669Sjacobs 	switch (pid = fork()) {
182355b4669Sjacobs 	case -1:	/* failed */
183355b4669Sjacobs 		break;
184355b4669Sjacobs 	case 0:	 /* child */
185355b4669Sjacobs 		dup2(fds[1], 1);
186355b4669Sjacobs 		execv(av[0], &av[0]);
187355b4669Sjacobs 		perror("exec");
188355b4669Sjacobs 		exit(1);
189355b4669Sjacobs 		break;
190355b4669Sjacobs 	default: {	/* parent */
191355b4669Sjacobs 		int err, status = 0;
192355b4669Sjacobs 
193*f4593de7SToomas Soome 		while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR))
194*f4593de7SToomas Soome 			;
195355b4669Sjacobs 		errno = WEXITSTATUS(status);
196355b4669Sjacobs 
197355b4669Sjacobs 		if (errno == 0)
198355b4669Sjacobs 			rc = recvfd(fds[0]);
199355b4669Sjacobs 
200355b4669Sjacobs 		err = errno;
201355b4669Sjacobs 		close(fds[0]);
202355b4669Sjacobs 		close(fds[1]);
203355b4669Sjacobs 		errno = err;
204355b4669Sjacobs 		}
205355b4669Sjacobs 	}
206355b4669Sjacobs 
207355b4669Sjacobs 	return (rc);
208355b4669Sjacobs }
209