void CHttpController::CheckStatusCodeL( RHTTPTransaction& aTransaction )
	{
	TInt httpStatus( aTransaction.Response().StatusCode() );
	if ( httpStatus / 100 != 2 )//responce 200 - 299, no redirections allowed
		{
		User::Leave( KHttpErrorBase - httpStatus );
		}
	}
Exemplo n.º 2
0
const char *				/* O - Filename for PPD file */
cupsGetPPD2(http_t     *http,		/* I - HTTP connection */
            const char *name)		/* I - Printer name */
{
    int		http_port;		/* Port number */
    char		http_hostname[HTTP_MAX_HOST];
    /* Hostname associated with connection */
    http_t	*http2;			/* Alternate HTTP connection */
    int		fd;			/* PPD file */
    char		localhost[HTTP_MAX_URI],/* Local hostname */
                hostname[HTTP_MAX_URI],	/* Hostname */
                resource[HTTP_MAX_URI];	/* Resource name */
    int		port;			/* Port number */
    http_status_t	status;			/* HTTP status from server */
    _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */


    /*
     * Range check input...
     */

    DEBUG_printf(("cupsGetPPD2(http=%p, name=\"%s\")\n", http,
                  name ? name : "(null)"));

    if (!http || !name)
    {
        if (!http)
            _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
        else
            _cupsSetError(IPP_INTERNAL_ERROR, "No printer name!");

        return (NULL);
    }

    /*
     * Try finding a printer URI for this printer...
     */

    if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port,
                              resource, sizeof(resource), 0))
        return (NULL);

    DEBUG_printf(("cupsGetPPD3: Printer hostname=\"%s\", port=%d\n", hostname, port));

    /*
     * Remap local hostname to localhost...
     */

    httpGetHostname(NULL, localhost, sizeof(localhost));

    DEBUG_printf(("Local hostname=\"%s\"\n", localhost));

    if (!strcasecmp(localhost, hostname))
        strcpy(hostname, "localhost");

    /*
     * 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();

    DEBUG_printf(("Connection hostname=\"%s\", port=%d\n", http_hostname,
                  http_port));

    /*
     * Reconnect to the correct server as needed...
     */

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

        return (NULL);
    }

    /*
     * Get a temp file...
     */

    if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0)
    {
        /*
         * Can't open file; close the server connection and return NULL...
         */

        _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno));

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

        return (NULL);
    }

    /*
     * And send a request to the HTTP server...
     */

    strlcat(resource, ".ppd", sizeof(resource));

    status = cupsGetFd(http2, resource, fd);

    close(fd);

    /*
     * See if we actually got the file or an error...
     */

    if (status != HTTP_OK)
    {
        switch (status)
        {
        case HTTP_NOT_FOUND :
            _cupsSetError(IPP_NOT_FOUND, httpStatus(status));
            break;

        case HTTP_UNAUTHORIZED :
            _cupsSetError(IPP_NOT_AUTHORIZED, httpStatus(status));
            break;

        default :
            DEBUG_printf(("HTTP error %d mapped to IPP_SERVICE_UNAVAILABLE!\n",
                          status));
            _cupsSetError(IPP_SERVICE_UNAVAILABLE, httpStatus(status));
            break;
        }

        unlink(cg->ppd_filename);

        return (NULL);
    }

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

    /*
     * Return the PPD file...
     */

    return (cg->ppd_filename);
}
Exemplo n.º 3
0
void
_cupsSetHTTPError(http_status_t status)	/* I - HTTP status code */
{
  switch (status)
  {
    case HTTP_STATUS_NOT_FOUND :
	_cupsSetError(IPP_STATUS_ERROR_NOT_FOUND, httpStatus(status), 0);
	break;

    case HTTP_STATUS_UNAUTHORIZED :
	_cupsSetError(IPP_STATUS_ERROR_NOT_AUTHENTICATED, httpStatus(status), 0);
	break;

    case HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED :
	_cupsSetError(IPP_STATUS_ERROR_CUPS_AUTHENTICATION_CANCELED, httpStatus(status), 0);
	break;

    case HTTP_STATUS_FORBIDDEN :
	_cupsSetError(IPP_STATUS_ERROR_FORBIDDEN, httpStatus(status), 0);
	break;

    case HTTP_STATUS_BAD_REQUEST :
	_cupsSetError(IPP_STATUS_ERROR_BAD_REQUEST, httpStatus(status), 0);
	break;

    case HTTP_STATUS_REQUEST_TOO_LARGE :
	_cupsSetError(IPP_STATUS_ERROR_REQUEST_VALUE, httpStatus(status), 0);
	break;

    case HTTP_STATUS_NOT_IMPLEMENTED :
	_cupsSetError(IPP_STATUS_ERROR_OPERATION_NOT_SUPPORTED, httpStatus(status), 0);
	break;

    case HTTP_STATUS_NOT_SUPPORTED :
	_cupsSetError(IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED, httpStatus(status), 0);
	break;

    case HTTP_STATUS_UPGRADE_REQUIRED :
	_cupsSetError(IPP_STATUS_ERROR_CUPS_UPGRADE_REQUIRED, httpStatus(status), 0);
        break;

    case HTTP_STATUS_CUPS_PKI_ERROR :
	_cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, httpStatus(status), 0);
        break;

    case HTTP_STATUS_ERROR :
	_cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
        break;

    default :
	DEBUG_printf(("4_cupsSetHTTPError: HTTP error %d mapped to "
	              "IPP_STATUS_ERROR_SERVICE_UNAVAILABLE!", status));
	_cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, httpStatus(status), 0);
	break;
  }
}
Exemplo n.º 4
0
static void
cups_create_localizations(
    http_t       *http,			/* I - Connection to destination */
    cups_dinfo_t *dinfo)		/* I - Destination informations */
{
  http_t		*http2;		/* Connection for strings file */
  http_status_t		status;		/* Request status */
  ipp_attribute_t	*attr;		/* "printer-strings-uri" attribute */
  char			scheme[32],	/* URI scheme */
  			userpass[256],	/* Username/password info */
  			hostname[256],	/* Hostname */
  			resource[1024],	/* Resource */
  			http_hostname[256],
  					/* Hostname of connection */
			tempfile[1024];	/* Temporary filename */
  int			port;		/* Port number */
  http_encryption_t	encryption;	/* Encryption to use */
  cups_file_t		*temp;		/* Temporary file */


 /*
  * Create an empty message catalog...
  */

  dinfo->localizations = _cupsMessageNew(NULL);

 /*
  * See if there are any localizations...
  */

  if ((attr = ippFindAttribute(dinfo->attrs, "printer-strings-uri",
                               IPP_TAG_URI)) == NULL)
  {
   /*
    * Nope...
    */

    DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) "
               "value.");
    return;				/* Nope */
  }

 /*
  * Pull apart the URI and determine whether we need to try a different
  * server...
  */

  if (httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text,
                      scheme, sizeof(scheme), userpass, sizeof(userpass),
                      hostname, sizeof(hostname), &port, resource,
                      sizeof(resource)) < HTTP_URI_OK)
  {
    DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value "
                  "\"%s\".", attr->values[0].string.text));
    return;
  }

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

  if (!_cups_strcasecmp(http_hostname, hostname) &&
      port == _httpAddrPort(http->hostaddr))
  {
   /*
    * Use the same connection...
    */

    http2 = http;
  }
  else
  {
   /*
    * Connect to the alternate host...
    */

    if (!strcmp(scheme, "https"))
      encryption = HTTP_ENCRYPT_ALWAYS;
    else
      encryption = HTTP_ENCRYPT_IF_REQUESTED;

    if ((http2 = httpConnectEncrypt(hostname, port, encryption)) == NULL)
    {
      DEBUG_printf(("4cups_create_localizations: Unable to connect to "
                    "%s:%d: %s", hostname, port, cupsLastErrorString()));
      return;
    }
  }

 /*
  * Get a temporary file...
  */

  if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
  {
    DEBUG_printf(("4cups_create_localizations: Unable to create temporary "
                  "file: %s", cupsLastErrorString()));
    if (http2 != http)
      httpClose(http2);
    return;
  }

  status = cupsGetFd(http2, resource, cupsFileNumber(temp));

  DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource,
                httpStatus(status)));

  if (status == HTTP_OK)
  {
   /*
    * Got the file, read it...
    */

    char		buffer[8192],	/* Message buffer */
    			*id,		/* ID string */
    			*str;		/* Translated message */
    _cups_message_t	*m;		/* Current message */

    lseek(cupsFileNumber(temp), 0, SEEK_SET);

    while (cups_read_strings(temp, buffer, sizeof(buffer), &id, &str))
    {
      if ((m = malloc(sizeof(_cups_message_t))) == NULL)
        break;

      m->id  = strdup(id);
      m->str = strdup(str);

      if (m->id && m->str)
        cupsArrayAdd(dinfo->localizations, m);
      else
      {
        if (m->id)
          free(m->id);

        if (m->str)
          free(m->str);

        free(m);
        break;
      }
    }
  }

  DEBUG_printf(("4cups_create_localizations: %d messages loaded.",
                cupsArrayCount(dinfo->localizations)));

 /*
  * Cleanup...
  */

  unlink(tempfile);
  cupsFileClose(temp);

  if (http2 != http)
    httpClose(http2);
}
Exemplo n.º 5
0
int job_implObj::submit(const std::string_view &title)
{
	size_t s=title.size();

	char title_str[s+1];

	std::copy(title.begin(), title.end(), title_str);
	title_str[s]=0;

	job_info_t::lock job_lock{job_info};

	if (job_lock->documents.empty())
		return 0;

	destination_implObj::info_t::lock lock{*destination};

	int job_id;

	auto status=cupsCreateDestJob(lock->http,
				      lock->dest,
				      lock->info,
				      &job_id,
				      title_str,
				      job_lock->num_options,
				      job_lock->options);

	if (status != IPP_STATUS_OK)
		throw EXCEPTION(ippErrorString(status));

	auto job_sentry=make_sentry([&]
				    {
					    cupsCancelDestJob(lock->http,
							      lock->dest,
							      job_id);
				    });

	job_sentry.guard();

	for (const auto &doc:job_lock->documents)
	{
		auto [mime_type, contents]=doc.document();

		auto status=cupsStartDestDocument(lock->http,
						  lock->dest, lock->info,
						  job_id,
						  doc.name.c_str(),
						  mime_type.c_str(),
						  0, NULL, 0);
		if (status != HTTP_STATUS_CONTINUE)
			throw EXCEPTION(httpStatus(status));

		auto doc_sentry=make_sentry
			([&]
			 {
				 cupsFinishDestDocument(lock->http,
							lock->dest,
							lock->info);
			 });
		doc_sentry.guard();

		while (auto res=contents())
		{
			status=cupsWriteRequestData(lock->http,
						    res->data(),
						    res->size());

			if (status != HTTP_STATUS_CONTINUE)
				throw EXCEPTION(httpStatus(status));
		}
		doc_sentry.unguard();

		auto ipp_status=cupsFinishDestDocument(lock->http,
						       lock->dest,
						       lock->info);

		if (ipp_status != IPP_STATUS_OK)
			throw EXCEPTION(cupsLastErrorString());
	}

	job_sentry.unguard();

	auto ipp_status=cupsCloseDestJob(lock->http,
					 lock->dest,
					 lock->info,
					 job_id);

	if (ipp_status != IPP_STATUS_OK)
		throw EXCEPTION(cupsLastErrorString());
	return job_id;
}
Exemplo n.º 6
0
char *					/* O - Pathname or NULL */
file_find(const char *path,		/* I - Path "dir;dir;dir" */
          const char *s)		/* I - File to find */
{
  int		i;			/* Looping var */
  int		retry;			/* Current retry */
  char		*temp,			/* Current position in filename */
		method[HTTP_MAX_URI],	/* Method/scheme */
		username[HTTP_MAX_URI],	/* Username:password */
		hostname[HTTP_MAX_URI],	/* Hostname */
		resource[HTTP_MAX_URI];	/* Resource */
  int		port;			/* Port number */
  const char	*connhost;		/* Host to connect to */
  int		connport;		/* Port to connect to */
  char		connpath[HTTP_MAX_URI],	/* Path for GET */
		connauth[HTTP_MAX_VALUE];/* Auth string */
  http_status_t	status;			/* Status of request... */
  FILE		*fp;			/* Web file */
  int		bytes,			/* Bytes read */
		count,			/* Number of bytes so far */
		total;			/* Total bytes in file */
  static char	filename[HTTP_MAX_URI];	/* Current filename */


 /*
  * If the filename is NULL, return NULL...
  */

  if (s == NULL)
    return (NULL);

  if (strncmp(s, "http:", 5) == 0 ||
      (path != NULL && strncmp(path, "http:", 5) == 0))
    strcpy(method, "http");
#ifdef HAVE_LIBSSL
  else if (strncmp(s, "https:", 6) == 0 ||
           (path != NULL && strncmp(path, "https:", 6) == 0))
    strcpy(method, "https");
#endif /* HAVE_LIBSSL */
  else
    strcpy(method, "file");

  if (strcmp(method, "file") == 0)
  {
   /*
    * If the path is NULL or empty, return the filename...
    */

    if (path == NULL || !path[0])
      return ((char *)s);

   /*
    * Else loop through the path string until we reach the end...
    */

    while (*path != '\0')
    {
     /*
      * Copy the path directory...
      */

      temp = filename;

      while (*path != ';' && *path && temp < (filename + sizeof(filename) - 1))
	*temp++ = *path++;

      if (*path == ';')
	path ++;

     /*
      * Append a slash as needed...
      */

      if (temp > filename && temp < (filename + sizeof(filename) - 1) &&
          s[0] != '/')
	*temp++ = '/';

     /*
      * Append the filename...
      */

      strncpy(temp, s, sizeof(filename) - (temp - filename));
      filename[sizeof(filename) - 1] = '\0';

     /*
      * See if the file exists...
      */

      if (!access(filename, 0))
	return (filename);
    }
  }
  else
  {
   /*
    * Remote file; look it up in the web cache, and then try getting it
    * from the remote system...
    */

    for (i = 0; i < web_files; i ++)
      if (web_cache[i].url && strcmp(web_cache[i].url, s) == 0)
        return (web_cache[i].name);

#ifdef HAVE_LIBSSL
    if (strncmp(s, "http:", 5) == 0 || strncmp(s, "https:", 6) == 0)
#else
    if (strncmp(s, "http:", 5) == 0)
#endif /* HAVE_LIBSSL */
      httpSeparate(s, method, username, hostname, &port, resource);
    else if (s[0] == '/')
    {
      httpSeparate(path, method, username, hostname, &port, resource);
      strcpy(resource, s);
    }
    else
    {
      if (strncmp(s, "./", 2) == 0)
        snprintf(filename, sizeof(filename), "%s/%s", path, s + 2);
      else
        snprintf(filename, sizeof(filename), "%s/%s", path, s);

      httpSeparate(filename, method, username, hostname, &port, resource);
    }

    for (status = HTTP_ERROR, retry = 0;
         status == HTTP_ERROR && retry < 5;
         retry ++)
    {
      if (proxy_port)
      {
       /*
        * Send request to proxy host...
        */

        connhost = proxy_host;
        connport = proxy_port;
        snprintf(connpath, sizeof(connpath), "%s://%s:%d%s", method,
                 hostname, port, resource);
      }
      else
      {
       /*
        * Send request to host directly...
        */

        connhost = hostname;
        connport = port;
        strcpy(connpath, resource);
      }

      if (http != NULL && strcasecmp(http->hostname, hostname) != 0)
      {
        httpClose(http);
        http = NULL;
      }

      if (http == NULL)
      {
        progress_show("Connecting to %s...", connhost);
        atexit(file_cleanup);

#ifdef HAVE_LIBSSL
        if (strcmp(method, "http") == 0)
          http = httpConnect(connhost, connport);
	else
          http = httpConnectEncrypt(connhost, connport, HTTP_ENCRYPT_ALWAYS);
#else
        http = httpConnect(connhost, connport);
#endif /* HAVE_LIBSSL */

        if (http == NULL)
	{
          progress_hide();
          progress_error("Unable to connect to %s!", connhost);
          return (NULL);
        }
      }

      progress_show("Getting %s...", connpath);

      httpClearFields(http);
      httpSetField(http, HTTP_FIELD_HOST, hostname);
      httpSetField(http, HTTP_FIELD_USER_AGENT, "HTMLDOC v" SVERSION);
      httpSetField(http, HTTP_FIELD_CONNECTION, "Keep-Alive");

      if (username[0])
      {
        strcpy(connauth, "Basic ");
        httpEncode64(connauth + 6, username);
        httpSetField(http, HTTP_FIELD_AUTHORIZATION, connauth);
      }

      if (!httpGet(http, connpath))
	while ((status = httpUpdate(http)) == HTTP_CONTINUE);
      else
	status = HTTP_ERROR;

      if (status >= HTTP_MOVED_PERMANENTLY && status <= HTTP_SEE_OTHER)
      {
       /*
        * Flush text...
	*/

	httpFlush(http);

       /*
        * Grab new location from HTTP data...
	*/

        httpSeparate(httpGetField(http, HTTP_FIELD_LOCATION), method, username,
	             hostname, &port, resource);
        status = HTTP_ERROR;
      }
    }

    if (status != HTTP_OK)
    {
      progress_hide();
      progress_error("HTTP error %d: %s!", status, httpStatus(status));
      httpFlush(http);
      return (NULL);
    }

    if ((fp = file_temp(filename, sizeof(filename))) == NULL)
    {
      progress_hide();
      progress_error("Unable to create temporary file \"%s\": %s", filename,
                     strerror(errno));
      httpFlush(http);
      return (NULL);
    }

    if ((total = atoi(httpGetField(http, HTTP_FIELD_CONTENT_LENGTH))) == 0)
      total = 8192;

    count = 0;
    while ((bytes = httpRead(http, resource, sizeof(resource))) > 0)
    {
      count += bytes;
      progress_update((100 * count / total) % 101);
      fwrite(resource, 1, bytes, fp);
    }

    progress_hide();

    fclose(fp);

    web_cache[web_files - 1].name = strdup(filename);
    web_cache[web_files - 1].url  = strdup(s);

    return (filename);
  }

  return (NULL);
}
Exemplo n.º 7
0
int
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i, j;			/* Looping var */
  int		job_id;			/* Job ID */
  char		ch;			/* Option character */
  char		*printer,		/* Destination printer or class */
		*instance;		/* Instance */
  const char	*title,			/* Job title */
		*val;			/* Environment variable name */
  int		num_copies;		/* Number of copies per file */
  int		num_files;		/* Number of files to print */
  const char	*files[1000];		/* Files to print */
  cups_dest_t	*dest;			/* Selected destination */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  int		deletefile;		/* Delete file after print? */
  char		buffer[8192];		/* Copy buffer */


  _cupsSetLocale(argv);

  deletefile  = 0;
  printer     = NULL;
  dest        = NULL;
  num_options = 0;
  options     = NULL;
  num_files   = 0;
  title       = NULL;

  for (i = 1; i < argc; i ++)
    if (argv[i][0] == '-')
      switch (ch = argv[i][1])
      {
        case 'E' : /* Encrypt */
#ifdef HAVE_SSL
	    cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
#else
            _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."),
	                    argv[0]);
