示例#1
0
char *					/* O - Message text or @code NULL@ */
cupsNotifyText(cups_lang_t *lang,	/* I - Language data */
               ipp_t       *event)	/* I - Event data */
{
  ipp_attribute_t	*notify_text;	/* notify-text */


 /*
  * Range check input...
  */

  if (!event || !lang)
    return (NULL);

 /*
  * Get the notify-text attribute from the server...
  */

  if ((notify_text = ippFindAttribute(event, "notify-text",
                                      IPP_TAG_TEXT)) == NULL)
    return (NULL);

 /*
  * Return a copy...
  */

  return (strdup(notify_text->values[0].string.text));
}
示例#2
0
///////////////////////////////////////////////////////////////////////////////////////////
//
// CS     : PUBLIC gint getPrinterStatus(gchar *pDestName, gchar *pStatus, gint bufSize)
// IN     : gchar *pDestName : Printer name.
//          gint bufSize : Size of output buffer.
// OUT    : gchar *pStatus : Printer status string.
// RETURN : ID_ERR_NO_ERROR : No error.
//          ID_ERR_CUPS_API_FAILED : Error occured in CUPS API.
//
PUBLIC gint getPrinterStatus(gchar *pDestName, gchar *pStatus, gint bufSize)
{
/*** Parameters start ***/
	http_t			*pHTTP;						// Pointer to HTTP connection.
	ipp_t			*pRequest,					// Pointer to CUPS IPP request.
					*pResponse;					// Pointer to CUPS IPP response.
	ipp_attribute_t	*pAttribute;				// Pointer to CUPS attributes.
	cups_lang_t		*pLanguage;					// Pointer to language.
	gchar			printerURI[HTTP_MAX_URI];	// Printer URI.
	gchar			serverName[HTTP_MAX_URI];	// CUPS server name.
	gint			retVal = ID_ERR_NO_ERROR;	// Return value.
/*** Parameters end ***/

	// Initialize buffer.
	memset(printerURI, 0, sizeof(printerURI));
	memset(serverName, 0, sizeof(serverName));

	// Get printer URI and CUPS server name.
	retVal = getPrinterURI(pDestName, printerURI, serverName, HTTP_MAX_URI);
	if (retVal == ID_ERR_NO_ERROR) {
		// CUPS http connect.
		if ((pHTTP = httpConnectEncrypt(serverName, ippPort(), cupsEncryption())) == NULL) {
			retVal = ID_ERR_CUPS_API_FAILED;
		}
		else {
			pRequest = ippNew();

			ippSetOperation(pRequest, IPP_GET_PRINTER_ATTRIBUTES);
			ippSetRequestId(pRequest, 1);

			pLanguage = bjcupsLangDefault();		// cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19

			ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage));
			ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language);
			ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printerURI);

			if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) {
				if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) {
					retVal = ID_ERR_CUPS_API_FAILED;
				}
				else {
					pAttribute = ippFindAttribute(pResponse, "printer-state-message", IPP_TAG_TEXT);
					if (pAttribute != NULL) {
						strncpy(pStatus, ippGetString(pAttribute, 0, NULL), bufSize);
					}
				}
				ippDelete(pResponse);
			}
			else {
				retVal = ID_ERR_CUPS_API_FAILED;
			}

			cupsLangFree(pLanguage);
			httpClose(pHTTP);
		}
	}

	return(retVal);
}// End getPrinterStatus
示例#3
0
文件: job.c 项目: istopwg/ippsample
void serverCreateJobFilename(
    server_printer_t *printer,		/* I - Printer */
    server_job_t     *job,		/* I - Job */
    const char     *format,		/* I - Format or NULL */
    char           *fname,		/* I - Filename buffer */
    size_t         fnamesize)		/* I - Size of filename buffer */
{
  char			name[256],	/* "Safe" filename */
			*nameptr;	/* Pointer into filename */
  const char		*ext,		/* Filename extension */
			*job_name;	/* job-name value */
  ipp_attribute_t	*job_name_attr;	/* job-name attribute */


 /*
  * Make a name from the job-name attribute...
  */

  if ((job_name_attr = ippFindAttribute(job->attrs, "job-name", IPP_TAG_NAME)) != NULL)
    job_name = ippGetString(job_name_attr, 0, NULL);
  else
    job_name = "untitled";

  for (nameptr = name; *job_name && nameptr < (name + sizeof(name) - 1); job_name ++)
    if (isalnum(*job_name & 255) || *job_name == '-')
      *nameptr++ = (char)tolower(*job_name & 255);
    else
      *nameptr++ = '_';

  *nameptr = '\0';

 /*
  * Figure out the extension...
  */

  if (!format)
    format = job->format;

  if (!strcasecmp(format, "image/jpeg"))
    ext = "jpg";
  else if (!strcasecmp(format, "image/png"))
    ext = "png";
  else if (!strcasecmp(format, "image/pwg-raster"))
    ext = "ras";
  else if (!strcasecmp(format, "image/urf"))
    ext = "urf";
  else if (!strcasecmp(format, "application/pdf"))
    ext = "pdf";
  else if (!strcasecmp(format, "application/postscript"))
    ext = "ps";
  else
    ext = "prn";

 /*
  * Create a filename with the job-id, job-name, and document-format (extension)...
  */

  snprintf(fname, fnamesize, "%s/%s/%d-%s.%s", SpoolDirectory, printer->name, job->id, name, ext);
}
示例#4
0
文件: util.c 项目: syedaunnraza/work
const char *				/* O - Default printer or NULL */
cupsGetDefault2(http_t *http)		/* I - HTTP connection */
{
    ipp_t		*request,		/* IPP Request */
                *response;		/* IPP Response */
    ipp_attribute_t *attr;		/* Current attribute */
    const char	*var;			/* Environment variable */
    _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */


    /*
     * First see if the LPDEST or PRINTER environment variables are
     * set...  However, if PRINTER is set to "lp", ignore it to work
     * around a "feature" in most Linux distributions - the default
     * user login scripts set PRINTER to "lp"...
     */

    if ((var = getenv("LPDEST")) != NULL)
        return (var);
    else if ((var = getenv("PRINTER")) != NULL && strcmp(var, "lp") != 0)
        return (var);

    /*
     * Range check input...
     */

    if (!http)
        return (NULL);

    /*
     * Build a CUPS_GET_DEFAULT request, which requires the following
     * attributes:
     *
     *    attributes-charset
     *    attributes-natural-language
     */

    request = ippNewRequest(CUPS_GET_DEFAULT);

    /*
     * Do the request and get back a response...
     */

    if ((response = cupsDoRequest(http, request, "/")) != NULL)
    {
        if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
        {
            strlcpy(cg->def_printer, attr->values[0].string.text, sizeof(cg->def_printer));
            ippDelete(response);
            return (cg->def_printer);
        }

        ippDelete(response);
    }

    return (NULL);
}
示例#5
0
static cups_ptype_t			/* O - printer-type value */
get_printer_type(http_t *http,		/* I - Server connection */
                 char   *printer,	/* I - Printer name */
		 char   *uri,		/* I - URI buffer */
                 size_t urisize)	/* I - Size of URI buffer */
{
  ipp_t			*request,	/* IPP request */
			*response;	/* IPP response */
  ipp_attribute_t	*attr;		/* printer-type attribute */
  cups_ptype_t		type;		/* printer-type value */


 /*
  * Build a GET_PRINTER_ATTRIBUTES request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requested-attributes
  *    requesting-user-name
  */

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, urisize, "ipp", NULL, "localhost",
                   ippPort(), "/printers/%s", printer);

  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
               "printer-uri", NULL, uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
               "requested-attributes", NULL, "printer-type");
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
               "requesting-user-name", NULL, cupsUser());

 /*
  * Do the request...
  */

  response = cupsDoRequest(http, request, "/");
  if ((attr = ippFindAttribute(response, "printer-type",
                               IPP_TAG_ENUM)) != NULL)
  {
    type = (cups_ptype_t)attr->values[0].integer;

    if (type & CUPS_PRINTER_CLASS)
      httpAssembleURIf(HTTP_URI_CODING_ALL, uri, urisize, "ipp", NULL,
		       "localhost", ippPort(), "/classes/%s", printer);
  }
  else
    type = CUPS_PRINTER_LOCAL;

  ippDelete(response);

  return (type);
}
示例#6
0
文件: job.c 项目: istopwg/ippsample
server_job_t *				/* O - Job or NULL */
serverFindJob(
    server_client_t *client,		/* I - Client */
    int             job_id)		/* I - Job ID to find or 0 to lookup */
{
  ipp_attribute_t	*attr;		/* job-id or job-uri attribute */
  server_job_t		key,		/* Job search key */
			*job;		/* Matching job, if any */


  if (job_id > 0)
  {
    key.id = job_id;
  }
  else if ((attr = ippFindAttribute(client->request, "job-uri", IPP_TAG_URI)) != NULL)
  {
    const char	*uri = ippGetString(attr, 0, NULL);
					/* job-uri value */
    char	scheme[32],		/* URI scheme */
		userpass[256],		/* username:password */
		host[256],		/* Hostname/IP */
		resource[1024];		/* Resource path */
    int		port;			/* Port number */

    if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) >= HTTP_URI_STATUS_OK &&
        !strncmp(resource, client->printer->resource, client->printer->resourcelen) &&
        resource[client->printer->resourcelen] == '/')
      key.id = atoi(resource + client->printer->resourcelen + 1);
    else
      return (NULL);
  }
  else if ((attr = ippFindAttribute(client->request, "job-id", IPP_TAG_INTEGER)) != NULL)
  {
    key.id = ippGetInteger(attr, 0);
  }

  _cupsRWLockRead(&(client->printer->rwlock));
  job = (server_job_t *)cupsArrayFind(client->printer->jobs, &key);
  _cupsRWUnlock(&(client->printer->rwlock));

  return (job);
}
示例#7
0
///////////////////////////////////////////////////////////////////////////////////////////
//
// CS     : PRIVATE gint checkPrinterState(gchar *pDestName, gchar *pURI, gchar *pServerName)
// IN     : gchar *pDestName : Printer name.
//          gchar *pURI : Printer URI.
//          gchar *pServerName : CUPS server name.
// OUT    : None.
// RETURN : ID_ERR_NO_ERROR : No error.
//          ID_ERR_UNKNOWN_PRINTER : No printer registerd in CUPS.
//          ID_ERR_CUPS_API_FAILED : Error occured in CUPS API.
//
PRIVATE gint checkPrinterState(gchar *pDestName, gchar *pURI, gchar *pServerName)
{
/*** Parameters start ***/
	http_t			*pHTTP;								// Pointer to HTTP connection.
	ipp_t			*pRequest,							// Pointer to CUPS IPP request.
					*pResponse;							// Pointer to CUPS IPP response.
	ipp_attribute_t	*pAttribute;						// Pointer to CUPS attributes.
	cups_lang_t		*pLanguage;							// Pointer to language.
	ipp_pstate_t	printerState = IPP_PRINTER_STOPPED;	// Pointer to printer state.
	gint			retVal = ID_ERR_UNKNOWN_PRINTER;	// Return value.
/*** Parameters end ***/

	// CUPS http connect.
	if ((pHTTP = httpConnectEncrypt(pServerName, ippPort(), cupsEncryption())) == NULL) {
		retVal = ID_ERR_CUPS_API_FAILED;
	}
	else {
		pRequest = ippNew();

		ippSetOperation(pRequest, IPP_GET_PRINTER_ATTRIBUTES);
		ippSetRequestId(pRequest, 1);

		pLanguage = bjcupsLangDefault();			// cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19

		ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage));
		ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language);
		ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, pURI);

		if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) {
			if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) {
				retVal = ID_ERR_CUPS_API_FAILED;
			}
			else {
				if ((pAttribute = ippFindAttribute(pResponse, "printer-state", IPP_TAG_ENUM)) != NULL) {
					printerState = (ipp_state_t) ippGetInteger(pAttribute, 0);
				}
			}

			ippDelete(pResponse);
		}
		else {
			retVal = ID_ERR_CUPS_API_FAILED;
		}

		cupsLangFree(pLanguage);
		httpClose(pHTTP);
	}

	if (printerState == IPP_PRINTER_IDLE || printerState == IPP_PRINTER_PROCESSING) {
		retVal = ID_ERR_NO_ERROR;
	}

	return(retVal);
}// End checkPrinterState
示例#8
0
文件: util.c 项目: AnotherView/cups
const char *				/* O - Default printer or @code NULL@ */
cupsGetDefault2(http_t *http)		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
{
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr;		/* Current attribute */
  _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */


 /*
  * See if we have a user default printer set...
  */

  if (_cupsUserDefault(cg->def_printer, sizeof(cg->def_printer)))
    return (cg->def_printer);

 /*
  * Connect to the server as needed...
  */

  if (!http)
    if ((http = _cupsConnect()) == NULL)
      return (NULL);

 /*
  * Build a CUPS_GET_DEFAULT request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  */

  request = ippNewRequest(CUPS_GET_DEFAULT);

 /*
  * Do the request and get back a response...
  */

  if ((response = cupsDoRequest(http, request, "/")) != NULL)
  {
    if ((attr = ippFindAttribute(response, "printer-name",
                                 IPP_TAG_NAME)) != NULL)
    {
      strlcpy(cg->def_printer, attr->values[0].string.text,
              sizeof(cg->def_printer));
      ippDelete(response);
      return (cg->def_printer);
    }

    ippDelete(response);
  }

  return (NULL);
}
示例#9
0
const char *
gtk_cups_request_ipp_get_string (GtkCupsRequest *request,
                                 ipp_tag_t       tag,
                                 const char     *name)
{
  ipp_attribute_t *attribute = NULL;

  if (request != NULL && request->ipp_request != NULL)
    attribute = ippFindAttribute (request->ipp_request,
                                  name,
                                  tag);

  if (attribute != NULL && ippGetCount (attribute) > 0)
      return ippGetString (attribute, 0, NULL);
  else
    return NULL;
}
示例#10
0
文件: gtkcupsutils.c 项目: krh/gtk
const char *
gtk_cups_request_ipp_get_string (GtkCupsRequest *request,
                                 ipp_tag_t       tag,
                                 const char     *name)
{
  ipp_attribute_t *attribute = NULL;

  if (request != NULL && request->ipp_request != NULL)
    attribute = ippFindAttribute (request->ipp_request,
                                  name,
                                  tag);

  if (attribute != NULL && attribute->values != NULL)
    return attribute->values[0].string.text;
  else
    return NULL;
}
示例#11
0
文件: request.c 项目: jelmer/cups
ipp_t *					/* O - Response or @code NULL@ on HTTP error */
cupsGetResponse(http_t     *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
                const char *resource)	/* I - HTTP resource for POST */
{
  http_status_t	status;			/* HTTP status */
  ipp_state_t	state;			/* IPP read state */
  ipp_t		*response = NULL;	/* IPP response */


  DEBUG_printf(("cupsGetResponse(http=%p, resource=\"%s\")", http, resource));

 /*
  * Connect to the default server as needed...
  */

  if (!http)
    http = _cupsConnect();

  if (!http || (http->state != HTTP_STATE_POST_RECV &&
                http->state != HTTP_STATE_POST_SEND))
    return (NULL);

 /*
  * Check for an unfinished chunked request...
  */

  if (http->data_encoding == HTTP_ENCODING_CHUNKED)
  {
   /*
    * Send a 0-length chunk to finish off the request...
    */

    DEBUG_puts("2cupsGetResponse: Finishing chunked POST...");

    if (httpWrite2(http, "", 0) < 0)
      return (NULL);
  }

 /*
  * Wait for a response from the server...
  */

  DEBUG_printf(("2cupsGetResponse: Update loop, http->status=%d...",
                http->status));

  do
  {
    status = httpUpdate(http);
  }
  while (status == HTTP_STATUS_CONTINUE);

  DEBUG_printf(("2cupsGetResponse: status=%d", status));

  if (status == HTTP_STATUS_OK)
  {
   /*
    * Get the IPP response...
    */

    response = ippNew();

    while ((state = ippRead(http, response)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    if (state == IPP_STATE_ERROR)
    {
     /*
      * Flush remaining data and delete the response...
      */

      DEBUG_puts("1cupsGetResponse: IPP read error!");

      httpFlush(http);

      ippDelete(response);
      response = NULL;

      http->status = status = HTTP_STATUS_ERROR;
      http->error  = EINVAL;
    }
  }
  else if (status != HTTP_STATUS_ERROR)
  {
   /*
    * Flush any error message...
    */

    httpFlush(http);

   /*
    * Then handle encryption and authentication...
    */

    if (status == HTTP_STATUS_UNAUTHORIZED)
    {
     /*
      * See if we can do authentication...
      */

      DEBUG_puts("2cupsGetResponse: Need authorization...");

      if (!cupsDoAuthentication(http, "POST", resource))
        httpReconnect2(http, 30000, NULL);
      else
        http->status = status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
    }

#ifdef HAVE_SSL
    else if (status == HTTP_STATUS_UPGRADE_REQUIRED)
    {
     /*
      * Force a reconnect with encryption...
      */

      DEBUG_puts("2cupsGetResponse: Need encryption...");

      if (!httpReconnect2(http, 30000, NULL))
        httpEncryption(http, HTTP_ENCRYPTION_REQUIRED);
    }
#endif /* HAVE_SSL */
  }

  if (response)
  {
    ipp_attribute_t	*attr;		/* status-message attribute */


    attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);

    DEBUG_printf(("1cupsGetResponse: status-code=%s, status-message=\"%s\"",
                  ippErrorString(response->request.status.status_code),
                  attr ? attr->values[0].string.text : ""));

    _cupsSetError(response->request.status.status_code,
                  attr ? attr->values[0].string.text :
		      ippErrorString(response->request.status.status_code), 0);
  }

  return (response);
}
示例#12
0
static int iprint_queue_get(const char *sharename,
			    enum printing_types printing_type,
			    char *lpq_command,
			    print_queue_struct **q, 
			    print_status_struct *status)
{
	fstring		printername;
	http_t		*http = NULL;		/* HTTP connection to server */
	ipp_t		*request = NULL,	/* IPP Request */
			*response = NULL;	/* IPP Response */
	ipp_attribute_t	*attr = NULL;		/* Current attribute */
	cups_lang_t	*language = NULL;	/* Default language */
	char		uri[HTTP_MAX_URI]; /* printer-uri attribute */
	char		serviceUri[HTTP_MAX_URI]; /* service-uri attribute */
	char		httpPath[HTTP_MAX_URI];	/* path portion of the uri */
	int		jobUseUnixTime = 0;	/* Whether job times should
                                                 * be assumed to be Unix time */
	int		qcount = 0,		/* Number of active queue entries */
			qalloc = 0;		/* Number of queue entries allocated */
	print_queue_struct *queue = NULL,	/* Queue entries */
			*temp;		/* Temporary pointer for queue */
	const char	*user_name,	/* job-originating-user-name attribute */
			*job_name;	/* job-name attribute */
	int		job_id;		/* job-id attribute */
	int		job_k_octets;	/* job-k-octets attribute */
	time_t		job_time;	/* time-at-creation attribute */
	time_t		printer_up_time = 0;	/* printer's uptime */
	ipp_jstate_t	job_status;	/* job-status attribute */
	int		job_priority;	/* job-priority attribute */
	static const char *jattrs[] =	/* Requested job attributes */
			{
			  "job-id",
			  "job-k-octets",
			  "job-name",
			  "job-originating-user-name",
			  "job-priority",
			  "job-state",
			  "time-at-creation",
			};
	static const char *pattrs[] =	/* Requested printer attributes */
			{
			  "printer-state",
			  "printer-state-message",
			  "printer-current-time",
			  "printer-up-time"
			};

	*q = NULL;

	/* HACK ALERT!!!  The porblem with support the 'printer name' 
	   option is that we key the tdb off the sharename.  So we will 
	   overload the lpq_command string to pass in the printername 
	   (which is basically what we do for non-cups printers ... using 
	   the lpq_command to get the queue listing). */

	fstrcpy( printername, lpq_command );

	DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status));

       /*
	* Make sure we don't ask for passwords...
	*/

	cupsSetPasswordCB(iprint_passwd_cb);

       /*
	* Try to connect to the server...
	*/

	if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
		DEBUG(0,("Unable to connect to iPrint server %s - %s\n", 
			 iprint_server(), strerror(errno)));
		goto out;
	}

       /*
	* Generate the printer URI and the service URI that goes with it...
	*/

	slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername);
	slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server());

       /*
	* For Linux iPrint servers from OES SP1 on, the iPrint server
	* uses Unix time for job start times unless it detects the iPrint
	* client in an http User-Agent header.  (This was done to accomodate
	* CUPS broken behavior.  According to RFC 2911, section 4.3.14, job
	* start times are supposed to be relative to how long the printer has
	* been up.)  Since libcups doesn't allow us to set that header before
	* the request is sent, this ugly hack allows us to detect the server
	* version and decide how to interpret the job time.
	*/
	if (iprint_get_server_version(http, serviceUri) >=
	    NOVELL_SERVER_VERSION_OES_SP1)
		jobUseUnixTime = 1;

	request = ippNew();

	ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
	ippSetRequestId(request, 2);

	language = cupsLangDefault();

	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
	             "attributes-charset", NULL, "utf-8");

	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
	             "attributes-natural-language", NULL, language->language);

	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
	             "printer-uri", NULL, uri);

	ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
	              "requested-attributes",
	              (sizeof(pattrs) / sizeof(pattrs[0])),
	              NULL, pattrs);

       /*
	* Do the request and get back a response...
	*/

	slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);

	if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
		DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
			 ippErrorString(cupsLastError())));
		*q = queue;
		goto out;
	}

	if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
		DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
			 ippErrorString(ippGetStatusCode(response))));
		*q = queue;
		goto out;
	}

       /*
	* Get the current printer status and convert it to the SAMBA values.
	*/

	if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
		if (ippGetInteger(attr, 0) == IPP_PRINTER_STOPPED)
			status->status = LPSTAT_STOPPED;
		else
			status->status = LPSTAT_OK;
	}

	if ((attr = ippFindAttribute(response, "printer-state-message",
	                             IPP_TAG_TEXT)) != NULL)
		fstrcpy(status->message, ippGetString(attr, 0, NULL));

	if ((attr = ippFindAttribute(response, "printer-up-time",
	                             IPP_TAG_INTEGER)) != NULL)
		printer_up_time = ippGetInteger(attr, 0);

	ippDelete(response);
	response = NULL;

       /*
	* Build an IPP_GET_JOBS request, which requires the following
	* attributes:
	*
	*    attributes-charset
	*    attributes-natural-language
	*    requested-attributes
	*    printer-uri
	*/

	request = ippNew();

	ippSetOperation(request, IPP_GET_JOBS);
	ippSetRequestId(request, 3);

	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
	             "attributes-charset", NULL, "utf-8");

	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
	             "attributes-natural-language", NULL, language->language);

	ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
	             "printer-uri", NULL, uri);

	ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
	              "requested-attributes",
	              (sizeof(jattrs) / sizeof(jattrs[0])),
	              NULL, jattrs);

       /*
	* Do the request and get back a response...
	*/

	slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);

	if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
		DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
			 ippErrorString(cupsLastError())));
		goto out;
	}

	if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
		DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
			 ippErrorString(ippGetStatusCode(response))));
		goto out;
	}

       /*
	* Process the jobs...
	*/

	qcount = 0;
	qalloc = 0;
	queue  = NULL;

	for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) {
	       /*
		* Skip leading attributes until we hit a job...
		*/

		while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_JOB)
			attr = ippNextAttribute(response);

		if (attr == NULL)
			break;

	       /*
		* Allocate memory as needed...
		*/
		if (qcount >= qalloc) {
			qalloc += 16;

			queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);

			if (queue == NULL) {
				DEBUG(0,("iprint_queue_get: Not enough memory!"));
				qcount = 0;
				goto out;
			}
		}

		temp = queue + qcount;
		memset(temp, 0, sizeof(print_queue_struct));

	       /*
		* Pull the needed attributes from this job...
		*/

		job_id       = 0;
		job_priority = 50;
		job_status   = IPP_JOB_PENDING;
		job_time     = 0;
		job_k_octets = 0;
		user_name    = NULL;
		job_name     = NULL;

		while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) {
			if (ippGetName(attr) == NULL) {
				attr = ippNextAttribute(response);
				break;
			}

			if (strcmp(ippGetName(attr), "job-id") == 0 &&
			    ippGetValueTag(attr) == IPP_TAG_INTEGER)
				job_id = ippGetInteger(attr, 0);

			if (strcmp(ippGetName(attr), "job-k-octets") == 0 &&
			    ippGetValueTag(attr) == IPP_TAG_INTEGER)
				job_k_octets = ippGetInteger(attr, 0);

			if (strcmp(ippGetName(attr), "job-priority") == 0 &&
			    ippGetValueTag(attr) == IPP_TAG_INTEGER)
				job_priority = ippGetInteger(attr, 0);

			if (strcmp(ippGetName(attr), "job-state") == 0 &&
			    ippGetValueTag(attr) == IPP_TAG_ENUM)
				job_status = (ipp_jstate_t)ippGetInteger(attr, 0);

			if (strcmp(ippGetName(attr), "time-at-creation") == 0 &&
			    ippGetValueTag(attr) == IPP_TAG_INTEGER)
			{
			       /*
				* If jobs times are in Unix time, the accuracy of the job
				* start time depends upon the iPrint server's time being
				* set correctly.  Otherwise, the accuracy depends upon
				* the Samba server's time being set correctly
				*/

				if (jobUseUnixTime)
					job_time = ippGetInteger(attr, 0);
				else
					job_time = time(NULL) - printer_up_time + ippGetInteger(attr, 0);
			}

			if (strcmp(ippGetName(attr), "job-name") == 0 &&
			    (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
			     ippGetValueTag(attr) == IPP_TAG_NAME))
				job_name = ippGetString(attr, 0, NULL);

			if (strcmp(ippGetName(attr), "job-originating-user-name") == 0 &&
			    (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
			     ippGetValueTag(attr) == IPP_TAG_NAME))
				user_name = ippGetString(attr, 0, NULL);

			attr = ippNextAttribute(response);
		}

	       /*
		* See if we have everything needed...
		*/

		if (user_name == NULL || job_name == NULL || job_id == 0) {
			if (attr == NULL)
				break;
			else
				continue;
		}

		temp->sysjob   = job_id;
		temp->size     = job_k_octets * 1024;
		temp->status   = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
		                 job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
                                 job_status == IPP_JOB_HELD ? LPQ_PAUSED :
                                 LPQ_PRINTING;
		temp->priority = job_priority;
		temp->time     = job_time;
		strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
		strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);

		qcount ++;

		if (attr == NULL)
			break;
	}

       /*
	* Return the job queue...
	*/

	*q = queue;

 out:
	if (response)
		ippDelete(response);

	if (language)
		cupsLangFree(language);

	if (http)
		httpClose(http);

	return qcount;
}
示例#13
0
文件: util.c 项目: syedaunnraza/work
static int				/* O - 1 on success, 0 on failure */
cups_get_printer_uri(
    http_t     *http,			/* I - HTTP connection */
    const char *name,			/* I - Name of printer or class */
    char       *host,			/* I - Hostname buffer */
    int        hostsize,		/* I - Size of hostname buffer */
    int        *port,			/* O - Port number */
    char       *resource,		/* I - Resource buffer */
    int        resourcesize,		/* I - Size of resource buffer */
    int        depth)			/* I - Depth of query */
{
    int		i;			/* Looping var */
    int		http_port;		/* Port number */
    http_t	*http2;			/* Alternate HTTP connection */
    ipp_t		*request,		/* IPP request */
                *response;		/* IPP response */
    ipp_attribute_t *attr;		/* Current attribute */
    char		uri[HTTP_MAX_URI],	/* printer-uri attribute */
                scheme[HTTP_MAX_URI],	/* Scheme name */
                username[HTTP_MAX_URI],	/* Username:password */
                classname[255],		/* Temporary class name */
                http_hostname[HTTP_MAX_HOST];
    /* Hostname associated with connection */
    static const char * const requested_attrs[] =
    {   /* Requested attributes */
        "printer-uri-supported",
        "printer-type",
        "member-uris"
    };


    DEBUG_printf(("cups_get_printer_uri(http=%p, name=\"%s\", host=%p, "
                  "hostsize=%d, resource=%p, resourcesize=%d, depth=%d)\n",
                  http, name ? name : "(null)", host, hostsize,
                  resource, resourcesize, depth));

    /*
     * Setup the printer URI...
     */

    if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                         "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
    {
        _cupsSetError(IPP_INTERNAL_ERROR, "Unable to create printer-uri!");

        *host     = '\0';
        *resource = '\0';

        return (0);
    }

    DEBUG_printf(("cups_get_printer_uri: printer-uri=\"%s\"\n", uri));

    /*
     * Get the hostname and port number we are connected to...
     */

    httpGetHostname(http, http_hostname, sizeof(http_hostname));

#ifdef AF_INET6
    if (http->hostaddr->addr.sa_family == AF_INET6)
        http_port = ntohs(http->hostaddr->ipv6.sin6_port);
    else
#endif /* AF_INET6 */
        if (http->hostaddr->addr.sa_family == AF_INET)
            http_port = ntohs(http->hostaddr->ipv4.sin_port);
        else
            http_port = ippPort();

    /*
     * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
     * attributes:
     *
     *    attributes-charset
     *    attributes-natural-language
     *    printer-uri
     *    requested-attributes
     */

    request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, uri);

    ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                  "requested-attributes",
                  sizeof(requested_attrs) / sizeof(requested_attrs[0]),
                  NULL, requested_attrs);

    /*
     * Do the request and get back a response...
     */

    if ((response = cupsDoRequest(http, request, "/")) != NULL)
    {
        if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
        {
            /*
             * Get the first actual printer name in the class...
             */

            for (i = 0; i < attr->num_values; i ++)
            {
                httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text,
                                scheme, sizeof(scheme), username, sizeof(username),
                                host, hostsize, port, resource, resourcesize);
                if (!strncmp(resource, "/printers/", 10))
                {
                    /*
                     * Found a printer!
                     */

                    ippDelete(response);

                    return (1);
                }
            }

            /*
             * No printers in this class - try recursively looking for a printer,
             * but not more than 3 levels deep...
             */

            if (depth < 3)
            {
                for (i = 0; i < attr->num_values; i ++)
                {
                    httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text,
                                    scheme, sizeof(scheme), username, sizeof(username),
                                    host, hostsize, port, resource, resourcesize);
                    if (!strncmp(resource, "/classes/", 9))
                    {
                        /*
                         * Found a class!  Connect to the right server...
                         */

                        if (!strcasecmp(http_hostname, host) && *port == http_port)
                            http2 = http;
                        else if ((http2 = httpConnectEncrypt(host, *port,
                                                             cupsEncryption())) == NULL)
                        {
                            DEBUG_puts("Unable to connect to server!");

                            continue;
                        }

                        /*
                        * Look up printers on that server...
                        */

                        strlcpy(classname, resource + 9, sizeof(classname));

                        cups_get_printer_uri(http2, classname, host, hostsize, port,
                                             resource, resourcesize, depth + 1);

                        /*
                        * Close the connection as needed...
                        */

                        if (http2 != http)
                            httpClose(http2);

                        if (*host)
                            return (1);
                    }
                }
            }
        }
        else if ((attr = ippFindAttribute(response, "printer-uri-supported",
                                          IPP_TAG_URI)) != NULL)
        {
            httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text,
                            scheme, sizeof(scheme), username, sizeof(username),
                            host, hostsize, port, resource, resourcesize);
            ippDelete(response);

            if (!strncmp(resource, "/classes/", 9))
            {
                _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found for class!"));

                *host     = '\0';
                *resource = '\0';

                return (0);
            }

            return (1);
        }

        ippDelete(response);
    }

    if (cupsLastError() != IPP_NOT_FOUND)
        _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found!"));

    *host     = '\0';
    *resource = '\0';

    return (0);
}
示例#14
0
文件: quotas.c 项目: ystk/debian-cups
cupsd_quota_t *				/* O - Quota data */
cupsdUpdateQuota(
    cupsd_printer_t *p,			/* I - Printer */
    const char      *username,		/* I - User */
    int             pages,		/* I - Number of pages */
    int             k)			/* I - Number of kilobytes */
{
  cupsd_quota_t		*q;		/* Quota data */
  cupsd_job_t		*job;		/* Current job */
  time_t		curtime;	/* Current time */
  ipp_attribute_t	*attr;		/* Job attribute */


  if (!p || !username)
    return (NULL);

  if (!p->k_limit && !p->page_limit)
    return (NULL);

  if ((q = cupsdFindQuota(p, username)) == NULL)
    return (NULL);

  cupsdLogMessage(CUPSD_LOG_DEBUG,
                  "cupsdUpdateQuota: p=%s username=%s pages=%d k=%d",
                  p->name, username, pages, k);

#if defined(__APPLE__) && defined(HAVE_DLFCN_H)
 /*
  * Use Apple PrintService quota enforcement if installed (X Server only)
  */

  if (AppleQuotas && PSQUpdateQuotaProc)
  { 
    q->page_count = (*PSQUpdateQuotaProc)(p->name, p->info, username, pages, 0);

    return (q);
  }
#endif /* __APPLE__ && HAVE_DLFCN_H */

  curtime = time(NULL);

  if (curtime < q->next_update)
  {
    q->page_count += pages;
    q->k_count    += k;

    return (q);
  }

  if (p->quota_period)
    curtime -= p->quota_period;
  else
    curtime = 0;

  q->next_update = 0;
  q->page_count  = 0;
  q->k_count     = 0;

  for (job = (cupsd_job_t *)cupsArrayFirst(Jobs);
       job;
       job = (cupsd_job_t *)cupsArrayNext(Jobs))
  {
   /*
    * We only care about the current printer/class and user...
    */

    if (strcasecmp(job->dest, p->name) != 0 ||
        strcasecmp(job->username, q->username) != 0)
      continue;

   /*
    * Make sure attributes are loaded; we always call cupsdLoadJob() to ensure
    * the access_time member is updated so the job isn't unloaded right away...
    */

    if (!cupsdLoadJob(job))
      continue;

    if ((attr = ippFindAttribute(job->attrs, "time-at-completion",
                                 IPP_TAG_INTEGER)) == NULL)
      if ((attr = ippFindAttribute(job->attrs, "time-at-processing",
                                   IPP_TAG_INTEGER)) == NULL)
        attr = ippFindAttribute(job->attrs, "time-at-creation",
                                IPP_TAG_INTEGER);

    if (attr->values[0].integer < curtime)
    {
     /*
      * This job is too old to count towards the quota, ignore it...
      */

      if (JobAutoPurge && !job->printer && job->state_value > IPP_JOB_STOPPED)
        cupsdDeleteJob(job, CUPSD_JOB_PURGE);

      continue;
    }

    if (q->next_update == 0)
      q->next_update = attr->values[0].integer + p->quota_period;

    if ((attr = ippFindAttribute(job->attrs, "job-media-sheets-completed",
                                 IPP_TAG_INTEGER)) != NULL)
      q->page_count += attr->values[0].integer;

    if ((attr = ippFindAttribute(job->attrs, "job-k-octets",
                                 IPP_TAG_INTEGER)) != NULL)
      q->k_count += attr->values[0].integer;
  }

  return (q);
}
示例#15
0
文件: dest-job.c 项目: jelmer/cups
ipp_status_t				/* O - IPP status code */
cupsCreateDestJob(
    http_t        *http,		/* I - Connection to destination */
    cups_dest_t   *dest,		/* I - Destination */
    cups_dinfo_t  *info, 		/* I - Destination information */
    int           *job_id,		/* O - Job ID or 0 on error */
    const char    *title,		/* I - Job name */
    int           num_options,		/* I - Number of job options */
    cups_option_t *options)		/* I - Job options */
{
  ipp_t			*request,	/* Create-Job request */
			*response;	/* Create-Job response */
  ipp_attribute_t	*attr;		/* job-id attribute */


  DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, "
                "job_id=%p, title=\"%s\", num_options=%d, options=%p)",
                http, dest, dest ? dest->name : NULL,
                dest ? dest->instance : NULL, info, job_id, title, num_options,
                options));

 /*
  * Range check input...
  */

  if (job_id)
    *job_id = 0;

  if (!http || !dest || !info || !job_id)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    DEBUG_puts("1cupsCreateDestJob: Bad arguments.");
    return (IPP_STATUS_ERROR_INTERNAL);
  }

 /*
  * Build a Create-Job request...
  */

  if ((request = ippNewRequest(IPP_OP_CREATE_JOB)) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
    DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request.");
    return (IPP_STATUS_ERROR_INTERNAL);
  }

  ippSetVersion(request, info->version / 10, info->version % 10);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
               NULL, info->uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  if (title)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
                 title);

  cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION);

 /*
  * Send the request and get the job-id...
  */

  response = cupsDoRequest(http, request, info->resource);

  if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
  {
    *job_id = attr->values[0].integer;
    DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id));
  }

  ippDelete(response);

 /*
  * Return the status code from the Create-Job request...
  */

  DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()),
                cupsLastErrorString()));

  return (cupsLastError());
}
示例#16
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  ipp_t			*msg;		/* Event message from scheduler */
  ipp_state_t		state;		/* IPP event state */
  struct sigaction	action;		/* POSIX sigaction data */
  DBusConnection	*con = NULL;	/* Connection to DBUS server */
  DBusError		error;		/* Error, if any */
  DBusMessage		*message;	/* Message to send */
  DBusMessageIter	iter;		/* Iterator for message data */
  int			lock_fd = -1;	/* Lock file descriptor */


 /*
  * Don't buffer stderr...
  */

  setbuf(stderr, NULL);

 /*
  * Ignore SIGPIPE signals...
  */

  memset(&action, 0, sizeof(action));
  action.sa_handler = SIG_IGN;
  sigaction(SIGPIPE, &action, NULL);

 /*
  * Validate command-line options...
  */

  if (argc != 3)
  {
    fputs("Usage: dbus dbus:/// notify-user-data\n", stderr);
    return (1);
  }

  if (strncmp(argv[1], "dbus:", 5))
  {
    fprintf(stderr, "ERROR: Bad URI \"%s\"!\n", argv[1]);
    return (1);
  }

 /*
  * Loop forever until we run out of events...
  */

  for (;;)
  {
    ipp_attribute_t	*attr;		/* Current attribute */
    const char		*event;		/* Event name */
    const char		*signame = NULL;/* DBUS signal name */
    char		*printer_reasons = NULL;
					/* Printer reasons string */
    char		*job_reasons = NULL;
					/* Job reasons string */
    const char		*nul = "";	/* Empty string value */
    int			no = 0;		/* Boolean "no" value */
    int			params = PARAMS_NONE;
					/* What parameters to include? */


   /*
    * Get the next event...
    */

    msg = ippNew();
    while ((state = ippReadFile(0, msg)) != IPP_DATA)
    {
      if (state <= IPP_IDLE)
        break;
    }

    fprintf(stderr, "DEBUG: state=%d\n", state);

    if (state == IPP_ERROR)
      fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr);

    if (state <= IPP_IDLE)
    {
     /*
      * Out of messages, free memory and then exit...
      */

      ippDelete(msg);
      break;
    }

   /*
    * Verify connection to DBUS server...
    */

    if (con && !dbus_connection_get_is_connected(con))
    {
      dbus_connection_unref(con);
      con = NULL;
    }

    if (!con)
    {
      dbus_error_init(&error);

      con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
      if (!con)
	dbus_error_free(&error);
      else
	fputs("DEBUG: Connected to D-BUS\n", stderr);
    }

    if (!con)
      continue;

    if (lock_fd == -1 &&
        acquire_lock(&lock_fd, lock_filename, sizeof(lock_filename)))
      continue;

    attr = ippFindAttribute(msg, "notify-subscribed-event",
			    IPP_TAG_KEYWORD);
    if (!attr)
      continue;

    event = ippGetString(attr, 0, NULL);
    if (!strncmp(event, "server-", 7))
    {
      const char *word2 = event + 7;	/* Second word */

      if (!strcmp(word2, "restarted"))
	signame = "ServerRestarted";
      else if (!strcmp(word2, "started"))
	signame = "ServerStarted";
      else if (!strcmp(word2, "stopped"))
	signame = "ServerStopped";
      else if (!strcmp(word2, "audit"))
	signame = "ServerAudit";
      else
	continue;
    }
    else if (!strncmp(event, "printer-", 8))
    {
      const char *word2 = event + 8;	/* Second word */

      params = PARAMS_PRINTER;
      if (!strcmp(word2, "restarted"))
	signame = "PrinterRestarted";
      else if (!strcmp(word2, "shutdown"))
	signame = "PrinterShutdown";
      else if (!strcmp(word2, "stopped"))
	signame = "PrinterStopped";
      else if (!strcmp(word2, "state-changed"))
	signame = "PrinterStateChanged";
      else if (!strcmp(word2, "finishings-changed"))
	signame = "PrinterFinishingsChanged";
      else if (!strcmp(word2, "media-changed"))
	signame = "PrinterMediaChanged";
      else if (!strcmp(word2, "added"))
	signame = "PrinterAdded";
      else if (!strcmp(word2, "deleted"))
	signame = "PrinterDeleted";
      else if (!strcmp(word2, "modified"))
	signame = "PrinterModified";
      else
	continue;
    }
    else if (!strncmp(event, "job-", 4))
    {
      const char *word2 = event + 4;	/* Second word */

      params = PARAMS_JOB;
      if (!strcmp(word2, "state-changed"))
	signame = "JobState";
      else if (!strcmp(word2, "created"))
	signame = "JobCreated";
      else if (!strcmp(word2, "completed"))
	signame = "JobCompleted";
      else if (!strcmp(word2, "stopped"))
	signame = "JobStopped";
      else if (!strcmp(word2, "config-changed"))
	signame = "JobConfigChanged";
      else if (!strcmp(word2, "progress"))
	signame = "JobProgress";
      else
	continue;
    }
    else
      continue;

    /*
     * Create and send the new message...
     */

    fprintf(stderr, "DEBUG: %s\n", signame);
    message = dbus_message_new_signal("/org/cups/cupsd/Notifier",
				      "org.cups.cupsd.Notifier",
				      signame);

    dbus_message_append_iter_init(message, &iter);
    attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT);
    if (attr)
    {
      const char *val = ippGetString(attr, 0, NULL);
      if (!dbus_message_iter_append_string(&iter, &val))
        goto bail;
    }
    else
      goto bail;

    if (params >= PARAMS_PRINTER)
    {
      char	*p;			/* Pointer into printer_reasons */
      size_t	reasons_length;		/* Required size of printer_reasons */
      int	i;			/* Looping var */
      int	have_printer_params = 1;/* Do we have printer URI? */

      /* STRING printer-uri or "" */
      attr = ippFindAttribute(msg, "notify-printer-uri", IPP_TAG_URI);
      if (attr)
      {
        const char *val = ippGetString(attr, 0, NULL);
        if (!dbus_message_iter_append_string(&iter, &val))
	  goto bail;
      }
      else
      {
	have_printer_params = 0;
	dbus_message_iter_append_string(&iter, &nul);
      }

      /* STRING printer-name */
      if (have_printer_params)
      {
	attr = ippFindAttribute(msg, "printer-name", IPP_TAG_NAME);
        if (attr)
        {
          const char *val = ippGetString(attr, 0, NULL);
          if (!dbus_message_iter_append_string(&iter, &val))
            goto bail;
        }
        else
          goto bail;
      }
      else
	dbus_message_iter_append_string(&iter, &nul);

      /* UINT32 printer-state */
      if (have_printer_params)
      {
	attr = ippFindAttribute(msg, "printer-state", IPP_TAG_ENUM);
	if (attr)
	{
	  dbus_uint32_t val = ippGetInteger(attr, 0);
	  dbus_message_iter_append_uint32(&iter, &val);
	}
	else
	  goto bail;
      }
      else
	dbus_message_iter_append_uint32(&iter, &no);

      /* STRING printer-state-reasons */
      if (have_printer_params)
      {
	attr = ippFindAttribute(msg, "printer-state-reasons",
				IPP_TAG_KEYWORD);
	if (attr)
	{
	  int num_values = ippGetCount(attr);
	  for (reasons_length = 0, i = 0; i < num_values; i++)
	    /* All need commas except the last, which needs a nul byte. */
	    reasons_length += 1 + strlen(ippGetString(attr, i, NULL));
	  printer_reasons = malloc(reasons_length);
	  if (!printer_reasons)
	    goto bail;
	  p = printer_reasons;
	  for (i = 0; i < num_values; i++)
	  {
	    if (i)
	      *p++ = ',';

	    strlcpy(p, ippGetString(attr, i, NULL),
	            reasons_length - (p - printer_reasons));
	    p += strlen(p);
	  }
	  if (!dbus_message_iter_append_string(&iter, &printer_reasons))
	    goto bail;
	}
	else
	  goto bail;
      }
      else
	dbus_message_iter_append_string(&iter, &nul);

      /* BOOL printer-is-accepting-jobs */
      if (have_printer_params)
      {
	attr = ippFindAttribute(msg, "printer-is-accepting-jobs",
				IPP_TAG_BOOLEAN);
	if (attr)
	{
	  dbus_bool_t val = ippGetBoolean(attr, 0);
	  dbus_message_iter_append_boolean(&iter, &val);
	}
	else
	  goto bail;
      }
      else
	dbus_message_iter_append_boolean(&iter, &no);
    }

    if (params >= PARAMS_JOB)
    {
      char	*p;			/* Pointer into job_reasons */
      size_t	reasons_length;		/* Required size of job_reasons */
      int	i;			/* Looping var */

      /* UINT32 job-id */
      attr = ippFindAttribute(msg, "notify-job-id", IPP_TAG_INTEGER);
      if (attr)
      {
        dbus_uint32_t val = ippGetInteger(attr, 0);
        dbus_message_iter_append_uint32(&iter, &val);
      }
      else
	goto bail;

      /* UINT32 job-state */
      attr = ippFindAttribute(msg, "job-state", IPP_TAG_ENUM);
      if (attr)
      {
        dbus_uint32_t val = ippGetInteger(attr, 0);
        dbus_message_iter_append_uint32(&iter, &val);
      }
      else
	goto bail;

      /* STRING job-state-reasons */
      attr = ippFindAttribute(msg, "job-state-reasons", IPP_TAG_KEYWORD);
      if (attr)
      {
	int num_values = ippGetCount(attr);
	for (reasons_length = 0, i = 0; i < num_values; i++)
	  /* All need commas except the last, which needs a nul byte. */
	  reasons_length += 1 + strlen(ippGetString(attr, i, NULL));
	job_reasons = malloc(reasons_length);
	if (!job_reasons)
	  goto bail;
	p = job_reasons;
	for (i = 0; i < num_values; i++)
	{
	  if (i)
	    *p++ = ',';

	  strlcpy(p, ippGetString(attr, i, NULL),
	          reasons_length - (p - job_reasons));
	  p += strlen(p);
	}
	if (!dbus_message_iter_append_string(&iter, &job_reasons))
	  goto bail;
      }
      else
	goto bail;

      /* STRING job-name or "" */
      attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME);
      if (attr)
      {
        const char *val = ippGetString(attr, 0, NULL);
        if (!dbus_message_iter_append_string(&iter, &val))
          goto bail;
      }
      else
	dbus_message_iter_append_string(&iter, &nul);

      /* UINT32 job-impressions-completed */
      attr = ippFindAttribute(msg, "job-impressions-completed",
			      IPP_TAG_INTEGER);
      if (attr)
      {
        dbus_uint32_t val = ippGetInteger(attr, 0);
        dbus_message_iter_append_uint32(&iter, &val);
      }
      else
	goto bail;
    }

    dbus_connection_send(con, message, NULL);
    dbus_connection_flush(con);

   /*
    * Cleanup...
    */

    bail:

    dbus_message_unref(message);

    if (printer_reasons)
      free(printer_reasons);

    if (job_reasons)
      free(job_reasons);

    ippDelete(msg);
  }

 /*
  * Remove lock file...
  */

  if (lock_fd >= 0)
  {
    close(lock_fd);
    release_lock();
  }

  return (0);
}
示例#17
0
文件: subscriptions.c 项目: aosm/cups
void
cupsdAddEvent(
    cupsd_eventmask_t event,		/* I - Event */
    cupsd_printer_t   *dest,		/* I - Printer associated with event */
    cupsd_job_t       *job,		/* I - Job associated with event */
    const char        *text,		/* I - Notification text */
    ...)				/* I - Additional arguments as needed */
{
  va_list		ap;		/* Pointer to additional arguments */
  char			ftext[1024];	/* Formatted text buffer */
  ipp_attribute_t	*attr;		/* Printer/job attribute */
  cupsd_event_t		*temp;		/* New event pointer */
  cupsd_subscription_t	*sub;		/* Current subscription */


  cupsdLogMessage(CUPSD_LOG_DEBUG2,
                  "cupsdAddEvent(event=%s, dest=%p(%s), job=%p(%d), text=\"%s\", ...)",
		  cupsdEventName(event), dest, dest ? dest->name : "",
		  job, job ? job->id : 0, text);

 /*
  * Keep track of events with any OS-supplied notification mechanisms...
  */

  LastEvent |= event;

#ifdef HAVE_DBUS
  cupsd_send_dbus(event, dest, job);
#endif /* HAVE_DBUS */

 /*
  * Return if we aren't keeping events...
  */

  if (MaxEvents <= 0)
  {
    cupsdLogMessage(CUPSD_LOG_WARN,
                    "cupsdAddEvent: Discarding %s event since MaxEvents is %d!",
                    cupsdEventName(event), MaxEvents);
    return;
  }

 /*
  * Then loop through the subscriptions and add the event to the corresponding
  * caches...
  */

  for (temp = NULL, sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions);
       sub;
       sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions))
  {
   /*
    * Check if this subscription requires this event...
    */

    if ((sub->mask & event) != 0 &&
        (sub->dest == dest || !sub->dest) &&
	(sub->job == job || !sub->job))
    {
     /*
      * Need this event, so create a new event record...
      */

      if ((temp = (cupsd_event_t *)calloc(1, sizeof(cupsd_event_t))) == NULL)
      {
	cupsdLogMessage(CUPSD_LOG_CRIT,
	                "Unable to allocate memory for event - %s",
        	        strerror(errno));
	return;
      }

      temp->event = event;
      temp->time  = time(NULL);
      temp->attrs = ippNew();
      temp->job   = job;

      if (dest)
        temp->dest = dest;
      else if (job)
        temp->dest = dest = cupsdFindPrinter(job->dest);

     /*
      * Add common event notification attributes...
      */

      ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_CHARSET,
                   "notify-charset", NULL, "utf-8");

      ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_LANGUAGE,
                   "notify-natural-language", NULL, "en-US");

      ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER,
	            "notify-subscription-id", sub->id);

      ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER,
	            "notify-sequence-number", sub->next_event_id);

      ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_KEYWORD,
	           "notify-subscribed-event", NULL, cupsdEventName(event));

      if (sub->user_data_len > 0)
        ippAddOctetString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
	                  "notify-user-data", sub->user_data,
			  sub->user_data_len);

      ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER,
	            "printer-up-time", time(NULL));

      va_start(ap, text);
      vsnprintf(ftext, sizeof(ftext), text, ap);
      va_end(ap);

      ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_TEXT,
	           "notify-text", NULL, ftext);

      if (dest)
      {
       /*
	* Add printer attributes...
	*/

	ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_URI,
	             "notify-printer-uri", NULL, dest->uri);

	ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME,
	             "printer-name", NULL, dest->name);

	ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM,
	              "printer-state", dest->state);

	if (dest->num_reasons == 0)
	  ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
	               IPP_TAG_KEYWORD, "printer-state-reasons", NULL,
		       dest->state == IPP_PRINTER_STOPPED ? "paused" : "none");
	else
	  ippAddStrings(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
	                IPP_TAG_KEYWORD, "printer-state-reasons",
			dest->num_reasons, NULL,
			(const char * const *)dest->reasons);

	ippAddBoolean(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
	              "printer-is-accepting-jobs", (char)dest->accepting);
      }

      if (job)
      {
       /*
	* Add job attributes...
	*/

	ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER,
	              "notify-job-id", job->id);
	ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_ENUM,
	              "job-state", job->state_value);

        if ((attr = ippFindAttribute(job->attrs, "job-name",
	                             IPP_TAG_NAME)) != NULL)
	  ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_NAME,
	               "job-name", NULL, attr->values[0].string.text);

	switch (job->state_value)
	{
	  case IPP_JOB_PENDING :
              if (dest && dest->state == IPP_PRINTER_STOPPED)
        	ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		             IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			     "printer-stopped");
              else
        	ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		             IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			     "none");
              break;

	  case IPP_JOB_HELD :
              if (ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_KEYWORD) != NULL ||
		  ippFindAttribute(job->attrs, "job-hold-until", IPP_TAG_NAME) != NULL)
        	ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		             IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			     "job-hold-until-specified");
              else
        	ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		             IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			     "job-incoming");
              break;

	  case IPP_JOB_PROCESSING :
              ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		           IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			   "job-printing");
              break;

	  case IPP_JOB_STOPPED :
              ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		           IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			   "job-stopped");
              break;

	  case IPP_JOB_CANCELED :
              ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		           IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			   "job-canceled-by-user");
              break;

	  case IPP_JOB_ABORTED :
              ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		           IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			   "aborted-by-system");
              break;

	  case IPP_JOB_COMPLETED :
              ippAddString(temp->attrs, IPP_TAG_EVENT_NOTIFICATION,
		           IPP_TAG_KEYWORD, "job-state-reasons", NULL,
			   "job-completed-successfully");
              break;
	}

	ippAddInteger(temp->attrs, IPP_TAG_EVENT_NOTIFICATION, IPP_TAG_INTEGER,
	              "job-impressions-completed",
		      job->sheets ? job->sheets->values[0].integer : 0);
      }

     /*
      * Send the notification for this subscription...
      */

      cupsd_send_notification(sub, temp);
    }
  }

  if (temp)
    cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS);
  else
    cupsdLogMessage(CUPSD_LOG_DEBUG, "Discarding unused %s event...",
                    cupsdEventName(event));
}
示例#18
0
char *					/* O - Subject string or @code NULL@ */
cupsNotifySubject(cups_lang_t *lang,	/* I - Language data */
                  ipp_t       *event)	/* I - Event data */
{
  char			buffer[1024];	/* Subject buffer */
  const char		*prefix,	/* Prefix on subject */
			*state;		/* Printer/job state string */
  ipp_attribute_t	*job_id,	/* notify-job-id */
			*job_name,	/* job-name */
			*job_state,	/* job-state */
			*printer_name,	/* printer-name */
			*printer_state,	/* printer-state */
			*printer_uri,	/* notify-printer-uri */
			*subscribed;	/* notify-subscribed-event */


 /*
  * Range check input...
  */

  if (!event || !lang)
    return (NULL);

 /*
  * Get the required attributes...
  */

  job_id        = ippFindAttribute(event, "notify-job-id", IPP_TAG_INTEGER);
  job_name      = ippFindAttribute(event, "job-name", IPP_TAG_NAME);
  job_state     = ippFindAttribute(event, "job-state", IPP_TAG_ENUM);
  printer_name  = ippFindAttribute(event, "printer-name", IPP_TAG_NAME);
  printer_state = ippFindAttribute(event, "printer-state", IPP_TAG_ENUM);
  printer_uri   = ippFindAttribute(event, "notify-printer-uri", IPP_TAG_URI);
  subscribed    = ippFindAttribute(event, "notify-subscribed-event",
                                   IPP_TAG_KEYWORD);


  if (job_id && printer_name && printer_uri && job_state)
  {
   /*
    * Job event...
    */

    prefix = _cupsLangString(lang, _("Print Job:"));

    switch (job_state->values[0].integer)
    {
      case IPP_JOB_PENDING :
          state = _cupsLangString(lang, _("pending"));
	  break;
      case IPP_JOB_HELD :
          state = _cupsLangString(lang, _("held"));
	  break;
      case IPP_JOB_PROCESSING :
          state = _cupsLangString(lang, _("processing"));
	  break;
      case IPP_JOB_STOPPED :
          state = _cupsLangString(lang, _("stopped"));
	  break;
      case IPP_JOB_CANCELED :
          state = _cupsLangString(lang, _("canceled"));
	  break;
      case IPP_JOB_ABORTED :
          state = _cupsLangString(lang, _("aborted"));
	  break;
      case IPP_JOB_COMPLETED :
          state = _cupsLangString(lang, _("completed"));
	  break;
      default :
          state = _cupsLangString(lang, _("unknown"));
	  break;
    }

    snprintf(buffer, sizeof(buffer), "%s %s-%d (%s) %s",
             prefix,
	     printer_name->values[0].string.text,
	     job_id->values[0].integer,
	     job_name ? job_name->values[0].string.text :
	         _cupsLangString(lang, _("untitled")),
	     state);
  }
  else if (printer_uri && printer_name && printer_state)
  {
   /*
    * Printer event...
    */

    prefix = _cupsLangString(lang, _("Printer:"));

    switch (printer_state->values[0].integer)
    {
      case IPP_PRINTER_IDLE :
          state = _cupsLangString(lang, _("idle"));
	  break;
      case IPP_PRINTER_PROCESSING :
          state = _cupsLangString(lang, _("processing"));
	  break;
      case IPP_PRINTER_STOPPED :
          state = _cupsLangString(lang, _("stopped"));
	  break;
      default :
          state = _cupsLangString(lang, _("unknown"));
	  break;
    }

    snprintf(buffer, sizeof(buffer), "%s %s %s",
             prefix,
	     printer_name->values[0].string.text,
	     state);
  }
  else if (subscribed)
    strlcpy(buffer, subscribed->values[0].string.text, sizeof(buffer));
  else
    return (NULL);

 /*
  * Duplicate and return the subject string...
  */

  return (strdup(buffer));
}
示例#19
0
static int				/* O - Number of options or -1 on error */
get_printer(http_t        *http,	/* I - HTTP connection */
            const char    *name,	/* I - Printer name from request */
	    char          *dest,	/* I - Destination buffer */
            size_t        destsize,	/* I - Size of destination buffer */
	    cups_option_t **options,	/* O - Printer options */
	    int           *accepting,	/* O - printer-is-accepting-jobs value */
	    int           *shared,	/* O - printer-is-shared value */
	    ipp_pstate_t  *state)	/* O - printer-state value */
{
  int		num_options;		/* Number of options */
  cups_file_t	*fp;			/* lpoptions file */
  char		line[1024],		/* Line from lpoptions file */
		*value,			/* Pointer to value on line */
		*optptr;		/* Pointer to options on line */
  int		linenum;		/* Line number in file */
  const char	*cups_serverroot;	/* CUPS_SERVERROOT env var */
  ipp_t		*request;		/* IPP request */
  ipp_t		*response;		/* IPP response */
  ipp_attribute_t *attr;		/* IPP attribute */
  char		uri[HTTP_MAX_URI];	/* Printer URI */
  static const char * const requested[] =
		{			/* Requested attributes */
		  "printer-info",
		  "printer-is-accepting-jobs",
		  "printer-is-shared",
		  "printer-name",
		  "printer-state"
		};


 /*
  * Initialize everything...
  */

  if (accepting)
    *accepting = 0;
  if (shared)
    *shared = 0;
  if (state)
    *state = IPP_PRINTER_STOPPED;
  if (options)
    *options = NULL;

 /*
  * See if the name is a queue name optionally with an instance name.
  */

  strlcpy(dest, name, destsize);
  if ((value = strchr(dest, '/')) != NULL)
    *value = '\0';

 /*
  * Setup the Get-Printer-Attributes request...
  */

  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
		   "localhost", 0, "/printers/%s", dest);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
	       NULL, uri);

  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
		"requested-attributes",
		(int)(sizeof(requested) / sizeof(requested[0])),
		NULL, requested);

 /*
  * Do the request...
  */

  response = cupsDoRequest(http, request, "/");

  if (!response || cupsLastError() > IPP_OK_CONFLICT)
  {
   /*
    * If we can't find the printer by name, look up the printer-name
    * using the printer-info values...
    */

    ipp_attribute_t	*accepting_attr,/* printer-is-accepting-jobs */
			*info_attr,	/* printer-info */
			*name_attr,	/* printer-name */
			*shared_attr,	/* printer-is-shared */
			*state_attr;	/* printer-state */


    ippDelete(response);

   /*
    * Setup the CUPS-Get-Printers request...
    */

    request = ippNewRequest(CUPS_GET_PRINTERS);

    ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                  "requested-attributes",
		  (int)(sizeof(requested) / sizeof(requested[0])),
                  NULL, requested);

   /*
    * Do the request...
    */

    response = cupsDoRequest(http, request, "/");

    if (!response || cupsLastError() > IPP_OK_CONFLICT)
    {
      syslog(LOG_ERR, "Unable to get list of printers - %s",
             cupsLastErrorString());

      ippDelete(response);

      return (-1);
    }

   /*
    * Scan the response for printers...
    */

    *dest = '\0';
    attr  = response->attrs;

    while (attr)
    {
     /*
      * Skip to the next printer...
      */

      while (attr && attr->group_tag != IPP_TAG_PRINTER)
        attr = attr->next;

      if (!attr)
        break;

     /*
      * Get all of the attributes for the current printer...
      */

      accepting_attr = NULL;
      info_attr      = NULL;
      name_attr      = NULL;
      shared_attr    = NULL;
      state_attr     = NULL;

      while (attr && attr->group_tag == IPP_TAG_PRINTER)
      {
        if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
	    attr->value_tag == IPP_TAG_BOOLEAN)
	  accepting_attr = attr;
	else if (!strcmp(attr->name, "printer-info") &&
	         attr->value_tag == IPP_TAG_TEXT)
	  info_attr = attr;
	else if (!strcmp(attr->name, "printer-name") &&
	         attr->value_tag == IPP_TAG_NAME)
	  name_attr = attr;
	else if (!strcmp(attr->name, "printer-is-shared") &&
	         attr->value_tag == IPP_TAG_BOOLEAN)
	  shared_attr = attr;
	else if (!strcmp(attr->name, "printer-state") &&
	         attr->value_tag == IPP_TAG_ENUM)
	  state_attr = attr;

        attr = attr->next;
      }

      if (info_attr && name_attr &&
          !_cups_strcasecmp(name, info_attr->values[0].string.text))
      {
       /*
        * Found a match, use this one!
	*/

	strlcpy(dest, name_attr->values[0].string.text, destsize);

	if (accepting && accepting_attr)
	  *accepting = accepting_attr->values[0].boolean;

	if (shared && shared_attr)
	  *shared = shared_attr->values[0].boolean;

	if (state && state_attr)
	  *state = (ipp_pstate_t)state_attr->values[0].integer;

        break;
      }
    }

    ippDelete(response);

    if (!*dest)
    {
      syslog(LOG_ERR, "Unable to find \"%s\" in list of printers!", name);

      return (-1);
    }

    name = dest;
  }
  else
  {
   /*
    * Get values from the response...
    */

    if (accepting)
    {
      if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs",
				   IPP_TAG_BOOLEAN)) == NULL)
	syslog(LOG_ERR, "No printer-is-accepting-jobs attribute found in "
			"response from server!");
      else
	*accepting = attr->values[0].boolean;
    }

    if (shared)
    {
      if ((attr = ippFindAttribute(response, "printer-is-shared",
				   IPP_TAG_BOOLEAN)) == NULL)
      {
	syslog(LOG_ERR, "No printer-is-shared attribute found in "
			"response from server!");
	*shared = 1;
      }
      else
	*shared = attr->values[0].boolean;
    }

    if (state)
    {
      if ((attr = ippFindAttribute(response, "printer-state",
				   IPP_TAG_ENUM)) == NULL)
	syslog(LOG_ERR, "No printer-state attribute found in "
			"response from server!");
      else
	*state = (ipp_pstate_t)attr->values[0].integer;
    }

    ippDelete(response);
  }

 /*
  * Next look for the printer in the lpoptions file...
  */

  num_options = 0;

  if (options && shared && accepting)
  {
    if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL)
      cups_serverroot = CUPS_SERVERROOT;

    snprintf(line, sizeof(line), "%s/lpoptions", cups_serverroot);
    if ((fp = cupsFileOpen(line, "r")) != NULL)
    {
      linenum = 0;
      while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
      {
       /*
	* Make sure we have "Dest name options" or "Default name options"...
	*/

	if ((_cups_strcasecmp(line, "Dest") && _cups_strcasecmp(line, "Default")) || !value)
          continue;

       /*
	* Separate destination name from options...
	*/

	for (optptr = value; *optptr && !isspace(*optptr & 255); optptr ++);

	while (*optptr == ' ')
	  *optptr++ = '\0';

       /*
	* If this is our destination, parse the options and break out of
	* the loop - we're done!
	*/

	if (!_cups_strcasecmp(value, name))
	{
          num_options = cupsParseOptions(optptr, num_options, options);
	  break;
	}
      }

      cupsFileClose(fp);
    }
  }
  else if (options)
    *options = NULL;

 /*
  * Return the number of options for this destination...
  */

  return (num_options);
}
示例#20
0
static int				/* O - Job ID or -1 on error */
create_job(http_t        *http,		/* I - HTTP connection */
           const char    *dest,		/* I - Destination name */
	   const char    *title,	/* I - job-name */
	   const char    *docname,	/* I - Name of job file */
           const char    *user,		/* I - requesting-user-name */
	   int           num_options,	/* I - Number of options for job */
	   cups_option_t *options)	/* I - Options for job */
{
  ipp_t		*request;		/* IPP request */
  ipp_t		*response;		/* IPP response */
  ipp_attribute_t *attr;		/* IPP attribute */
  char		uri[HTTP_MAX_URI];	/* Printer URI */
  int		id;			/* Job ID */


 /*
  * Setup the Create-Job request...
  */

  request = ippNewRequest(IPP_CREATE_JOB);

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   "localhost", 0, "/printers/%s", dest);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
               NULL, uri);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
               "requesting-user-name", NULL, user);

  if (title[0])
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
                 NULL, title);

  if (docname[0])
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
                 NULL, docname);

  cupsEncodeOptions(request, num_options, options);

 /*
  * Do the request...
  */

  snprintf(uri, sizeof(uri), "/printers/%s", dest);

  response = cupsDoRequest(http, request, uri);

  if (!response || cupsLastError() > IPP_OK_CONFLICT)
  {
    syslog(LOG_ERR, "Unable to create job - %s", cupsLastErrorString());

    ippDelete(response);

    return (-1);
  }

 /*
  * Get the job-id value from the response and return it...
  */

  if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL)
  {
    id = -1;

    syslog(LOG_ERR, "No job-id attribute found in response from server!");
  }
  else
  {
    id = attr->values[0].integer;

    syslog(LOG_INFO, "Print file - job ID = %d", id);
  }

  ippDelete(response);

  return (id);
}
static void
_pp_maintenance_command_execute_thread (GSimpleAsyncResult *res,
                                        GObject            *object,
                                        GCancellable       *cancellable)
{
  PpMaintenanceCommand        *command = (PpMaintenanceCommand *) object;
  PpMaintenanceCommandPrivate *priv = command->priv;
  static const char           *attrs[] = {"printer-commands"};
  ipp_attribute_t             *attr = NULL;
  gboolean                     success = FALSE;
  GError                      *error = NULL;
  ipp_t                       *request;
  ipp_t                       *response = NULL;
  gchar                       *printer_uri;
  gchar                       *printer_commands = NULL;
  gchar                       *printer_commands_lowercase = NULL;
  gchar                       *command_lowercase;
  gchar                       *file_name = NULL;
  int                          fd = -1;

  printer_uri = g_strdup_printf ("ipp://localhost/printers/%s",
                                 priv->printer_name);

  request = ippNewRequest (IPP_GET_PRINTER_ATTRIBUTES);
  ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
                "printer-uri", NULL, printer_uri);
  ippAddStrings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                 "requested-attributes", 1, NULL, attrs);
  response = cupsDoRequest (CUPS_HTTP_DEFAULT, request, "/");

  if (response)
    {
      if (ippGetStatusCode (response) <= IPP_OK_CONFLICT)
        {
          attr = ippFindAttribute (response, "printer-commands", IPP_TAG_ZERO);
          if (attr && ippGetCount (attr) > 0 && ippGetValueTag (attr) != IPP_TAG_NOVALUE)
            {
              if (ippGetValueTag (attr) == IPP_TAG_KEYWORD)
                {
                  printer_commands = g_strdup (ippGetString (attr, 0, NULL));
                }
            }
          else
            {
              success = TRUE;
            }
        }

      ippDelete (response);
    }

  if (printer_commands)
    {
      command_lowercase = g_ascii_strdown (priv->command, -1);
      printer_commands_lowercase = g_ascii_strdown (printer_commands, -1);

      if (g_strrstr (printer_commands_lowercase, command_lowercase))
        {
          request = ippNewRequest (IPP_PRINT_JOB);

          ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
                        "printer-uri", NULL, printer_uri);
          ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                        "job-name", NULL, priv->title);
          ippAddString (request, IPP_TAG_JOB, IPP_TAG_MIMETYPE,
                        "document-format", NULL, "application/vnd.cups-command");

          fd = g_file_open_tmp ("ccXXXXXX", &file_name, &error);

          if (fd != -1)
            {
              FILE *file;

              file = fdopen (fd, "w");
              fprintf (file, "#CUPS-COMMAND\n");
              fprintf (file, "%s\n", priv->command);
              fclose (file);

              response = cupsDoFileRequest (CUPS_HTTP_DEFAULT, request, "/", file_name);
              g_unlink (file_name);

              if (response)
                {
                  if (ippGetStatusCode (response) <= IPP_OK_CONFLICT)
                    {
                      success = TRUE;
                    }

                  ippDelete (response);
                }
            }

          g_free (file_name);
        }
      else
        {
          success = TRUE;
        }

      g_free (command_lowercase);
      g_free (printer_commands_lowercase);
      g_free (printer_commands);
    }

  g_free (printer_uri);

  if (!success)
    {
      g_simple_async_result_set_error (res,
                                       G_IO_ERROR,
                                       G_IO_ERROR_FAILED,
                                       "Execution of maintenance command failed.");
    }

  g_simple_async_result_set_op_res_gboolean (res, success);
}
示例#22
0
文件: request.c 项目: jelmer/cups
http_status_t				/* O - Initial HTTP status */
cupsSendRequest(http_t     *http,	/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
                ipp_t      *request,	/* I - IPP request */
                const char *resource,	/* I - Resource path */
		size_t     length)	/* I - Length of data to follow or @code CUPS_LENGTH_VARIABLE@ */
{
  http_status_t		status;		/* Status of HTTP request */
  int			got_status;	/* Did we get the status? */
  ipp_state_t		state;		/* State of IPP processing */
  http_status_t		expect;		/* Expect: header to use */


  DEBUG_printf(("cupsSendRequest(http=%p, request=%p(%s), resource=\"%s\", "
                "length=" CUPS_LLFMT ")", http, request,
		request ? ippOpString(request->request.op.operation_id) : "?",
		resource, CUPS_LLCAST length));

 /*
  * Range check input...
  */

  if (!request || !resource)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);

    return (HTTP_STATUS_ERROR);
  }

 /*
  * Get the default connection as needed...
  */

  if (!http)
    if ((http = _cupsConnect()) == NULL)
      return (HTTP_STATUS_SERVICE_UNAVAILABLE);

 /*
  * If the prior request was not flushed out, do so now...
  */

  if (http->state == HTTP_STATE_GET_SEND ||
      http->state == HTTP_STATE_POST_SEND)
  {
    DEBUG_puts("2cupsSendRequest: Flush prior response.");
    httpFlush(http);
  }
  else if (http->state != HTTP_STATE_WAITING)
  {
    DEBUG_printf(("1cupsSendRequest: Unknown HTTP state (%d), "
                  "reconnecting.", http->state));
    if (httpReconnect2(http, 30000, NULL))
      return (HTTP_STATUS_ERROR);
  }

