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/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Use is subject to license terms.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs *
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/* $Id: send-document.c 146 2006-03-24 00:26:54Z njacobs $ */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#pragma ident "%Z%%M% %I% %E% SMI"
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <stdio.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <papi.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <ipp.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs#include <ipp-listener.h>
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs/*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * papiJobClose(), this will be much cleaner and more efficient, but in the
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * meantime, we are using a private, non-standard interface to do this.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobspapi_status_t
355b4669e025ff377602b6fc7caaf30dbc218371jacobsipp_send_document(papi_service_t svc, papi_attribute_t **request,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_attribute_t ***response, ipp_reader_t iread, void *fd)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs{
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_status_t status;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_stream_t s = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_job_t j = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_attribute_t **operational = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_attribute_t **job_attributes = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *queue = NULL;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ssize_t rc;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs int id = -1;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char buf[BUFSIZ];
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char last = PAPI_FALSE;
355b4669e025ff377602b6fc7caaf30dbc218371jacobs char *keys[] = { "attributes-natural-language", "attributes-charset",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs "printer-uri", "job-id", "job-uri", "last-document",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs NULL };
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* Get operational attributes from the request */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs (void) papiAttributeListGetCollection(request, NULL,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs "operational-attributes-group", &operational);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * the operational-attributes-group must contain:
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * job-uri (or printer-uri/job-id)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * last-document
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs get_printer_id(operational, &queue, &id);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (id < 0) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_set_status(response, PAPI_BAD_REQUEST,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs "missing job-uri or job-id");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (PAPI_BAD_REQUEST);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs } else if (queue == NULL) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_set_status(response, PAPI_BAD_REQUEST,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs "missing printer-uri or job-uri");
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (PAPI_BAD_REQUEST);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs status = papiAttributeListGetBoolean(operational, NULL,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs "last-document", &last);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (status != PAPI_OK) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_set_status(response, status, "last-document: %s",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiStatusString(status));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (PAPI_BAD_REQUEST);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /*
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * the operational-attributes-group may contain:
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * document-name
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * compression
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * document-format
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * document-natural-language
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * Simply copy the entire contents of the operational-attributes-group
355b4669e025ff377602b6fc7caaf30dbc218371jacobs * for the PAPI call's possible use.
355b4669e025ff377602b6fc7caaf30dbc218371jacobs */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs split_and_copy_attributes(keys, operational, NULL, &job_attributes);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* copy any job-attributes-group attributes for the PAPI call */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (papiAttributeListGetCollection(request, NULL,
355b4669e025ff377602b6fc7caaf30dbc218371jacobs "job-attributes-group", &operational) == PAPI_OK)
355b4669e025ff377602b6fc7caaf30dbc218371jacobs copy_attributes(&job_attributes, operational);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* create a stream to write the document data on */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs status = papiJobStreamAdd(svc, queue, id, &s);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiAttributeListFree(job_attributes);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (status != PAPI_OK) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_set_status(response, status, "job submission: %s",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_svc_status_mesg(svc, status));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (status);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* copy the document data from the IPP connection to the stream */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0))
355b4669e025ff377602b6fc7caaf30dbc218371jacobs status = papiJobStreamWrite(svc, s, buf, rc);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (status != PAPI_OK) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_set_status(response, status, "write job data: %s",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_svc_status_mesg(svc, status));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (status);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* close the stream */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs status = papiJobStreamClose(svc, s, &j);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (status != PAPI_OK) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_set_status(response, status, "close job stream: %s",
355b4669e025ff377602b6fc7caaf30dbc218371jacobs ipp_svc_status_mesg(svc, status));
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiJobFree(j); /* we shouldn't have a job, but just in case */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (status);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* if it's the last document, commit the job */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (last == PAPI_TRUE) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs status = papiJobCommit(svc, queue, id);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs /* add the job attributes to the response in a job-attributes-group */
355b4669e025ff377602b6fc7caaf30dbc218371jacobs if (j != NULL) {
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs papiJobFree(j);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs }
355b4669e025ff377602b6fc7caaf30dbc218371jacobs
355b4669e025ff377602b6fc7caaf30dbc218371jacobs return (status);
355b4669e025ff377602b6fc7caaf30dbc218371jacobs}