Lines Matching +full:command +full:- +full:and +full:- +full:control

4  * Copyright 2007-2016 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
15 #include <cups/cups-private.h>
33 * LPD "mini-daemon" for CUPS. This program must be used in conjunction
34 * with inetd or another similar program that monitors ports and starts
37 * printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
42 * - This daemon does not check to make sure that the source port is
43 * between 721 and 731, since it isn't necessary for proper
44 * functioning and port-based security is no security at all!
46 * - The "Print any waiting jobs" command is a no-op.
48 * The LPD-to-IPP mapping is as defined in RFC 2569. The report formats
49 * currently match the Solaris LPD mini-daemon.
74 * 'main()' - Process an incoming LPD request...
77 int /* O - Exit status */
78 main(int argc, /* I - Number of command-line arguments */ in main()
79 char *argv[]) /* I - Command-line arguments */ in main()
84 char line[256], /* Command string */ in main()
85 command, /* Command code */ in main() local
109 * Log things using the "cups-lpd" name... in main()
112 openlog("cups-lpd", LOG_PID, LOG_LPR); in main()
115 * Scan the command-line for options... in main()
123 if (argv[i][0] == '-') in main()
127 case 'h' : /* -h hostname[:port] */ in main()
136 syslog(LOG_WARNING, "Expected hostname string after -h option!"); in main()
151 syslog(LOG_WARNING, "Expected option string after -o option!"); in main()
165 syslog(LOG_WARNING, "Unknown command-line option \"%s\" ignored!", in main()
176 syslog(LOG_WARNING, "Unable to get client address - %s", strerror(errno)); in main()
199 num_defaults = cupsAddOption("job-originating-host-name", hostname, in main()
203 * RFC1179 specifies that only 1 daemon command can be received for in main()
210 * Unable to get command from client! Send an error status and return. in main()
213 syslog(LOG_ERR, "Unable to get command line from client!"); in main()
224 * The first byte is the command byte. After that will be the queue name, in main()
225 * resource list, and/or user name. in main()
228 if ((command = line[0]) == '\0') in main()
233 if (command == 0x02) in main()
244 * Do the command... in main()
247 switch (command) in main()
249 default : /* Unknown command */ in main()
250 syslog(LOG_ERR, "Unknown LPD command 0x%02X!", command); in main()
251 syslog(LOG_ERR, "Command line = %s", line + 1); in main()
258 syslog(LOG_INFO, "Print waiting jobs (no-op)"); in main()
273 /* no status byte for this command */ in main()
280 /* no status byte for this command */ in main()
289 * Grab the agent and skip to the list of users and/or jobs. in main()
321 * 'create_job()' - Create a new print job.
324 static int /* O - Job ID or -1 on error */
325 create_job(http_t *http, /* I - HTTP connection */ in create_job()
326 const char *dest, /* I - Destination name */ in create_job()
327 const char *title, /* I - job-name */ in create_job()
328 const char *user, /* I - requesting-user-name */ in create_job()
329 int num_options, /* I - Number of options for job */ in create_job()
330 cups_option_t *options) /* I - Options for job */ in create_job()
340 * Setup the Create-Job request... in create_job()
348 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", in create_job()
352 "requesting-user-name", NULL, user); in create_job()
355 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", in create_job()
370 syslog(LOG_ERR, "Unable to create job - %s", cupsLastErrorString()); in create_job()
374 return (-1); in create_job()
378 * Get the job-id value from the response and return it... in create_job()
381 if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) in create_job()
383 id = -1; in create_job()
385 syslog(LOG_ERR, "No job-id attribute found in response from server!"); in create_job()
389 id = attr->values[0].integer; in create_job()
391 syslog(LOG_INFO, "Print file - job ID = %d", id); in create_job()
401 * 'get_printer()' - Get the named printer and its options.
404 static int /* O - Number of options or -1 on error */
405 get_printer(http_t *http, /* I - HTTP connection */ in get_printer()
406 const char *name, /* I - Printer name from request */ in get_printer()
407 char *dest, /* I - Destination buffer */ in get_printer()
408 size_t destsize, /* I - Size of destination buffer */ in get_printer()
409 cups_option_t **options, /* O - Printer options */ in get_printer()
410 int *accepting, /* O - printer-is-accepting-jobs value */ in get_printer()
411 int *shared, /* O - printer-is-shared value */ in get_printer()
412 ipp_pstate_t *state) /* O - printer-state value */ in get_printer()
427 "printer-info", in get_printer()
428 "printer-is-accepting-jobs", in get_printer()
429 "printer-is-shared", in get_printer()
430 "printer-name", in get_printer()
431 "printer-state" in get_printer()
457 * Setup the Get-Printer-Attributes request... in get_printer()
465 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", in get_printer()
469 "requested-attributes", in get_printer()
482 * If we can't find the printer by name, look up the printer-name in get_printer()
483 * using the printer-info values... in get_printer()
486 ipp_attribute_t *accepting_attr,/* printer-is-accepting-jobs */ in get_printer()
487 *info_attr, /* printer-info */ in get_printer()
488 *name_attr, /* printer-name */ in get_printer()
489 *shared_attr, /* printer-is-shared */ in get_printer()
490 *state_attr; /* printer-state */ in get_printer()
496 * Setup the CUPS-Get-Printers request... in get_printer()
502 "requested-attributes", in get_printer()
514 syslog(LOG_ERR, "Unable to get list of printers - %s", in get_printer()
519 return (-1); in get_printer()
527 attr = response->attrs; in get_printer()
535 while (attr && attr->group_tag != IPP_TAG_PRINTER) in get_printer()
536 attr = attr->next; in get_printer()
551 while (attr && attr->group_tag == IPP_TAG_PRINTER) in get_printer()
553 if (!strcmp(attr->name, "printer-is-accepting-jobs") && in get_printer()
554 attr->value_tag == IPP_TAG_BOOLEAN) in get_printer()
556 else if (!strcmp(attr->name, "printer-info") && in get_printer()
557 attr->value_tag == IPP_TAG_TEXT) in get_printer()
559 else if (!strcmp(attr->name, "printer-name") && in get_printer()
560 attr->value_tag == IPP_TAG_NAME) in get_printer()
562 else if (!strcmp(attr->name, "printer-is-shared") && in get_printer()
563 attr->value_tag == IPP_TAG_BOOLEAN) in get_printer()
565 else if (!strcmp(attr->name, "printer-state") && in get_printer()
566 attr->value_tag == IPP_TAG_ENUM) in get_printer()
569 attr = attr->next; in get_printer()
573 !_cups_strcasecmp(name, info_attr->values[0].string.text)) in get_printer()
579 strlcpy(dest, name_attr->values[0].string.text, destsize); in get_printer()
582 *accepting = accepting_attr->values[0].boolean; in get_printer()
585 *shared = shared_attr->values[0].boolean; in get_printer()
588 *state = (ipp_pstate_t)state_attr->values[0].integer; in get_printer()
600 return (-1); in get_printer()
613 if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", in get_printer()
615 syslog(LOG_ERR, "No printer-is-accepting-jobs attribute found in " in get_printer()
618 *accepting = attr->values[0].boolean; in get_printer()
623 if ((attr = ippFindAttribute(response, "printer-is-shared", in get_printer()
626 syslog(LOG_ERR, "No printer-is-shared attribute found in " in get_printer()
631 *shared = attr->values[0].boolean; in get_printer()
636 if ((attr = ippFindAttribute(response, "printer-state", in get_printer()
638 syslog(LOG_ERR, "No printer-state attribute found in " in get_printer()
641 *state = (ipp_pstate_t)attr->values[0].integer; in get_printer()
681 * If this is our destination, parse the options and break out of in get_printer()
682 * the loop - we're done! in get_printer()
707 * 'print_file()' - Add a file to the current job.
710 static int /* O - 0 on success, -1 on failure */
711 print_file(http_t *http, /* I - HTTP connection */ in print_file()
712 int id, /* I - Job ID */ in print_file()
713 const char *filename, /* I - File to print */ in print_file()
714 const char *docname, /* I - document-name */ in print_file()
715 const char *user, /* I - requesting-user-name */ in print_file()
716 const char *format, /* I - document-format */ in print_file()
717 int last) /* I - 1 = last file in job */ in print_file()
724 * Setup the Send-Document request... in print_file()
730 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); in print_file()
733 "requesting-user-name", NULL, user); in print_file()
737 "document-name", NULL, docname); in print_file()
741 "document-format", NULL, format); in print_file()
743 ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", (char)last); in print_file()
755 syslog(LOG_ERR, "Unable to send document - %s", cupsLastErrorString()); in print_file()
757 return (-1); in print_file()
765 * 'recv_print_job()' - Receive a print job from the client.
768 static int /* O - Command status */
770 const char *queue, /* I - Printer name */ in recv_print_job()
771 int num_defaults, /* I - Number of default options */ in recv_print_job()
772 cups_option_t *defaults) /* I - Default options */ in recv_print_job()
776 int status; /* Command status */ in recv_print_job()
783 command, /* Command from line */ in recv_print_job() local
788 char control[1024], /* Control filename */ in recv_print_job() local
795 int accepting, /* printer-is-accepting */ in recv_print_job()
796 shared, /* printer-is-shared */ in recv_print_job()
848 fd = -1; in recv_print_job()
850 control[0] = '\0'; in recv_print_job()
860 command = line[0]; in recv_print_job()
867 switch (command) in recv_print_job()
874 case 0x02 : /* Receive control file */ in recv_print_job()
877 syslog(LOG_ERR, "Bad control file name \"%s\"", name); in recv_print_job()
883 if (control[0]) in recv_print_job()
886 * Append to the existing control file - the LPD spec is in recv_print_job()
888 * multiple control files per connection... in recv_print_job()
891 if ((fd = open(control, O_WRONLY)) < 0) in recv_print_job()
894 "Unable to append to temporary control file \"%s\" - %s", in recv_print_job()
895 control, strerror(errno)); in recv_print_job()
905 if ((fd = cupsTempFd(control, sizeof(control))) < 0) in recv_print_job()
907 syslog(LOG_ERR, "Unable to open temporary control file \"%s\" - %s", in recv_print_job()
908 control, strerror(errno)); in recv_print_job()
914 strlcpy(filename, control, sizeof(filename)); in recv_print_job()
943 syslog(LOG_ERR, "Unable to open temporary data file \"%s\" - %s", in recv_print_job()
962 * Copy the data or control file from the client... in recv_print_job()
965 for (total = (size_t)strtoll(count, NULL, 10); total > 0; total -= (size_t)bytes) in recv_print_job()
977 syslog(LOG_ERR, "Error while reading file - %s", in recv_print_job()
993 syslog(LOG_ERR, "Error while reading trailing nul - %s", in recv_print_job()
1005 * Close the file and send an acknowledgement... in recv_print_job()
1019 * Process the control file and print stuff... in recv_print_job()
1022 if ((fp = fopen(control, "rb")) == NULL) in recv_print_job()
1047 * Process control lines... in recv_print_job()
1066 * If a banner was requested and it's not overridden by a in recv_print_job()
1067 * command line option and the destination's default is none in recv_print_job()
1071 if (cupsGetOption("job-sheets", num_defaults, defaults) == NULL && in recv_print_job()
1072 ((job_sheets = cupsGetOption("job-sheets", num_options, in recv_print_job()
1076 num_options = cupsAddOption("job-sheets", "standard", in recv_print_job()
1085 case 'l' : /* Print file leaving control characters (raw) */ in recv_print_job()
1089 case 'r' : /* File to print with FORTRAN carriage control */ in recv_print_job()
1095 !cupsGetOption("document-format", num_options, options)) in recv_print_job()
1139 * Process control lines... in recv_print_job()
1152 case 'l' : /* Print file leaving control characters (raw) */ in recv_print_job()
1156 case 'r' : /* File to print with FORTRAN carriage control */ in recv_print_job()
1180 cupsGetOption("document-format", num_options, in recv_print_job()
1204 * Clean up all temporary files and return... in recv_print_job()
1207 unlink(control); in recv_print_job()
1217 * 'remove_jobs()' - Cancel one or more jobs.
1220 static int /* O - Command status */
1221 remove_jobs(const char *dest, /* I - Destination */ in remove_jobs()
1222 const char *agent, /* I - User agent */ in remove_jobs()
1223 const char *list) /* I - List of jobs or users */ in remove_jobs()
1263 * attributes-charset in remove_jobs()
1264 * attributes-natural-language in remove_jobs()
1265 * job-uri in remove_jobs()
1266 * requesting-user-name in remove_jobs()
1272 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); in remove_jobs()
1275 "requesting-user-name", NULL, agent); in remove_jobs()
1278 * Do the request and get back a response... in remove_jobs()
1301 * 'send_state()' - Send the queue state.
1304 static int /* O - Command status */
1305 send_state(const char *queue, /* I - Destination */ in send_state()
1306 const char *list, /* I - Job or user */ in send_state()
1307 int longstatus) /* I - List of jobs or users */ in send_state()
1315 const char *jobdest, /* Pointer into job-printer-uri */ in send_state()
1316 *jobuser, /* Pointer to job-originating-user-name */ in send_state()
1317 *jobname; /* Pointer to job-name */ in send_state()
1318 ipp_jstate_t jobstate; /* job-state */ in send_state()
1319 int jobid, /* job-id */ in send_state()
1320 jobsize, /* job-k-octets */ in send_state()
1343 "job-id", in send_state()
1344 "job-k-octets", in send_state()
1345 "job-state", in send_state()
1346 "job-printer-uri", in send_state()
1347 "job-originating-user-name", in send_state()
1348 "job-name", in send_state()
1366 * Get the actual destination name and printer state... in send_state()
1387 printf("%s is ready and printing\n", dest); in send_state()
1398 * attributes-charset in send_state()
1399 * attributes-natural-language in send_state()
1400 * job-uri or printer-uri in send_state()
1410 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", in send_state()
1414 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", id); in send_state()
1418 "requesting-user-name", NULL, list); in send_state()
1419 ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); in send_state()
1423 "requested-attributes", in send_state()
1428 * Do the request and get back a response... in send_state()
1436 printf("get-jobs failed: %s\n", cupsLastErrorString()); in send_state()
1442 * Loop through the job list and display them... in send_state()
1445 for (attr = response->attrs, rank = 1; attr; attr = attr->next) in send_state()
1451 while (attr && (attr->group_tag != IPP_TAG_JOB || !attr->name)) in send_state()
1452 attr = attr->next; in send_state()
1469 while (attr && attr->group_tag == IPP_TAG_JOB) in send_state()
1471 if (!strcmp(attr->name, "job-id") && in send_state()
1472 attr->value_tag == IPP_TAG_INTEGER) in send_state()
1473 jobid = attr->values[0].integer; in send_state()
1475 if (!strcmp(attr->name, "job-k-octets") && in send_state()
1476 attr->value_tag == IPP_TAG_INTEGER) in send_state()
1477 jobsize = attr->values[0].integer; in send_state()
1479 if (!strcmp(attr->name, "job-state") && in send_state()
1480 attr->value_tag == IPP_TAG_ENUM) in send_state()
1481 jobstate = (ipp_jstate_t)attr->values[0].integer; in send_state()
1483 if (!strcmp(attr->name, "job-printer-uri") && in send_state()
1484 attr->value_tag == IPP_TAG_URI) in send_state()
1485 if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) in send_state()
1488 if (!strcmp(attr->name, "job-originating-user-name") && in send_state()
1489 attr->value_tag == IPP_TAG_NAME) in send_state()
1490 jobuser = attr->values[0].string.text; in send_state()
1492 if (!strcmp(attr->name, "job-name") && in send_state()
1493 attr->value_tag == IPP_TAG_NAME) in send_state()
1494 jobname = attr->values[0].string.text; in send_state()
1496 if (!strcmp(attr->name, "copies") && in send_state()
1497 attr->value_tag == IPP_TAG_INTEGER) in send_state()
1498 jobcopies = attr->values[0].integer; in send_state()
1500 attr = attr->next; in send_state()
1542 printf("%s: %-33.33s [job %d localhost]\n", jobuser, rankstr, jobid); in send_state()
1543 printf(" %-39.39s %.0f bytes\n", namestr, 1024.0 * jobsize); in send_state()
1546 printf("%-7s %-7.7s %-7d %-31.31s %.0f bytes\n", rankstr, jobuser, in send_state()
1565 * 'smart_gets()' - Get a line of text, removing the trailing CR and/or LF.
1568 static char * /* O - Line read or NULL */
1569 smart_gets(char *s, /* I - Pointer to line buffer */ in smart_gets()
1570 int len, /* I - Size of line buffer */ in smart_gets()
1571 FILE *fp) /* I - File to read from */ in smart_gets()
1586 end = s + len - 1; in smart_gets()
1619 * 'smart_strlcpy()' - Copy a string and convert from ISO-8859-1 to UTF-8 as needed.
1623 smart_strlcpy(char *dst, /* I - Output buffer */ in smart_strlcpy()
1624 const char *src, /* I - Input string */ in smart_strlcpy()
1625 size_t dstsize) /* I - Size of output buffer */ in smart_strlcpy()
1630 int saw_8859 = 0; /* Saw an extended character that was not UTF-8? */ in smart_strlcpy()
1633 …for (srcptr = (unsigned char *)src, dstptr = (unsigned char *)dst, dstend = dstptr + dstsize - 1; … in smart_strlcpy()
1640 * Map ISO-8859-1 (most likely character set for legacy LPD clients) to in smart_strlcpy()
1641 * UTF-8... in smart_strlcpy()
1644 if (dstptr > (dstend - 2)) in smart_strlcpy()
1653 * 2-byte UTF-8 sequence... in smart_strlcpy()
1656 if (dstptr > (dstend - 2)) in smart_strlcpy()
1665 * 3-byte UTF-8 sequence... in smart_strlcpy()
1668 if (dstptr > (dstend - 3)) in smart_strlcpy()
1678 * 4-byte UTF-8 sequence... in smart_strlcpy()
1681 if (dstptr > (dstend - 4)) in smart_strlcpy()
1692 * Bad UTF-8 sequence, this must be an ISO-8859-1 string... in smart_strlcpy()
1697 if (dstptr > (dstend - 2)) in smart_strlcpy()