#ifdef HAVE_SSL
 /*
  * See if we have an auth-info attribute and are communicating over
  * a non-local link.  If so, encrypt the link so that we can pass
  * the authentication information securely...
  */

  if (ippFindAttribute(request, "auth-info", IPP_TAG_TEXT) &&
      !httpAddrLocalhost(http->hostaddr) && !http->tls &&
      httpEncryption(http, HTTP_ENCRYPTION_REQUIRED))
  {
    DEBUG_puts("1cupsSendRequest: Unable to encrypt connection.");
    return (HTTP_STATUS_SERVICE_UNAVAILABLE);
  }
#endif /* HAVE_SSL */

 /*
  * Reconnect if the last response had a "Connection: close"...
  */

  if (!_cups_strcasecmp(http->fields[HTTP_FIELD_CONNECTION], "close"))
  {
    DEBUG_puts("2cupsSendRequest: Connection: close");
    httpClearFields(http);
    if (httpReconnect2(http, 30000, NULL))
    {
      DEBUG_puts("1cupsSendRequest: Unable to reconnect.");
      return (HTTP_STATUS_SERVICE_UNAVAILABLE);
    }
  }

 /*
  * Loop until we can send the request without authorization problems.
  */

  expect = HTTP_STATUS_CONTINUE;

  for (;;)
  {
    DEBUG_puts("2cupsSendRequest: Setup...");

   /*
    * Setup the HTTP variables needed...
    */

    httpClearFields(http);
    httpSetExpect(http, expect);
    httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
    httpSetLength(http, length);

#ifdef HAVE_GSSAPI
    if (http->authstring && !strncmp(http->authstring, "Negotiate", 9))
    {
     /*
      * Do not use cached Kerberos credentials since they will look like a
      * "replay" attack...
      */

      _cupsSetNegotiateAuthString(http, "POST", resource);
    }
#endif /* HAVE_GSSAPI */

    httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);

    DEBUG_printf(("2cupsSendRequest: authstring=\"%s\"", http->authstring));

   /*
    * Try the request...
    */

    DEBUG_puts("2cupsSendRequest: Sending HTTP POST...");

    if (httpPost(http, resource))
    {
      DEBUG_puts("2cupsSendRequest: POST failed, reconnecting.");
      if (httpReconnect2(http, 30000, NULL))
      {
        DEBUG_puts("1cupsSendRequest: Unable to reconnect.");
        return (HTTP_STATUS_SERVICE_UNAVAILABLE);
      }
      else
        continue;
    }

   /*
    * Send the IPP data...
    */

    DEBUG_puts("2cupsSendRequest: Writing IPP request...");

    request->state = IPP_STATE_IDLE;
    status         = HTTP_STATUS_CONTINUE;
    got_status     = 0;

    while ((state = ippWrite(http, request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;
      else if (httpCheck(http))
      {
        got_status = 1;

        _httpUpdate(http, &status);
	if (status >= HTTP_STATUS_MULTIPLE_CHOICES)
	  break;
      }

    if (state == IPP_STATE_ERROR)
    {
      DEBUG_puts("1cupsSendRequest: Unable to send IPP request.");

      http->status = HTTP_STATUS_ERROR;
      http->state  = HTTP_STATE_WAITING;

      return (HTTP_STATUS_ERROR);
    }

   /*
    * Wait up to 1 second to get the 100-continue response as needed...
    */

    if (!got_status)
    {
      if (expect == HTTP_STATUS_CONTINUE)
      {
	DEBUG_puts("2cupsSendRequest: Waiting for 100-continue...");

	if (httpWait(http, 1000))
	  _httpUpdate(http, &status);
      }
      else if (httpCheck(http))
	_httpUpdate(http, &status);
    }

    DEBUG_printf(("2cupsSendRequest: status=%d", status));

   /*
    * Process the current HTTP status...
    */

    if (status >= HTTP_STATUS_MULTIPLE_CHOICES)
    {
      int temp_status;			/* Temporary status */

      _cupsSetHTTPError(status);

      do
      {
	temp_status = httpUpdate(http);
      }
      while (temp_status != HTTP_STATUS_ERROR &&
             http->state == HTTP_STATE_POST_RECV);

      httpFlush(http);
    }

    switch (status)
    {
      case HTTP_STATUS_CONTINUE :
      case HTTP_STATUS_OK :
      case HTTP_STATUS_ERROR :
          DEBUG_printf(("1cupsSendRequest: Returning %d.", status));
          return (status);

      case HTTP_STATUS_UNAUTHORIZED :
          if (cupsDoAuthentication(http, "POST", resource))
	  {
            DEBUG_puts("1cupsSendRequest: Returning HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED.");
	    return (HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED);
	  }

          DEBUG_puts("2cupsSendRequest: Reconnecting after HTTP_STATUS_UNAUTHORIZED.");

	  if (httpReconnect2(http, 30000, NULL))
	  {
	    DEBUG_puts("1cupsSendRequest: Unable to reconnect.");
	    return (HTTP_STATUS_SERVICE_UNAVAILABLE);
	  }
	  break;

#ifdef HAVE_SSL
      case HTTP_STATUS_UPGRADE_REQUIRED :
	 /*
	  * Flush any error message, reconnect, and then upgrade with
	  * encryption...
	  */

          DEBUG_puts("2cupsSendRequest: Reconnecting after "
	             "HTTP_STATUS_UPGRADE_REQUIRED.");

	  if (httpReconnect2(http, 30000, NULL))
	  {
	    DEBUG_puts("1cupsSendRequest: Unable to reconnect.");
	    return (HTTP_STATUS_SERVICE_UNAVAILABLE);
	  }

	  DEBUG_puts("2cupsSendRequest: Upgrading to TLS.");
	  if (httpEncryption(http, HTTP_ENCRYPTION_REQUIRED))
	  {
	    DEBUG_puts("1cupsSendRequest: Unable to encrypt connection.");
	    return (HTTP_STATUS_SERVICE_UNAVAILABLE);
	  }
	  break;
#endif /* HAVE_SSL */

      case HTTP_STATUS_EXPECTATION_FAILED :
	 /*
	  * Don't try using the Expect: header the next time around...
	  */

	  expect = (http_status_t)0;

          DEBUG_puts("2cupsSendRequest: Reconnecting after "
	             "HTTP_EXPECTATION_FAILED.");

	  if (httpReconnect2(http, 30000, NULL))
	  {
	    DEBUG_puts("1cupsSendRequest: Unable to reconnect.");
	    return (HTTP_STATUS_SERVICE_UNAVAILABLE);
	  }
	  break;

      default :
         /*
	  * Some other error...
	  */

	  return (status);
    }
  }
}
示例#23
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int			status;		/* Status of tests (0 = success, 1 = fail) */
  const char		*ppdfile;	/* PPD filename */
  ppd_file_t		*ppd;		/* PPD file */
  _ppd_cache_t		*pc;		/* PPD cache and PWG mapping data */
  const pwg_media_t	*pwgmedia;	/* PWG media size */
  size_t		i,		/* Looping var */
			num_media;	/* Number of media sizes */
  const pwg_media_t	*mediatable;	/* Media size table */
  int			dupmedia = 0;	/* Duplicate media sizes? */


  status = 0;

  if (argc < 2 || argc > 3)
  {
    puts("Usage: ./testpwg filename.ppd [jobfile]");
    return (1);
  }

  ppdfile = argv[1];

  printf("ppdOpenFile(%s): ", ppdfile);
  if ((ppd = ppdOpenFile(ppdfile)) == NULL)
  {
    ppd_status_t err;			/* Last error in file */
    int		line;			/* Line number in file */


    err = ppdLastError(&line);

    printf("FAIL (%s on line %d)\n", ppdErrorString(err), line);

    return (1);
  }
  else
    puts("PASS");

  fputs("_ppdCacheCreateWithPPD(ppd): ", stdout);
  if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
  {
    puts("FAIL");
    status ++;
  }
  else
  {
    puts("PASS");
    status += test_ppd_cache(pc, ppd);

    if (argc == 3)
    {
     /*
      * Test PageSize mapping code.
      */

      int		fd;		/* Job file descriptor */
      const char	*pagesize;	/* PageSize value */
      ipp_t		*job;		/* Job attributes */
      ipp_attribute_t	*media;		/* Media attribute */

      if ((fd = open(argv[2], O_RDONLY)) >= 0)
      {
	job = ippNew();
	ippReadFile(fd, job);
	close(fd);

        if ((media = ippFindAttribute(job, "media", IPP_TAG_ZERO)) != NULL &&
	    media->value_tag != IPP_TAG_NAME &&
	    media->value_tag != IPP_TAG_KEYWORD)
	  media = NULL;

	if (media)
	  printf("_ppdCacheGetPageSize(media=%s): ",
	         media->values[0].string.text);
	else
	  fputs("_ppdCacheGetPageSize(media-col): ", stdout);

        fflush(stdout);

	if ((pagesize = _ppdCacheGetPageSize(pc, job, NULL, NULL)) == NULL)
	{
	  puts("FAIL (Not Found)");
	  status = 1;
	}
	else if (media && _cups_strcasecmp(pagesize, media->values[0].string.text))
	{
	  printf("FAIL (Got \"%s\", Expected \"%s\")\n", pagesize,
		 media->values[0].string.text);
	  status = 1;
	}
	else
	  printf("PASS (%s)\n", pagesize);

	ippDelete(job);
      }
      else
      {
        perror(argv[2]);
	status = 1;
      }
    }

   /*
    * _ppdCacheDestroy should never fail...
    */

    fputs("_ppdCacheDestroy(pc): ", stdout);
    _ppdCacheDestroy(pc);
    puts("PASS");
  }

  fputs("pwgMediaForPWG(\"iso_a4_210x297mm\"): ", stdout);
  if ((pwgmedia = pwgMediaForPWG("iso_a4_210x297mm")) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "iso_a4_210x297mm"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else if (pwgmedia->width != 21000 || pwgmedia->length != 29700)
  {
    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
    status ++;
  }
  else
    puts("PASS");

  fputs("pwgMediaForPWG(\"roll_max_36.1025x3622.0472in\"): ", stdout);
  if ((pwgmedia = pwgMediaForPWG("roll_max_36.1025x3622.0472in")) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (pwgmedia->width != 91700 || pwgmedia->length != 9199999)
  {
    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
    status ++;
  }
  else
    printf("PASS (%dx%d)\n", pwgmedia->width, pwgmedia->length);

  fputs("pwgMediaForLegacy(\"na-letter\"): ", stdout);
  if ((pwgmedia = pwgMediaForLegacy("na-letter")) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "na_letter_8.5x11in"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else if (pwgmedia->width != 21590 || pwgmedia->length != 27940)
  {
    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
    status ++;
  }
  else
    puts("PASS");

  fputs("pwgMediaForPPD(\"4x6\"): ", stdout);
  if ((pwgmedia = pwgMediaForPPD("4x6")) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "na_index-4x6_4x6in"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else if (pwgmedia->width != 10160 || pwgmedia->length != 15240)
  {
    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
    status ++;
  }
  else
    puts("PASS");

  fputs("pwgMediaForPPD(\"10x15cm\"): ", stdout);
  if ((pwgmedia = pwgMediaForPPD("10x15cm")) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "om_100x150mm_100x150mm"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else if (pwgmedia->width != 10000 || pwgmedia->length != 15000)
  {
    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
    status ++;
  }
  else
    puts("PASS");

  fputs("pwgMediaForPPD(\"Custom.10x15cm\"): ", stdout);
  if ((pwgmedia = pwgMediaForPPD("Custom.10x15cm")) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "custom_10x15cm_100x150mm"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else if (pwgmedia->width != 10000 || pwgmedia->length != 15000)
  {
    printf("FAIL (%dx%d)\n", pwgmedia->width, pwgmedia->length);
    status ++;
  }
  else
    puts("PASS");

  fputs("pwgMediaForSize(29700, 42000): ", stdout);
  if ((pwgmedia = pwgMediaForSize(29700, 42000)) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "iso_a3_297x420mm"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else
    puts("PASS");

  fputs("pwgMediaForSize(9842, 19050): ", stdout);
  if ((pwgmedia = pwgMediaForSize(9842, 19050)) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "na_monarch_3.875x7.5in"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else
    printf("PASS (%s)\n", pwgmedia->pwg);

  fputs("pwgMediaForSize(9800, 19000): ", stdout);
  if ((pwgmedia = pwgMediaForSize(9800, 19000)) == NULL)
  {
    puts("FAIL (not found)");
    status ++;
  }
  else if (strcmp(pwgmedia->pwg, "jpn_you6_98x190mm"))
  {
    printf("FAIL (%s)\n", pwgmedia->pwg);
    status ++;
  }
  else
    printf("PASS (%s)\n", pwgmedia->pwg);

  fputs("Duplicate size test: ", stdout);
  for (mediatable = _pwgMediaTable(&num_media);
       num_media > 1;
       num_media --, mediatable ++)
  {
    for (i = num_media - 1, pwgmedia = mediatable + 1; i > 0; i --, pwgmedia ++)
    {
      if (pwgmedia->width == mediatable->width &&
          pwgmedia->length == mediatable->length)
      {
        if (!dupmedia)
        {
          dupmedia = 1;
          status ++;
          puts("FAIL");
        }

        printf("    %s and %s have the same dimensions (%dx%d)\n",
               pwgmedia->pwg, mediatable->pwg, pwgmedia->width,
               pwgmedia->length);
      }
    }
  }
  if (!dupmedia)
    puts("PASS");


  return (status);
}
示例#24
0
文件: testipp.c 项目: lanceit/cups
int				/* O - Exit status */
main(int  argc,			/* I - Number of command-line arguments */
     char *argv[])		/* I - Command-line arguments */
{
  _ippdata_t	data;		/* IPP buffer */
  ipp_uchar_t	buffer[8192];	/* Write buffer data */
  ipp_t		*cols[2],	/* Collections */
		*size;		/* media-size collection */
  ipp_t		*request;	/* Request */
  ipp_attribute_t *media_col,	/* media-col attribute */
		*media_size,	/* media-size attribute */
		*attr;		/* Other attribute */
  ipp_state_t	state;		/* State */
  size_t	length;		/* Length of data */
  cups_file_t	*fp;		/* File pointer */
  size_t	i;		/* Looping var */
  int		status;		/* Status of tests (0 = success, 1 = fail) */
#ifdef DEBUG
  const char	*name;		/* Option name */
#endif /* DEBUG */


  status = 0;

  if (argc == 1)
  {
   /*
    * Test request generation code...
    */

    printf("Create Sample Request: ");

    request = ippNew();
    request->request.op.version[0]   = 0x01;
    request->request.op.version[1]   = 0x01;
    request->request.op.operation_id = IPP_OP_PRINT_JOB;
    request->request.op.request_id   = 1;

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
        	 "attributes-charset", NULL, "utf-8");
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
        	 "attributes-natural-language", NULL, "en");
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
        	 "printer-uri", NULL, "ipp://localhost/printers/foo");

    cols[0] = ippNew();
    size    = ippNew();
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590);
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940);
    ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size);
    ippDelete(size);
    ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
                 "blue");
    ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
                 "plain");

    cols[1] = ippNew();
    size    = ippNew();
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000);
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700);
    ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size);
    ippDelete(size);
    ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
                 "plaid");
    ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
		 "glossy");

    ippAddCollections(request, IPP_TAG_JOB, "media-col", 2,
                      (const ipp_t **)cols);
    ippDelete(cols[0]);
    ippDelete(cols[1]);

    length = ippLength(request);
    if (length != sizeof(collection))
    {
      printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
             (int)length, (int)sizeof(collection));
      status = 1;
    }
    else
      puts("PASS");

   /*
    * Write test #1...
    */

    printf("Write Sample to Memory: ");

    data.wused   = 0;
    data.wsize   = sizeof(buffer);
    data.wbuffer = buffer;

    while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL,
                               request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    if (state != IPP_STATE_DATA)
    {
      printf("FAIL - %d bytes written.\n", (int)data.wused);
      status = 1;
    }
    else if (data.wused != sizeof(collection))
    {
      printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused,
             (int)sizeof(collection));
      hex_dump("Bytes Written", data.wbuffer, data.wused);
      hex_dump("Baseline", collection, sizeof(collection));
      status = 1;
    }
    else if (memcmp(data.wbuffer, collection, data.wused))
    {
      for (i = 0; i < data.wused; i ++)
        if (data.wbuffer[i] != collection[i])
	  break;

      printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i);
      hex_dump("Bytes Written", data.wbuffer, data.wused);
      hex_dump("Baseline", collection, sizeof(collection));
      status = 1;
    }
    else
      puts("PASS");

    ippDelete(request);

   /*
    * Read the data back in and confirm...
    */

    printf("Read Sample from Memory: ");

    request     = ippNew();
    data.rpos = 0;

    while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
                              request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    length = ippLength(request);

    if (state != IPP_STATE_DATA)
    {
      printf("FAIL - %d bytes read.\n", (int)data.rpos);
      status = 1;
    }
    else if (data.rpos != data.wused)
    {
      printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
             (int)data.wused);
      print_attributes(request, 8);
      status = 1;
    }
    else if (length != sizeof(collection))
    {
      printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
             (int)length, (int)sizeof(collection));
      print_attributes(request, 8);
      status = 1;
    }
    else
      puts("PASS");

    fputs("ippFindAttribute(media-col): ", stdout);
    if ((media_col = ippFindAttribute(request, "media-col",
                                      IPP_TAG_BEGIN_COLLECTION)) == NULL)
    {
      if ((media_col = ippFindAttribute(request, "media-col",
                                        IPP_TAG_ZERO)) == NULL)
        puts("FAIL (not found)");
      else
        printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag));

      status = 1;
    }
    else if (media_col->num_values != 2)
    {
      printf("FAIL (wrong count - %d)\n", media_col->num_values);
      status = 1;
    }
    else
      puts("PASS");

    if (media_col)
    {
      fputs("ippFindAttribute(media-size 1): ", stdout);
      if ((media_size = ippFindAttribute(media_col->values[0].collection,
					 "media-size",
					 IPP_TAG_BEGIN_COLLECTION)) == NULL)
      {
	if ((media_size = ippFindAttribute(media_col->values[0].collection,
					   "media-col",
					   IPP_TAG_ZERO)) == NULL)
	  puts("FAIL (not found)");
	else
	  printf("FAIL (wrong type - %s)\n",
	         ippTagString(media_size->value_tag));

	status = 1;
      }
      else
      {
	if ((attr = ippFindAttribute(media_size->values[0].collection,
				     "x-dimension", IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "x-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing x-dimension)");
	  else
	    printf("FAIL (wrong type for x-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 21590)
	{
	  printf("FAIL (wrong value for x-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else if ((attr = ippFindAttribute(media_size->values[0].collection,
					  "y-dimension",
					  IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "y-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing y-dimension)");
	  else
	    printf("FAIL (wrong type for y-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 27940)
	{
	  printf("FAIL (wrong value for y-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else
	  puts("PASS");
      }

      fputs("ippFindAttribute(media-size 2): ", stdout);
      if ((media_size = ippFindAttribute(media_col->values[1].collection,
					 "media-size",
					 IPP_TAG_BEGIN_COLLECTION)) == NULL)
      {
	if ((media_size = ippFindAttribute(media_col->values[1].collection,
					   "media-col",
					   IPP_TAG_ZERO)) == NULL)
	  puts("FAIL (not found)");
	else
	  printf("FAIL (wrong type - %s)\n",
	         ippTagString(media_size->value_tag));

	status = 1;
      }
      else
      {
	if ((attr = ippFindAttribute(media_size->values[0].collection,
				     "x-dimension",
				     IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "x-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing x-dimension)");
	  else
	    printf("FAIL (wrong type for x-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 21000)
	{
	  printf("FAIL (wrong value for x-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else if ((attr = ippFindAttribute(media_size->values[0].collection,
					  "y-dimension",
					  IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "y-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing y-dimension)");
	  else
	    printf("FAIL (wrong type for y-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 29700)
	{
	  printf("FAIL (wrong value for y-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else
	  puts("PASS");
      }
    }

   /*
    * Test hierarchical find...
    */

    fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout);
    if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
    {
      if (ippGetInteger(attr, 0) != 21590)
      {
        printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
        status = 1;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (not found)");
      status = 1;
    }

    fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout);
    if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
    {
      if (ippGetInteger(attr, 0) != 21000)
      {
        printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
        status = 1;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (not found)");
      status = 1;
    }

    fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout);
    if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
    {
      printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0));
      status = 1;
    }
    else
      puts("PASS");

    ippDelete(request);

   /*
    * Read the mixed data and confirm we converted everything to rangeOfInteger
    * values...
    */

    printf("Read Mixed integer/rangeOfInteger from Memory: ");

    request = ippNew();
    data.rpos    = 0;
    data.wused   = sizeof(mixed);
    data.wsize   = sizeof(mixed);
    data.wbuffer = mixed;

    while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
                              request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    length = ippLength(request);

    if (state != IPP_STATE_DATA)
    {
      printf("FAIL - %d bytes read.\n", (int)data.rpos);
      status = 1;
    }
    else if (data.rpos != sizeof(mixed))
    {
      printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
             (int)sizeof(mixed));
      print_attributes(request, 8);
      status = 1;
    }
    else if (length != (sizeof(mixed) + 4))
    {
      printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
             (int)length, (int)sizeof(mixed) + 4);
      print_attributes(request, 8);
      status = 1;
    }
    else
      puts("PASS");

    fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout);
    if ((attr = ippFindAttribute(request, "notify-lease-duration-supported",
                                 IPP_TAG_ZERO)) == NULL)
    {
      puts("FAIL (not found)");
      status = 1;
    }
    else if (attr->value_tag != IPP_TAG_RANGE)
    {
      printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag));
      status = 1;
    }
    else if (attr->num_values != 2)
    {
      printf("FAIL (wrong count - %d)\n", attr->num_values);
      status = 1;
    }
    else if (attr->values[0].range.lower != 1 ||
             attr->values[0].range.upper != 1 ||
             attr->values[1].range.lower != 16 ||
             attr->values[1].range.upper != 32)
    {
      printf("FAIL (wrong values - %d,%d and %d,%d)\n",
             attr->values[0].range.lower,
             attr->values[0].range.upper,
             attr->values[1].range.lower,
             attr->values[1].range.upper);
      status = 1;
    }
    else
      puts("PASS");

    ippDelete(request);

#ifdef DEBUG
   /*
    * Test that private option array is sorted...
    */

    fputs("_ippCheckOptions: ", stdout);
    if ((name = _ippCheckOptions()) == NULL)
      puts("PASS");
    else
    {
      printf("FAIL (\"%s\" out of order)\n", name);
      status = 1;
    }
#endif /* DEBUG */

   /*
    * Test _ippFindOption() private API...
    */

    fputs("_ippFindOption(\"printer-type\"): ", stdout);
    if (_ippFindOption("printer-type"))
      puts("PASS");
    else
    {
      puts("FAIL");
      status = 1;
    }

   /*
    * Summarize...
    */

    putchar('\n');

    if (status)
      puts("Core IPP tests failed.");
    else
      puts("Core IPP tests passed.");
  }
  else
  {
   /*
    * Read IPP files...
    */

    for (i = 1; i < (size_t)argc; i ++)
    {
      if ((fp = cupsFileOpen(argv[i], "r")) == NULL)
      {
	printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno));
	status = 1;
	continue;
      }

      request = ippNew();
      while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
                                request)) == IPP_STATE_ATTRIBUTE);

      if (state != IPP_STATE_DATA)
      {
	printf("Error reading IPP message from \"%s\"!\n", argv[i]);
	status = 1;
      }
      else
      {
	printf("\n%s:\n", argv[i]);
	print_attributes(request, 4);
      }

      ippDelete(request);
      cupsFileClose(fp);
    }
  }

  return (status);
}
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  const char	*opt,			/* Current option character */
		*name = NULL,		/* Service name */
		*type = "_ipp._tcp",	/* Service type */
		*domain = "local.";	/* Service domain */
