static int delete_printer_from_class()

in systemv/lpadmin.c [27:671]


static int		delete_printer_from_class(http_t *http, char *printer,
			                          char *pclass);
static int		delete_printer_option(http_t *http, char *printer,
			                      char *option);
static int		enable_printer(http_t *http, char *printer);
static cups_ptype_t	get_printer_type(http_t *http, char *printer, char *uri,
			                 size_t urisize);
static int		set_printer_options(http_t *http, char *printer,
			                    int num_options, cups_option_t *options,
					    char *file, int enable);
static void		usage(void) _CUPS_NORETURN;
static int		validate_name(const char *name);


/*
 * 'main()' - Parse options and configure the scheduler.
 */

int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		i;			/* Looping var */
  http_t	*http;			/* Connection to server */
  char		*printer,		/* Destination printer */
		*pclass,		/* Printer class name */
		*opt,			/* Option pointer */
		*val;			/* Pointer to allow/deny value */
  int		enable = 0;		/* Enable/resume printer? */
  int		num_options;		/* Number of options */
  cups_option_t	*options;		/* Options */
  char		*file,			/* New PPD file */
		evefile[1024] = "";	/* IPP Everywhere PPD */
  const char	*ppd_name,		/* ppd-name value */
		*device_uri;		/* device-uri value */


  _cupsSetLocale(argv);

  http        = NULL;
  printer     = NULL;
  num_options = 0;
  options     = NULL;
  file        = NULL;

  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 'c' : /* Add printer to class */
	      if (!http)
	      {
		http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);

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

	      if (printer == NULL)
	      {
		_cupsLangPuts(stderr,
			      _("lpadmin: Unable to add a printer to the class:\n"
				"         You must specify a printer name first."));
		return (1);
	      }

	      if (opt[1] != '\0')
	      {
		pclass = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected class name after \"-c\" option."));
		  usage();
		}

		pclass = argv[i];
	      }

	      if (!validate_name(pclass))
	      {
		_cupsLangPuts(stderr,
			      _("lpadmin: Class name can only contain printable "
				"characters."));
		return (1);
	      }

	      if (add_printer_to_class(http, printer, pclass))
		return (1);
	      break;

	  case 'd' : /* Set as default destination */
	      if (!http)
	      {
		http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);

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

	      if (opt[1] != '\0')
	      {
		printer = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected printer name after \"-d\" option."));
		  usage();
		}

		printer = argv[i];
	      }

	      if (!validate_name(printer))
	      {
		_cupsLangPuts(stderr, _("lpadmin: Printer name can only contain printable characters."));
		return (1);
	      }

	      if (default_printer(http, printer))
		return (1);

	      i = argc;
	      break;

	  case 'h' : /* Connect to host */
	      if (http)
	      {
		httpClose(http);
		http = NULL;
	      }

	      if (opt[1] != '\0')
	      {
		cupsSetServer(opt + 1);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected hostname after \"-h\" option."));
		  usage();
		}

		cupsSetServer(argv[i]);
	      }
	      break;

	  case 'P' : /* Use the specified PPD file */
	  case 'i' : /* Use the specified PPD file */
	      if (opt[1] != '\0')
	      {
		file = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPrintf(stderr, _("lpadmin: Expected PPD after \"-%c\" option."), argv[i - 1][1]);
		  usage();
		}

		file = argv[i];
	      }

	      if (*opt == 'i')
	      {
	       /*
	        * Check to see that the specified file is, in fact, a PPD...
	        */

                cups_file_t *fp = cupsFileOpen(file, "r");
                char line[256];

                if (!cupsFileGets(fp, line, sizeof(line)) || strncmp(line, "*PPD-Adobe", 10))
                {
                  _cupsLangPuts(stderr, _("lpadmin: System V interface scripts are no longer supported for security reasons."));
                  cupsFileClose(fp);
                  return (1);
                }

                cupsFileClose(fp);
	      }
	      break;

	  case 'E' : /* Enable the printer/enable encryption */
	      if (printer == NULL)
	      {
#ifdef HAVE_TLS
		cupsSetEncryption(HTTP_ENCRYPTION_REQUIRED);

		if (http)
		  httpEncryption(http, HTTP_ENCRYPTION_REQUIRED);
#else
		_cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), argv[0]);
