Esempio n. 1
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		i,			/* Looping var */
		num_settings;		/* Number of settings */
  cups_option_t	*settings;		/* Settings */
  http_t	*http;			/* Connection to server */


 /*
  * Connect to the server using the defaults...
  */

  http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC,
                      cupsEncryption(), 1, 30000, NULL);

 /*
  * Set the current configuration if we have anything on the command-line...
  */

  if (argc > 1)
  {
    for (i = 1, num_settings = 0, settings = NULL; i < argc; i ++)
      num_settings = cupsParseOptions(argv[i], num_settings, &settings);

    if (cupsAdminSetServerSettings(http, num_settings, settings))
    {
      puts("New server settings:");
      cupsFreeOptions(num_settings, settings);
    }
    else
    {
      printf("Server settings not changed: %s\n", cupsLastErrorString());
      return (1);
    }
  }
  else
    puts("Current server settings:");

 /*
  * Get the current configuration...
  */

  if (cupsAdminGetServerSettings(http, &num_settings, &settings))
  {
    show_settings(num_settings, settings);
    cupsFreeOptions(num_settings, settings);
    return (0);
  }
  else
  {
    printf("    %s\n", cupsLastErrorString());
    return (1);
  }
}
Esempio n. 2
0
static void
cups_globals_free(_cups_globals_t *cg)	/* I - Pointer to global data */
{
  _cups_buffer_t	*buffer,	/* Current read/write buffer */
			*next;		/* Next buffer */


  if (cg->last_status_message)
    _cupsStrFree(cg->last_status_message);

  for (buffer = cg->cups_buffers; buffer; buffer = next)
  {
    next = buffer->next;
    free(buffer);
  }

  cupsArrayDelete(cg->leg_size_lut);
  cupsArrayDelete(cg->ppd_size_lut);
  cupsArrayDelete(cg->pwg_size_lut);

  httpClose(cg->http);

  _httpFreeCredentials(cg->tls_credentials);

  cupsFileClose(cg->stdio_files[0]);
  cupsFileClose(cg->stdio_files[1]);
  cupsFileClose(cg->stdio_files[2]);

  cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);

  free(cg);
}
Esempio n. 3
0
void ofxCUPS::printImage(string filename)
{
    int num_options = 0;  
    cups_option_t *options = NULL;  
    
    string path = ofFilePath::getAbsolutePath("");
    string currentFile = filename;
    string printFile = path + currentFile;
    //optionen = "media=DS_PC_size"; //ds40
    
    //num_options = cupsParseOptions(optionen.c_str(), num_options, &options);  
    
    
    int last_job_id = cupsPrintFile(
                                    printerName.c_str(),
                                    printFile.c_str(),
                                    jobTitle.c_str() ? jobTitle.c_str() : "print from ofxCUPS",
                                    num_options,
                                    options);  
    
    cout << "the job id is: " << last_job_id << endl;
    if (last_job_id == 0)
    {
        cout << "print Error: " << cupsLastErrorString() << endl;
    }
    
    
    
    cupsFreeOptions(num_options,options);
}
Esempio n. 4
0
void ofxCUPS::printImage(string filename, bool isAbsolutePath) {
    int num_options = 0;
    cups_option_t *options = NULL;  

    string printFile;
    if(isAbsolutePath) {
        printFile = filename;
    }
    else {
        printFile = ofToDataPath("./",true) + filename;
    }

    //optionen = "media=DS_PC_size"; //ds40
    
    //num_options = cupsParseOptions(optionen.c_str(), num_options, &options);  
    
    
    int last_job_id = cupsPrintFile(
                                    printerName.c_str(),
                                    printFile.c_str(),
                                    jobTitle.c_str() ? jobTitle.c_str() : "print from ofxCUPS",
                                    num_options,
                                    options);  
    
    cout << "the job id is: " << last_job_id << endl;
    if (last_job_id == 0)
    {
        cout << "print Error: " << cupsLastErrorString() << endl;
    }
    
    
    
    cupsFreeOptions(num_options,options);
}
Esempio n. 5
0
int getPrinterSharingStatus() {
  http_t* cups = nullptr;
  int num_settings = 0;
  cups_option_t* settings = nullptr;
  const char* value = nullptr;

  cups = httpConnect2(cupsServer(),
                      ippPort(),
                      nullptr,
                      AF_INET,
                      cupsEncryption(),
                      1,
                      30000,
                      nullptr);
  if (cups == nullptr) {
    return 0;
  }
  int ret = cupsAdminGetServerSettings(cups, &num_settings, &settings);
  if (ret != 0) {
    value = cupsGetOption("_share_printers", num_settings, settings);
    cupsFreeOptions(num_settings, settings);
  } else {
    VLOG(1) << "Unable to get CUPS server settings: " << cupsLastErrorString();
  }
  httpClose(cups);

  if (value != nullptr) {
    return *value == '1' ? 1 : 0;
  }
  return 0;
}
Esempio n. 6
0
static void
invalidate_cupsd_cache(
    _cups_globals_t *cg)		/* I - Global data */
{
  cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings);

  cg->cupsd_hostname[0]  = '\0';
  cg->cupsd_update       = 0;
  cg->cupsd_num_settings = 0;
  cg->cupsd_settings     = NULL;
}
Esempio n. 7
0
/*
 * Ouverture et fermeture du fichier PPD
 * Opening or closing PPD file
 */