#ifdef HAVE_DNSSD
  DNSServiceRef	ref;			/* Browsing service reference */
#endif /* HAVE_DNSSD */
#ifdef HAVE_AVAHI
  AvahiClient	*client;		/* Client information */
  int		error;			/* Error code, if any */
#endif /* HAVE_AVAHI */


  for (i = 1; i < argc; i ++)
    if (!strcmp(argv[i], "snmp"))
      snmponly = 1;
    else if (!strcmp(argv[i], "ipp"))
      ipponly = 1;
    else
    {
      puts("Usage: ./ipp-printers [{ipp | snmp}]");
      return (1);
    }

 /*
  * Create an array to track devices...
  */

  devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL);

 /*
  * Browse for different kinds of printers...
  */

  if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError)
  {
    perror("ERROR: Unable to create service connection");
    return (1);
  }

  fd = DNSServiceRefSockFD(main_ref);

  ipp_ref = main_ref;
  DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0,
                   "_ipp._tcp", NULL, browse_callback, devices);

 /*
  * Loop until we are killed...
  */

  progress();

  for (;;)
  {
    FD_ZERO(&input);
    FD_SET(fd, &input);

    timeout.tv_sec  = 2;
    timeout.tv_usec = 500000;

    if (select(fd + 1, &input, NULL, NULL, &timeout) <= 0)
    {
      time_t curtime = time(NULL);

      for (device = (cups_device_t *)cupsArrayFirst(devices);
           device;
	   device = (cups_device_t *)cupsArrayNext(devices))
        if (!device->got_resolve)
        {
          if (!device->ref)
            break;

          if ((curtime - device->resolve_time) > 10)
          {
            device->got_resolve = -1;
	    fprintf(stderr, "\rUnable to resolve \"%s\": timeout\n",
		    device->name);
	    progress();
	  }
          else
            break;
        }

      if (!device)
        break;
    }

    if (FD_ISSET(fd, &input))
    {
     /*
      * Process results of our browsing...
      */

      progress();
      DNSServiceProcessResult(main_ref);
    }
    else
    {
     /*
      * Query any devices we've found...
      */

      DNSServiceErrorType	status;	/* DNS query status */
      int			count;	/* Number of queries */


      for (device = (cups_device_t *)cupsArrayFirst(devices), count = 0;
           device;
	   device = (cups_device_t *)cupsArrayNext(devices))
      {
        if (!device->ref && !device->sent)
	{
	 /*
	  * Found the device, now get the TXT record(s) for it...
	  */

          if (count < 50)
	  {
	    device->resolve_time = time(NULL);
	    device->ref          = main_ref;

	    status = DNSServiceResolve(&(device->ref),
				       kDNSServiceFlagsShareConnection,
				       0, device->name, device->regtype,
				       device->domain, resolve_callback,
				       device);
            if (status != kDNSServiceErr_NoError)
            {
	      fprintf(stderr, "\rUnable to resolve \"%s\": %d\n",
	              device->name, status);
	      progress();
	    }
	    else
	      count ++;
          }
	}
	else if (!device->sent && device->got_resolve)
	{
	 /*
	  * Got the TXT records, now report the device...
	  */

	  DNSServiceRefDeallocate(device->ref);
	  device->ref  = 0;
	  device->sent = 1;
        }
      }
    }
  }

