示例#1
0
static void read_config_ppd() {
  ppd_option_t *option;
  ppd_file_t *ppd_file;
  char * ppd_name;

  ppd_name = getenv("PPD");
  if (ppd_name == NULL) {
    log_event(CPERROR, "Could not retrieve PPD name");
    return;
  }
  ppd_file = ppdOpenFile(ppd_name);
  if (ppd_file == NULL) {
    log_event(CPERROR, "Could not open PPD file: %s", ppd_name);
    return;
  }
  ppdMarkDefaults(ppd_file);

  option = ppdFirstOption(ppd_file);
  while (option != NULL) {
    _assign_value(SEC_PPD, option->keyword, option->defchoice);
    option = ppdNextOption(ppd_file);
  }
  ppdClose(ppd_file);

  return;
}
示例#2
0
int					/* O - Number of conflicts found */
ppdConflicts(ppd_file_t *ppd)		/* I - PPD to check */
{
  int			i,		/* Looping variable */
			conflicts;	/* Number of conflicts */
  cups_array_t		*active;	/* Active conflicts */
  _ppd_cups_uiconsts_t	*c;		/* Current constraints */
  _ppd_cups_uiconst_t	*cptr;		/* Current constraint */
  ppd_option_t	*o;			/* Current option */


  if (!ppd)
    return (0);

 /*
  * Clear all conflicts...
  */

  cupsArraySave(ppd->options);

  for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd))
    o->conflicted = 0;

  cupsArrayRestore(ppd->options);

 /*
  * Test for conflicts...
  */

  active    = ppd_test_constraints(ppd, NULL, NULL, 0, NULL,
                                   _PPD_ALL_CONSTRAINTS);
  conflicts = cupsArrayCount(active);

 /*
  * Loop through all of the UI constraints and flag any options
  * that conflict...
  */

  for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active);
       c;
       c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
  {
    for (i = c->num_constraints, cptr = c->constraints;
         i > 0;
	 i --, cptr ++)
      cptr->option->conflicted = 1;
  }

  cupsArrayDelete(active);

 /*
  * Return the number of conflicts found...
  */

  return (conflicts);
}
示例#3
0
static int				/* O - Exit status */
auto_configure(ppd_file_t *ppd,		/* I - PPD file */
               const char *user)	/* I - Printing user */
{
  int		status = 0;		/* Exit status */
  ppd_option_t	*option;		/* Current option in PPD */
  ppd_attr_t	*attr;			/* Query command attribute */
  const char	*valptr;		/* Pointer into attribute value */
  char		buffer[1024],		/* String buffer */
		*bufptr;		/* Pointer into buffer */
  ssize_t	bytes;			/* Number of bytes read */
  int		datalen;		/* Side-channel data length */


 /*
  * See if the backend supports bidirectional I/O...
  */

  datalen = 1;
  if (cupsSideChannelDoRequest(CUPS_SC_CMD_GET_BIDI, buffer, &datalen,
                               30.0) != CUPS_SC_STATUS_OK ||
      buffer[0] != CUPS_SC_BIDI_SUPPORTED)
  {
    fputs("DEBUG: Unable to auto-configure PostScript Printer - no "
          "bidirectional I/O available!\n", stderr);
    return (1);
  }

 /*
  * Put the printer in PostScript mode...
  */

  begin_ps(ppd, user);

 /*
  * (STR #4028)
  *
  * As a lot of PPDs contain bad PostScript query code, we need to prevent one
  * bad query sequence from affecting all auto-configuration.  The following
  * error handler allows us to log PostScript errors to cupsd.
  */

  puts("/cups_handleerror {\n"
       "  $error /newerror false put\n"
       "  (:PostScript error in \") print cups_query_keyword print (\": ) "
       "print\n"
       "  $error /errorname get 128 string cvs print\n"
       "  (; offending command:) print $error /command get 128 string cvs "
       "print (\n) print flush\n"
       "} bind def\n"
       "errordict /timeout {} put\n"
       "/cups_query_keyword (?Unknown) def\n");
  fflush(stdout);

 /*
  * Wait for the printer to become connected...
  */

  do
  {
    sleep(1);
    datalen = 1;
  }
  while (cupsSideChannelDoRequest(CUPS_SC_CMD_GET_CONNECTED, buffer, &datalen,
                                  5.0) == CUPS_SC_STATUS_OK && !buffer[0]);

 /*
  * Then loop through every option in the PPD file and ask for the current
  * value...
  */

  fputs("DEBUG: Auto-configuring PostScript printer...\n", stderr);

  for (option = ppdFirstOption(ppd); option; option = ppdNextOption(ppd))
  {
   /*
    * See if we have a query command for this option...
    */

    snprintf(buffer, sizeof(buffer), "?%s", option->keyword);

    if ((attr = ppdFindAttr(ppd, buffer, NULL)) == NULL || !attr->value)
    {
      fprintf(stderr, "DEBUG: Skipping %s option...\n", option->keyword);
      continue;
    }

   /*
    * Send the query code to the printer...
    */

    fprintf(stderr, "DEBUG: Querying %s...\n", option->keyword);

    for (bufptr = buffer, valptr = attr->value; *valptr; valptr ++)
    {
     /*
      * Log the query code, breaking at newlines...
      */

      if (*valptr == '\n')
      {
        *bufptr = '\0';
        fprintf(stderr, "DEBUG: %s\\n\n", buffer);
        bufptr = buffer;
      }
      else if (*valptr < ' ')
      {
        if (bufptr >= (buffer + sizeof(buffer) - 4))
        {
	  *bufptr = '\0';
	  fprintf(stderr, "DEBUG: %s\n", buffer);
	  bufptr = buffer;
        }

        if (*valptr == '\r')
        {
          *bufptr++ = '\\';
          *bufptr++ = 'r';
        }
        else if (*valptr == '\t')
        {
          *bufptr++ = '\\';
          *bufptr++ = 't';
        }
        else
        {
          *bufptr++ = '\\';
          *bufptr++ = '0' + ((*valptr / 64) & 7);
          *bufptr++ = '0' + ((*valptr / 8) & 7);
          *bufptr++ = '0' + (*valptr & 7);
        }
      }
      else
      {
        if (bufptr >= (buffer + sizeof(buffer) - 1))
        {
	  *bufptr = '\0';
	  fprintf(stderr, "DEBUG: %s\n", buffer);
	  bufptr = buffer;
        }

	*bufptr++ = *valptr;
      }
    }

    if (bufptr > buffer)
    {
      *bufptr = '\0';
      fprintf(stderr, "DEBUG: %s\n", buffer);
    }

    printf("/cups_query_keyword (?%s) def\n", option->keyword);
					/* Set keyword for error reporting */
    fputs("{ (", stdout);
    for (valptr = attr->value; *valptr; valptr ++)
    {
      if (*valptr == '(' || *valptr == ')' || *valptr == '\\')
        putchar('\\');
      putchar(*valptr);
    }
    fputs(") cvx exec } stopped { cups_handleerror } if clear\n", stdout);
    					/* Send query code */
    fflush(stdout);

    datalen = 0;
    cupsSideChannelDoRequest(CUPS_SC_CMD_DRAIN_OUTPUT, buffer, &datalen, 5.0);

   /*
    * Read the response data...
    */

    bufptr    = buffer;
    buffer[0] = '\0';
    while ((bytes = cupsBackChannelRead(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer) - 1, 10.0)) > 0)
    {
     /*
      * No newline at the end? Go on reading ...
      */

      bufptr += bytes;
      *bufptr = '\0';

      if (bytes == 0 ||
          (bufptr > buffer && bufptr[-1] != '\r' && bufptr[-1] != '\n'))
	continue;

     /*
      * Trim whitespace and control characters from both ends...
      */

      bytes = bufptr - buffer;

      for (bufptr --; bufptr >= buffer; bufptr --)
        if (isspace(*bufptr & 255) || iscntrl(*bufptr & 255))
	  *bufptr = '\0';
	else
	  break;

      for (bufptr = buffer; isspace(*bufptr & 255) || iscntrl(*bufptr & 255);
	   bufptr ++);

      if (bufptr > buffer)
      {
        _cups_strcpy(buffer, bufptr);
	bufptr = buffer;
      }

      fprintf(stderr, "DEBUG: Got %d bytes.\n", (int)bytes);

     /*
      * Skip blank lines...
      */

      if (!buffer[0])
        continue;

     /*
      * Check the response...
      */

      if ((bufptr = strchr(buffer, ':')) != NULL)
      {
       /*
        * PostScript code for this option in the PPD is broken; show the
        * interpreter's error message that came back...
        */

	fprintf(stderr, "DEBUG%s\n", bufptr);
	break;
      }

     /*
      * Verify the result is a valid option choice...
      */

      if (!ppdFindChoice(option, buffer))
      {
	if (!strcasecmp(buffer, "Unknown"))
	  break;

	bufptr    = buffer;
	buffer[0] = '\0';
        continue;
      }

     /*
      * Write out the result and move on to the next option...
      */

      fprintf(stderr, "PPD: Default%s=%s\n", option->keyword, buffer);
      break;
    }

   /*
    * Printer did not answer this option's query
    */

    if (bytes <= 0)
    {
      fprintf(stderr,
	      "DEBUG: No answer to query for option %s within 10 seconds.\n",
	      option->keyword);
      status = 1;
    }
  }

 /*
  * Finish the job...
  */

  fflush(stdout);
  end_ps(ppd);

 /*
  * Return...
  */

  if (status)
    _cupsLangPrintFilter(stderr, "WARNING",
                         _("Unable to configure printer options."));

  return (0);
}