bool PPDFile::open(const char *file, const char *version, const char *useropts)
{
    const char *fileVersion;
    cups_option_t *options;
    int nr;

    // Check if a PPD file was previously opened
    if (_ppd) {
        ERRORMSG(_("Internal warning: a PPD file was previously opened. Please "
            "close it before opening a new one."));
        close();
    }

    // Open the PPD file
    _ppd = ppdOpenFile(file);
    if (!_ppd) {
        ERRORMSG(_("Cannot open PPD file %s"), file);
        return false;
    }

    // Mark the default values and the user options
    ppdMarkDefaults(_ppd);
    nr = cupsParseOptions(useropts, 0, &options);
    cupsMarkOptions(_ppd, nr, options);
    cupsFreeOptions(nr, options);

    // Check if the PPD version is compatible with this filter
    fileVersion = get("FileVersion");
    if (!fileVersion) { 
        ERRORMSG(_("No FileVersion found in the PPD file: invalid "
            "PPD file"));
        ppdClose(_ppd);
        _ppd = NULL;
        return false;
    }
    if (strcmp(fileVersion, version)) {
        ERRORMSG(_("Invalid PPD file version: %s but the PPD file "
            "is designed for SpliX V. %s"), version, fileVersion);
        ppdClose(_ppd);
        _ppd = NULL;
        return false;
    }

    return true;
}
Esempio n. 8
0
static void
ppd_mark_choices(ppd_file_t *ppd,	/* I - PPD file */
                 const char *s)		/* I - "*Option Choice ..." string */
{
  int		i,			/* Looping var */
		num_options;		/* Number of options */
  cups_option_t	*options,		/* Options */
		*option;		/* Current option */


  if (!s)
    return;

  options     = NULL;
  num_options = _ppdParseOptions(s, 0, &options, 0);

  for (i = num_options, option = options; i > 0; i --, option ++)
    ppd_mark_option(ppd, option->name, option->value);

  cupsFreeOptions(num_options, options);
}
Esempio n. 9
0
job_implObj::~job_implObj()
{
	job_info_t::lock lock{job_info};

	cupsFreeOptions(lock->num_options, lock->options);
}
Esempio n. 10
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		i,			/* Looping var */
		num_settings;		/* Number of settings */
  cups_option_t	*settings;		/* Settings */
  const char	*opt;			/* Current option character */
  http_t	*http;			/* Connection to server */


 /*
  * Process the command-line...
  */

  _cupsSetLocale(argv);

  num_settings = 0;
  settings     = NULL;

  for (i = 1; i < argc; i ++)
  {
    if (!strcmp(argv[i], "--help"))
      usage(NULL);
    else if (argv[i][0] == '-')
    {
      if (argv[i][1] == '-')
      {
        if (!strcmp(argv[i], "--debug-logging"))
	  num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-debug-logging"))
	  num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--remote-admin"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-remote-admin"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--remote-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-remote-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--share-printers"))
	  num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-share-printers"))
	  num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, "0",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--user-cancel-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, "1",
	                               num_settings, &settings);
        else if (!strcmp(argv[i], "--no-user-cancel-any"))
	  num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, "0",
	                               num_settings, &settings);
        else
	  usage(argv[i]);
      }
      else
      {
        for (opt = argv[i] + 1; *opt; opt ++)
	  switch (*opt)
	  {
	    case 'E' :
	        cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
	        break;

	    case 'U' :
	        i ++;
		if (i >= argc)
		  usage(NULL);

                cupsSetUser(argv[i]);
	        break;

	    case 'h' :
	        i ++;
		if (i >= argc)
		  usage(NULL);

                cupsSetServer(argv[i]);
	        break;

	    default :
	        usage(opt);
		break;
	  }
      }
    }
    else if (strchr(argv[i], '='))
      num_settings = cupsParseOptions(argv[i], num_settings, &settings);
    else
      usage(argv[i]);
  }

  if (cupsGetOption("Listen", num_settings, settings) ||
      cupsGetOption("Port", num_settings, settings))
  {
    _cupsLangPuts(stderr, _("cupsctl: Cannot set Listen or Port directly."));
    return (1);
  }

 /*
  * Connect to the server using the defaults...
  */

  if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
                                 cupsEncryption())) == NULL)
  {
    _cupsLangPrintf(stderr, _("cupsctl: Unable to connect to server: %s"),
                    strerror(errno));
    return (1);
  }

 /*
  * Set the current configuration if we have anything on the command-line...
  */

  if (num_settings > 0)
  {
    if (!cupsAdminSetServerSettings(http, num_settings, settings))
    {
      _cupsLangPrintf(stderr, "cupsctl: %s", cupsLastErrorString());
      return (1);
    }
  }
  else if (!cupsAdminGetServerSettings(http, &num_settings, &settings))
  {
    _cupsLangPrintf(stderr, "cupsctl: %s", cupsLastErrorString());
    return (1);
  }
  else
  {
    for (i = 0; i < num_settings; i ++)
      _cupsLangPrintf(stdout, "%s=%s", settings[i].name, settings[i].value);
  }

  cupsFreeOptions(num_settings, settings);
  return (0);
}
Esempio n. 11
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int			fd;		/* File descriptor */
  cups_raster_t		*ras;		/* Raster stream for printing */
  cups_page_header2_t	header;		/* Page header from file */
  unsigned		y;		/* Current line */
  ppd_file_t		*ppd;		/* PPD file */
  int			num_options;	/* Number of options */
  cups_option_t		*options;	/* Options */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
  struct sigaction action;		/* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */


 /*
  * Make sure status messages are not buffered...
  */

  setbuf(stderr, NULL);

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

  if (argc < 6 || argc > 7)
  {
   /*
    * We don't have the correct number of arguments; write an error message
    * and return.
    */

    _cupsLangPrintFilter(stderr, "ERROR",
                         _("%s job-id user title copies options [file]"),
			 "rastertolabel");
    return (1);
  }

 /*
  * Open the page stream...
  */

  if (argc == 7)
  {
    if ((fd = open(argv[6], O_RDONLY)) == -1)
    {
      _cupsLangPrintError("ERROR", _("Unable to open raster file"));
      sleep(1);
      return (1);
    }
  }
  else
    fd = 0;

  ras = cupsRasterOpen(fd, CUPS_RASTER_READ);

 /*
  * Register a signal handler to eject the current page if the
  * job is cancelled.
  */

  Canceled = 0;

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

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

 /*
  * Open the PPD file and apply options...
  */

  num_options = cupsParseOptions(argv[5], 0, &options);

  ppd = ppdOpenFile(getenv("PPD"));
  if (!ppd)
  {
    ppd_status_t	status;		/* PPD error */
    int			linenum;	/* Line number */

    _cupsLangPrintFilter(stderr, "ERROR",
                         _("The PPD file could not be opened."));

    status = ppdLastError(&linenum);

    fprintf(stderr, "DEBUG: %s on line %d.\n", ppdErrorString(status), linenum);

    return (1);
  }

  ppdMarkDefaults(ppd);
  cupsMarkOptions(ppd, num_options, options);

 /*
  * Initialize the print device...
  */

  Setup(ppd);

 /*
  * Process pages as needed...
  */

  Page = 0;

  while (cupsRasterReadHeader2(ras, &header))
  {
   /*
    * Write a status message with the page number and number of copies.
    */

    if (Canceled)
      break;

    Page ++;

    fprintf(stderr, "PAGE: %d 1\n", Page);
    _cupsLangPrintFilter(stderr, "INFO", _("Starting page %d."), Page);

   /*
    * Start the page...
    */

    StartPage(ppd, &header);

   /*
    * Loop for each line on the page...
    */

    for (y = 0; y < header.cupsHeight && !Canceled; y ++)
    {
     /*
      * Let the user know how far we have progressed...
      */

      if (Canceled)
	break;

      if ((y & 15) == 0)
      {
        _cupsLangPrintFilter(stderr, "INFO",
	                     _("Printing page %d, %u%% complete."),
			     Page, 100 * y / header.cupsHeight);
        fprintf(stderr, "ATTR: job-media-progress=%u\n",
		100 * y / header.cupsHeight);
      }

     /*
      * Read a line of graphics...
      */

      if (cupsRasterReadPixels(ras, Buffer, header.cupsBytesPerLine) < 1)
        break;

     /*
      * Write it to the printer...
      */

      OutputLine(ppd, &header, y);
    }

   /*
    * Eject the page...
    */

    _cupsLangPrintFilter(stderr, "INFO", _("Finished page %d."), Page);

    EndPage(ppd, &header);

    if (Canceled)
      break;
  }

 /*
  * Close the raster stream...
  */

  cupsRasterClose(ras);
  if (fd != 0)
    close(fd);

 /*
  * Close the PPD file and free the options...
  */

  ppdClose(ppd);
  cupsFreeOptions(num_options, options);

 /*
  * If no pages were printed, send an error message...
  */

  if (Page == 0)
  {
    _cupsLangPrintFilter(stderr, "ERROR", _("No pages were found."));
    return (1);
  }
  else
    return (0);
}
Esempio n. 12
0
void dt_print_file(const int32_t imgid, const char *filename, const char *job_title, const dt_print_info_t *pinfo)
{
  // first for safety check that filename exists and is readable

  if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
  {
    dt_control_log(_("file `%s' to print not found for image %d on `%s'"), filename, imgid, pinfo->printer.name);
    return;
  }

  cups_option_t *options = NULL;
  int num_options = 0;

  // for turboprint drived printer, use the turboprint dialog
  if (pinfo->printer.is_turboprint)
  {
    const char *tp_intent_name[] = { "perception_0", "colorimetric-relative_1", "saturation_1", "colorimetric-absolute_1" };
    char tmpfile[PATH_MAX] = { 0 };

    dt_loc_get_tmp_dir(tmpfile, sizeof(tmpfile));
    g_strlcat(tmpfile, "/dt_cups_opts_XXXXXX", sizeof(tmpfile));

    gint fd = g_mkstemp(tmpfile);
    if(fd == -1)
    {
      dt_control_log(_("failed to create temporary file for printing options"));
      fprintf(stderr, "failed to create temporary pdf for printing options\n");
      return;
    }
    close(fd);

    // ensure that intent is in the range, may happen if at some point we add new intent in the list
    const int intent = (pinfo->printer.intent < 4) ? pinfo->printer.intent : 0;

    // spawn turboprint command
    gchar * argv[15] = { 0 };

    argv[0] = "turboprint";
    argv[1] = g_strdup_printf("--printer=%s", pinfo->printer.name);
    argv[2] = "--options";
    argv[3] = g_strdup_printf("--output=%s", tmpfile);
    argv[4] = "-o";
    argv[5] = "copies=1";
    argv[6] = "-o";
    argv[7] = g_strdup_printf("PageSize=%s", pinfo->paper.common_name);
    argv[8] = "-o";
    argv[9] = "InputSlot=AutoSelect";
    argv[10] = "-o";
    argv[11] = g_strdup_printf("zedoIntent=%s", tp_intent_name[intent]);
    argv[12] = "-o";
    argv[13] = g_strdup_printf("MediaType=%s", pinfo->medium.name);
    argv[14] = NULL;

    gint exit_status = 0;

    g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
                  NULL, NULL, NULL, NULL, &exit_status, NULL);

    g_free(argv[1]);
    g_free(argv[3]);
    g_free(argv[7]);
    g_free(argv[11]);
    g_free(argv[13]);

    if (exit_status==0)
    {
      FILE *stream = g_fopen(tmpfile, "rb");

      while(1)
      {
        char optname[100];
        char optvalue[100];
        const int ropt = fscanf(stream, "%*s %[^= ]=%s", optname, optvalue);

        // if we parsed an option name=value
        if (ropt==2)
        {
          char *v = optvalue;

          // remove possible single quote around value
          if (*v == '\'') v++;
          if (v[strlen(v)-1] == '\'') v[strlen(v)-1] = '\0';

          num_options = cupsAddOption(optname, v, num_options, &options);
        }
        else if (ropt == EOF)
          break;
      }
      fclose(stream);
      g_unlink(tmpfile);
    }
    else
    {
      dt_print(DT_DEBUG_PRINT, "[print]   command fails with %d, cancel printing\n", exit_status);
      return;
    }
  }
  else
  {
    cups_dest_t *dests;
    int num_dests = cupsGetDests(&dests);
    cups_dest_t *dest = cupsGetDest(pinfo->printer.name, NULL, num_dests, dests);

    for (int 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);

    cupsFreeDests(num_dests, dests);

    // if we have a profile, disable cm on CUPS, this is important as dt does the cm

    num_options = cupsAddOption("cm-calibration", *pinfo->printer.profile ? "true" : "false", num_options, &options);

    // media to print on

    num_options = cupsAddOption("media", pinfo->paper.name, num_options, &options);

    // the media type to print on

    num_options = cupsAddOption("MediaType", pinfo->medium.name, num_options, &options);

    // never print two-side

    num_options = cupsAddOption("sides", "one-sided", num_options, &options);

    // and a single image per page

    num_options = cupsAddOption("number-up", "1", num_options, &options);

    // if the printer has no hardward margins activate the borderless mode

    if (pinfo->printer.hw_margin_top == 0 || pinfo->printer.hw_margin_bottom == 0
        || pinfo->printer.hw_margin_left == 0 || pinfo->printer.hw_margin_right == 0)
    {
      // there is many variant for this parameter
      num_options = cupsAddOption("StpFullBleed", "true", num_options, &options);
      num_options = cupsAddOption("STP_FullBleed", "true", num_options, &options);
      num_options = cupsAddOption("Borderless", "true", num_options, &options);
    }

    num_options = cupsAddOption("landscape", pinfo->page.landscape ? "true" : "false", num_options, &options);
  }

  // print lp options

  dt_print(DT_DEBUG_PRINT, "[print] printer options (%d)\n", num_options);
  for (int k=0; k<num_options; k++)
    dt_print(DT_DEBUG_PRINT, "[print]   %2d  %s=%s\n", k+1, options[k].name, options[k].value);

  const int job_id = cupsPrintFile(pinfo->printer.name, filename, job_title, num_options, options);

  if (job_id == 0)
    dt_control_log(_("error while printing `%s' on `%s'"), job_title, pinfo->printer.name);
  else
    dt_control_log(_("printing `%s' on `%s'"), job_title, pinfo->printer.name);

  cupsFreeOptions (num_options, options);
}
Esempio n. 13
0
void
cupsEncodeOptions2(
    ipp_t         *ipp,			/* I - Request to add to */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    ipp_tag_t     group_tag)		/* I - Group to encode */
{
  int		i, j;			/* Looping vars */
  int		count;			/* Number of values */
  char		*s,			/* Pointer into option value */
		*val,			/* Pointer to option value */
		*copy,			/* Copy of option value */
		*sep,			/* Option separator */
		quote;			/* Quote character */
  ipp_attribute_t *attr;		/* IPP attribute */
  ipp_tag_t	value_tag;		/* IPP value tag */
  cups_option_t	*option;		/* Current option */
  ipp_t		*collection;		/* Collection value */
  int		num_cols;		/* Number of collection values */
  cups_option_t	*cols;			/* Collection values */


  DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, "
                "group_tag=%x)", ipp, num_options, options, group_tag));

 /*
  * Range check input...
  */

  if (!ipp || num_options < 1 || !options)
    return;

 /*
  * Do special handling for the document-format/raw options...
  */

  if (group_tag == IPP_TAG_OPERATION)
  {
   /*
    * Handle the document format stuff first...
    */

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

 /*
  * Then loop through the options...
  */

  for (i = num_options, option = options; i > 0; i --, option ++)
  {
    _ipp_option_t	*match;		/* Matching attribute */


   /*
    * Skip document format options that are handled above...
    */

    if (!_cups_strcasecmp(option->name, "raw") ||
        !_cups_strcasecmp(option->name, "document-format") ||
	!option->name[0])
      continue;

   /*
    * Figure out the proper value and group tags for this option...
    */

    if ((match = _ippFindOption(option->name)) != NULL)
    {
      if (match->group_tag != group_tag)
        continue;

      value_tag = match->value_tag;
    }
    else
    {
      int	namelen;		/* Length of name */


      namelen = (int)strlen(option->name);

      if (namelen < 9 || strcmp(option->name + namelen - 8, "-default"))
      {
	if (group_tag != IPP_TAG_JOB)
          continue;
      }
      else if (group_tag != IPP_TAG_PRINTER)
        continue;

      if (!_cups_strcasecmp(option->value, "true") ||
          !_cups_strcasecmp(option->value, "false"))
	value_tag = IPP_TAG_BOOLEAN;
      else
	value_tag = IPP_TAG_NAME;
    }

   /*
    * Count the number of values...
    */

    if (match && match->multivalue)
    {
      for (count = 1, sep = option->value, quote = 0; *sep; sep ++)
      {
	if (*sep == quote)
	  quote = 0;
	else if (!quote && (*sep == '\'' || *sep == '\"'))
	{
	 /*
	  * Skip quoted option value...
	  */

	  quote = *sep++;
	}
	else if (*sep == ',' && !quote)
	  count ++;
	else if (*sep == '\\' && sep[1])
	  sep ++;
      }
    }
    else
      count = 1;

    DEBUG_printf(("2cupsEncodeOptions2: option=\"%s\", count=%d",
                  option->name, count));

   /*
    * Allocate memory for the attribute values...
    */

    if ((attr = _ippAddAttr(ipp, count)) == NULL)
    {
     /*
      * Ran out of memory!
      */

      DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for attributes!");
      return;
    }

   /*
    * Now figure out what type of value we have...
    */

    attr->group_tag = group_tag;
    attr->value_tag = value_tag;

   /*
    * Copy the name over...
    */

    attr->name = _cupsStrAlloc(option->name);

    if (count > 1)
    {
     /*
      * Make a copy of the value we can fiddle with...
      */

      if ((copy = strdup(option->value)) == NULL)
      {
       /*
	* Ran out of memory!
	*/

	DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for value copy!");
	ippDeleteAttribute(ipp, attr);
	return;
      }

      val = copy;
    }
    else
    {
     /*
      * Since we have a single value, use the value directly...
      */

      val  = option->value;
      copy = NULL;
    }

   /*
    * Scan the value string for values...
    */

    for (j = 0, sep = val; j < count; val = sep, j ++)
    {
     /*
      * Find the end of this value and mark it if needed...
      */

      if (count > 1)
      {
	for (quote = 0; *sep; sep ++)
	{
	  if (*sep == quote)
	  {
	   /*
	    * Finish quoted value...
	    */

	    quote = 0;
	  }
	  else if (!quote && (*sep == '\'' || *sep == '\"'))
	  {
	   /*
	    * Handle quoted option value...
	    */

	    quote = *sep;
	  }
	  else if (*sep == ',' && count > 1)
	    break;
	  else if (*sep == '\\' && sep[1])
	  {
	   /*
	    * Skip quoted character...
	    */

	    sep ++;
	  }
	}

	if (*sep == ',')
	  *sep++ = '\0';
      }

     /*
      * Copy the option value(s) over as needed by the type...
      */

      switch (attr->value_tag)
      {
	case IPP_TAG_INTEGER :
	case IPP_TAG_ENUM :
	   /*
	    * Integer/enumeration value...
	    */

            attr->values[j].integer = strtol(val, &s, 10);

            DEBUG_printf(("2cupsEncodeOptions2: Added integer option value "
	                  "%d...", attr->values[j].integer));
            break;

	case IPP_TAG_BOOLEAN :
	    if (!_cups_strcasecmp(val, "true") ||
	        !_cups_strcasecmp(val, "on") ||
	        !_cups_strcasecmp(val, "yes"))
	    {
	     /*
	      * Boolean value - true...
	      */

	      attr->values[j].boolean = 1;

              DEBUG_puts("2cupsEncodeOptions2: Added boolean true value...");
	    }
	    else
	    {
	     /*
	      * Boolean value - false...
	      */

	      attr->values[j].boolean = 0;

              DEBUG_puts("2cupsEncodeOptions2: Added boolean false value...");
	    }
            break;

	case IPP_TAG_RANGE :
	   /*
	    * Range...
	    */

            if (*val == '-')
	    {
	      attr->values[j].range.lower = 1;
	      s = val;
	    }
	    else
	      attr->values[j].range.lower = strtol(val, &s, 10);

	    if (*s == '-')
	    {
	      if (s[1])
		attr->values[j].range.upper = strtol(s + 1, NULL, 10);
	      else
		attr->values[j].range.upper = 2147483647;
            }
	    else
	      attr->values[j].range.upper = attr->values[j].range.lower;

	    DEBUG_printf(("2cupsEncodeOptions2: Added range option value "
	                  "%d-%d...", attr->values[j].range.lower,
			  attr->values[j].range.upper));
            break;

	case IPP_TAG_RESOLUTION :
	   /*
	    * Resolution...
	    */

	    attr->values[j].resolution.xres = strtol(val, &s, 10);

	    if (*s == 'x')
	      attr->values[j].resolution.yres = strtol(s + 1, &s, 10);
	    else
	      attr->values[j].resolution.yres = attr->values[j].resolution.xres;

	    if (!_cups_strcasecmp(s, "dpc"))
              attr->values[j].resolution.units = IPP_RES_PER_CM;
            else
              attr->values[j].resolution.units = IPP_RES_PER_INCH;

	    DEBUG_printf(("2cupsEncodeOptions2: Added resolution option value "
	                  "%s...", val));
            break;

	case IPP_TAG_STRING :
           /*
	    * octet-string
	    */

            attr->values[j].unknown.length = (int)strlen(val);
	    attr->values[j].unknown.data   = strdup(val);

            DEBUG_printf(("2cupsEncodeOptions2: Added octet-string value "
	                  "\"%s\"...", (char *)attr->values[j].unknown.data));
            break;

        case IPP_TAG_BEGIN_COLLECTION :
	   /*
	    * Collection value
	    */

	    num_cols   = cupsParseOptions(val, 0, &cols);
	    if ((collection = ippNew()) == NULL)
	    {
	      cupsFreeOptions(num_cols, cols);

	      if (copy)
	        free(copy);

	      ippDeleteAttribute(ipp, attr);
	      return;
            }

	    attr->values[j].collection = collection;
	    cupsEncodeOptions2(collection, num_cols, cols, IPP_TAG_JOB);
            cupsFreeOptions(num_cols, cols);
	    break;

	default :
	    if ((attr->values[j].string.text = _cupsStrAlloc(val)) == NULL)
	    {
	     /*
	      * Ran out of memory!
	      */

	      DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for string!");

	      if (copy)
	        free(copy);

	      ippDeleteAttribute(ipp, attr);
	      return;
	    }

	    DEBUG_printf(("2cupsEncodeOptions2: Added string value \"%s\"...",
	                  val));
            break;
      }
    }

    if (copy)
      free(copy);
  }
}
Esempio n. 14
0
int					/* O - 0 on success, -1 on failure */
backendGetMakeModel(
    const char *device_id,		/* O - 1284 device ID */
    char       *make_model,		/* O - Make/model */
    size_t     make_model_size)		/* I - Size of buffer */
{
  int		num_values;		/* Number of keys and values */
  cups_option_t	*values;		/* Keys and values */
  const char	*mfg,			/* Manufacturer string */
		*mdl,			/* Model string */
		*des;			/* Description string */


  DEBUG_printf(("backendGetMakeModel(device_id=\"%s\", make_model=%p, make_model_size=" CUPS_LLFMT ")\n", device_id, make_model, CUPS_LLCAST make_model_size));

 /*
  * Range check input...
  */

  if (!device_id || !*device_id || !make_model || make_model_size < 32)
  {
    DEBUG_puts("backendGetMakeModel: Bad args!");
    return (-1);
  }

  *make_model = '\0';

 /*
  * Look for the description field...
  */

  num_values = _cupsGet1284Values(device_id, &values);

  if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
    mdl = cupsGetOption("MDL", num_values, values);

  if (mdl)
  {
   /*
    * Build a make-model string from the manufacturer and model attributes...
    */

    if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
      mfg = cupsGetOption("MFG", num_values, values);

    if (!mfg || !_cups_strncasecmp(mdl, mfg, strlen(mfg)))
    {
     /*
      * Just copy the model string, since it has the manufacturer...
      */

      _ppdNormalizeMakeAndModel(mdl, make_model, make_model_size);
    }
    else
    {
     /*
      * Concatenate the make and model...
      */

      char	temp[1024];		/* Temporary make and model */

      snprintf(temp, sizeof(temp), "%s %s", mfg, mdl);

      _ppdNormalizeMakeAndModel(temp, make_model, make_model_size);
    }
  }
  else if ((des = cupsGetOption("DESCRIPTION", num_values, values)) != NULL ||
           (des = cupsGetOption("DES", num_values, values)) != NULL)
  {
   /*
    * Make sure the description contains something useful, since some
    * printer manufacturers (HP) apparently don't follow the standards
    * they helped to define...
    *
    * Here we require the description to be 8 or more characters in length,
    * containing at least one space and one letter.
    */

    if (strlen(des) >= 8)
    {
      const char	*ptr;		/* Pointer into description */
      int		letters,	/* Number of letters seen */
			spaces;		/* Number of spaces seen */


      for (ptr = des, letters = 0, spaces = 0; *ptr; ptr ++)
      {
	if (isspace(*ptr & 255))
	  spaces ++;
	else if (isalpha(*ptr & 255))
	  letters ++;

	if (spaces && letters)
	  break;
      }

      if (spaces && letters)
        _ppdNormalizeMakeAndModel(des, make_model, make_model_size);
    }
  }

  if (!make_model[0])
  {
   /*
    * Use "Unknown" as the printer make and model...
    */

    strlcpy(make_model, "Unknown", make_model_size);
  }

  cupsFreeOptions(num_values, values);

  return (0);
}
Esempio n. 15
0
int					/* O - 0 on success, -1 on failure */
backendGetDeviceID(
    int        fd,			/* I - File descriptor */
    char       *device_id,		/* O - 1284 device ID */
    int        device_id_size,		/* I - Size of buffer */
    char       *make_model,		/* O - Make/model */
    int        make_model_size,		/* I - Size of buffer */
    const char *scheme,			/* I - URI scheme */
    char       *uri,			/* O - Device URI */
    int        uri_size)		/* I - Size of buffer */
{
#ifdef __APPLE__ /* This function is a no-op */
  (void)fd;
  (void)device_id;
  (void)device_id_size;
  (void)make_model;
  (void)make_model_size;
  (void)scheme;
  (void)uri;
  (void)uri_size;

  return (-1);

#else /* Get the device ID from the specified file descriptor... */
#  ifdef __linux
  int	length;				/* Length of device ID info */
  int   got_id = 0;
#  endif /* __linux */
#  if defined(__sun) && defined(ECPPIOC_GETDEVID)
  struct ecpp_device_id did;		/* Device ID buffer */
#  endif /* __sun && ECPPIOC_GETDEVID */
  char	*ptr;				/* Pointer into device ID */


  DEBUG_printf(("backendGetDeviceID(fd=%d, device_id=%p, device_id_size=%d, "
                "make_model=%p, make_model_size=%d, scheme=\"%s\", "
		"uri=%p, uri_size=%d)\n", fd, device_id, device_id_size,
		make_model, make_model_size, scheme ? scheme : "(null)",
		uri, uri_size));

 /*
  * Range check input...
  */

  if (!device_id || device_id_size < 32)
  {
    DEBUG_puts("backendGetDeviceID: Bad args!");
    return (-1);
  }

  if (make_model)
    *make_model = '\0';

  if (fd >= 0)
  {
   /*
    * Get the device ID string...
    */

    *device_id = '\0';

#  ifdef __linux
    if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id))
    {
     /*
      * Linux has to implement things differently for every device it seems.
      * Since the standard parallel port driver does not provide a simple
      * ioctl() to get the 1284 device ID, we have to open the "raw" parallel
      * device corresponding to this port and do some negotiation trickery
      * to get the current device ID.
      */

      if (uri && !strncmp(uri, "parallel:/dev/", 14))
      {
	char	devparport[16];		/* /dev/parportN */
	int	devparportfd,		/* File descriptor for raw device */
		  mode;			/* Port mode */


       /*
	* Since the Linux parallel backend only supports 4 parallel port
	* devices, just grab the trailing digit and use it to construct a
	* /dev/parportN filename...
	*/

	snprintf(devparport, sizeof(devparport), "/dev/parport%s",
		 uri + strlen(uri) - 1);

	if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1)
	{
	 /*
	  * Claim the device...
	  */

	  if (!ioctl(devparportfd, PPCLAIM))
	  {
	    fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK);

	    mode = IEEE1284_MODE_COMPAT;

	    if (!ioctl(devparportfd, PPNEGOT, &mode))
	    {
	     /*
	      * Put the device into Device ID mode...
	      */

	      mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID;

	      if (!ioctl(devparportfd, PPNEGOT, &mode))
	      {
	       /*
		* Read the 1284 device ID...
		*/

		if ((length = read(devparportfd, device_id, (size_t)device_id_size - 1)) >= 2)
		{
		  device_id[length] = '\0';
		  got_id = 1;
		}
	      }
	    }

	   /*
	    * Release the device...
	    */

	    ioctl(devparportfd, PPRELEASE);
	  }

	  close(devparportfd);
	}
      }
    }
    else
      got_id = 1;

    if (got_id)
    {
     /*
      * Extract the length of the device ID string from the first two
      * bytes.  The 1284 spec says the length is stored MSB first...
      */

      length = (int)((((unsigned)device_id[0] & 255) << 8) + ((unsigned)device_id[1] & 255));

     /*
      * Check to see if the length is larger than our buffer; first
      * assume that the vendor incorrectly implemented the 1284 spec,
      * and then limit the length to the size of our buffer...
      */

      if (length > device_id_size || length < 14)
	length = (int)((((unsigned)device_id[1] & 255) << 8) + ((unsigned)device_id[0] & 255));

      if (length > device_id_size)
	length = device_id_size;

     /*
      * The length field counts the number of bytes in the string
      * including the length field itself (2 bytes).  The minimum
      * length for a valid/usable device ID is 14 bytes:
      *
      *     <LENGTH> MFG: <MFG> ;MDL: <MDL> ;
      *        2  +   4  +  1  +  5 +  1 +  1
      */

      if (length < 14)
      {
       /*
	* Can't use this device ID, so don't try to copy it...
	*/

	device_id[0] = '\0';
	got_id       = 0;
      }
      else
      {
       /*
	* Copy the device ID text to the beginning of the buffer and
	* nul-terminate.
	*/

	length -= 2;

	memmove(device_id, device_id + 2, (size_t)length);
	device_id[length] = '\0';
      }
    }
    else
    {
      DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n",
                    strerror(errno)));
      *device_id = '\0';
    }