#endif /* HAVE_TLS */
		break;
	      }

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

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

              enable = 1;
	      break;

	  case 'm' : /* Use the specified standard script/PPD file */
	      if (opt[1] != '\0')
	      {
		num_options = cupsAddOption("ppd-name", opt + 1, num_options, &options);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected model after \"-m\" option."));
		  usage();
		}

		num_options = cupsAddOption("ppd-name", argv[i], num_options, &options);
	      }
	      break;

	  case 'o' : /* Set option */
	      if (opt[1] != '\0')
	      {
		num_options = cupsParseOptions(opt + 1, num_options, &options);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected name=value after \"-o\" option."));
		  usage();
		}

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

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

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected printer after \"-p\" option."));
		  usage();
		}

		printer = argv[i];
	      }

	      if (!validate_name(printer))
	      {
		_cupsLangPuts(stderr, _("lpadmin: Printer name can only contain printable characters."));
		return (1);
	      }
	      break;

	  case 'r' : /* Remove printer from class */
	      if (!http)
	      {
		http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);

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

	      if (printer == NULL)
	      {
		_cupsLangPuts(stderr,
			      _("lpadmin: Unable to remove a printer from the class:\n"
				"         You must specify a printer name first."));
		return (1);
	      }

	      if (opt[1] != '\0')
	      {
		pclass = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected class after \"-r\" option."));
		  usage();
		}

		pclass = argv[i];
	      }

	      if (!validate_name(pclass))
	      {
		_cupsLangPuts(stderr, _("lpadmin: Class name can only contain printable characters."));
		return (1);
	      }

	      if (delete_printer_from_class(http, printer, pclass))
		return (1);
	      break;

	  case 'R' : /* Remove option */
	      if (!http)
	      {
		http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);

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

	      if (printer == NULL)
	      {
		_cupsLangPuts(stderr,
			      _("lpadmin: Unable to delete option:\n"
				"         You must specify a printer name first."));
		return (1);
	      }

	      if (opt[1] != '\0')
	      {
		val = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected name after \"-R\" option."));
		  usage();
		}

		val = argv[i];
	      }

	      if (delete_printer_option(http, printer, val))
		return (1);
	      break;

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

		cupsSetUser(argv[i]);
	      }
	      break;

	  case 'u' : /* Allow/deny users */
	      if (opt[1] != '\0')
	      {
		val = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected allow/deny:userlist after \"-u\" option."));
		  usage();
		}

		val = argv[i];
	      }

	      if (!_cups_strncasecmp(val, "allow:", 6))
		num_options = cupsAddOption("requesting-user-name-allowed", val + 6, num_options, &options);
	      else if (!_cups_strncasecmp(val, "deny:", 5))
		num_options = cupsAddOption("requesting-user-name-denied", val + 5, num_options, &options);
	      else
	      {
		_cupsLangPrintf(stderr, _("lpadmin: Unknown allow/deny option \"%s\"."), val);
		return (1);
	      }
	      break;

	  case 'v' : /* Set the device-uri attribute */
	      if (opt[1] != '\0')
	      {
		num_options = cupsAddOption("device-uri", opt + 1, num_options, &options);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected device URI after \"-v\" option."));
		  usage();
		}

		num_options = cupsAddOption("device-uri", argv[i], num_options, &options);
	      }
	      break;

	  case 'x' : /* Delete a printer */
	      if (!http)
	      {
		http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);

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

	      if (opt[1] != '\0')
	      {
		printer = opt + 1;
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected printer or class after \"-x\" option."));
		  usage();
		}

		printer = argv[i];
	      }

	      if (!validate_name(printer))
	      {
		_cupsLangPuts(stderr, _("lpadmin: Printer name can only contain printable characters."));
		return (1);
	      }

	      if (delete_printer(http, printer))
		return (1);

	      i = argc;
	      break;

	  case 'D' : /* Set the printer-info attribute */
	      if (opt[1] != '\0')
	      {
		num_options = cupsAddOption("printer-info", opt + 1, num_options, &options);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected description after \"-D\" option."));
		  usage();
		}

		num_options = cupsAddOption("printer-info", argv[i], num_options, &options);
	      }
	      break;

	  case 'I' : /* Set the supported file types (ignored) */
	      i ++;

	      if (i >= argc)
	      {
		_cupsLangPuts(stderr, _("lpadmin: Expected file type(s) after \"-I\" option."));
		usage();
	      }

	      _cupsLangPuts(stderr, _("lpadmin: Warning - content type list ignored."));
	      break;

	  case 'L' : /* Set the printer-location attribute */
	      if (opt[1] != '\0')
	      {
		num_options = cupsAddOption("printer-location", opt + 1, num_options, &options);
		opt += strlen(opt) - 1;
	      }
	      else
	      {
		i ++;

		if (i >= argc)
		{
		  _cupsLangPuts(stderr, _("lpadmin: Expected location after \"-L\" option."));
		  usage();
		}

		num_options = cupsAddOption("printer-location", argv[i], num_options, &options);
	      }
	      break;

	  default :
	      _cupsLangPrintf(stderr, _("lpadmin: Unknown option \"%c\"."), *opt);
	      usage();
	}
      }
    }
    else
    {
      _cupsLangPrintf(stderr, _("lpadmin: Unknown argument \"%s\"."), argv[i]);
      usage();
    }
  }

 /*
  * Set options as needed...
  */

  ppd_name   = cupsGetOption("ppd-name", num_options, options);
  device_uri = cupsGetOption("device-uri", num_options, options);

  if (ppd_name && !strcmp(ppd_name, "raw"))
  {
#ifdef __APPLE__
    _cupsLangPuts(stderr, _("lpadmin: Raw queues are no longer supported on macOS."));
#else
    _cupsLangPuts(stderr, _("lpadmin: Raw queues are deprecated and will stop working in a future version of CUPS."));
#endif /* __APPLE__ */

    if (device_uri && (!strncmp(device_uri, "ipp://", 6) || !strncmp(device_uri, "ipps://", 7)) && strstr(device_uri, "/printers/"))
      _cupsLangPuts(stderr, _("lpadmin: Use the 'everywhere' model for shared printers."));

#ifdef __APPLE__
    return (1);
#endif /* __APPLE__ */
  }
  else if ((ppd_name && strcmp(ppd_name, "everywhere")) || file)
  {
    _cupsLangPuts(stderr, _("lpadmin: Printer drivers are deprecated and will stop working in a future version of CUPS."));
  }

  if (num_options || file)
  {
    if (printer == NULL)
    {
      _cupsLangPuts(stderr,
                    _("lpadmin: Unable to set the printer options:\n"
                      "         You must specify a printer name first."));
      return (1);
    }

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

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

    if (set_printer_options(http, printer, num_options, options, file, enable))
      return (1);
  }
  else if (enable && enable_printer(http, printer))
    return (1);

  if (evefile[0])
    unlink(evefile);

  if (printer == NULL)
    usage();

  if (http)
    httpClose(http);

  return (0);
}