#ifndef DEBUG
  fprintf(stderr, "\rFound %d printers. Now querying for capabilities...\n",
          cupsArrayCount(devices));
#endif /* !DEBUG */

  puts("#!/bin/sh -x");
  puts("test -d results && rm -rf results");
  puts("mkdir results");
  puts("CUPS_DEBUG_LEVEL=6; export CUPS_DEBUG_LEVEL");
  puts("CUPS_DEBUG_FILTER='^(ipp|http|_ipp|_http|cupsGetResponse|cupsSend|"
       "cupsWrite|cupsDo).*'; export CUPS_DEBUG_FILTER");

  for (device = (cups_device_t *)cupsArrayFirst(devices);
       device;
       device = (cups_device_t *)cupsArrayNext(devices))
  {
    if (device->got_resolve <= 0 || device->cups_shared)
      continue;

#ifdef DEBUG
    fprintf(stderr, "Checking \"%s\" (got_resolve=%d, cups_shared=%d, uri=%s)\n",
            device->name, device->got_resolve, device->cups_shared, device->uri);
#else
    fprintf(stderr, "Checking \"%s\"...\n", device->name);
#endif /* DEBUG */

    if ((http = httpConnect(device->host, device->port)) == NULL)
    {
      fprintf(stderr, "Failed to connect to \"%s\": %s\n", device->name,
              cupsLastErrorString());
      continue;
    }

    request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
                 device->uri);

    response = cupsDoRequest(http, request, device->rp);

    if (cupsLastError() > IPP_OK_SUBST)
      fprintf(stderr, "Failed to query \"%s\": %s\n", device->name,
              cupsLastErrorString());
    else
    {
      if ((attr = ippFindAttribute(response, "ipp-versions-supported",
				   IPP_TAG_KEYWORD)) != NULL)
      {
	version = attr->values[0].string.text;

	for (i = 1; i < attr->num_values; i ++)
	  if (strcmp(attr->values[i].string.text, version) > 0)
	    version = attr->values[i].string.text;
      }
      else
	version = "1.0";

      testfile = NULL;

      if ((attr = ippFindAttribute(response, "document-format-supported",
                                   IPP_TAG_MIMETYPE)) != NULL)
      {
       /*
        * Figure out the test file for printing, preferring PDF and PostScript
        * over JPEG and plain text...
        */

        for (i = 0; i < attr->num_values; i ++)
        {
          if (!strcasecmp(attr->values[i].string.text, "application/pdf"))
          {
            testfile = "testfile.pdf";
            break;
          }
          else if (!strcasecmp(attr->values[i].string.text,
                               "application/postscript"))
            testfile = "testfile.ps";
          else if (!strcasecmp(attr->values[i].string.text, "image/jpeg") &&
                   !testfile)
            testfile = "testfile.jpg";
          else if (!strcasecmp(attr->values[i].string.text, "text/plain") &&
                   !testfile)
            testfile = "testfile.txt";
          else if (!strcasecmp(attr->values[i].string.text,
                               "application/vnd.hp-PCL") && !testfile)
            testfile = "testfile.pcl";
        }

        if (!testfile)
        {
          fprintf(stderr,
                  "Printer \"%s\" reports the following IPP file formats:\n",
                  device->name);
          for (i = 0; i < attr->num_values; i ++)
            fprintf(stderr, "    \"%s\"\n", attr->values[i].string.text);
        }
      }

      if (!testfile && device->pdl)
      {
	char	*pdl,			/* Copy of pdl string */
		*start, *end;		/* Pointers into pdl string */


        pdl = strdup(device->pdl);
	for (start = device->pdl; start && *start; start = end)
	{
	  if ((end = strchr(start, ',')) != NULL)
	    *end++ = '\0';

	  if (!strcasecmp(start, "application/pdf"))
	  {
	    testfile = "testfile.pdf";
	    break;
	  }
	  else if (!strcasecmp(start, "application/postscript"))
	    testfile = "testfile.ps";
	  else if (!strcasecmp(start, "image/jpeg") && !testfile)
	    testfile = "testfile.jpg";
	  else if (!strcasecmp(start, "text/plain") && !testfile)
	    testfile = "testfile.txt";
	  else if (!strcasecmp(start, "application/vnd.hp-PCL") && !testfile)
	    testfile = "testfile.pcl";
	}
	free(pdl);

        if (testfile)
        {
	  fprintf(stderr,
		  "Using \"%s\" for printer \"%s\" based on TXT record pdl "
		  "info.\n", testfile, device->name);
        }
        else
        {
	  fprintf(stderr,
		  "Printer \"%s\" reports the following TXT file formats:\n",
		  device->name);
	  fprintf(stderr, "    \"%s\"\n", device->pdl);
	}
      }

      if (!device->ty &&
	  (attr = ippFindAttribute(response, "printer-make-and-model",
				   IPP_TAG_TEXT)) != NULL)
	device->ty = strdup(attr->values[0].string.text);

      if (strcmp(version, "1.0") && testfile && device->ty)
      {
	char		filename[1024],	/* Filename */
			*fileptr;	/* Pointer into filename */
	const char	*typtr;		/* Pointer into ty */

        if (!strncasecmp(device->ty, "DeskJet", 7) ||
            !strncasecmp(device->ty, "DesignJet", 9) ||
            !strncasecmp(device->ty, "OfficeJet", 9) ||
            !strncasecmp(device->ty, "Photosmart", 10))
          strlcpy(filename, "HP_", sizeof(filename));
        else
          filename[0] = '\0';

	fileptr = filename + strlen(filename);

        if (!strncasecmp(device->ty, "Lexmark International Lexmark", 29))
          typtr = device->ty + 22;
        else
          typtr = device->ty;

	while (*typtr && fileptr < (filename + sizeof(filename) - 1))
	{
	  if (isalnum(*typtr & 255) || *typtr == '-')
	    *fileptr++ = *typtr++;
	  else
	  {
	    *fileptr++ = '_';
	    typtr++;
	  }
	}

	*fileptr = '\0';

        printf("# %s\n", device->name);
        printf("echo \"Testing %s...\"\n", device->name);

        if (!ipponly)
        {
	  printf("echo \"snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 "
	         "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1\" > results/%s.snmpwalk\n",
	         device->host, filename);
	  printf("snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 "
	         "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1 | "
	         "tee -a results/%s.snmpwalk\n",
	         device->host, filename);
        }

        if (!snmponly)
        {
	  printf("echo \"./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s "
	         "ipp-%s.test\" > results/%s.log\n", testfile, version,
	         device->uri, version, filename);
	  printf("CUPS_DEBUG_LOG=results/%s.debug_log "
	         "./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s "
	         "ipp-%s.test | tee -a results/%s.log\n", filename,
	         testfile, version, device->uri,
	         version, filename);
        }

	puts("");
      }
      else if (!device->ty)
	fprintf(stderr,
		"Ignoring \"%s\" since it doesn't provide a make and model.\n",
		device->name);
      else if (!testfile)
	fprintf(stderr,
	        "Ignoring \"%s\" since it does not support a common format.\n",
		device->name);
      else
	fprintf(stderr, "Ignoring \"%s\" since it only supports IPP/1.0.\n",
		device->name);
    }

    ippDelete(response);
    httpClose(http);
  }

  return (0);
}
示例#26
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  const char	*printer;		/* Printer name */
  const char	*user;			/* Username */
  http_t	*http;			/* Connection to the server */
  ipp_t		*request,		/* IPP request */
		*response;		/* IPP response */
  ipp_attribute_t *attr;		/* IPP attribute */
  const char	*op;			/* Operation to perform, if any */
  static const char *def_attrs[] =	/* Attributes for default printer */
		{
		  "printer-name",
		  "printer-uri-supported"
		};


 /*
  * Get any form variables...
  */

  cgiInitialize();

  op = cgiGetVariable("OP");

 /*
  * Set the web interface section...
  */

  cgiSetVariable("SECTION", "printers");
  cgiSetVariable("REFRESH_PAGE", "");

 /*
  * See if we are displaying a printer or all printers...
  */

  if ((printer = getenv("PATH_INFO")) != NULL)
  {
    printer ++;

    if (!*printer)
      printer = NULL;

    if (printer)
      cgiSetVariable("PRINTER_NAME", printer);
  }

 /*
  * See who is logged in...
  */

  user = getenv("REMOTE_USER");

 /*
  * Connect to the HTTP server...
  */

  http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());

 /*
  * Get the default printer...
  */

  if (!op || !cgiIsPOST())
  {
   /*
    * Get the default destination...
    */

    request = ippNewRequest(CUPS_GET_DEFAULT);

    ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                  "requested-attributes",
		  sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs);

    if ((response = cupsDoRequest(http, request, "/")) != NULL)
    {
      if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
        cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text);

      if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
      {
	char	url[HTTP_MAX_URI];	/* New URL */


        cgiSetVariable("DEFAULT_URI",
	               cgiRewriteURL(attr->values[0].string.text,
		                     url, sizeof(url), NULL));
      }

      ippDelete(response);
    }

   /*
    * See if we need to show a list of printers or the status of a
    * single printer...
    */

    if (!printer)
      show_all_printers(http, user);
    else
      show_printer(http, printer);
  }
  else if (printer)
  {
    if (!*op)
    {
      const char *server_port = getenv("SERVER_PORT");
					/* Port number string */
      int	port = atoi(server_port ? server_port : "0");
      					/* Port number */
      char	uri[1024];		/* URL */

      httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri),
		       getenv("HTTPS") ? "https" : "http", NULL,
		       getenv("SERVER_NAME"), port, "/printers/%s", printer);

      printf("Location: %s\n\n", uri);
    }
    else if (!strcmp(op, "start-printer"))
      do_printer_op(http, printer, IPP_RESUME_PRINTER,
                    cgiText(_("Resume Printer")));
    else if (!strcmp(op, "stop-printer"))
      do_printer_op(http, printer, IPP_PAUSE_PRINTER,
                    cgiText(_("Pause Printer")));
    else if (!strcmp(op, "accept-jobs"))
      do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs")));
    else if (!strcmp(op, "reject-jobs"))
      do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs")));
    else if (!strcmp(op, "purge-jobs"))
      do_printer_op(http, printer, IPP_PURGE_JOBS, cgiText(_("Purge Jobs")));
    else if (!_cups_strcasecmp(op, "print-self-test-page"))
      cgiPrintCommand(http, printer, "PrintSelfTestPage",
                      cgiText(_("Print Self-Test Page")));
    else if (!_cups_strcasecmp(op, "clean-print-heads"))
      cgiPrintCommand(http, printer, "Clean all",
                      cgiText(_("Clean Print Heads")));
    else if (!_cups_strcasecmp(op, "print-test-page"))
      cgiPrintTestPage(http, printer);
    else if (!_cups_strcasecmp(op, "move-jobs"))
      cgiMoveJobs(http, printer, 0);
    else
    {
     /*
      * Unknown/bad operation...
      */

      cgiStartHTML(printer);
      cgiCopyTemplateLang("error-op.tmpl");
      cgiEndHTML();
    }
  }
  else
  {
   /*
    * Unknown/bad operation...
    */

    cgiStartHTML(cgiText(_("Printers")));
    cgiCopyTemplateLang("error-op.tmpl");
    cgiEndHTML();
  }

 /*
  * Close the HTTP server connection...
  */

  httpClose(http);

 /*
  * Return with no errors...
  */

  return (0);
}
示例#27
0
static void
process_children(void)
{
  int		status;			/* Exit status of child */
  int		pid,			/* Process ID of child */
		job_id;			/* Job ID of child */
  cupsd_job_t	*job;			/* Current job */
  int		i;			/* Looping var */
  char		name[1024];		/* Process name */
  const char	*type;			/* Type of program */


  cupsdLogMessage(CUPSD_LOG_DEBUG2, "process_children()");

 /*
  * Reset the dead_children flag...
  */

  dead_children = 0;

 /*
  * Collect the exit status of some children...
  */

#ifdef HAVE_WAITPID
  while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
#elif defined(HAVE_WAIT3)
  while ((pid = wait3(&status, WNOHANG, NULL)) > 0)
#else
  if ((pid = wait(&status)) > 0)
#endif /* HAVE_WAITPID */
  {
   /*
    * Collect the name of the process that finished...
    */

    cupsdFinishProcess(pid, name, sizeof(name), &job_id);

   /*
    * Delete certificates for CGI processes...
    */

    if (pid)
      cupsdDeleteCert(pid);

   /*
    * Handle completed job filters...
    */

    if (job_id > 0)
      job = cupsdFindJob(job_id);
    else
      job  = NULL;

    if (job)
    {
      for (i = 0; job->filters[i]; i ++)
	if (job->filters[i] == pid)
	  break;

      if (job->filters[i] || job->backend == pid)
      {
       /*
	* OK, this process has gone away; what's left?
	*/

	if (job->filters[i])
	{
	  job->filters[i] = -pid;
	  type            = "Filter";
	}
	else
	{
	  job->backend = -pid;
	  type         = "Backend";
	}

	if (status && status != SIGTERM && status != SIGKILL &&
	    status != SIGPIPE)
	{
	 /*
	  * An error occurred; save the exit status so we know to stop
	  * the printer or cancel the job when all of the filters finish...
	  *
	  * A negative status indicates that the backend failed and the
	  * printer needs to be stopped.
	  *
	  * In order to preserve the most serious status, we always log
	  * when a process dies due to a signal (e.g. SIGABRT, SIGSEGV,
	  * and SIGBUS) and prefer to log the backend exit status over a
	  * filter's.
	  */

	  int old_status = abs(job->status);

          if (WIFSIGNALED(status) ||	/* This process crashed, or */
              !job->status ||		/* No process had a status, or */
              (!job->filters[i] && WIFEXITED(old_status)))
          {				/* Backend and filter didn't crash */
	    if (job->filters[i])
	      job->status = status;	/* Filter failed */
	    else
	      job->status = -status;	/* Backend failed */
          }

	  if (job->state_value == IPP_JOB_PROCESSING &&
	      job->status_level > CUPSD_LOG_ERROR &&
	      (job->filters[i] || !WIFEXITED(status)))
	  {
	    char	message[1024];	/* New printer-state-message */


	    job->status_level = CUPSD_LOG_ERROR;

	    snprintf(message, sizeof(message), "%s failed", type);

            if (job->printer)
	    {
	      strlcpy(job->printer->state_message, message,
		       sizeof(job->printer->state_message));
	    }

	    if (!job->attrs)
	      cupsdLoadJob(job);

	    if (!job->printer_message && job->attrs)
	    {
	      if ((job->printer_message =
	               ippFindAttribute(job->attrs, "job-printer-state-message",
					IPP_TAG_TEXT)) == NULL)
		job->printer_message = ippAddString(job->attrs, IPP_TAG_JOB,
		                                    IPP_TAG_TEXT,
						    "job-printer-state-message",
						    NULL, NULL);
	    }

	    if (job->printer_message)
	      cupsdSetString(&(job->printer_message->values[0].string.text),
			     message);
	  }
	}

       /*
	* If this is not the last file in a job, see if all of the
	* filters are done, and if so move to the next file.
	*/

	if (job->current_file < job->num_files && job->printer)
	{
	  for (i = 0; job->filters[i] < 0; i ++);

	  if (!job->filters[i] &&
	      (!job->printer->pc || !job->printer->pc->single_file ||
	       job->backend <= 0))
	  {
	   /*
	    * Process the next file...
	    */

	    cupsdContinueJob(job);
	  }
	}
	else if (job->state_value >= IPP_JOB_CANCELED)
	{
	 /*
	  * Remove the job from the active list if there are no processes still
	  * running for it...
	  */

	  for (i = 0; job->filters[i] < 0; i++);

	  if (!job->filters[i] && job->backend <= 0)
	    cupsArrayRemove(ActiveJobs, job);
	}
      }
    }

   /*
    * Show the exit status as needed, ignoring SIGTERM and SIGKILL errors
    * since they come when we kill/end a process...
    */

    if (status == SIGTERM || status == SIGKILL)
    {
      cupsdLogJob(job, CUPSD_LOG_DEBUG,
		  "PID %d (%s) was terminated normally with signal %d.", pid,
		  name, status);
    }
    else if (status == SIGPIPE)
    {
      cupsdLogJob(job, CUPSD_LOG_DEBUG,
		  "PID %d (%s) did not catch or ignore signal %d.", pid, name,
		  status);
    }
    else if (status)
    {
      if (WIFEXITED(status))
      {
        int code = WEXITSTATUS(status);	/* Exit code */

        if (code > 100)
	  cupsdLogJob(job, CUPSD_LOG_DEBUG,
		      "PID %d (%s) stopped with status %d (%s)", pid, name,
		      code, strerror(code - 100));
	else
	  cupsdLogJob(job, CUPSD_LOG_DEBUG,
		      "PID %d (%s) stopped with status %d.", pid, name, code);
      }
      else
	cupsdLogJob(job, CUPSD_LOG_DEBUG, "PID %d (%s) crashed on signal %d.",
		    pid, name, WTERMSIG(status));

      if (LogLevel < CUPSD_LOG_DEBUG)
        cupsdLogJob(job, CUPSD_LOG_INFO,
		    "Hint: Try setting the LogLevel to \"debug\" to find out "
		    "more.");
    }
    else
      cupsdLogJob(job, CUPSD_LOG_DEBUG, "PID %d (%s) exited with no errors.",
		  pid, name);
  }

 /*
  * If wait*() is interrupted by a signal, tell main() to call us again...
  */

  if (pid < 0 && errno == EINTR)
    dead_children = 1;
}
示例#28
0
static void
show_printer(http_t     *http,		/* I - Connection to server */
             const char *printer)	/* I - Name of printer */
{
  ipp_t		*request,		/* IPP request */
		*response;		/* IPP response */
  ipp_attribute_t *attr;		/* IPP attribute */
  char		uri[HTTP_MAX_URI];	/* Printer URI */
  char		refresh[1024];		/* Refresh URL */


  fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n",
          http, printer ? printer : "(null)");

 /*
  * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  */

  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   "localhost", 0, "/printers/%s", printer);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
               uri);

  cgiGetAttributes(request, "printer.tmpl");

 /*
  * Do the request and get back a response...
  */

  if ((response = cupsDoRequest(http, request, "/")) != NULL)
  {
   /*
    * Got the result; set the CGI variables and check the status of a
    * single-queue request...
    */

    cgiSetIPPVars(response, NULL, NULL, NULL, 0);

    if (printer && (attr = ippFindAttribute(response, "printer-state",
                                            IPP_TAG_ENUM)) != NULL &&
        attr->values[0].integer == IPP_PRINTER_PROCESSING)
    {
     /*
      * Printer is processing - automatically refresh the page until we
      * are done printing...
      */

      cgiFormEncode(uri, printer, sizeof(uri));
      snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri);
      cgiSetVariable("refresh_page", refresh);
    }

   /*
    * Delete the response...
    */

    ippDelete(response);

   /*
    * Show the standard header...
    */

    cgiStartHTML(printer);

   /*
    * Show the printer status...
    */

    cgiCopyTemplateLang("printer.tmpl");

   /*
    * Show jobs for the specified printer...
    */

    cgiCopyTemplateLang("printer-jobs-header.tmpl");
    cgiShowJobs(http, printer);
  }
  else
  {
   /*
    * Show the IPP error...
    */

    cgiStartHTML(printer);
    cgiShowIPPError(_("Unable to get printer status"));
  }

   cgiEndHTML();
}
示例#29
0
文件: dest-job.c 项目: jelmer/cups
ipp_status_t				/* O - IPP status code */
cupsCloseDestJob(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *info, 		/* I - Destination information */
    int          job_id)		/* I - Job ID */
{
  int			i;		/* Looping var */
  ipp_t			*request = NULL;/* Close-Job/Send-Document request */
  ipp_attribute_t	*attr;		/* operations-supported attribute */


  DEBUG_printf(("cupsCloseDestJob(http=%p, dest=%p(%s/%s), info=%p, job_id=%d)",
                http, dest, dest ? dest->name : NULL,
                dest ? dest->instance : NULL, info, job_id));

 /*
  * Range check input...
  */

  if (!http || !dest || !info || job_id <= 0)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    DEBUG_puts("1cupsCloseDestJob: Bad arguments.");
    return (IPP_STATUS_ERROR_INTERNAL);
  }

 /*
  * Build a Close-Job or empty Send-Document request...
  */

  if ((attr = ippFindAttribute(info->attrs, "operations-supported",
                               IPP_TAG_ENUM)) != NULL)
  {
    for (i = 0; i < attr->num_values; i ++)
      if (attr->values[i].integer == IPP_OP_CLOSE_JOB)
      {
        request = ippNewRequest(IPP_OP_CLOSE_JOB);
        break;
      }
  }

  if (!request)
    request = ippNewRequest(IPP_OP_SEND_DOCUMENT);

  if (!request)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
    DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document "
               "request.");
    return (IPP_STATUS_ERROR_INTERNAL);
  }

  ippSetVersion(request, info->version / 10, info->version % 10);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
               NULL, info->uri);
  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
                job_id);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  if (ippGetOperation(request) == IPP_OP_SEND_DOCUMENT)
    ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);

 /*
  * Send the request and return the status...
  */

  ippDelete(cupsDoRequest(http, request, info->resource));

  DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()),
                cupsLastErrorString()));

  return (cupsLastError());
}
示例#30
0
文件: util.c 项目: syedaunnraza/work
int					/* O - Job ID */
cupsPrintFiles2(http_t        *http,	/* I - HTTP connection */
                const char    *name,	/* I - Printer or class name */
                int           num_files,/* I - Number of files */
                const char    **files,	/* I - File(s) to print */
                const char    *title,	/* I - Title of job */
                int           num_options,
                /* I - Number of options */
                cups_option_t *options)	/* I - Options */
{
    int		i;			/* Looping var */
    const char	*val;			/* Pointer to option value */
    ipp_t		*request;		/* IPP request */
    ipp_t		*response;		/* IPP response */
    ipp_attribute_t *attr;		/* IPP job-id attribute */
    char		uri[HTTP_MAX_URI];	/* Printer URI */
    int		jobid;			/* New job ID */
    const char	*base;			/* Basename of current filename */


    DEBUG_printf(("cupsPrintFiles(http=%p, name=\"%s\", num_files=%d, "
                  "files=%p, title=\"%s\", num_options=%d, options=%p)\n",
                  http, name, num_files, files, title, num_options, options));

    /*
     * Range check input...
     */

    if (!http || !name || num_files < 1 || files == NULL)
    {
        _cupsSetError(IPP_INTERNAL_ERROR, NULL);

        return (0);
    }

    /*
     * Setup the printer URI...
     */

    if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                         "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
    {
        _cupsSetError(IPP_INTERNAL_ERROR, NULL);

        return (0);
    }

    /*
     * Build a standard CUPS URI for the printer and fill the standard IPP
     * attributes...
     */

    if ((request = ippNewRequest(num_files == 1 ? IPP_PRINT_JOB :
                                 IPP_CREATE_JOB)) == NULL)
    {
        _cupsSetError(IPP_INTERNAL_ERROR, NULL);

        return (0);
    }

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
                 NULL, uri);

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
                 NULL, cupsUser());

    if (title)
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
                     title);

    /*
     * Then add all options...
     */

    cupsEncodeOptions(request, num_options, options);

    /*
     * Do the request...
     */

    snprintf(uri, sizeof(uri), "/printers/%s", name);

    if (num_files == 1)
        response = cupsDoFileRequest(http, request, uri, *files);
    else
        response = cupsDoRequest(http, request, uri);

    if (response == NULL)
        jobid = 0;
    else if (response->request.status.status_code > IPP_OK_CONFLICT)
    {
        DEBUG_printf(("IPP response code was 0x%x!\n",
                      response->request.status.status_code));
        jobid = 0;
    }
    else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL)
    {
        DEBUG_puts("No job ID!");

        _cupsSetError(IPP_INTERNAL_ERROR, NULL);

        jobid = 0;
    }
    else
        jobid = attr->values[0].integer;

    if (response != NULL)
        ippDelete(response);

    /*
     * Handle multiple file jobs if the create-job operation worked...
     */

    if (jobid > 0 && num_files > 1)
        for (i = 0; i < num_files; i ++)
        {
            /*
             * Build a standard CUPS URI for the job and fill the standard IPP
             * attributes...
             */

            if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL)
                return (0);

            snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", jobid);

            ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
                         NULL, uri);

            /*
             * Handle raw print files...
             */

            if (cupsGetOption("raw", num_options, options))
                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
                             "document-format", NULL, "application/vnd.cups-raw");
            else if ((val = cupsGetOption("document-format", num_options,
                                          options)) != NULL)
                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
                             "document-format", NULL, val);
            else
                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
                             "document-format", NULL, "application/octet-stream");

            ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                         "requesting-user-name", NULL, cupsUser());

            /*
             * Add the original document filename...
             */

            if ((base = strrchr(files[i], '/')) != NULL)
                base ++;
            else
                base = files[i];

            ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
                         NULL, base);

            /*
             * Is this the last document?
             */

            if (i == (num_files - 1))
                ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);

            /*
             * Send the file...
             */

            snprintf(uri, sizeof(uri), "/printers/%s", name);

            if ((response = cupsDoFileRequest(http, request, uri,
                                              files[i])) != NULL)
                ippDelete(response);
        }

    return (jobid);
}