#  endif /* __linux */

#   if defined(__sun) && defined(ECPPIOC_GETDEVID)
    did.mode = ECPP_CENTRONICS;
    did.len  = device_id_size - 1;
    did.rlen = 0;
    did.addr = device_id;

    if (!ioctl(fd, ECPPIOC_GETDEVID, &did))
    {
     /*
      * Nul-terminate the device ID text.
      */

      if (did.rlen < (device_id_size - 1))
	device_id[did.rlen] = '\0';
      else
	device_id[device_id_size - 1] = '\0';
    }
#    ifdef DEBUG
    else
      DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n",
                    strerror(errno)));
#    endif /* DEBUG */
#  endif /* __sun && ECPPIOC_GETDEVID */
  }

 /*
  * Check whether device ID is valid. Turn line breaks and tabs to spaces and
  * reject device IDs with non-printable characters.
  */

  for (ptr = device_id; *ptr; ptr ++)
    if (_cups_isspace(*ptr))
      *ptr = ' ';
    else if ((*ptr & 255) < ' ' || *ptr == 127)
    {
      DEBUG_printf(("backendGetDeviceID: Bad device_id character %d.",
                    *ptr & 255));
      *device_id = '\0';
      break;
    }

  DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id));

  if (scheme && uri)
    *uri = '\0';

  if (!*device_id)
    return (-1);

 /*
  * Get the make and model...
  */

  if (make_model)
    backendGetMakeModel(device_id, make_model, (size_t)make_model_size);

 /*
  * Then generate a device URI...
  */

  if (scheme && uri && uri_size > 32)
  {
    int			num_values;	/* Number of keys and values */
    cups_option_t	*values;	/* Keys and values in device ID */
    const char		*mfg,		/* Manufacturer */
			*mdl,		/* Model */
			*sern;		/* Serial number */
    char		temp[256],	/* Temporary manufacturer string */
			*tempptr;	/* Pointer into temp string */


   /*
    * Get the make, model, and serial numbers...
    */

    num_values = _cupsGet1284Values(device_id, &values);

    if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL)
      if ((sern = cupsGetOption("SERN", num_values, values)) == NULL)
        sern = cupsGetOption("SN", num_values, values);

    if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL)
      mfg = cupsGetOption("MFG", num_values, values);

    if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL)
      mdl = cupsGetOption("MDL", num_values, values);

    if (mfg)
    {
      if (!_cups_strcasecmp(mfg, "Hewlett-Packard"))
        mfg = "HP";
      else if (!_cups_strcasecmp(mfg, "Lexmark International"))
        mfg = "Lexmark";
    }
    else
    {
      strlcpy(temp, make_model, sizeof(temp));

      if ((tempptr = strchr(temp, ' ')) != NULL)
        *tempptr = '\0';

      mfg = temp;
    }

    if (!mdl)
      mdl = "";

    if (!_cups_strncasecmp(mdl, mfg, strlen(mfg)))
    {
      mdl += strlen(mfg);

      while (isspace(*mdl & 255))
        mdl ++;
    }

   /*
    * Generate the device URI from the manufacturer, make_model, and
    * serial number strings.
    */

    httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, scheme, NULL, mfg, 0,
                     "/%s%s%s", mdl, sern ? "?serial=" : "", sern ? sern : "");

    cupsFreeOptions(num_values, values);
  }

  return (0);
#endif /* __APPLE__ */
}
Esempio n. 16
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  ppd_file_t	*ppd;			/* PPD file loaded from disk */
  char		line[256],		/* Input buffer */
		*ptr,			/* Pointer into buffer */
		*optr,			/* Pointer to first option name */
		*cptr;			/* Pointer to first choice */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  char		*option,		/* Current option */
		*choice;		/* Current choice */


  if (argc != 2)
  {
    puts("Usage: testconflicts filename.ppd");
    return (1);
  }

  if ((ppd = ppdOpenFile(argv[1])) == NULL)
  {
    ppd_status_t	err;		/* Last error in file */
    int			linenum;	/* Line number in file */

    err = ppdLastError(&linenum);

    printf("Unable to open PPD file \"%s\": %s on line %d\n", argv[1],
           ppdErrorString(err), linenum);
    return (1);
  }

  ppdMarkDefaults(ppd);

  option = NULL;
  choice = NULL;

  for (;;)
  {
    num_options = 0;
    options     = NULL;

    if (!cupsResolveConflicts(ppd, option, choice, &num_options, &options))
      puts("Unable to resolve conflicts!");
    else if ((!option && num_options > 0) || (option && num_options > 1))
    {
      fputs("Resolved conflicts with the following options:\n   ", stdout);
      for (i = 0; i < num_options; i ++)
        if (!option || _cups_strcasecmp(option, options[i].name))
	  printf(" %s=%s", options[i].name, options[i].value);
      putchar('\n');

      cupsFreeOptions(num_options, options);
    }

    if (option)
    {
      free(option);
      option = NULL;
    }

    if (choice)
    {
      free(choice);
      choice = NULL;
    }

    printf("\nNew Option(s): ");
    fflush(stdout);
    if (!fgets(line, sizeof(line), stdin) || line[0] == '\n')
      break;

    for (ptr = line; isspace(*ptr & 255); ptr ++);
    for (optr = ptr; *ptr && *ptr != '='; ptr ++);
    if (!*ptr)
      break;
    for (*ptr++ = '\0', cptr = ptr; *ptr && !isspace(*ptr & 255); ptr ++);
    if (!*ptr)
      break;
    *ptr++ = '\0';

    option      = strdup(optr);
    choice      = strdup(cptr);
    num_options = cupsParseOptions(ptr, 0, &options);

    ppdMarkOption(ppd, option, choice);
    if (cupsMarkOptions(ppd, num_options, options))
      puts("Options Conflict!");
    cupsFreeOptions(num_options, options);
  }

  if (option)
    free(option);
  if (choice)
    free(choice);

  return (0);
}
Esempio n. 17
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i, j;			/* Looping vars */
  int		changes;		/* Did we make changes? */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  int		num_dests;		/* Number of destinations */
  cups_dest_t	*dests;			/* Destinations */
  cups_dest_t	*dest;			/* Current destination */
  char		*opt,			/* Option pointer */
		*printer,		/* Printer name */
		*instance,		/* Instance name */
 		*option;		/* Current option */


  _cupsSetLocale(argv);

 /*
  * Loop through the command-line arguments...
  */

  dest        = NULL;
  num_dests   = 0;
  dests       = NULL;
  num_options = 0;
  options     = NULL;
  changes     = 0;

  for (i = 1; i < argc; i ++)
  {
    if (!strcmp(argv[i], "--help"))
      usage();
    else if (argv[i][0] == '-')
    {
      for (opt = argv[i] + 1; *opt; opt ++)
      {
	switch (*opt)
	{
	  case 'd' : /* -d printer */
	      if (opt[1] != '\0')
	      {
		printer = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;
		if (i >= argc)
		  usage();

		printer = argv[i];
	      }

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

	      if (num_dests == 0)
		num_dests = cupsGetDests(&dests);

	      if (num_dests == 0 || !dests || (dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
	      {
		_cupsLangPuts(stderr, _("lpoptions: Unknown printer or class."));
		return (1);
	      }

	     /*
	      * Set the default destination...
	      */

	      for (j = 0; j < num_dests; j ++)
		dests[j].is_default = 0;

	      dest->is_default = 1;

	      cupsSetDests(num_dests, dests);

	      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 'h' : /* -h server */
	      if (opt[1] != '\0')
	      {
		cupsSetServer(opt + 1);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;
		if (i >= argc)
		  usage();

		cupsSetServer(argv[i]);
	      }
	      break;

	  case 'E' : /* Encrypt connection */
	      cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
	      break;

	  case 'l' : /* -l (list options) */
	      if (dest == NULL)
	      {
		if (num_dests == 0)
		  num_dests = cupsGetDests(&dests);

		if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
		  dest = dests;
	      }

	      if (dest == NULL)
		_cupsLangPuts(stderr, _("lpoptions: No printers."));
	      else
		list_options(dest);

	      changes = -1;
	      break;

	  case 'o' : /* -o option[=value] */
	      if (dest == NULL)
	      {
		if (num_dests == 0)
		  num_dests = cupsGetDests(&dests);

		if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
		  dest = dests;

		if (dest == NULL)
		{
		  _cupsLangPuts(stderr, _("lpoptions: No printers."));
		  return (1);
		}

		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 (opt[1] != '\0')
	      {
		num_options = cupsParseOptions(opt + 1, num_options, &options);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;
		if (i >= argc)
		  usage();

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

	      changes = 1;
	      break;

	  case 'p' : /* -p printer */
	      if (opt[1] != '\0')
	      {
		printer = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;
		if (i >= argc)
		  usage();

		printer = argv[i];
	      }

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

	      if (num_dests == 0)
		num_dests = cupsGetDests(&dests);

	      if ((dest = cupsGetDest(printer, instance, num_dests, dests)) == NULL)
	      {
		num_dests = cupsAddDest(printer, instance, num_dests, &dests);
		dest      = cupsGetDest(printer, instance, num_dests, dests);

		if (dest == NULL)
		{
		  _cupsLangPrintf(stderr, _("lpoptions: Unable to add printer or instance: %s"), strerror(errno));
		  return (1);
		}
	      }

	      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 'r' : /* -r option (remove) */
	      if (dest == NULL)
	      {
		if (num_dests == 0)
		  num_dests = cupsGetDests(&dests);

		if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
		  dest = dests;

		if (dest == NULL)
		{
		  _cupsLangPuts(stderr, _("lpoptions: No printers."));
		  return (1);
		}

		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 (opt[1] != '\0')
	      {
		option = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;
		if (i >= argc)
		  usage();

		option = argv[i];
	      }

              num_options = cupsRemoveOption(option, num_options, &options);

	      changes = 1;
	      break;

	  case 'x' : /* -x printer */
	      if (opt[1] != '\0')
	      {
		printer = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;
		if (i >= argc)
		  usage();

		printer = argv[i];
	      }

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

	      if (num_dests == 0)
		num_dests = cupsGetDests(&dests);

              num_dests = cupsRemoveDest(printer, instance, num_dests, &dests);

	      cupsSetDests(num_dests, dests);
	      dest    = NULL;
	      changes = -1;
	      break;

	  default :
	      usage();
	}
      }
    }
    else
    {
      usage();
    }
  }

  if (num_dests == 0)
    num_dests = cupsGetDests(&dests);

  if (dest == NULL)
  {
    if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != 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);
    }
  }

  if (dest == NULL)
    return (0);

  if (changes > 0)
  {
   /*
    * Set printer options...
    */

    cupsFreeOptions(dest->num_options, dest->options);

    dest->num_options = num_options;
    dest->options     = options;

    cupsSetDests(num_dests, dests);
  }
  else if (changes == 0)
  {
    char	buffer[10240],		/* String for options */
		*ptr;			/* Pointer into string */

    num_options = dest->num_options;
    options     = dest->options;

    for (i = 0, ptr = buffer;
         ptr < (buffer + sizeof(buffer) - 1) && i < num_options;
	 i ++)
    {
      if (i)
        *ptr++ = ' ';

      if (!options[i].value[0])
        strlcpy(ptr, options[i].name, sizeof(buffer) - (size_t)(ptr - buffer));
      else if (strchr(options[i].value, ' ') != NULL ||
               strchr(options[i].value, '\t') != NULL)
	snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s=\'%s\'", options[i].name, options[i].value);
      else
	snprintf(ptr, sizeof(buffer) - (size_t)(ptr - buffer), "%s=%s", options[i].name, options[i].value);

      ptr += strlen(ptr);
    }

    _cupsLangPuts(stdout, buffer);
  }

  return (0);
}
Esempio n. 18
0
int					/* O  - 1 on success, 0 on failure */
cupsResolveConflicts(
    ppd_file_t    *ppd,			/* I  - PPD file */
    const char    *option,		/* I  - Newly selected option or @code NULL@ for none */
    const char    *choice,		/* I  - Newly selected choice or @code NULL@ for none */
    int           *num_options,		/* IO - Number of additional selected options */
    cups_option_t **options)		/* IO - Additional selected options */
{
  int			i,		/* Looping var */
			tries,		/* Number of tries */
			num_newopts;	/* Number of new options */
  cups_option_t		*newopts;	/* New options */
  cups_array_t		*active = NULL,	/* Active constraints */
			*pass,		/* Resolvers for this pass */
			*resolvers,	/* Resolvers we have used */
			*test;		/* Test array for conflicts */
  _ppd_cups_uiconsts_t	*consts;	/* Current constraints */
  _ppd_cups_uiconst_t	*constptr;	/* Current constraint */
  ppd_attr_t		*resolver;	/* Current resolver */
  const char		*resval;	/* Pointer into resolver value */
  char			resoption[PPD_MAX_NAME],
					/* Current resolver option */
			reschoice[PPD_MAX_NAME],
					/* Current resolver choice */
			*resptr,	/* Pointer into option/choice */
			firstpage[255];	/* AP_FIRSTPAGE_Keyword string */
  const char		*value;		/* Selected option value */
  int			changed;	/* Did we change anything? */
  ppd_choice_t		*marked;	/* Marked choice */


 /*
  * Range check input...
  */

  if (!ppd || !num_options || !options || (option == NULL) != (choice == NULL))
    return (0);

 /*
  * Build a shadow option array...
  */

  num_newopts = 0;
  newopts     = NULL;

  for (i = 0; i < *num_options; i ++)
    num_newopts = cupsAddOption((*options)[i].name, (*options)[i].value,
                                num_newopts, &newopts);
  if (option && _cups_strcasecmp(option, "Collate"))
    num_newopts = cupsAddOption(option, choice, num_newopts, &newopts);

 /*
  * Loop until we have no conflicts...
  */

  cupsArraySave(ppd->sorted_attrs);

  resolvers = NULL;
  pass      = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL);
  tries     = 0;

  while (tries < 100 &&
         (active = ppd_test_constraints(ppd, NULL, NULL, num_newopts, newopts,
                                        _PPD_ALL_CONSTRAINTS)) != NULL)
  {
    tries ++;

    if (!resolvers)
      resolvers = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL);

    for (consts = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active), changed = 0;
         consts;
	 consts = (_ppd_cups_uiconsts_t *)cupsArrayNext(active))
    {
      if (consts->resolver[0])
      {
       /*
        * Look up the resolver...
	*/

        if (cupsArrayFind(pass, consts->resolver))
	  continue;			/* Already applied this resolver... */

        if (cupsArrayFind(resolvers, consts->resolver))
	{
	 /*
	  * Resolver loop!
	  */

	  DEBUG_printf(("1cupsResolveConflicts: Resolver loop with %s!",
	                consts->resolver));
          goto error;
	}

        if ((resolver = ppdFindAttr(ppd, "cupsUIResolver",
	                            consts->resolver)) == NULL)
        {
	  DEBUG_printf(("1cupsResolveConflicts: Resolver %s not found!",
	                consts->resolver));
	  goto error;
	}

        if (!resolver->value)
	{
	  DEBUG_printf(("1cupsResolveConflicts: Resolver %s has no value!",
	                consts->resolver));
	  goto error;
	}

       /*
        * Add the options from the resolver...
	*/

        cupsArrayAdd(pass, consts->resolver);
	cupsArrayAdd(resolvers, consts->resolver);

        for (resval = resolver->value; *resval && !changed;)
	{
	  while (_cups_isspace(*resval))
	    resval ++;

	  if (*resval != '*')
	    break;

	  for (resval ++, resptr = resoption;
	       *resval && !_cups_isspace(*resval);
	       resval ++)
            if (resptr < (resoption + sizeof(resoption) - 1))
	      *resptr++ = *resval;

          *resptr = '\0';

	  while (_cups_isspace(*resval))
	    resval ++;

	  for (resptr = reschoice;
	       *resval && !_cups_isspace(*resval);
	       resval ++)
            if (resptr < (reschoice + sizeof(reschoice) - 1))
	      *resptr++ = *resval;

          *resptr = '\0';

          if (!resoption[0] || !reschoice[0])
	    break;

         /*
	  * Is this the option we are changing?
	  */

          snprintf(firstpage, sizeof(firstpage), "AP_FIRSTPAGE_%s", resoption);

	  if (option &&
	      (!_cups_strcasecmp(resoption, option) ||
	       !_cups_strcasecmp(firstpage, option) ||
	       (!_cups_strcasecmp(option, "PageSize") &&
		!_cups_strcasecmp(resoption, "PageRegion")) ||
	       (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") &&
		!_cups_strcasecmp(resoption, "PageSize")) ||
	       (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageSize") &&
		!_cups_strcasecmp(resoption, "PageRegion")) ||
	       (!_cups_strcasecmp(option, "PageRegion") &&
	        !_cups_strcasecmp(resoption, "PageSize")) ||
	       (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion") &&
	        !_cups_strcasecmp(resoption, "PageSize")) ||
	       (!_cups_strcasecmp(option, "AP_FIRSTPAGE_PageRegion") &&
	        !_cups_strcasecmp(resoption, "PageRegion"))))
	    continue;

	 /*
	  * Try this choice...
	  */

          if ((test = ppd_test_constraints(ppd, resoption, reschoice,
					   num_newopts, newopts,
					   _PPD_ALL_CONSTRAINTS)) == NULL)
	  {
	   /*
	    * That worked...
	    */

            changed = 1;
	  }
	  else
            cupsArrayDelete(test);

	 /*
	  * Add the option/choice from the resolver regardless of whether it
	  * worked; this makes sure that we can cascade several changes to
	  * make things resolve...
	  */

	  num_newopts = cupsAddOption(resoption, reschoice, num_newopts,
				      &newopts);
        }
      }
      else
      {
       /*
        * Try resolving by choosing the default values for non-installable
	* options, then by iterating through the possible choices...
	*/

        int		j;		/* Looping var */
	ppd_choice_t	*cptr;		/* Current choice */
        ppd_size_t	*size;		/* Current page size */


        for (i = consts->num_constraints, constptr = consts->constraints;
	     i > 0 && !changed;
	     i --, constptr ++)
	{
	 /*
	  * Can't resolve by changing an installable option...
	  */

	  if (constptr->installable)
	    continue;

         /*
	  * Is this the option we are changing?
	  */

	  if (option &&
	      (!_cups_strcasecmp(constptr->option->keyword, option) ||
	       (!_cups_strcasecmp(option, "PageSize") &&
		!_cups_strcasecmp(constptr->option->keyword, "PageRegion")) ||
	       (!_cups_strcasecmp(option, "PageRegion") &&
		!_cups_strcasecmp(constptr->option->keyword, "PageSize"))))
	    continue;

         /*
	  * Get the current option choice...
	  */

          if ((value = cupsGetOption(constptr->option->keyword, num_newopts,
	                             newopts)) == NULL)
          {
	    if (!_cups_strcasecmp(constptr->option->keyword, "PageSize") ||
	        !_cups_strcasecmp(constptr->option->keyword, "PageRegion"))
	    {
	      if ((value = cupsGetOption("PageSize", num_newopts,
	                                 newopts)) == NULL)
                value = cupsGetOption("PageRegion", num_newopts, newopts);

              if (!value)
	      {
	        if ((size = ppdPageSize(ppd, NULL)) != NULL)
		  value = size->name;
		else
		  value = "";
	      }
	    }
	    else
	    {
	      marked = ppdFindMarkedChoice(ppd, constptr->option->keyword);
	      value  = marked ? marked->choice : "";
	    }
	  }

	  if (!_cups_strncasecmp(value, "Custom.", 7))
	    value = "Custom";

         /*
	  * Try the default choice...
	  */

          test = NULL;

          if (_cups_strcasecmp(value, constptr->option->defchoice) &&
	      (test = ppd_test_constraints(ppd, constptr->option->keyword,
	                                   constptr->option->defchoice,
					   num_newopts, newopts,
					   _PPD_OPTION_CONSTRAINTS)) == NULL)
	  {
	   /*
	    * That worked...
	    */

	    num_newopts = cupsAddOption(constptr->option->keyword,
	                                constptr->option->defchoice,
					num_newopts, &newopts);
            changed     = 1;
	  }
	  else
	  {
	   /*
	    * Try each choice instead...
	    */

            for (j = constptr->option->num_choices,
	             cptr = constptr->option->choices;
		 j > 0;
		 j --, cptr ++)
            {
	      cupsArrayDelete(test);
	      test = NULL;

	      if (_cups_strcasecmp(value, cptr->choice) &&
	          _cups_strcasecmp(constptr->option->defchoice, cptr->choice) &&
		  _cups_strcasecmp("Custom", cptr->choice) &&
	          (test = ppd_test_constraints(ppd, constptr->option->keyword,
	                                       cptr->choice, num_newopts,
					       newopts,
					       _PPD_OPTION_CONSTRAINTS)) == NULL)
	      {
	       /*
		* This choice works...
		*/

		num_newopts = cupsAddOption(constptr->option->keyword,
					    cptr->choice, num_newopts,
					    &newopts);
		changed     = 1;
		break;
	      }
	    }

	    cupsArrayDelete(test);
          }
        }
      }
    }

    if (!changed)
    {
      DEBUG_puts("1cupsResolveConflicts: Unable to automatically resolve "
		 "constraint!");
      goto error;
    }

    cupsArrayClear(pass);
    cupsArrayDelete(active);
    active = NULL;
  }

  if (tries >= 100)
    goto error;

 /*
  * Free the caller's option array...
  */

  cupsFreeOptions(*num_options, *options);

 /*
  * If Collate is the option we are testing, add it here.  Otherwise, remove
  * any Collate option from the resolve list since the filters automatically
  * handle manual collation...
  */

  if (option && !_cups_strcasecmp(option, "Collate"))
    num_newopts = cupsAddOption(option, choice, num_newopts, &newopts);
  else
    num_newopts = cupsRemoveOption("Collate", num_newopts, &newopts);

 /*
  * Return the new list of options to the caller...
  */

  *num_options = num_newopts;
  *options     = newopts;

  cupsArrayDelete(pass);
  cupsArrayDelete(resolvers);

  cupsArrayRestore(ppd->sorted_attrs);

  DEBUG_printf(("1cupsResolveConflicts: Returning %d options:", num_newopts));
