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