#endif /* HAVE_SSL */
	    break;

        case 'U' : /* Username */
	    if (argv[i][2] != '\0')
	      cupsSetUser(argv[i] + 2);
	    else
	    {
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPrintf(stderr,
		                _("%s: Error - expected username after "
				  "\"-U\" option."), argv[0]);
	        return (1);
	      }

              cupsSetUser(argv[i]);
	    }
	    break;

        case 'H' : /* Connect to host */
	    if (argv[i][2] != '\0')
              cupsSetServer(argv[i] + 2);
	    else
	    {
	      i ++;

	      if (i >= argc)
	      {
	        _cupsLangPrintf(stderr,
		        	_("%s: Error - expected hostname after "
			          "\"-H\" option."), argv[0]);
		return (1);
              }
	      else
                cupsSetServer(argv[i]);
	    }
	    break;

	case '1' : /* TROFF font set 1 */
	case '2' : /* TROFF font set 2 */
	case '3' : /* TROFF font set 3 */
	case '4' : /* TROFF font set 4 */
	case 'i' : /* indent */
	case 'w' : /* width */
	    if (argv[i][2] == '\0')
	    {
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPrintf(stderr,
		                _("%s: Error - expected value after \"-%c\" "
				  "option."), argv[0], ch);
		return (1);
	      }
	    }

        case 'c' : /* CIFPLOT */
	case 'd' : /* DVI */
	case 'f' : /* FORTRAN */
	case 'g' : /* plot */
	case 'n' : /* Ditroff */
	case 't' : /* Troff */
	case 'v' : /* Raster image */
	    _cupsLangPrintf(stderr,
	                    _("%s: Warning - \"%c\" format modifier not "
			      "supported - output may not be correct."),
			    argv[0], ch);
	    break;

	case 'o' : /* Option */
	    if (argv[i][2] != '\0')
	      num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
	    else
	    {
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPrintf(stderr,
		                _("%s: Error - expected option=value after "
			          "\"-o\" option."), argv[0]);
		return (1);
	      }

	      num_options = cupsParseOptions(argv[i], num_options, &options);
	    }
	    break;

	case 'l' : /* Literal/raw */
            num_options = cupsAddOption("raw", "true", num_options, &options);
	    break;

	case 'p' : /* Prettyprint */
            num_options = cupsAddOption("prettyprint", "true", num_options,
	                                &options);
	    break;

	case 'h' : /* Suppress burst page */
            num_options = cupsAddOption("job-sheets", "none", num_options,
	                                &options);
	    break;

	case 's' : /* Don't use symlinks */
	    break;

	case 'm' : /* Mail on completion */
	    {
	      char	email[1024];	/* EMail address */


	      snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(),
	               httpGetHostname(NULL, buffer, sizeof(buffer)));
	      num_options = cupsAddOption("notify-recipient-uri", email,
	                                  num_options, &options);
	    }
	    break;

	case 'q' : /* Queue file but don't print */
            num_options = cupsAddOption("job-hold-until", "indefinite",
	                                num_options, &options);
	    break;

	case 'r' : /* Remove file after printing */
	    deletefile = 1;
	    break;

        case 'P' : /* Destination printer or class */
	    if (argv[i][2] != '\0')
	      printer = argv[i] + 2;
	    else
	    {
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPrintf(stderr,
		        	_("%s: Error - expected destination after "
			          "\"-P\" option."), argv[0]);
		return (1);
	      }

	      printer = argv[i];
	    }

            if ((instance = strrchr(printer, '/')) != NULL)
	      *instance++ = '\0';

            if ((dest = cupsGetNamedDest(NULL, printer, instance)) != NULL)
	    {
	      for (j = 0; j < dest->num_options; j ++)
	        if (cupsGetOption(dest->options[j].name, num_options,
		                  options) == NULL)
	          num_options = cupsAddOption(dest->options[j].name,
		                              dest->options[j].value,
					      num_options, &options);
	    }
	    break;

	case '#' : /* Number of copies */
	    if (argv[i][2] != '\0')
	      num_copies = atoi(argv[i] + 2);
	    else
	    {
	      i ++;
	      if (i >= argc)
	      {
	        _cupsLangPrintf(stderr,
		        	_("%s: Error - expected copies after "
			          "\"-#\" option."), argv[0]);
		return (1);
	      }

	      num_copies = atoi(argv[i]);
	    }

            sprintf(buffer, "%d", num_copies);
            num_options = cupsAddOption("copies", buffer, num_options, &options);
	    break;

	case 'C' : /* Class */
	case 'J' : /* Job name */
	case 'T' : /* Title */
	    if (argv[i][2] != '\0')
	      title = argv[i] + 2;
	    else
	    {
	      i ++;
	      if (i >= argc)
	      {
		_cupsLangPrintf(stderr,
		                _("%s: Error - expected name after \"-%c\" "
				  "option."), argv[0], ch);
		return (1);
	      }

	      title = argv[i];
	    }
	    break;

	default :
	    _cupsLangPrintf(stderr,
	                    _("%s: Error - unknown option \"%c\"."), argv[0],
			    argv[i][1]);
	    return (1);
      }
    else if (num_files < 1000)
    {
     /*
      * Print a file...
      */

      if (access(argv[i], R_OK) != 0)
      {
        _cupsLangPrintf(stderr,
	                _("%s: Error - unable to access \"%s\" - %s"),
		        argv[0], argv[i], strerror(errno));
        return (1);
      }

      files[num_files] = argv[i];
      num_files ++;

      if (title == NULL)
      {
        if ((title = strrchr(argv[i], '/')) != NULL)
	  title ++;
	else
          title = argv[i];
      }
    }
    else
      _cupsLangPrintf(stderr,
                      _("%s: Error - too many files - \"%s\"."), argv[0],
		      argv[i]);
 /*
  * See if we have any files to print; if not, print from stdin...
  */

  if (printer == NULL)
  {
    if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL)
    {
      printer = dest->name;

      for (j = 0; j < dest->num_options; j ++)
	if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
	  num_options = cupsAddOption(dest->options[j].name,
		                      dest->options[j].value,
				      num_options, &options);
    }
  }

  if (printer == NULL)
  {
    val = NULL;

    if ((printer = getenv("LPDEST")) == NULL)
    {
      if ((printer = getenv("PRINTER")) != NULL)
      {
        if (!strcmp(printer, "lp"))
          printer = NULL;
	else
	  val = "PRINTER";
      }
    }
    else
      val = "LPDEST";

    if (printer && !cupsGetNamedDest(NULL, printer, NULL))
      _cupsLangPrintf(stderr,
                      _("%s: Error - %s environment variable names "
		        "non-existent destination \"%s\"."), argv[0], val,
		      printer);
    else if (cupsLastError() == IPP_NOT_FOUND)
      _cupsLangPrintf(stderr,
                      _("%s: Error - no default destination available."),
		      argv[0]);
    else
      _cupsLangPrintf(stderr, _("%s: Error - scheduler not responding."),
		      argv[0]);

    return (1);
  }

  if (num_files > 0)
  {
    job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);

    if (deletefile && job_id > 0)
    {
     /*
      * Delete print files after printing...
      */

      for (i = 0; i < num_files; i ++)
        unlink(files[i]);
    }
  }
  else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
                                   title ? title : "(stdin)",
                                   num_options, options)) > 0)
  {
    http_status_t	status;		/* Write status */
    const char		*format;	/* Document format */
    ssize_t		bytes;		/* Bytes read */

    if (cupsGetOption("raw", num_options, options))
      format = CUPS_FORMAT_RAW;
    else if ((format = cupsGetOption("document-format", num_options,
                                     options)) == NULL)
      format = CUPS_FORMAT_AUTO;

    status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
                               format, 1);

    while (status == HTTP_CONTINUE &&
           (bytes = read(0, buffer, sizeof(buffer))) > 0)
      status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes);

    if (status != HTTP_CONTINUE)
    {
      _cupsLangPrintf(stderr, _("%s: Error - unable to queue from stdin - %s."),
		      argv[0], httpStatus(status));
      cupsFinishDocument(CUPS_HTTP_DEFAULT, printer);
      cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
      return (1);
    }

    if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
    {
      _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
      cupsCancelJob2(CUPS_HTTP_DEFAULT, printer, job_id, 0);
      return (1);
    }
  }

  if (job_id < 1)
  {
    _cupsLangPrintf(stderr, "%s: %s", argv[0], cupsLastErrorString());
    return (1);
  }

  return (0);
}
Exemplo n.º 8
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  ipp_t		*event;			/* Event from scheduler */
  ipp_state_t	state;			/* IPP event state */
  char		scheme[32],		/* URI scheme ("rss") */
		username[256],		/* Username for remote RSS */
		host[1024],		/* Hostname for remote RSS */
		resource[1024],		/* RSS file */
		*options;		/* Options */
  int		port,			/* Port number for remote RSS */
		max_events;		/* Maximum number of events */
  http_t	*http;			/* Connection to remote server */
  http_status_t	status;			/* HTTP GET/PUT status code */
  char		filename[1024],		/* Local filename */
		newname[1024];		/* filename.N */
  cups_lang_t	*language;		/* Language information */
  ipp_attribute_t *printer_up_time,	/* Timestamp on event */
		*notify_sequence_number,/* Sequence number */
		*notify_printer_uri;	/* Printer URI */
  char		*subject,		/* Subject for notification message */
		*text,			/* Text for notification message */
		link_url[1024],		/* Link to printer */
		link_scheme[32],	/* Scheme for link */
		link_username[256],	/* Username for link */
		link_host[1024],	/* Host for link */
		link_resource[1024];	/* Resource for link */
  int		link_port;		/* Link port */
  cups_array_t	*rss;			/* RSS message array */
  _cups_rss_t	*msg;			/* RSS message */
  char		baseurl[1024];		/* Base URL */
  fd_set	input;			/* Input set for select() */
  struct timeval timeout;		/* Timeout for select() */
  int		changed;		/* Has the RSS data changed? */
  int		exit_status;		/* Exit status */


  fprintf(stderr, "DEBUG: argc=%d\n", argc);
  for (i = 0; i < argc; i ++)
    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);

 /*
  * See whether we are publishing this RSS feed locally or remotely...
  */

  if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme),
                      username, sizeof(username), host, sizeof(host), &port,
		      resource, sizeof(resource)) < HTTP_URI_OK)
  {
    fprintf(stderr, "ERROR: Bad RSS URI \"%s\"!\n", argv[1]);
    return (1);
  }

  max_events = 20;

  if ((options = strchr(resource, '?')) != NULL)
  {
    *options++ = '\0';

    if (!strncmp(options, "max_events=", 11))
    {
      max_events = atoi(options + 11);

      if (max_events <= 0)
        max_events = 20;
    }
  }

  rss = cupsArrayNew((cups_array_func_t)compare_rss, NULL);

  if (host[0])
  {
   /*
    * Remote feed, see if we can get the current file...
    */

    int	fd;				/* Temporary file */


    if ((rss_password = strchr(username, ':')) != NULL)
      *rss_password++ = '\0';

    cupsSetPasswordCB(password_cb);
    cupsSetUser(username);

    if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
    {
      fprintf(stderr, "ERROR: Unable to create temporary file: %s\n",
              strerror(errno));

      return (1);
    }

    if ((http = httpConnect(host, port)) == NULL)
    {
      fprintf(stderr, "ERROR: Unable to connect to %s on port %d: %s\n",
              host, port, strerror(errno));

      close(fd);
      unlink(filename);

      return (1);
    }

    status = cupsGetFd(http, resource, fd);

    close(fd);

    if (status != HTTP_OK && status != HTTP_NOT_FOUND)
    {
      fprintf(stderr, "ERROR: Unable to GET %s from %s on port %d: %d %s\n",
	      resource, host, port, status, httpStatus(status));

      httpClose(http);
      unlink(filename);

      return (1);
    }

    strlcpy(newname, filename, sizeof(newname));

    httpAssembleURI(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http",
                    NULL, host, port, resource);
  }
  else
  {
    const char	*cachedir,		/* CUPS_CACHEDIR */
		*server_name,		/* SERVER_NAME */
		*server_port;		/* SERVER_PORT */


    http = NULL;

    if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL)
      cachedir = CUPS_CACHEDIR;

    if ((server_name = getenv("SERVER_NAME")) == NULL)
      server_name = "localhost";

    if ((server_port = getenv("SERVER_PORT")) == NULL)
      server_port = "631";

    snprintf(filename, sizeof(filename), "%s/rss%s", cachedir, resource);
    snprintf(newname, sizeof(newname), "%s.N", filename);

    httpAssembleURIf(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http",
                     NULL, server_name, atoi(server_port), "/rss%s", resource);
  }

 /*
  * Load the previous RSS file, if any...
  */

  load_rss(rss, filename);

  changed = cupsArrayCount(rss) == 0;

 /*
  * Localize for the user's chosen language...
  */

  language = cupsLangDefault();

 /*
  * Read events and update the RSS file until we are out of events.
  */

  for (exit_status = 0, event = NULL;;)
  {
    if (changed)
    {
     /*
      * Save the messages to the file again, uploading as needed...
      */

      if (save_rss(rss, newname, baseurl))
      {
	if (http)
	{
	 /*
          * Upload the RSS file...
	  */

          if ((status = cupsPutFile(http, resource, filename)) != HTTP_CREATED)
            fprintf(stderr, "ERROR: Unable to PUT %s from %s on port %d: %d %s\n",
	            resource, host, port, status, httpStatus(status));
	}
	else
	{
	 /*
          * Move the new RSS file over top the old one...
	  */

          if (rename(newname, filename))
            fprintf(stderr, "ERROR: Unable to rename %s to %s: %s\n",
	            newname, filename, strerror(errno));
	}

	changed = 0;
      }
    }

   /*
    * Wait up to 30 seconds for an event...
    */

    timeout.tv_sec  = 30;
    timeout.tv_usec = 0;

    FD_ZERO(&input);
    FD_SET(0, &input);

    if (select(1, &input, NULL, NULL, &timeout) < 0)
      continue;
    else if (!FD_ISSET(0, &input))
    {
      fprintf(stderr, "DEBUG: %s is bored, exiting...\n", argv[1]);
      break;
    }

   /*
    * Read the next event...
    */

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

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

    if (state <= IPP_IDLE)
      break;

   /*
    * Collect the info from the event...
    */

    printer_up_time        = ippFindAttribute(event, "printer-up-time",
                                              IPP_TAG_INTEGER);
    notify_sequence_number = ippFindAttribute(event, "notify-sequence-number",
                                	      IPP_TAG_INTEGER);
    notify_printer_uri     = ippFindAttribute(event, "notify-printer-uri",
                                	      IPP_TAG_URI);
    subject                = cupsNotifySubject(language, event);
    text                   = cupsNotifyText(language, event);

    if (printer_up_time && notify_sequence_number && subject && text)
    {
     /*
      * Create a new RSS message...
      */

      if (notify_printer_uri)
      {
        httpSeparateURI(HTTP_URI_CODING_ALL,
	                notify_printer_uri->values[0].string.text,
			link_scheme, sizeof(link_scheme),
                        link_username, sizeof(link_username),
			link_host, sizeof(link_host), &link_port,
		        link_resource, sizeof(link_resource));
        httpAssembleURI(HTTP_URI_CODING_ALL, link_url, sizeof(link_url),
	                "http", link_username, link_host, link_port,
			link_resource);
      }

      msg = new_message(notify_sequence_number->values[0].integer,
                        xml_escape(subject), xml_escape(text),
			notify_printer_uri ? xml_escape(link_url) : NULL,
			printer_up_time->values[0].integer);

      if (!msg)
      {
        fprintf(stderr, "ERROR: Unable to create message: %s\n",
	        strerror(errno));
        exit_status = 1;
	break;
      }

     /*
      * Add it to the array...
      */

      cupsArrayAdd(rss, msg);

      changed = 1;

     /*
      * Trim the array as needed...
      */

      while (cupsArrayCount(rss) > max_events)
      {
        msg = cupsArrayFirst(rss);

	cupsArrayRemove(rss, msg);

	delete_message(msg);
      }
    }

    if (subject)
      free(subject);

    if (text)
      free(text);

    ippDelete(event);
    event = NULL;
  }

 /*
  * We only get here when idle or error...
  */

  ippDelete(event);

  if (http)
  {
    unlink(filename);
    httpClose(http);
  }

  return (exit_status);
}
Exemplo n.º 9
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  const char	*device_uri;            /* URI with which we were called */
  char queue_name[1024],
       filename[1024];
  FILE *fp;
  char *ptr1, *ptr2;
  int i, n;
  char dest_host[1024];	/* Destination host */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */

 /*
  * Don't buffer stderr, and catch SIGTERM...
  */

  setbuf(stderr, NULL);