#ifdef DEBUG
  for (i = 0; i < num_newopts; i ++)
    DEBUG_printf(("1cupsResolveConflicts: options[%d]: %s=%s", i,
                  newopts[i].name, newopts[i].value));
#endif /* DEBUG */

  return (1);

 /*
  * If we get here, we failed to resolve...
  */

  error:

  cupsFreeOptions(num_newopts, newopts);

  cupsArrayDelete(active);
  cupsArrayDelete(pass);
  cupsArrayDelete(resolvers);

  cupsArrayRestore(ppd->sorted_attrs);

  DEBUG_puts("1cupsResolveConflicts: Unable to resolve conflicts!");

  return (0);
}
Esempio n. 19
0
static int				/* O - Command status */
recv_print_job(
    const char    *queue,		/* I - Printer name */
    int           num_defaults,		/* I - Number of default options */
    cups_option_t *defaults)		/* I - Default options */
{
  http_t	*http;			/* HTTP connection */
  int		i;			/* Looping var */
  int		status;			/* Command status */
  int		fd;			/* Temporary file */
  FILE		*fp;			/* File pointer */
  char		filename[1024];		/* Temporary filename */
  ssize_t	bytes;			/* Bytes received */
  size_t	total;			/* Total bytes */
  char		line[256],		/* Line from file/stdin */
		command,		/* Command from line */
		*count,			/* Number of bytes */
		*name;			/* Name of file */
  const char	*job_sheets;		/* Job sheets */
  int		num_data;		/* Number of data files */
  char		control[1024],		/* Control filename */
		data[100][256],		/* Data files */
		temp[100][1024];	/* Temporary files */
  char		user[1024],		/* User name */
		title[1024],		/* Job title */
		docname[1024],		/* Document name */
		dest[256];		/* Printer/class queue */
  int		accepting,		/* printer-is-accepting */
		shared,			/* printer-is-shared */
		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  int		id;			/* Job ID */
  int		docnumber,		/* Current document number */
		doccount;		/* Count of documents */


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

  http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
  if (!http)
  {
    syslog(LOG_ERR, "Unable to connect to server: %s", strerror(errno));

    putchar(1);

    return (1);
  }

 /*
  * See if the printer is available...
  */

  num_options = get_printer(http, queue, dest, sizeof(dest), &options,
                            &accepting, &shared, NULL);

  if (num_options < 0 || !accepting || !shared)
  {
    if (dest[0])
      syslog(LOG_INFO, "Rejecting job because \"%s\" is not %s", dest,
             !accepting ? "accepting jobs" : "shared");
    else
      syslog(LOG_ERR, "Unable to get printer information for \"%s\"", queue);

    httpClose(http);

    putchar(1);

    return (1);
  }

  putchar(0);				/* OK so far... */

 /*
  * Read the request...
  */

  status   = 0;
  num_data = 0;
  fd       = -1;

  control[0] = '\0';

  while (smart_gets(line, sizeof(line), stdin) != NULL)
  {
    if (strlen(line) < 2)
    {
      status = 1;
      break;
    }

    command = line[0];
    count   = line + 1;

    for (name = count + 1; *name && !isspace(*name & 255); name ++);
    while (isspace(*name & 255))
      *name++ = '\0';

    switch (command)
    {
      default :
      case 0x01 : /* Abort */
          status = 1;
	  break;

      case 0x02 : /* Receive control file */
          if (strlen(name) < 2)
	  {
	    syslog(LOG_ERR, "Bad control file name \"%s\"", name);
	    putchar(1);
	    status = 1;
	    break;
	  }

          if (control[0])
	  {
	   /*
	    * Append to the existing control file - the LPD spec is
	    * not entirely clear, but at least the OS/2 LPD code sends
	    * multiple control files per connection...
	    */

	    if ((fd = open(control, O_WRONLY)) < 0)
	    {
	      syslog(LOG_ERR,
	             "Unable to append to temporary control file \"%s\" - %s",
        	     control, strerror(errno));
	      putchar(1);
	      status = 1;
	      break;
	    }

	    lseek(fd, 0, SEEK_END);
          }
	  else
	  {
	    if ((fd = cupsTempFd(control, sizeof(control))) < 0)
	    {
	      syslog(LOG_ERR, "Unable to open temporary control file \"%s\" - %s",
        	     control, strerror(errno));
	      putchar(1);
	      status = 1;
	      break;
	    }

	    strlcpy(filename, control, sizeof(filename));
	  }
	  break;

      case 0x03 : /* Receive data file */
          if (strlen(name) < 2)
	  {
	    syslog(LOG_ERR, "Bad data file name \"%s\"", name);
	    putchar(1);
	    status = 1;
	    break;
	  }

          if (num_data >= (int)(sizeof(data) / sizeof(data[0])))
	  {
	   /*
	    * Too many data files...
	    */

	    syslog(LOG_ERR, "Too many data files (%d)", num_data);
	    putchar(1);
	    status = 1;
	    break;
	  }

	  strlcpy(data[num_data], name, sizeof(data[0]));

          if ((fd = cupsTempFd(temp[num_data], sizeof(temp[0]))) < 0)
	  {
	    syslog(LOG_ERR, "Unable to open temporary data file \"%s\" - %s",
        	   temp[num_data], strerror(errno));
	    putchar(1);
	    status = 1;
	    break;
	  }

	  strlcpy(filename, temp[num_data], sizeof(filename));

          num_data ++;
	  break;
    }

    putchar(status);

    if (status)
      break;

   /*
    * Copy the data or control file from the client...
    */

    for (total = (size_t)strtoll(count, NULL, 10); total > 0; total -= (size_t)bytes)
    {
      if (total > sizeof(line))
        bytes = (ssize_t)sizeof(line);
      else
        bytes = (ssize_t)total;

      if ((bytes = (ssize_t)fread(line, 1, (size_t)bytes, stdin)) > 0)
        bytes = write(fd, line, (size_t)bytes);

      if (bytes < 1)
      {
	syslog(LOG_ERR, "Error while reading file - %s",
               strerror(errno));
        status = 1;
	break;
      }
    }

   /*
    * Read trailing nul...
    */

    if (!status)
    {
      if (fread(line, 1, 1, stdin) < 1)
      {
        status = 1;
	syslog(LOG_ERR, "Error while reading trailing nul - %s",
               strerror(errno));
      }
      else if (line[0])
      {
        status = 1;
	syslog(LOG_ERR, "Trailing character after file is not nul (%02X)!",
	       line[0]);
      }
    }

   /*
    * Close the file and send an acknowledgement...
    */

    close(fd);

    putchar(status);

    if (status)
      break;
  }

  if (!status)
  {
   /*
    * Process the control file and print stuff...
    */

    if ((fp = fopen(control, "rb")) == NULL)
      status = 1;
    else
    {
     /*
      * Copy the default options...
      */

      for (i = 0; i < num_defaults; i ++)
	num_options = cupsAddOption(defaults[i].name,
		                    defaults[i].value,
		                    num_options, &options);

     /*
      * Grab the job information...
      */

      title[0]   = '\0';
      user[0]    = '\0';
      docname[0] = '\0';
      doccount   = 0;

      while (smart_gets(line, sizeof(line), fp) != NULL)
      {
       /*
        * Process control lines...
	*/

	switch (line[0])
	{
	  case 'J' : /* Job name */
	      strlcpy(title, line + 1, sizeof(title));
	      break;

          case 'N' : /* Document name */
              strlcpy(docname, line + 1, sizeof(docname));
              break;

	  case 'P' : /* User identification */
	      strlcpy(user, line + 1, sizeof(user));
	      break;

	  case 'L' : /* Print banner page */
	     /*
	      * If a banner was requested and it's not overridden by a
	      * command line option and the destination's default is none
	      * then add the standard banner...
	      */

	      if (cupsGetOption("job-sheets", num_defaults, defaults) == NULL &&
        	  ((job_sheets = cupsGetOption("job-sheets", num_options,
					       options)) == NULL ||
        	   !strcmp(job_sheets, "none,none")))
	      {
		num_options = cupsAddOption("job-sheets", "standard",
		                	    num_options, &options);
	      }
	      break;

	  case 'c' : /* Plot CIF file */
	  case 'd' : /* Print DVI file */
	  case 'f' : /* Print formatted file */
	  case 'g' : /* Plot file */
	  case 'l' : /* Print file leaving control characters (raw) */
	  case 'n' : /* Print ditroff output file */
	  case 'o' : /* Print PostScript output file */
	  case 'p' : /* Print file with 'pr' format (prettyprint) */
	  case 'r' : /* File to print with FORTRAN carriage control */
	  case 't' : /* Print troff output file */
	  case 'v' : /* Print raster file */
	      doccount ++;

	      if (line[0] == 'l' &&
	          !cupsGetOption("document-format", num_options, options))
		num_options = cupsAddOption("raw", "", num_options, &options);

              if (line[0] == 'p')
		num_options = cupsAddOption("prettyprint", "", num_options,
		                	    &options);
              break;
	}

	if (status)
	  break;
      }

     /*
      * Check that we have a username...
      */

      if (!user[0])
      {
	syslog(LOG_WARNING, "No username specified by client! "
		            "Using \"anonymous\"...");
	strlcpy(user, "anonymous", sizeof(user));
      }

     /*
      * Create the job...
      */

      if ((id = create_job(http, dest, title, docname, user, num_options,
                           options)) < 0)
        status = 1;
      else
      {
       /*
	* Then print the job files...
	*/

	rewind(fp);

	docname[0] = '\0';
	docnumber  = 0;

	while (smart_gets(line, sizeof(line), fp) != NULL)
	{
	 /*
          * Process control lines...
	  */

	  switch (line[0])
	  {
	    case 'N' : /* Document name */
		strlcpy(docname, line + 1, sizeof(docname));
		break;

	    case 'c' : /* Plot CIF file */
	    case 'd' : /* Print DVI file */
	    case 'f' : /* Print formatted file */
	    case 'g' : /* Plot file */
	    case 'l' : /* Print file leaving control characters (raw) */
	    case 'n' : /* Print ditroff output file */
	    case 'o' : /* Print PostScript output file */
	    case 'p' : /* Print file with 'pr' format (prettyprint) */
	    case 'r' : /* File to print with FORTRAN carriage control */
	    case 't' : /* Print troff output file */
	    case 'v' : /* Print raster file */
               /*
		* Figure out which file we are printing...
		*/

		for (i = 0; i < num_data; i ++)
	          if (!strcmp(data[i], line + 1))
		    break;

        	if (i >= num_data)
		{
	          status = 1;
		  break;
		}

               /*
		* Send the print file...
		*/

        	docnumber ++;

        	if (print_file(http, id, temp[i], docname, user,
		               cupsGetOption("document-format", num_options,
			                     options),
	                       docnumber == doccount))
                  status = 1;
		else
	          status = 0;

		break;
	  }

	  if (status)
	    break;
	}
      }

      fclose(fp);
    }
  }

  cupsFreeOptions(num_options, options);

  httpClose(http);

 /*
  * Clean up all temporary files and return...
  */

  unlink(control);

  for (i = 0; i < num_data; i ++)
    unlink(temp[i]);

  return (status);
}
Esempio n. 20
0
int					/* O - 1 on success, 0 on failure */
cupsAdminSetServerSettings(
    http_t        *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
    int           num_settings,		/* I - Number of settings */
    cups_option_t *settings)		/* I - Settings */
{
  int		i;			/* Looping var */
  http_status_t status;			/* GET/PUT status */
  const char	*server_port_env;	/* SERVER_PORT env var */
  int		server_port;		/* IPP port for server */
  cups_file_t	*cupsd;			/* cupsd.conf file */
  char		cupsdconf[1024];	/* cupsd.conf filename */
  int		remote;			/* Remote cupsd.conf file? */
  char		tempfile[1024];		/* Temporary new cupsd.conf */
  cups_file_t	*temp;			/* Temporary file */
  char		line[1024],		/* Line from cupsd.conf file */
		*value;			/* Value on line */
  int		linenum,		/* Line number in file */
		in_location,		/* In a location section? */
		in_policy,		/* In a policy section? */
		in_default_policy,	/* In the default policy section? */
		in_cancel_job,		/* In a cancel-job section? */
		in_admin_location,	/* In the /admin location? */
		in_conf_location,	/* In the /admin/conf location? */
		in_log_location,	/* In the /admin/log location? */
		in_root_location;	/* In the / location? */
  const char	*val;			/* Setting value */
  int		share_printers,		/* Share local printers */
		remote_admin,		/* Remote administration allowed? */
		remote_any,		/* Remote access from anywhere? */
		user_cancel_any,	/* Cancel-job policy set? */
		debug_logging;		/* LogLevel debug set? */
  int		wrote_port_listen,	/* Wrote the port/listen lines? */
		wrote_browsing,		/* Wrote the browsing lines? */
		wrote_policy,		/* Wrote the policy? */
		wrote_loglevel,		/* Wrote the LogLevel line? */
		wrote_admin_location,	/* Wrote the /admin location? */
		wrote_conf_location,	/* Wrote the /admin/conf location? */
		wrote_log_location,	/* Wrote the /admin/log location? */
		wrote_root_location;	/* Wrote the / location? */
  int		indent;			/* Indentation */
  int		cupsd_num_settings;	/* New number of settings */
  int		old_share_printers,	/* Share local printers */
		old_remote_admin,	/* Remote administration allowed? */
		old_remote_any,		/* Remote access from anywhere? */
		old_user_cancel_any,	/* Cancel-job policy set? */
		old_debug_logging;	/* LogLevel debug set? */
  cups_option_t	*cupsd_settings,	/* New settings */
		*setting;		/* Current setting */
  _cups_globals_t *cg = _cupsGlobals();	/* Global data */


 /*
  * Range check input...
  */

  if (!http)
    http = _cupsConnect();

  if (!http || !num_settings || !settings)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);

    return (0);
  }

 /*
  * Get the cupsd.conf file...
  */

  if (get_cupsd_conf(http, cg, 0, cupsdconf, sizeof(cupsdconf),
                     &remote) == HTTP_STATUS_OK)
  {
    if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL)
    {
      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
      return (0);
    }
  }
  else
    return (0);

 /*
  * Get current settings...
  */

  if (!cupsAdminGetServerSettings(http, &cupsd_num_settings,
				  &cupsd_settings))
    return (0);

  if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, cupsd_num_settings,
                           cupsd_settings)) != NULL)
    old_debug_logging = atoi(val);
  else
    old_debug_logging = 0;

  DEBUG_printf(("1cupsAdminSetServerSettings: old debug_logging=%d",
                old_debug_logging));

  if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, cupsd_num_settings,
                           cupsd_settings)) != NULL)
    old_remote_admin = atoi(val);
  else
    old_remote_admin = 0;

  DEBUG_printf(("1cupsAdminSetServerSettings: old remote_admin=%d",
                old_remote_admin));

  if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, cupsd_num_settings,
                           cupsd_settings)) != NULL)
    old_remote_any = atoi(val);
  else
    old_remote_any = 0;

  DEBUG_printf(("1cupsAdminSetServerSettings: old remote_any=%d",
                old_remote_any));

  if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, cupsd_num_settings,
                           cupsd_settings)) != NULL)
    old_share_printers = atoi(val);
  else
    old_share_printers = 0;

  DEBUG_printf(("1cupsAdminSetServerSettings: old share_printers=%d",
                old_share_printers));

  if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, cupsd_num_settings,
                           cupsd_settings)) != NULL)
    old_user_cancel_any = atoi(val);
  else
    old_user_cancel_any = 0;

  DEBUG_printf(("1cupsAdminSetServerSettings: old user_cancel_any=%d",
                old_user_cancel_any));

  cupsFreeOptions(cupsd_num_settings, cupsd_settings);

 /*
  * Get basic settings...
  */

  if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings,
                           settings)) != NULL)
  {
    debug_logging = atoi(val);

    if (debug_logging == old_debug_logging)
    {
     /*
      * No change to this setting...
      */

      debug_logging = -1;
    }
  }
  else
    debug_logging = -1;

  DEBUG_printf(("1cupsAdminSetServerSettings: debug_logging=%d",
                debug_logging));

  if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, settings)) != NULL)
  {
    remote_any = atoi(val);

    if (remote_any == old_remote_any)
    {
     /*
      * No change to this setting...
      */

      remote_any = -1;
    }
  }
  else
    remote_any = -1;

  DEBUG_printf(("1cupsAdminSetServerSettings: remote_any=%d", remote_any));

  if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings,
                           settings)) != NULL)
  {
    remote_admin = atoi(val);

    if (remote_admin == old_remote_admin)
    {
     /*
      * No change to this setting...
      */

      remote_admin = -1;
    }
  }
  else
    remote_admin = -1;

  DEBUG_printf(("1cupsAdminSetServerSettings: remote_admin=%d",
                remote_admin));

  if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings,
                           settings)) != NULL)
  {
    share_printers = atoi(val);

    if (share_printers == old_share_printers)
    {
     /*
      * No change to this setting...
      */

      share_printers = -1;
    }
  }
  else
    share_printers = -1;

  DEBUG_printf(("1cupsAdminSetServerSettings: share_printers=%d",
                share_printers));

  if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings,
                           settings)) != NULL)
  {
    user_cancel_any = atoi(val);

    if (user_cancel_any == old_user_cancel_any)
    {
     /*
      * No change to this setting...
      */

      user_cancel_any = -1;
    }
  }
  else
    user_cancel_any = -1;

  DEBUG_printf(("1cupsAdminSetServerSettings: user_cancel_any=%d",
                user_cancel_any));

 /*
  * Create a temporary file for the new cupsd.conf file...
  */

  if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
  {
    cupsFileClose(cupsd);

    if (remote)
      unlink(cupsdconf);

    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0);
    return (0);
  }

 /*
  * Copy the old file to the new, making changes along the way...
  */

  cupsd_num_settings   = 0;
  in_admin_location    = 0;
  in_cancel_job        = 0;
  in_conf_location     = 0;
  in_default_policy    = 0;
  in_location          = 0;
  in_log_location      = 0;
  in_policy            = 0;
  in_root_location     = 0;
  linenum              = 0;
  wrote_admin_location = 0;
  wrote_browsing       = 0;
  wrote_conf_location  = 0;
  wrote_log_location   = 0;
  wrote_loglevel       = 0;
  wrote_policy         = 0;
  wrote_port_listen    = 0;
  wrote_root_location  = 0;
  indent               = 0;

  if ((server_port_env = getenv("SERVER_PORT")) != NULL)
  {
    if ((server_port = atoi(server_port_env)) <= 0)
      server_port = ippPort();
  }
  else
    server_port = ippPort();

  if (server_port <= 0)
    server_port = IPP_PORT;

  while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum))
  {
    if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) &&
        (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
    {
      if (!wrote_port_listen)
      {
        wrote_port_listen = 1;

	if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
	{
	  cupsFilePuts(temp, "# Allow remote access\n");
	  cupsFilePrintf(temp, "Port %d\n", server_port);
	}
	else
	{
	  cupsFilePuts(temp, "# Only listen for connections from the local "
	                     "machine.\n");
	  cupsFilePrintf(temp, "Listen localhost:%d\n", server_port);
	}

#ifdef CUPS_DEFAULT_DOMAINSOCKET
        if ((!value || strcmp(CUPS_DEFAULT_DOMAINSOCKET, value)) &&
	    !access(CUPS_DEFAULT_DOMAINSOCKET, 0))
          cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n");
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
      }
      else if (value && value[0] == '/'
#ifdef CUPS_DEFAULT_DOMAINSOCKET
               && strcmp(CUPS_DEFAULT_DOMAINSOCKET, value)
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
               )
        cupsFilePrintf(temp, "Listen %s\n", value);
    }
    else if ((!_cups_strcasecmp(line, "Browsing") ||
              !_cups_strcasecmp(line, "BrowseLocalProtocols")) &&
	     share_printers >= 0)
    {
      if (!wrote_browsing)
      {
	int new_share_printers = (share_printers > 0 ||
				  (share_printers == -1 &&
				   old_share_printers > 0));

        wrote_browsing = 1;

        if (new_share_printers)
	{
	  const char *localp = cupsGetOption("BrowseLocalProtocols",
					     num_settings, settings);

          if (!localp || !localp[0])
	    localp = cupsGetOption("BrowseLocalProtocols", cupsd_num_settings,
	                           cupsd_settings);

	  cupsFilePuts(temp, "# Share local printers on the local network.\n");
	  cupsFilePuts(temp, "Browsing On\n");

	  if (!localp)
	    localp = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS;

	  cupsFilePrintf(temp, "BrowseLocalProtocols %s\n", localp);

	  cupsd_num_settings = cupsAddOption("BrowseLocalProtocols", localp,
					     cupsd_num_settings,
					     &cupsd_settings);
        }
	else
	{
	  cupsFilePuts(temp, "# Disable printer sharing.\n");
	  cupsFilePuts(temp, "Browsing Off\n");
	}
      }
    }
    else if (!_cups_strcasecmp(line, "LogLevel") && debug_logging >= 0)
    {
      wrote_loglevel = 1;

      if (debug_logging)
      {
        cupsFilePuts(temp,
	             "# Show troubleshooting information in error_log.\n");
	cupsFilePuts(temp, "LogLevel debug\n");
      }
      else
      {
        cupsFilePuts(temp, "# Show general information in error_log.\n");
	cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n");
      }
    }
    else if (!_cups_strcasecmp(line, "<Policy"))
    {
      in_default_policy = !_cups_strcasecmp(value, "default");
      in_policy         = 1;

      cupsFilePrintf(temp, "%s %s>\n", line, value);
      indent += 2;
    }
    else if (!_cups_strcasecmp(line, "</Policy>"))
    {
      indent -= 2;
      if (!wrote_policy && in_default_policy)
      {
	wrote_policy = 1;

        if (!user_cancel_any)
	  cupsFilePuts(temp, "  # Only the owner or an administrator can "
	                     "cancel a job...\n"
	                     "  <Limit Cancel-Job>\n"
	                     "    Order deny,allow\n"
			     "    Require user @OWNER "
			     CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n"
			     "  </Limit>\n");
      }

      in_policy         = 0;
      in_default_policy = 0;

      cupsFilePuts(temp, "</Policy>\n");
    }
    else if (!_cups_strcasecmp(line, "<Location"))
    {
      in_location = 1;
      indent += 2;
      if (!strcmp(value, "/admin"))
	in_admin_location = 1;
      else if (!strcmp(value, "/admin/conf"))
	in_conf_location = 1;
      else if (!strcmp(value, "/admin/log"))
	in_log_location = 1;
      else if (!strcmp(value, "/"))
	in_root_location = 1;

      cupsFilePrintf(temp, "%s %s>\n", line, value);
    }
    else if (!_cups_strcasecmp(line, "</Location>"))
    {
      in_location = 0;
      indent -= 2;
      if (in_admin_location && remote_admin >= 0)
      {
	wrote_admin_location = 1;

	if (remote_admin)
          cupsFilePuts(temp, "  # Allow remote administration...\n");
	else if (remote_admin == 0)
          cupsFilePuts(temp, "  # Restrict access to the admin pages...\n");

        cupsFilePuts(temp, "  Order allow,deny\n");

	if (remote_admin)
	  cupsFilePrintf(temp, "  Allow %s\n",
	                 remote_any > 0 ? "all" : "@LOCAL");
      }
      else if (in_conf_location && remote_admin >= 0)
      {
	wrote_conf_location = 1;

	if (remote_admin)
          cupsFilePuts(temp, "  # Allow remote access to the configuration "
	                     "files...\n");
	else
          cupsFilePuts(temp, "  # Restrict access to the configuration "
	                     "files...\n");

        cupsFilePuts(temp, "  Order allow,deny\n");

	if (remote_admin)
	  cupsFilePrintf(temp, "  Allow %s\n",
	                 remote_any > 0 ? "all" : "@LOCAL");
      }
      else if (in_log_location && remote_admin >= 0)
      {
	wrote_log_location = 1;

	if (remote_admin)
          cupsFilePuts(temp, "  # Allow remote access to the log "
	                     "files...\n");
	else
          cupsFilePuts(temp, "  # Restrict access to the log "
	                     "files...\n");

        cupsFilePuts(temp, "  Order allow,deny\n");

	if (remote_admin)
	  cupsFilePrintf(temp, "  Allow %s\n",
	                 remote_any > 0 ? "all" : "@LOCAL");
      }
      else if (in_root_location &&
               (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
      {
	wrote_root_location = 1;

	if (remote_admin > 0 && share_printers > 0)
          cupsFilePuts(temp, "  # Allow shared printing and remote "
	                     "administration...\n");
	else if (remote_admin > 0)
          cupsFilePuts(temp, "  # Allow remote administration...\n");
	else if (share_printers > 0)
          cupsFilePuts(temp, "  # Allow shared printing...\n");
	else if (remote_any > 0)
          cupsFilePuts(temp, "  # Allow remote access...\n");
	else
          cupsFilePuts(temp, "  # Restrict access to the server...\n");

        cupsFilePuts(temp, "  Order allow,deny\n");

	if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
	  cupsFilePrintf(temp, "  Allow %s\n",
	                 remote_any > 0 ? "all" : "@LOCAL");
      }

      in_admin_location = 0;
      in_conf_location  = 0;
      in_log_location   = 0;
      in_root_location  = 0;

      cupsFilePuts(temp, "</Location>\n");
    }
    else if (!_cups_strcasecmp(line, "<Limit"))
    {
      if (in_default_policy)
      {
       /*
	* See if the policy limit is for the Cancel-Job operation...
	*/

	char	*valptr;		/* Pointer into value */


	if (!_cups_strcasecmp(value, "cancel-job") && user_cancel_any >= 0)
	{
	 /*
	  * Don't write anything for this limit section...
	  */

	  in_cancel_job = 2;
	}
	else
	{
	  cupsFilePrintf(temp, "%*s%s", indent, "", line);

	  while (*value)
	  {
	    for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++);

	    if (*valptr)
	      *valptr++ = '\0';

	    if (!_cups_strcasecmp(value, "cancel-job") && user_cancel_any >= 0)
	    {
	     /*
	      * Write everything except for this definition...
	      */

	      in_cancel_job = 1;
	    }
	    else
	      cupsFilePrintf(temp, " %s", value);

	    for (value = valptr; _cups_isspace(*value); value ++);
	  }

	  cupsFilePuts(temp, ">\n");
	}
      }
      else
        cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value);

      indent += 2;
    }
    else if (!_cups_strcasecmp(line, "</Limit>") && in_cancel_job)
    {
      indent -= 2;

      if (in_cancel_job == 1)
	cupsFilePuts(temp, "  </Limit>\n");

      wrote_policy = 1;

      if (!user_cancel_any)
	cupsFilePuts(temp, "  # Only the owner or an administrator can cancel "
			   "a job...\n"
			   "  <Limit Cancel-Job>\n"
			   "    Order deny,allow\n"
			   "    Require user @OWNER "
			   CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n"
			   "  </Limit>\n");

      in_cancel_job = 0;
    }
    else if ((((in_admin_location || in_conf_location || in_root_location) &&
               (remote_admin >= 0 || remote_any >= 0)) ||
              (in_root_location && share_printers >= 0)) &&
             (!_cups_strcasecmp(line, "Allow") || !_cups_strcasecmp(line, "Deny") ||
	      !_cups_strcasecmp(line, "Order")))
      continue;
    else if (in_cancel_job == 2)
      continue;
    else if (line[0] == '<')
    {
      if (value)
      {
        cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value);
	indent += 2;
      }
      else
      {
	if (line[1] == '/')
	  indent -= 2;

	cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
      }
    }
    else if (!in_policy && !in_location &&
             (val = cupsGetOption(line, num_settings, settings)) != NULL)
    {
     /*
      * Replace this directive's value with the new one...
      */

      cupsd_num_settings = cupsAddOption(line, val, cupsd_num_settings,
                                         &cupsd_settings);

     /*
      * Write the new value in its place, without indentation since we
      * only support setting root directives, not in sections...
      */

      cupsFilePrintf(temp, "%s %s\n", line, val);
    }
    else if (value)
    {
      if (!in_policy && !in_location)
      {
       /*
        * Record the non-policy, non-location directives that we find
	* in the server settings, since we cache this info and record it
	* in cupsAdminGetServerSettings()...
	*/

	cupsd_num_settings = cupsAddOption(line, value, cupsd_num_settings,
                                           &cupsd_settings);
      }

      cupsFilePrintf(temp, "%*s%s %s\n", indent, "", line, value);
    }
    else
      cupsFilePrintf(temp, "%*s%s\n", indent, "", line);
  }

 /*
  * Write any missing info...
  */

  if (!wrote_browsing && share_printers >= 0)
  {
    if (share_printers > 0)
    {
      cupsFilePuts(temp, "# Share local printers on the local network.\n");
      cupsFilePuts(temp, "Browsing On\n");
    }
    else
    {
      cupsFilePuts(temp, "# Disable printer sharing and shared printers.\n");
      cupsFilePuts(temp, "Browsing Off\n");
    }
  }

  if (!wrote_loglevel && debug_logging >= 0)
  {
    if (debug_logging)
    {
      cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n");
      cupsFilePuts(temp, "LogLevel debug\n");
    }
    else
    {
      cupsFilePuts(temp, "# Show general information in error_log.\n");
      cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n");
    }
  }

  if (!wrote_port_listen &&
      (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
  {
    if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
    {
      cupsFilePuts(temp, "# Allow remote access\n");
      cupsFilePrintf(temp, "Port %d\n", ippPort());
    }
    else
    {
      cupsFilePuts(temp,
                   "# Only listen for connections from the local machine.\n");
      cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort());
    }

#ifdef CUPS_DEFAULT_DOMAINSOCKET
    if (!access(CUPS_DEFAULT_DOMAINSOCKET, 0))
      cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n");
#endif /* CUPS_DEFAULT_DOMAINSOCKET */
  }

  if (!wrote_root_location &&
      (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0))
  {
    if (remote_admin > 0 && share_printers > 0)
      cupsFilePuts(temp,
                   "# Allow shared printing and remote administration...\n");
    else if (remote_admin > 0)
      cupsFilePuts(temp, "# Allow remote administration...\n");
    else if (share_printers > 0)
      cupsFilePuts(temp, "# Allow shared printing...\n");
    else if (remote_any > 0)
      cupsFilePuts(temp, "# Allow remote access...\n");
    else
      cupsFilePuts(temp, "# Restrict access to the server...\n");

    cupsFilePuts(temp, "<Location />\n"
                       "  Order allow,deny\n");

    if (remote_admin > 0 || remote_any > 0 || share_printers > 0)
      cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");

    cupsFilePuts(temp, "</Location>\n");
  }

  if (!wrote_admin_location && remote_admin >= 0)
  {
    if (remote_admin)
      cupsFilePuts(temp, "# Allow remote administration...\n");
    else
      cupsFilePuts(temp, "# Restrict access to the admin pages...\n");

    cupsFilePuts(temp, "<Location /admin>\n"
                       "  Order allow,deny\n");

    if (remote_admin)
      cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");

    cupsFilePuts(temp, "</Location>\n");
  }

  if (!wrote_conf_location && remote_admin >= 0)
  {
    if (remote_admin)
      cupsFilePuts(temp,
                   "# Allow remote access to the configuration files...\n");
    else
      cupsFilePuts(temp, "# Restrict access to the configuration files...\n");

    cupsFilePuts(temp, "<Location /admin/conf>\n"
                       "  AuthType Default\n"
                       "  Require user @SYSTEM\n"
                       "  Order allow,deny\n");

    if (remote_admin)
      cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");

    cupsFilePuts(temp, "</Location>\n");
  }

  if (!wrote_log_location && remote_admin >= 0)
  {
    if (remote_admin)
      cupsFilePuts(temp,
                   "# Allow remote access to the log files...\n");
    else
      cupsFilePuts(temp, "# Restrict access to the log files...\n");

    cupsFilePuts(temp, "<Location /admin/log>\n"
                       "  AuthType Default\n"
                       "  Require user @SYSTEM\n"
                       "  Order allow,deny\n");

    if (remote_admin)
      cupsFilePrintf(temp, "  Allow %s\n", remote_any > 0 ? "all" : "@LOCAL");

    cupsFilePuts(temp, "</Location>\n");
  }

  if (!wrote_policy && user_cancel_any >= 0)
  {
    cupsFilePuts(temp, "<Policy default>\n"
                       "  # Job-related operations must be done by the owner "
		       "or an administrator...\n"
                       "  <Limit Send-Document Send-URI Hold-Job Release-Job "
		       "Restart-Job Purge-Jobs Set-Job-Attributes "
		       "Create-Job-Subscription Renew-Subscription "
		       "Cancel-Subscription Get-Notifications Reprocess-Job "
		       "Cancel-Current-Job Suspend-Current-Job Resume-Job "
		       "CUPS-Move-Job>\n"
                       "    Require user @OWNER @SYSTEM\n"
                       "    Order deny,allow\n"
                       "  </Limit>\n"
                       "  # All administration operations require an "
		       "administrator to authenticate...\n"
		       "  <Limit Pause-Printer Resume-Printer "
                       "Set-Printer-Attributes Enable-Printer "
		       "Disable-Printer Pause-Printer-After-Current-Job "
		       "Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer "
		       "Activate-Printer Restart-Printer Shutdown-Printer "
		       "Startup-Printer Promote-Job Schedule-Job-After "
		       "CUPS-Add-Printer CUPS-Delete-Printer "
		       "CUPS-Add-Class CUPS-Delete-Class "
		       "CUPS-Accept-Jobs CUPS-Reject-Jobs "
		       "CUPS-Set-Default CUPS-Add-Device CUPS-Delete-Device>\n"
                       "    AuthType Default\n"
		       "    Require user @SYSTEM\n"
                       "    Order deny,allow\n"
                       "</Limit>\n");

    if (!user_cancel_any)
      cupsFilePuts(temp, "  # Only the owner or an administrator can cancel "
                         "a job...\n"
	                 "  <Limit Cancel-Job>\n"
	                 "    Order deny,allow\n"
	                 "    Require user @OWNER "
			 CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n"
			 "  </Limit>\n");

    cupsFilePuts(temp, "  <Limit All>\n"
                       "  Order deny,allow\n"
                       "  </Limit>\n"
		       "</Policy>\n");
  }

  for (i = num_settings, setting = settings; i > 0; i --, setting ++)
    if (setting->name[0] != '_' &&
        _cups_strcasecmp(setting->name, "Listen") &&
	_cups_strcasecmp(setting->name, "Port") &&
        !cupsGetOption(setting->name, cupsd_num_settings, cupsd_settings))
    {
     /*
      * Add this directive to the list of directives we have written...
      */

      cupsd_num_settings = cupsAddOption(setting->name, setting->value,
                                         cupsd_num_settings, &cupsd_settings);

     /*
      * Write the new value, without indentation since we only support
      * setting root directives, not in sections...
      */

      cupsFilePrintf(temp, "%s %s\n", setting->name, setting->value);
    }

  cupsFileClose(cupsd);
  cupsFileClose(temp);

 /*
  * Upload the configuration file to the server...
  */

  status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile);

  if (status == HTTP_STATUS_CREATED)
  {
   /*
    * Updated OK, add the basic settings...
    */

    if (debug_logging >= 0)
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
                                	 debug_logging ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);
    else
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
                                	 old_debug_logging ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);

    if (remote_admin >= 0)
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
                                	 remote_admin ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);
    else
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
                                	 old_remote_admin ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);

    if (remote_any >= 0)
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
					 remote_any ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);
    else
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
					 old_remote_any ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);

    if (share_printers >= 0)
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
                                	 share_printers ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);
    else
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
                                	 old_share_printers ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);

    if (user_cancel_any >= 0)
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
                                	 user_cancel_any ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);
    else
      cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
                                	 old_user_cancel_any ? "1" : "0",
					 cupsd_num_settings, &cupsd_settings);

   /*
    * Save the new values...
    */

    invalidate_cupsd_cache(cg);

    cg->cupsd_num_settings = cupsd_num_settings;
    cg->cupsd_settings     = cupsd_settings;
    cg->cupsd_update       = time(NULL);

    httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname));
  }
  else
    cupsFreeOptions(cupsd_num_settings, cupsd_settings);

 /*
  * Remote our temp files and return...
  */

  if (remote)
    unlink(cupsdconf);

  unlink(tempfile);

  return (status == HTTP_STATUS_CREATED);
}
Esempio n. 21
0
void dt_print_file(const int32_t imgid, const char *filename, const dt_print_info_t *pinfo)
{
  // first for safety check that filename exists and is readable

  if (!g_file_test(filename, G_FILE_TEST_IS_REGULAR))
  {
    dt_control_log(_("file `%s' to print not found for image %d on `%s'"), filename, imgid, pinfo->printer.name);
    return;
  }

  cups_dest_t *dests;
  int num_dests = cupsGetDests(&dests);
  cups_dest_t *dest = cupsGetDest(pinfo->printer.name, NULL, num_dests, dests);

  cups_option_t *options = NULL;
  int num_options = 0;

  for (int 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);

  // disable cm on CUPS, this is important as dt does the cm

  if (*pinfo->printer.profile)
    num_options = cupsAddOption("cm-calibration", "true", num_options, &options);

  // media to print on

  num_options = cupsAddOption("media", pinfo->paper.name, num_options, &options);

  // never print two-side

  num_options = cupsAddOption("sides", "one-sided", num_options, &options);

  // and a single image per page

  num_options = cupsAddOption("number-up", "1", num_options, &options);

  // if the printer has no hardward margins activate the borderless mode

  if (pinfo->printer.hw_margin_top == 0 || pinfo->printer.hw_margin_bottom == 0
      || pinfo->printer.hw_margin_left == 0 || pinfo->printer.hw_margin_right == 0)
  {
    // there is many variant for this parameter
    num_options = cupsAddOption("StpFullBleed", "true", num_options, &options);
    num_options = cupsAddOption("STP_FullBleed", "true", num_options, &options);
    num_options = cupsAddOption("Borderless", "true", num_options, &options);
  }

  if (pinfo->page.landscape)
    num_options = cupsAddOption("landscape", "true", num_options, &options);
  else
    num_options = cupsAddOption("landscape", "false", num_options, &options);

  // print lp options

  dt_print(DT_DEBUG_PRINT, "[print] printer options (%d)\n", num_options);
  for (int k=0; k<num_options; k++)
    dt_print(DT_DEBUG_PRINT, "[print]   %s=%s\n", options[k].name, options[k].value);

  const int job_id = cupsPrintFile(pinfo->printer.name, filename,  "darktable", num_options, options);

  if (job_id == 0)
    dt_control_log(_("error while printing image %d on `%s'"), imgid, pinfo->printer.name);
  else
    dt_control_log(_("printing image %d on `%s'"), imgid, pinfo->printer.name);

  cupsFreeOptions (num_options, options);
}
Esempio n. 22
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  ppd_file_t	*ppd;			/* PPD file loaded from disk */
  int		status;			/* Status of tests (0 = success, 1 = fail) */
  int		conflicts;		/* Number of conflicts */
  char		*s;			/* String */
  char		buffer[8192];		/* String buffer */
  const char	*text,			/* Localized text */
		*val;			/* Option value */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  ppd_size_t	minsize,		/* Minimum size */
		maxsize,		/* Maximum size */
		*size;			/* Current size */
  ppd_attr_t	*attr;			/* Current attribute */
  _ppd_cache_t	*pc;			/* PPD cache */


  status = 0;

  if (argc == 1)
  {
   /*
    * Setup directories for locale stuff...
    */

    if (access("locale", 0))
    {
      mkdir("locale", 0777);
      mkdir("locale/fr", 0777);
      symlink("../../../locale/cups_fr.po", "locale/fr/cups_fr.po");
      mkdir("locale/zh_TW", 0777);
      symlink("../../../locale/cups_zh_TW.po", "locale/zh_TW/cups_zh_TW.po");
    }

    putenv("LOCALEDIR=locale");
    putenv("SOFTWARE=CUPS");

   /*
    * Do tests with test.ppd...
    */

    fputs("ppdOpenFile(test.ppd): ", stdout);

    if ((ppd = _ppdOpenFile("test.ppd", _PPD_LOCALIZATION_ALL)) != NULL)
      puts("PASS");
    else
    {
      ppd_status_t	err;		/* Last error in file */
      int		line;		/* Line number in file */


      status ++;
      err = ppdLastError(&line);

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

    fputs("ppdFindAttr(wildcard): ", stdout);
    if ((attr = ppdFindAttr(ppd, "cupsTest", NULL)) == NULL)
    {
      status ++;
      puts("FAIL (not found)");
    }
    else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdFindNextAttr(wildcard): ", stdout);
    if ((attr = ppdFindNextAttr(ppd, "cupsTest", NULL)) == NULL)
    {
      status ++;
      puts("FAIL (not found)");
    }
    else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Bar"))
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdFindAttr(Foo): ", stdout);
    if ((attr = ppdFindAttr(ppd, "cupsTest", "Foo")) == NULL)
    {
      status ++;
      puts("FAIL (not found)");
    }
    else if (strcmp(attr->name, "cupsTest") || strcmp(attr->spec, "Foo"))
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdFindNextAttr(Foo): ", stdout);
    if ((attr = ppdFindNextAttr(ppd, "cupsTest", "Foo")) != NULL)
    {
      status ++;
      printf("FAIL (got \"%s %s\")\n", attr->name, attr->spec);
    }
    else
      puts("PASS");

    fputs("ppdMarkDefaults: ", stdout);
    ppdMarkDefaults(ppd);

    if ((conflicts = ppdConflicts(ppd)) == 0)
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d conflicts)\n", conflicts);
    }

    fputs("ppdEmitString (defaults): ", stdout);
    if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
	!strcmp(s, default_code))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
	     (int)strlen(default_code));

      if (s)
	puts(s);
    }

    if (s)
      free(s);

    fputs("ppdEmitString (custom size and string): ", stdout);
    ppdMarkOption(ppd, "PageSize", "Custom.400x500");
    ppdMarkOption(ppd, "StringOption", "{String1=\"value 1\" String2=value(2)}");

    if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
	!strcmp(s, custom_code))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
	     (int)strlen(custom_code));

      if (s)
	puts(s);
    }

    if (s)
      free(s);

   /*
    * Test constraints...
    */

    fputs("cupsGetConflicts(InputSlot=Envelope): ", stdout);
    ppdMarkOption(ppd, "PageSize", "Letter");

    num_options = cupsGetConflicts(ppd, "InputSlot", "Envelope", &options);
    if (num_options != 2 ||
        (val = cupsGetOption("PageRegion", num_options, options)) == NULL ||
	_cups_strcasecmp(val, "Letter") ||
	(val = cupsGetOption("PageSize", num_options, options)) == NULL ||
	_cups_strcasecmp(val, "Letter"))
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
      puts("PASS");

    fputs("ppdConflicts(): ", stdout);
    ppdMarkOption(ppd, "InputSlot", "Envelope");

    if ((conflicts = ppdConflicts(ppd)) == 2)
      puts("PASS (2)");
    else
    {
      printf("FAIL (%d)\n", conflicts);
      status ++;
    }

    fputs("cupsResolveConflicts(InputSlot=Envelope): ", stdout);
    num_options = 0;
    options     = NULL;
    if (!cupsResolveConflicts(ppd, "InputSlot", "Envelope", &num_options,
                             &options))
    {
      puts("FAIL (Unable to resolve)");
      status ++;
    }
    else if (num_options != 2 ||
             !cupsGetOption("PageSize", num_options, options))
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
      puts("PASS (Resolved by changing PageSize)");

    cupsFreeOptions(num_options, options);

    fputs("cupsResolveConflicts(No option/choice): ", stdout);
    num_options = 0;
    options     = NULL;
    if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
        num_options == 1 && !_cups_strcasecmp(options[0].name, "InputSlot") &&
	!_cups_strcasecmp(options[0].value, "Tray"))
      puts("PASS (Resolved by changing InputSlot)");
    else if (num_options > 0)
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
    {
      puts("FAIL (Unable to resolve)");
      status ++;
    }
    cupsFreeOptions(num_options, options);

    fputs("ppdInstallableConflict(): ", stdout);
    if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
        !ppdInstallableConflict(ppd, "Duplex", "None"))
      puts("PASS");
    else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
    {
      puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
      status ++;
    }
    else
    {
      puts("FAIL (Duplex=None conflicted)");
      status ++;
    }

   /*
    * ppdPageSizeLimits
    */

    fputs("ppdPageSizeLimits: ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 36 || minsize.length != 36 ||
          maxsize.width != 1080 || maxsize.length != 86400)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=36x36, max=1080x86400)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

   /*
    * cupsMarkOptions with PWG and IPP size names.
    */

    fputs("cupsMarkOptions(media=iso-a4): ", stdout);
    num_options = cupsAddOption("media", "iso-a4", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "A4"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

    fputs("cupsMarkOptions(media=na_letter_8.5x11in): ", stdout);
    num_options = cupsAddOption("media", "na_letter_8.5x11in", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "Letter"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

    fputs("cupsMarkOptions(media=oe_letter-fullbleed_8.5x11in): ", stdout);
    num_options = cupsAddOption("media", "oe_letter-fullbleed_8.5x11in", 0,
                                &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "Letter.Fullbleed"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

    fputs("cupsMarkOptions(media=A4): ", stdout);
    num_options = cupsAddOption("media", "A4", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "A4"))
    {
      printf("FAIL (%s)\n", size ? size->name : "unknown");
      status ++;
    }
    else
      puts("PASS");

   /*
    * Custom sizes...
    */

    fputs("cupsMarkOptions(media=Custom.8x10in): ", stdout);
    num_options = cupsAddOption("media", "Custom.8x10in", 0, &options);
    cupsMarkOptions(ppd, num_options, options);
    cupsFreeOptions(num_options, options);

    size = ppdPageSize(ppd, NULL);
    if (!size || strcmp(size->name, "Custom") ||
        size->width != 576 || size->length != 720)
    {
      printf("FAIL (%s - %gx%g)\n", size ? size->name : "unknown",
             size ? size->width : 0.0, size ? size->length : 0.0);
      status ++;
    }
    else
      puts("PASS");

   /*
    * Test localization...
    */

    fputs("ppdLocalizeIPPReason(text): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
        !strcmp(buffer, "Foo Reason"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Foo Reason\")\n", buffer);
    }

    fputs("ppdLocalizeIPPReason(http): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", "http", buffer, sizeof(buffer)) &&
        !strcmp(buffer, "http://foo/bar.html"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"http://foo/bar.html\")\n", buffer);
    }

    fputs("ppdLocalizeIPPReason(help): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", "help", buffer, sizeof(buffer)) &&
        !strcmp(buffer, "help:anchor='foo'%20bookID=Vendor%20Help"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"help:anchor='foo'%%20bookID=Vendor%%20Help\")\n", buffer);
    }

    fputs("ppdLocalizeIPPReason(file): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", "file", buffer, sizeof(buffer)) &&
        !strcmp(buffer, "/help/foo/bar.html"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"/help/foo/bar.html\")\n", buffer);
    }

    putenv("LANG=fr");
    putenv("LC_ALL=fr");
    putenv("LC_CTYPE=fr");
    putenv("LC_MESSAGES=fr");

    fputs("ppdLocalizeIPPReason(fr text): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
        !strcmp(buffer, "La Long Foo Reason"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"La Long Foo Reason\")\n", buffer);
    }

    putenv("LANG=zh_TW");
    putenv("LC_ALL=zh_TW");
    putenv("LC_CTYPE=zh_TW");
    putenv("LC_MESSAGES=zh_TW");

    fputs("ppdLocalizeIPPReason(zh_TW text): ", stdout);
    if (ppdLocalizeIPPReason(ppd, "foo", NULL, buffer, sizeof(buffer)) &&
        !strcmp(buffer, "Number 1 Foo Reason"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Number 1 Foo Reason\")\n", buffer);
    }

   /*
    * cupsMarkerName localization...
    */

    putenv("LANG=en");
    putenv("LC_ALL=en");
    putenv("LC_CTYPE=en");
    putenv("LC_MESSAGES=en");

    fputs("ppdLocalizeMarkerName(bogus): ", stdout);

    if ((text = ppdLocalizeMarkerName(ppd, "bogus")) != NULL)
    {
      status ++;
      printf("FAIL (\"%s\" instead of NULL)\n", text);
    }
    else
      puts("PASS");

    fputs("ppdLocalizeMarkerName(cyan): ", stdout);

    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
        !strcmp(text, "Cyan Toner"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Cyan Toner\")\n",
             text ? text : "(null)");
    }

    putenv("LANG=fr");
    putenv("LC_ALL=fr");
    putenv("LC_CTYPE=fr");
    putenv("LC_MESSAGES=fr");

    fputs("ppdLocalizeMarkerName(fr cyan): ", stdout);
    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
        !strcmp(text, "La Toner Cyan"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"La Toner Cyan\")\n",
             text ? text : "(null)");
    }

    putenv("LANG=zh_TW");
    putenv("LC_ALL=zh_TW");
    putenv("LC_CTYPE=zh_TW");
    putenv("LC_MESSAGES=zh_TW");

    fputs("ppdLocalizeMarkerName(zh_TW cyan): ", stdout);
    if ((text = ppdLocalizeMarkerName(ppd, "cyan")) != NULL &&
        !strcmp(text, "Number 1 Cyan Toner"))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (\"%s\" instead of \"Number 1 Cyan Toner\")\n",
             text ? text : "(null)");
    }

    ppdClose(ppd);

   /*
    * Test new constraints...
    */

    fputs("ppdOpenFile(test2.ppd): ", stdout);

    if ((ppd = ppdOpenFile("test2.ppd")) != NULL)
      puts("PASS");
    else
    {
      ppd_status_t	err;		/* Last error in file */
      int		line;		/* Line number in file */


      status ++;
      err = ppdLastError(&line);

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

    fputs("ppdMarkDefaults: ", stdout);
    ppdMarkDefaults(ppd);

    if ((conflicts = ppdConflicts(ppd)) == 0)
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d conflicts)\n", conflicts);
    }

    fputs("ppdEmitString (defaults): ", stdout);
    if ((s = ppdEmitString(ppd, PPD_ORDER_ANY, 0.0)) != NULL &&
	!strcmp(s, default2_code))
      puts("PASS");
    else
    {
      status ++;
      printf("FAIL (%d bytes instead of %d)\n", s ? (int)strlen(s) : 0,
	     (int)strlen(default2_code));

      if (s)
	puts(s);
    }

    if (s)
      free(s);

    fputs("ppdConflicts(): ", stdout);
    ppdMarkOption(ppd, "PageSize", "Env10");
    ppdMarkOption(ppd, "InputSlot", "Envelope");
    ppdMarkOption(ppd, "Quality", "Photo");

    if ((conflicts = ppdConflicts(ppd)) == 1)
      puts("PASS (1)");
    else
    {
      printf("FAIL (%d)\n", conflicts);
      status ++;
    }

    fputs("cupsResolveConflicts(Quality=Photo): ", stdout);
    num_options = 0;
    options     = NULL;
    if (cupsResolveConflicts(ppd, "Quality", "Photo", &num_options,
                             &options))
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
      puts("PASS (Unable to resolve)");
    cupsFreeOptions(num_options, options);

    fputs("cupsResolveConflicts(No option/choice): ", stdout);
    num_options = 0;
    options     = NULL;
    if (cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options) &&
        num_options == 1 && !_cups_strcasecmp(options->name, "Quality") &&
	!_cups_strcasecmp(options->value, "Normal"))
      puts("PASS");
    else if (num_options > 0)
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
      status ++;
    }
    else
    {
      puts("FAIL (Unable to resolve!)");
      status ++;
    }
    cupsFreeOptions(num_options, options);

    fputs("cupsResolveConflicts(loop test): ", stdout);
    ppdMarkOption(ppd, "PageSize", "A4");
    ppdMarkOption(ppd, "InputSlot", "Tray");
    ppdMarkOption(ppd, "Quality", "Photo");
    num_options = 0;
    options     = NULL;
    if (!cupsResolveConflicts(ppd, NULL, NULL, &num_options, &options))
      puts("PASS");
    else if (num_options > 0)
    {
      printf("FAIL (%d options:", num_options);
      for (i = 0; i < num_options; i ++)
        printf(" %s=%s", options[i].name, options[i].value);
      puts(")");
    }
    else
      puts("FAIL (No conflicts!)");

    fputs("ppdInstallableConflict(): ", stdout);
    if (ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble") &&
        !ppdInstallableConflict(ppd, "Duplex", "None"))
      puts("PASS");
    else if (!ppdInstallableConflict(ppd, "Duplex", "DuplexNoTumble"))
    {
      puts("FAIL (Duplex=DuplexNoTumble did not conflict)");
      status ++;
    }
    else
    {
      puts("FAIL (Duplex=None conflicted)");
      status ++;
    }

   /*
    * ppdPageSizeLimits
    */

    ppdMarkDefaults(ppd);

    fputs("ppdPageSizeLimits(default): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 36 || minsize.length != 36 ||
          maxsize.width != 1080 || maxsize.length != 86400)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=36x36, max=1080x86400)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

    ppdMarkOption(ppd, "InputSlot", "Manual");

    fputs("ppdPageSizeLimits(InputSlot=Manual): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 100 || minsize.length != 100 ||
          maxsize.width != 1000 || maxsize.length != 1000)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=100x100, max=1000x1000)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

    ppdMarkOption(ppd, "Quality", "Photo");

    fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 200 || minsize.length != 200 ||
          maxsize.width != 1000 || maxsize.length != 1000)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=200x200, max=1000x1000)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }

    ppdMarkOption(ppd, "InputSlot", "Tray");

    fputs("ppdPageSizeLimits(Quality=Photo): ", stdout);
    if (ppdPageSizeLimits(ppd, &minsize, &maxsize))
    {
      if (minsize.width != 300 || minsize.length != 300 ||
          maxsize.width != 1080 || maxsize.length != 86400)
      {
        printf("FAIL (got min=%.0fx%.0f, max=%.0fx%.0f, "
	       "expected min=300x300, max=1080x86400)\n", minsize.width,
	       minsize.length, maxsize.width, maxsize.length);
        status ++;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (returned 0)");
      status ++;
    }
  }
  else
  {
    const char	*filename;		/* PPD filename */
    struct stat	fileinfo;		/* File information */


    if (!strncmp(argv[1], "-d", 2))
    {
      const char *printer;		/* Printer name */

      if (argv[1][2])
	printer = argv[1] + 2;
      else if (argv[2])
	printer = argv[2];
      else
      {
        puts("Usage: ./testppd -d printer");
	return (1);
      }

      filename = cupsGetPPD(printer);

      if (!filename)
      {
        printf("%s: %s\n", printer, cupsLastErrorString());
        return (1);
      }
    }
    else
      filename = argv[1];

    if (lstat(filename, &fileinfo))
    {
      printf("%s: %s\n", filename, strerror(errno));
      return (1);
    }

    if (S_ISLNK(fileinfo.st_mode))
    {
      char	realfile[1024];		/* Real file path */
      ssize_t	realsize;		/* Size of real file path */


      if ((realsize = readlink(filename, realfile, sizeof(realfile) - 1)) < 0)
        strlcpy(realfile, "Unknown", sizeof(realfile));
      else
        realfile[realsize] = '\0';

      if (stat(realfile, &fileinfo))
	printf("%s: symlink to \"%s\", %s\n", filename, realfile,
	       strerror(errno));
      else
	printf("%s: symlink to \"%s\", %ld bytes\n", filename, realfile,
	       (long)fileinfo.st_size);
    }
    else
      printf("%s: regular file, %ld bytes\n", filename, (long)fileinfo.st_size);

    if ((ppd = ppdOpenFile(filename)) == NULL)
    {
      ppd_status_t	err;		/* Last error in file */
      int		line;		/* Line number in file */


      status ++;
      err = ppdLastError(&line);

      printf("%s: %s on line %d\n", argv[1], ppdErrorString(err), line);
    }
    else
    {
      int		j, k;		/* Looping vars */
      ppd_group_t	*group;		/* Option group */
      ppd_option_t	*option;	/* Option */
      ppd_coption_t	*coption;	/* Custom option */
      ppd_cparam_t	*cparam;	/* Custom parameter */
      ppd_const_t	*c;		/* UIConstraints */
      char		lang[255],	/* LANG environment variable */
			lc_all[255],	/* LC_ALL environment variable */
			lc_ctype[255],	/* LC_CTYPE environment variable */
			lc_messages[255];/* LC_MESSAGES environment variable */


      if (argc > 2)
      {
        snprintf(lang, sizeof(lang), "LANG=%s", argv[2]);
	putenv(lang);
        snprintf(lc_all, sizeof(lc_all), "LC_ALL=%s", argv[2]);
	putenv(lc_all);
        snprintf(lc_ctype, sizeof(lc_ctype), "LC_CTYPE=%s", argv[2]);
	putenv(lc_ctype);
        snprintf(lc_messages, sizeof(lc_messages), "LC_MESSAGES=%s", argv[2]);
	putenv(lc_messages);
      }

      ppdLocalize(ppd);
      ppdMarkDefaults(ppd);

      if (argc > 3)
      {
        text = ppdLocalizeIPPReason(ppd, argv[3], NULL, buffer, sizeof(buffer));
	printf("ppdLocalizeIPPReason(%s)=%s\n", argv[3],
	       text ? text : "(null)");
	return (text == NULL);
      }

      for (i = ppd->num_groups, group = ppd->groups;
	   i > 0;
	   i --, group ++)
      {
	printf("%s (%s):\n", group->name, group->text);

	for (j = group->num_options, option = group->options;
	     j > 0;
	     j --, option ++)
	{
	  printf("    %s (%s):\n", option->keyword, option->text);

	  for (k = 0; k < option->num_choices; k ++)
	    printf("        - %s%s (%s)\n",
	           option->choices[k].marked ? "*" : "",
		   option->choices[k].choice, option->choices[k].text);

          if ((coption = ppdFindCustomOption(ppd, option->keyword)) != NULL)
	  {
	    for (cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params);
	         cparam;
		 cparam = (ppd_cparam_t *)cupsArrayNext(coption->params))
            {
	      switch (cparam->type)
	      {
	        case PPD_CUSTOM_CURVE :
		    printf("              %s(%s): PPD_CUSTOM_CURVE (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_curve,
			   cparam->maximum.custom_curve);
		    break;

	        case PPD_CUSTOM_INT :
		    printf("              %s(%s): PPD_CUSTOM_INT (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_int,
			   cparam->maximum.custom_int);
		    break;

	        case PPD_CUSTOM_INVCURVE :
		    printf("              %s(%s): PPD_CUSTOM_INVCURVE (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_invcurve,
			   cparam->maximum.custom_invcurve);
		    break;

	        case PPD_CUSTOM_PASSCODE :
		    printf("              %s(%s): PPD_CUSTOM_PASSCODE (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_passcode,
			   cparam->maximum.custom_passcode);
		    break;

	        case PPD_CUSTOM_PASSWORD :
		    printf("              %s(%s): PPD_CUSTOM_PASSWORD (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_password,
			   cparam->maximum.custom_password);
		    break;

	        case PPD_CUSTOM_POINTS :
		    printf("              %s(%s): PPD_CUSTOM_POINTS (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_points,
			   cparam->maximum.custom_points);
		    break;

	        case PPD_CUSTOM_REAL :
		    printf("              %s(%s): PPD_CUSTOM_REAL (%g to %g)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_real,
			   cparam->maximum.custom_real);
		    break;

	        case PPD_CUSTOM_STRING :
		    printf("              %s(%s): PPD_CUSTOM_STRING (%d to %d)\n",
		           cparam->name, cparam->text,
			   cparam->minimum.custom_string,
			   cparam->maximum.custom_string);
		    break;
	      }
	    }
	  }
	}
      }

      puts("\nSizes:");
      for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
        printf("    %s = %gx%g, [%g %g %g %g]\n", size->name, size->width,
	       size->length, size->left, size->bottom, size->right, size->top);

      puts("\nConstraints:");

      for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++)
        printf("    *UIConstraints: *%s %s *%s %s\n", c->option1, c->choice1,
	       c->option2, c->choice2);
      if (ppd->num_consts == 0)
        puts("    NO CONSTRAINTS");

      puts("\nFilters:");

      for (i = 0; i < ppd->num_filters; i ++)
        printf("    %s\n", ppd->filters[i]);

      if (ppd->num_filters == 0)
        puts("    NO FILTERS");

      puts("\nAttributes:");

      for (attr = (ppd_attr_t *)cupsArrayFirst(ppd->sorted_attrs);
           attr;
	   attr = (ppd_attr_t *)cupsArrayNext(ppd->sorted_attrs))
        printf("    *%s %s/%s: \"%s\"\n", attr->name, attr->spec,
	       attr->text, attr->value ? attr->value : "");

      puts("\nPPD Cache:");
      if ((pc = _ppdCacheCreateWithPPD(ppd)) == NULL)
        printf("    Unable to create: %s\n", cupsLastErrorString());
      else
      {
        _ppdCacheWriteFile(pc, "t.cache", NULL);
        puts("    Wrote t.cache.");
      }
    }

    if (!strncmp(argv[1], "-d", 2))
      unlink(filename);
  }

