355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * CDDL HEADER START
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * The contents of this file are subject to the terms of the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Common Development and Distribution License (the "License").
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * You may not use this file except in compliance with the License.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * or http://www.opensolaris.org/os/licensing.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * See the License for the specific language governing permissions
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * and limitations under the License.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * When distributing Covered Code, include this CDDL HEADER in each
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * If applicable, add the following below this CDDL HEADER, with the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * fields enclosed by brackets "[]" replaced with your own identifying
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * information: Portions Copyright [yyyy] [name of copyright owner]
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * CDDL HEADER END
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Use is subject to license terms.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#define __EXTENSIONS__ /* for strtok_r() */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <stdio.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <stdlib.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <unistd.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <sys/types.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <fcntl.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <stdarg.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <string.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <signal.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <sys/socket.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <errno.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <wait.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <stropts.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <papi_impl.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <config-site.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobschar *
355b4669e025ff377602b6fc7caaf30dbc218371jacobsfdgets(char *buf, size_t len, int fd)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char tmp;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int count = 0;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs memset(buf, 0, len);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs while ((count < len) && (read(fd, &tmp, 1) > 0))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if ((buf[count++] = tmp) == '\n') break;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (count != 0)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (buf);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (NULL);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobschar *
355b4669e025ff377602b6fc7caaf30dbc218371jacobsqueue_name_from_uri(uri_t *uri)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *result = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if ((uri != NULL) && (uri->path != NULL)) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *ptr = strrchr(uri->path, '/');
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (ptr == NULL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs result = uri->path;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs result = ++ptr;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (result);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsstatic int
355b4669e025ff377602b6fc7caaf30dbc218371jacobsrecvfd(int sockfd)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int fd = -1;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#if defined(sun) && defined(unix) && defined(I_RECVFD)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs struct strrecvfd recv_fd;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs memset(&recv_fd, NULL, sizeof (recv_fd));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs fd = recv_fd.fd;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs struct iovec iov[1];
355b4669e025ff377602b6fc7caaf30dbc218371jacobs struct msghdr msg;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef CMSG_DATA
355b4669e025ff377602b6fc7caaf30dbc218371jacobs struct cmsghdr cmp[1];
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char buf[24]; /* send/recv 2 byte protocol */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs memset(buf, 0, sizeof (buf));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs iov[0].iov_base = buf;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs iov[0].iov_len = sizeof (buf);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_control = cmp;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs iov[0].iov_base = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs iov[0].iov_len = 0;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_accrights = (caddr_t)&fd;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_accrights = sizeof (fd);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_iov = iov;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_iovlen = 1;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_name = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs msg.msg_namelen = 0;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (recvmsg(sockfd, &msg, 0) < 0)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs fd = -1;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifdef CMSG_DATA
355b4669e025ff377602b6fc7caaf30dbc218371jacobs else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs fd = * (int *)CMSG_DATA(cmp);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (fd);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobsint
355b4669e025ff377602b6fc7caaf30dbc218371jacobslpd_open(service_t *svc, char type, char **args, int timeout)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int ac, rc = -1, fds[2];
355b4669e025ff377602b6fc7caaf30dbc218371jacobs pid_t pid;
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs char *av[64], *tmp, buf[BUFSIZ];
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if ((svc == NULL) || (svc->uri == NULL))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (-1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#ifndef SUID_LPD_PORT
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#define SUID_LPD_PORT "/usr/lib/print/lpd-port"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs av[0] = SUID_LPD_PORT; ac = 1;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs /* server */
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs av[ac++] = "-H";
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs av[ac++] = svc->uri->host;
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs /* timeout */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (timeout > 0) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(buf, sizeof (buf), "%d", timeout);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs av[ac++] = "-t";
355b4669e025ff377602b6fc7caaf30dbc218371jacobs av[ac++] = strdup(buf);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs /* operation */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs snprintf(buf, sizeof (buf), "-%c", type);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs av[ac++] = buf;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs /* queue */
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka if (svc->uri->path == NULL) {
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka tmp = "";
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka } else {
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka if ((tmp = strrchr(svc->uri->path, '/')) == NULL)
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka tmp = svc->uri->path;
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka else
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka tmp++;
e059026e2da8f12ef0ebea9d686d67f32660cfc0Keerthi Kondaka }
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs av[ac++] = tmp;
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs
10144ea86a21f583d4eec553d1a18da7544ba6dejacobs /* args */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (args != NULL)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs while ((*args != NULL) && (ac < 62))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs av[ac++] = *args++;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs av[ac++] = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#if defined(sun) && defined(unix) && defined(I_RECVFD)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs pipe(fds);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#else
355b4669e025ff377602b6fc7caaf30dbc218371jacobs socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#endif
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs switch (pid = fork()) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs case -1: /* failed */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs break;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs case 0: /* child */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs dup2(fds[1], 1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs execv(av[0], &av[0]);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs perror("exec");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs exit(1);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs break;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs default: { /* parent */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int err, status = 0;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs errno = WEXITSTATUS(status);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (errno == 0)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs rc = recvfd(fds[0]);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs err = errno;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs close(fds[0]);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs close(fds[1]);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs errno = err;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (rc);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}