#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
  sigset(SIGTERM, sigterm_handler);
#elif defined(HAVE_SIGACTION)
  memset(&action, 0, sizeof(action));

  sigemptyset(&action.sa_mask);
  action.sa_handler = sigterm_handler;
  sigaction(SIGTERM, &action, NULL);
#else
  signal(SIGTERM, sigterm_handler);
#endif /* HAVE_SIGSET */

 /*
  * Check command-line...
  */

  if (argc >= 6)
  {
    if ((device_uri = getenv("DEVICE_URI")) == NULL)
    {
      if (!argv || !argv[0] || !strchr(argv[0], ':'))
	return (-1);

      device_uri = argv[0];
    }
    if ((ptr1 = strchr(device_uri, ':')) == NULL) {
    }
    ptr1 ++;
    strncpy(queue_name, ptr1, sizeof(queue_name));
    snprintf(filename, sizeof(filename), IMPLICIT_CLASS_DEST_HOST_FILE,
	     queue_name);
    for (i = 0; i < 40; i++) {
      /* Wait up to 20 sec for cups-browsed to supply the destination host */
      /* Try reading the file where cups-browsed has deposited the destination
	 host */
      fp = fopen(filename, "r");
      if (fp == NULL)
	goto failed;
      ptr1 = dest_host;
      /* Destination host is between double quotes, as double quotes are
	 illegal in host names one easily recognizes whether the file is
	 complete and avoids accepting a partially written host name */
      n = fscanf(fp, "\"%s", ptr1);
      fclose(fp);
      if (n == 1 && strlen(ptr1) > 0) {
	if ((ptr2 = strchr((const char *)ptr1, '"')) != NULL) {
	  *ptr2 = '\0';
	  break;
	}
      }
    failed:
      /* Pause half a second before next attempt */
      usleep(500000);
    }

    /* Delete host name file after having read it once, so that we wait for
       cups-browsed's decision again on the next job */
    unlink(filename);
    
    if (i >= 40) {
      /* Timeout, no useful data from cups-browsed received */
      fprintf(stderr, "ERROR: No destination host name supplied by cups-browsed for printer \"%s\", is cups-browsed running?\n",
	      queue_name);
      return (CUPS_BACKEND_STOP);
    }
    
    if (!strcmp(dest_host, "NO_DEST_FOUND")) {
      /* All remote queues are either disabled or not accepting jobs, let
	 CUPS retry after the usual interval */
      fprintf(stderr, "ERROR: No suitable destination host found by cups-browsed.\n");
      return (CUPS_BACKEND_RETRY);
    } else if (!strcmp(dest_host, "ALL_DESTS_BUSY")) {
      /* We queue on the client and all remote queues are busy, so we wait
	 5 sec  and check again then */
      fprintf(stderr, "DEBUG: No free destination host found by cups-browsed, retrying in 5 sec.\n");
      sleep(5);
      return (CUPS_BACKEND_RETRY_CURRENT);
    } else {
      /* We have the destination host name now, do the job */
      char server_str[1024];
      const char *title;
      int num_options = 0;
      cups_option_t *options = NULL;
      int fd, job_id;
      char buffer[8192];

      fprintf(stderr, "DEBUG: Received destination host name from cups-browsed: %s\n",
	      dest_host);
      /* Instead of fdeeding the job into the IPP backend, we re-print it into
	 the server's CUPS queue. This way the job gets spooled on the server
	 and we are not blocked until the job is printed. So a subsequent job
	 will be immediately processed and sent out to another server */
      /* Set destination server */
      snprintf(server_str, sizeof(server_str), "%s:%d", dest_host,
	       ippPort());
      cupsSetServer(server_str);
      /* Parse the command line option and prepare them for the new print
	 job */
      cupsSetUser(argv[2]);
      title = argv[3];
      if (title == NULL)
      {
	if (argc == 7) {
	  if ((title = strrchr(argv[6], '/')) != NULL)
	    title ++;
	  else
	    title = argv[6];
	} else
	  title = "(stdin)";
      }
      num_options = cupsAddOption("copies", argv[4], num_options, &options);
      num_options = cupsParseOptions(argv[5], num_options, &options);
      if (argc == 7)
	fd = open(argv[6], O_RDONLY);
      else
	fd = 0; /* stdin */
      
      /* Queue the job directly on the server */
      if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, queue_name,
				  title ? title : "(stdin)",
				  num_options, options)) > 0) {
	http_status_t       status;         /* Write status */
	const char          *format;        /* Document format */
	ssize_t             bytes;          /* Bytes read */

	if (cupsGetOption("raw", num_options, options))
	  format = CUPS_FORMAT_RAW;
	else if ((format = cupsGetOption("document-format", num_options,
					 options)) == NULL)
	  format = CUPS_FORMAT_AUTO;
	
	status = cupsStartDocument(CUPS_HTTP_DEFAULT, queue_name, job_id, NULL,
				   format, 1);

	while (status == HTTP_CONTINUE &&
	       (bytes = read(fd, buffer, sizeof(buffer))) > 0)
	  status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes);

	if (status != HTTP_CONTINUE) {
	  fprintf(stderr, "ERROR: %s: Unable to queue the print data - %s. Retrying.",
		  argv[0], httpStatus(status));
	  cupsFinishDocument(CUPS_HTTP_DEFAULT, queue_name);
	  cupsCancelJob2(CUPS_HTTP_DEFAULT, queue_name, job_id, 0);
	  return (CUPS_BACKEND_RETRY_CURRENT);
	}

	if (cupsFinishDocument(CUPS_HTTP_DEFAULT, queue_name) != IPP_OK) {
	  fprintf(stderr, "ERROR: %s: Unable to complete the job - %s. Retrying.",
		  argv[0], cupsLastErrorString());
	  cupsCancelJob2(CUPS_HTTP_DEFAULT, queue_name, job_id, 0);
	  return (CUPS_BACKEND_RETRY_CURRENT);
	}
      }

      if (job_id < 1) {
	fprintf(stderr, "ERROR: %s: Unable to create job - %s. Retrying.",
		argv[0], cupsLastErrorString());
	return (CUPS_BACKEND_RETRY_CURRENT);
      }

      return (CUPS_BACKEND_OK);
    }
  }
  else if (argc != 1)
  {
    fprintf(stderr,
	    "Usage: %s job-id user title copies options [file]",
	    argv[0]);
    return (CUPS_BACKEND_FAILED);
  }

 /*
  * No discovery mode at all for this backend
  */

  return (CUPS_BACKEND_OK);
}