#ifdef __APPLE__
  if (getenv("MallocStackLogging") && getenv("MallocStackLoggingNoCompact"))
  {
    char	command[1024];		/* malloc_history command */

    snprintf(command, sizeof(command), "malloc_history %d -all_by_size",
	     getpid());
    fflush(stdout);
    system(command);
  }
#endif /* __APPLE__ */

  ppdClose(ppd);

  return (status);
}
Esempio n. 23
0
static void
ppd_mark_option(ppd_file_t *ppd,	/* I - PPD file */
                const char *option,	/* I - Option name */
                const char *choice)	/* I - Choice name */
{
  int		i, j;			/* Looping vars */
  ppd_option_t	*o;			/* Option pointer */
  ppd_choice_t	*c,			/* Choice pointer */
		*oldc,			/* Old choice pointer */
		key;			/* Search key for choice */
  struct lconv	*loc;			/* Locale data */


  DEBUG_printf(("7ppd_mark_option(ppd=%p, option=\"%s\", choice=\"%s\")",
        	ppd, option, choice));

 /*
  * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
  * it clears the regular InputSlot choices...
  */

  if (!_cups_strcasecmp(option, "AP_D_InputSlot"))
  {
    cupsArraySave(ppd->options);

    if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
    {
      key.option = o;
      if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
      {
        oldc->marked = 0;
        cupsArrayRemove(ppd->marked, oldc);
      }
    }

    cupsArrayRestore(ppd->options);
  }

 /*
  * Check for custom options...
  */

  cupsArraySave(ppd->options);

  o = ppdFindOption(ppd, option);

  cupsArrayRestore(ppd->options);

  if (!o)
    return;

  loc = localeconv();

  if (!_cups_strncasecmp(choice, "Custom.", 7))
  {
   /*
    * Handle a custom option...
    */

    if ((c = ppdFindChoice(o, "Custom")) == NULL)
      return;

    if (!_cups_strcasecmp(option, "PageSize"))
    {
     /*
      * Handle custom page sizes...
      */

      ppdPageSize(ppd, choice);
    }
    else
    {
     /*
      * Handle other custom options...
      */

      ppd_coption_t	*coption;	/* Custom option */
      ppd_cparam_t	*cparam;	/* Custom parameter */
      char		*units;		/* Custom points units */


      if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
      {
        if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL)
	  return;

        switch (cparam->type)
	{
	  case PPD_CUSTOM_CURVE :
	  case PPD_CUSTOM_INVCURVE :
	  case PPD_CUSTOM_REAL :
	      cparam->current.custom_real = (float)_cupsStrScand(choice + 7,
	                                                         NULL, loc);
	      break;

	  case PPD_CUSTOM_POINTS :
	      cparam->current.custom_points = (float)_cupsStrScand(choice + 7,
	                                                           &units,
	                                                           loc);

              if (units)
	      {
        	if (!_cups_strcasecmp(units, "cm"))
	          cparam->current.custom_points *= 72.0f / 2.54f;
        	else if (!_cups_strcasecmp(units, "mm"))
	          cparam->current.custom_points *= 72.0f / 25.4f;
        	else if (!_cups_strcasecmp(units, "m"))
	          cparam->current.custom_points *= 72.0f / 0.0254f;
        	else if (!_cups_strcasecmp(units, "in"))
	          cparam->current.custom_points *= 72.0f;
        	else if (!_cups_strcasecmp(units, "ft"))
	          cparam->current.custom_points *= 12.0f * 72.0f;
              }
	      break;

	  case PPD_CUSTOM_INT :
	      cparam->current.custom_int = atoi(choice + 7);
	      break;

	  case PPD_CUSTOM_PASSCODE :
	  case PPD_CUSTOM_PASSWORD :
	  case PPD_CUSTOM_STRING :
	      if (cparam->current.custom_string)
	        _cupsStrFree(cparam->current.custom_string);

	      cparam->current.custom_string = _cupsStrAlloc(choice + 7);
	      break;
	}
      }
    }

   /*
    * Make sure that we keep the option marked below...
    */

    choice = "Custom";
  }
  else if (choice[0] == '{')
  {
   /*
    * Handle multi-value custom options...
    */

    ppd_coption_t	*coption;	/* Custom option */
    ppd_cparam_t	*cparam;	/* Custom parameter */
    char		*units;		/* Custom points units */
    int			num_vals;	/* Number of values */
    cups_option_t	*vals,		/* Values */
			*val;		/* Value */


    if ((c = ppdFindChoice(o, "Custom")) == NULL)
      return;

    if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
    {
      num_vals = cupsParseOptions(choice, 0, &vals);

      for (i = 0, val = vals; i < num_vals; i ++, val ++)
      {
        if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL)
	  continue;

	switch (cparam->type)
	{
	  case PPD_CUSTOM_CURVE :
	  case PPD_CUSTOM_INVCURVE :
	  case PPD_CUSTOM_REAL :
	      cparam->current.custom_real = (float)_cupsStrScand(val->value,
	                                                         NULL, loc);
	      break;

	  case PPD_CUSTOM_POINTS :
	      cparam->current.custom_points = (float)_cupsStrScand(val->value,
	                                                           &units,
	                                                           loc);

	      if (units)
	      {
        	if (!_cups_strcasecmp(units, "cm"))
		  cparam->current.custom_points *= 72.0f / 2.54f;
        	else if (!_cups_strcasecmp(units, "mm"))
		  cparam->current.custom_points *= 72.0f / 25.4f;
        	else if (!_cups_strcasecmp(units, "m"))
		  cparam->current.custom_points *= 72.0f / 0.0254f;
        	else if (!_cups_strcasecmp(units, "in"))
		  cparam->current.custom_points *= 72.0f;
        	else if (!_cups_strcasecmp(units, "ft"))
		  cparam->current.custom_points *= 12.0f * 72.0f;
	      }
	      break;

	  case PPD_CUSTOM_INT :
	      cparam->current.custom_int = atoi(val->value);
	      break;

	  case PPD_CUSTOM_PASSCODE :
	  case PPD_CUSTOM_PASSWORD :
	  case PPD_CUSTOM_STRING :
	      if (cparam->current.custom_string)
		_cupsStrFree(cparam->current.custom_string);

	      cparam->current.custom_string = _cupsStrRetain(val->value);
	      break;
	}
      }

      cupsFreeOptions(num_vals, vals);
    }
  }
  else
  {
    for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
      if (!_cups_strcasecmp(c->choice, choice))
        break;

    if (!i)
      return;
  }

 /*
  * Option found; mark it and then handle unmarking any other options.
  */

  if (o->ui != PPD_UI_PICKMANY)
  {
   /*
    * Unmark all other choices...
    */

    if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL)
    {
      oldc->marked = 0;
      cupsArrayRemove(ppd->marked, oldc);
    }

    if (!_cups_strcasecmp(option, "PageSize") || !_cups_strcasecmp(option, "PageRegion"))
    {
     /*
      * Mark current page size...
      */

      for (j = 0; j < ppd->num_sizes; j ++)
	ppd->sizes[j].marked = !_cups_strcasecmp(ppd->sizes[j].name,
		                           choice);

     /*
      * Unmark the current PageSize or PageRegion setting, as
      * appropriate...
      */

      cupsArraySave(ppd->options);

      if (!_cups_strcasecmp(option, "PageSize"))
      {
	if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
        {
          key.option = o;
          if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
          {
            oldc->marked = 0;
            cupsArrayRemove(ppd->marked, oldc);
          }
        }
      }
      else
      {
	if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
        {
          key.option = o;
          if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
          {
            oldc->marked = 0;
            cupsArrayRemove(ppd->marked, oldc);
          }
        }
      }

      cupsArrayRestore(ppd->options);
    }
    else if (!_cups_strcasecmp(option, "InputSlot"))
    {
     /*
      * Unmark ManualFeed option...
      */

      cupsArraySave(ppd->options);

      if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL)
      {
        key.option = o;
        if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
        {
          oldc->marked = 0;
          cupsArrayRemove(ppd->marked, oldc);
        }
      }

      cupsArrayRestore(ppd->options);
    }
    else if (!_cups_strcasecmp(option, "ManualFeed") &&
	     !_cups_strcasecmp(choice, "True"))
    {
     /*
      * Unmark InputSlot option...
      */

      cupsArraySave(ppd->options);

      if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
      {
        key.option = o;
        if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
        {
          oldc->marked = 0;
          cupsArrayRemove(ppd->marked, oldc);
        }
      }

      cupsArrayRestore(ppd->options);
    }
  }

  c->marked = 1;

  cupsArrayAdd(ppd->marked, c);
}
Esempio n. 24
0
int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line args */
     char *argv[])			/* I - Command-line arguments */
{
  int		errors;			/* Number of errors */
  const char	*ext;			/* Filename extension */


  if (argc == 1)
  {
    errors = do_ps_tests();
    errors += do_raster_tests(CUPS_RASTER_WRITE);
    errors += do_raster_tests(CUPS_RASTER_WRITE_COMPRESSED);
    errors += do_raster_tests(CUPS_RASTER_WRITE_PWG);
  }
  else
  {
    int			i;		/* Looping var */
    int			num_options;	/* Number of options */
    cups_option_t	*options;	/* Options */


    for (errors = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++)
    {
      if (argv[i][0] == '-')
      {
        if (argv[i][1] == 'o')
        {
          if (argv[i][2])
            num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
          else
          {
            i ++;
            if (i < argc)
              num_options = cupsParseOptions(argv[i], num_options, &options);
            else
            {
              puts("Usage: testraster [-o name=value ...] [filename.ppd ...]");
              puts("       testraster [filename.ras ...]");
              return (1);
            }
          }
        }
        else
        {
          puts("Usage: testraster [-o name=value ...] [filename.ppd ...]");
	  puts("       testraster [filename.ras ...]");
          return (1);
        }
      }
      else if ((ext = strrchr(argv[i], '.')) != NULL)
      {
        if (!strcmp(ext, ".ppd"))
	  errors += do_ppd_tests(argv[i], num_options, options);
	else
	  errors += do_ras_file(argv[i]);
      }
      else
      {
	puts("Usage: testraster [-o name=value ...] [filename.ppd ...]");
	puts("       testraster [filename.ras ...]");
	return (1);
      }
    }

    cupsFreeOptions(num_options, options);
  }

  return (errors);
}
Esempio n. 25
0
static int				/* O - 0 on success, 1 on fail */
set_printer_options(
    http_t        *http,		/* I - Server connection */
    char          *printer,		/* I - Printer */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    char          *file)		/* I - PPD file/interface script */
{
  ipp_t		*request;		/* IPP Request */
  const char	*ppdfile;		/* PPD filename */
  int		ppdchanged = 0;		/* PPD changed? */
  ppd_file_t	*ppd;			/* PPD file */
  ppd_choice_t	*choice;		/* Marked choice */
  char		uri[HTTP_MAX_URI],	/* URI for printer/class */
		line[1024],		/* Line from PPD file */
		keyword[1024],		/* Keyword from Default line */
		*keyptr,		/* Pointer into keyword... */
		tempfile[1024];		/* Temporary filename */
  cups_file_t	*in,			/* PPD file */
		*out;			/* Temporary file */
  const char	*ppdname,		/* ppd-name value */
		*protocol,		/* Old protocol option */
		*customval,		/* Custom option value */
		*boolval;		/* Boolean value */
  int		wrote_ipp_supplies = 0,	/* Wrote cupsIPPSupplies keyword? */
		wrote_snmp_supplies = 0,/* Wrote cupsSNMPSupplies keyword? */
		copied_options = 0;	/* Copied options? */


  DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, "
                "options=%p, file=\"%s\")\n", http, printer, num_options,
		options, file));

 /*
  * Build a CUPS-Add-Modify-Printer or CUPS-Add-Modify-Class request,
  * which requires the following attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  *    other options
  */

  if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)
    request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_CLASS);
  else
    request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_PRINTER);

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

 /*
  * Add the options...
  */

  if (file)
    ppdfile = file;
  else if ((ppdname = cupsGetOption("ppd-name", num_options, options)) != NULL && strcmp(ppdname, "raw") && num_options > 1)
  {
    if ((ppdfile = cupsGetServerPPD(http, ppdname)) != NULL)
    {
     /*
      * Copy options array and remove ppd-name from it...
      */

      cups_option_t *temp = NULL, *optr;
      int i, num_temp = 0;
      for (i = num_options, optr = options; i > 0; i --, optr ++)
        if (strcmp(optr->name, "ppd-name"))
	  num_temp = cupsAddOption(optr->name, optr->value, num_temp, &temp);

      copied_options = 1;
      ppdchanged     = 1;
      num_options    = num_temp;
      options        = temp;
    }
  }
  else if (request->request.op.operation_id == IPP_OP_CUPS_ADD_MODIFY_PRINTER)
    ppdfile = cupsGetPPD(printer);
  else
    ppdfile = NULL;

  cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);

  if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL)
  {
    if (!_cups_strcasecmp(protocol, "bcp"))
      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
                   NULL, "bcp");
    else if (!_cups_strcasecmp(protocol, "tbcp"))
      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
                   NULL, "tbcp");
  }

  if (ppdfile)
  {
   /*
    * Set default options in the PPD file...
    */

    if ((ppd = ppdOpenFile(ppdfile)) == NULL)
    {
      int		linenum;	/* Line number of error */
      ppd_status_t	status = ppdLastError(&linenum);
					/* Status code */

      _cupsLangPrintf(stderr, _("lpadmin: Unable to open PPD \"%s\": %s on line %d."), ppdfile, ppdErrorString(status), linenum);
    }

    ppdMarkDefaults(ppd);
    cupsMarkOptions(ppd, num_options, options);

    if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
    {
      _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file"));
      ippDelete(request);
      if (ppdfile != file)
        unlink(ppdfile);
      if (copied_options)
        cupsFreeOptions(num_options, options);
      return (1);
    }

    if ((in = cupsFileOpen(ppdfile, "r")) == NULL)
    {
      _cupsLangPrintf(stderr,
                      _("lpadmin: Unable to open PPD file \"%s\" - %s"),
        	      ppdfile, strerror(errno));
      ippDelete(request);
      if (ppdfile != file)
	unlink(ppdfile);
      if (copied_options)
        cupsFreeOptions(num_options, options);
      cupsFileClose(out);
      unlink(tempfile);
      return (1);
    }

    while (cupsFileGets(in, line, sizeof(line)))
    {
      if (!strncmp(line, "*cupsIPPSupplies:", 17) &&
	  (boolval = cupsGetOption("cupsIPPSupplies", num_options,
	                           options)) != NULL)
      {
        wrote_ipp_supplies = 1;
        cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
	               (!_cups_strcasecmp(boolval, "true") ||
		        !_cups_strcasecmp(boolval, "yes") ||
		        !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
      }
      else if (!strncmp(line, "*cupsSNMPSupplies:", 18) &&
	       (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
	                                options)) != NULL)
      {
        wrote_snmp_supplies = 1;
        cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
	               (!_cups_strcasecmp(boolval, "true") ||
		        !_cups_strcasecmp(boolval, "yes") ||
		        !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
      }
      else if (strncmp(line, "*Default", 8))
        cupsFilePrintf(out, "%s\n", line);
      else
      {
       /*
        * Get default option name...
	*/

        strlcpy(keyword, line + 8, sizeof(keyword));

	for (keyptr = keyword; *keyptr; keyptr ++)
	  if (*keyptr == ':' || isspace(*keyptr & 255))
	    break;

        *keyptr++ = '\0';
        while (isspace(*keyptr & 255))
	  keyptr ++;

        if (!strcmp(keyword, "PageRegion") ||
	    !strcmp(keyword, "PageSize") ||
	    !strcmp(keyword, "PaperDimension") ||
	    !strcmp(keyword, "ImageableArea"))
	{
	  if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL)
	    choice = ppdFindMarkedChoice(ppd, "PageRegion");
        }
	else
	  choice = ppdFindMarkedChoice(ppd, keyword);

        if (choice && strcmp(choice->choice, keyptr))
	{
	  if (strcmp(choice->choice, "Custom"))
	  {
	    cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice);
	    ppdchanged = 1;
	  }
	  else if ((customval = cupsGetOption(keyword, num_options,
	                                      options)) != NULL)
	  {
	    cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval);
	    ppdchanged = 1;
	  }
	  else
	    cupsFilePrintf(out, "%s\n", line);
	}
	else
	  cupsFilePrintf(out, "%s\n", line);
      }
    }

    if (!wrote_ipp_supplies &&
	(boolval = cupsGetOption("cupsIPPSupplies", num_options,
				 options)) != NULL)
    {
      cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
		     (!_cups_strcasecmp(boolval, "true") ||
		      !_cups_strcasecmp(boolval, "yes") ||
		      !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
    }

    if (!wrote_snmp_supplies &&
        (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
			         options)) != NULL)
    {
      cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
		     (!_cups_strcasecmp(boolval, "true") ||
		      !_cups_strcasecmp(boolval, "yes") ||
		      !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
    }

    cupsFileClose(in);
    cupsFileClose(out);
    ppdClose(ppd);

   /*
    * Do the request...
    */

    ippDelete(cupsDoFileRequest(http, request, "/admin/",
                                ppdchanged ? tempfile : file));

   /*
    * Clean up temp files... (TODO: catch signals in case we CTRL-C during
    * lpadmin)
    */

    if (ppdfile != file)
      unlink(ppdfile);
    unlink(tempfile);
  }
  else
  {
   /*
    * No PPD file - just set the options...
    */

    ippDelete(cupsDoRequest(http, request, "/admin/"));
  }

  if (copied_options)
    cupsFreeOptions(num_options, options);

 /*
  * Check the response...
  */

  if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    return (1);
  }
  else
    return (0);
}
static 
int check_options( FILE** fp, short *is_setregi, int *utilbyte,
				  char* tmp_file, char* option , short *is_direct)
{

	cups_option_t *p_opt = NULL;
	int num_opt = 0; 
	int i,result = 0;
	short regi_flag=0;
	short direct_flag=0;
	int cmdlen = 0;
	int bscc_id = 0;

	if( (num_opt = cupsParseOptions(option, 0, &p_opt)) > 0 ){
		for( i=0; i< num_opt; i++ ){
	
			/* bscc */	
			if( strcmp( p_opt[i].name, REGI_OPTION)== 0){
				bscc_id = atoi(p_opt[i].value);
				regi_flag = 1;
			}
			else if( strcmp( p_opt[i].name, UTIL_OPTION)== 0 ){
				cmdlen = atoi(p_opt[i].value);
				*utilbyte = cmdlen;
			}
			/* Ver.3.20 */
			else if( strcmp( p_opt[i].name, DIRECT_OPTION)== 0 ){
				direct_flag = 1;
			}
		}
	}
	
	if( regi_flag ){
		char model_name[MODEL_NAME_STR_LEN] ;
		char bscc_file[256];
		char bscc_buf[256];
		char cmd_buf[512];
		int r_size,total_size;
		FILE* tmp_fp = NULL;

		sprintf( tmp_file, "/tmp/CNBjBackend%d", getpid());
//		if( (tmp_fp =fopen( tmp_file, "w")) == NULL )
		if( (tmp_fp =fopen( tmp_file, "w+b")) == NULL ){	/* Ver.2.90 */
			fprintf(stderr,"CNBjBackend open_error\n");
			goto open_error;	
		}

		total_size = cmdlen;
		while( total_size > 0 ){
			r_size = fread( cmd_buf, 1,total_size,(FILE*)(*fp) );
			fwrite( cmd_buf, r_size, 1, tmp_fp);
			total_size -= r_size;
		}
		fseek( tmp_fp, 0, SEEK_SET );
		
		r_size = fread( bscc_buf, 1, 256, (FILE*)(*fp) );
		fprintf(stderr,"bscc_buf r_size=%d\n",r_size);
		/* bscc file */
		get_model_name( model_name );
		sprintf( bscc_file, "%scif%s.bscc", BSCCFILEPATH, model_name );
		//sprintf( bscc_file, "%sbjfilter%s.bscc", BSCCFILEPATH, model_name );
		
		if( write_to_bsccfile( bscc_file, bscc_buf, bscc_id ) )
			result = -1;

		*fp = tmp_fp;
	}
	
	*is_setregi = regi_flag;
	*is_direct = direct_flag;	/* Ver.3.20 */
	
	cupsFreeOptions( num_opt, p_opt );
	return result;
	
 open_error:
	cupsFreeOptions( num_opt, p_opt );
	return -1;
		
}