/vp_plugins/sptsd/samples/lpr.c.smp

http://cupsfilter.googlecode.com/ · Unknown · 431 lines · 371 code · 60 blank · 0 comment · 0 complexity · 0c03bba9b5e36919ec607089bcdfa43d MD5 · raw file

  1. /*
  2. * "$Id: lpr.c 7720 2008-07-11 22:46:21Z mike $"
  3. *
  4. * "lpr" command for the Common UNIX Printing System (CUPS).
  5. *
  6. * Copyright 2007-2008 by Apple Inc.
  7. * Copyright 1997-2007 by Easy Software Products.
  8. *
  9. * These coded instructions, statements, and computer programs are the
  10. * property of Apple Inc. and are protected by Federal copyright
  11. * law. Distribution and use rights are outlined in the file "LICENSE.txt"
  12. * which should have been included with this file. If this file is
  13. * file is missing or damaged, see the license at "http://www.cups.org/".
  14. *
  15. * Contents:
  16. *
  17. * main() - Parse options and send files for printing.
  18. */
  19. /*
  20. * Include necessary headers...
  21. */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <errno.h>
  25. #include <cups/string.h>
  26. #include <cups/cups.h>
  27. #include <cups/i18n.h>
  28. /*
  29. * 'main()' - Parse options and send files for printing.
  30. */
  31. int
  32. main(int argc, /* I - Number of command-line arguments */
  33. char *argv[]) /* I - Command-line arguments */
  34. {
  35. int i, j; /* Looping var */
  36. int job_id; /* Job ID */
  37. char ch; /* Option character */
  38. char *printer, /* Destination printer or class */
  39. *instance; /* Instance */
  40. const char *title, /* Job title */
  41. *val; /* Environment variable name */
  42. int num_copies; /* Number of copies per file */
  43. int num_files; /* Number of files to print */
  44. const char *files[1000]; /* Files to print */
  45. cups_dest_t *dest; /* Selected destination */
  46. int num_options; /* Number of options */
  47. cups_option_t *options; /* Options */
  48. int deletefile; /* Delete file after print? */
  49. char buffer[8192]; /* Copy buffer */
  50. _cupsSetLocale(argv);
  51. deletefile = 0;
  52. printer = NULL;
  53. dest = NULL;
  54. num_options = 0;
  55. options = NULL;
  56. num_files = 0;
  57. title = NULL;
  58. for (i = 1; i < argc; i ++)
  59. if (argv[i][0] == '-')
  60. switch (ch = argv[i][1])
  61. {
  62. case 'E' : /* Encrypt */
  63. #ifdef HAVE_SSL
  64. cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
  65. #else
  66. _cupsLangPrintf(stderr,
  67. _("%s: Sorry, no encryption support compiled in!\n"),
  68. argv[0]);
  69. #endif /* HAVE_SSL */
  70. break;
  71. case 'U' : /* Username */
  72. if (argv[i][2] != '\0')
  73. cupsSetUser(argv[i] + 2);
  74. else
  75. {
  76. i ++;
  77. if (i >= argc)
  78. {
  79. _cupsLangPrintf(stderr,
  80. _("%s: Error - expected username after "
  81. "\'-U\' option!\n"),
  82. argv[0]);
  83. return (1);
  84. }
  85. cupsSetUser(argv[i]);
  86. }
  87. break;
  88. case 'H' : /* Connect to host */
  89. if (argv[i][2] != '\0')
  90. cupsSetServer(argv[i] + 2);
  91. else
  92. {
  93. i ++;
  94. if (i >= argc)
  95. {
  96. _cupsLangPrintf(stderr,
  97. _("%s: Error - expected hostname after "
  98. "\'-H\' option!\n"),
  99. argv[0]);
  100. return (1);
  101. }
  102. else
  103. cupsSetServer(argv[i]);
  104. }
  105. break;
  106. case '1' : /* TROFF font set 1 */
  107. case '2' : /* TROFF font set 2 */
  108. case '3' : /* TROFF font set 3 */
  109. case '4' : /* TROFF font set 4 */
  110. case 'i' : /* indent */
  111. case 'w' : /* width */
  112. if (argv[i][2] == '\0')
  113. {
  114. i ++;
  115. if (i >= argc)
  116. {
  117. _cupsLangPrintf(stderr,
  118. _("%s: Error - expected value after \'-%c\' "
  119. "option!\n"), argv[0], ch);
  120. return (1);
  121. }
  122. }
  123. case 'c' : /* CIFPLOT */
  124. case 'd' : /* DVI */
  125. case 'f' : /* FORTRAN */
  126. case 'g' : /* plot */
  127. case 'n' : /* Ditroff */
  128. case 't' : /* Troff */
  129. case 'v' : /* Raster image */
  130. _cupsLangPrintf(stderr,
  131. _("%s: Warning - \'%c\' format modifier not "
  132. "supported - output may not be correct!\n"),
  133. argv[0], ch);
  134. break;
  135. case 'o' : /* Option */
  136. if (argv[i][2] != '\0')
  137. num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
  138. else
  139. {
  140. i ++;
  141. if (i >= argc)
  142. {
  143. _cupsLangPrintf(stderr,
  144. _("%s: error - expected option=value after "
  145. "\'-o\' option!\n"),
  146. argv[0]);
  147. return (1);
  148. }
  149. num_options = cupsParseOptions(argv[i], num_options, &options);
  150. }
  151. break;
  152. case 'l' : /* Literal/raw */
  153. num_options = cupsAddOption("raw", "true", num_options, &options);
  154. break;
  155. case 'p' : /* Prettyprint */
  156. num_options = cupsAddOption("prettyprint", "true", num_options,
  157. &options);
  158. break;
  159. case 'h' : /* Suppress burst page */
  160. num_options = cupsAddOption("job-sheets", "none", num_options,
  161. &options);
  162. break;
  163. case 's' : /* Don't use symlinks */
  164. break;
  165. case 'm' : /* Mail on completion */
  166. {
  167. char email[1024]; /* EMail address */
  168. snprintf(email, sizeof(email), "mailto:%s@%s", cupsUser(),
  169. httpGetHostname(NULL, buffer, sizeof(buffer)));
  170. num_options = cupsAddOption("notify-recipient-uri", email,
  171. num_options, &options);
  172. }
  173. break;
  174. case 'q' : /* Queue file but don't print */
  175. num_options = cupsAddOption("job-hold-until", "indefinite",
  176. num_options, &options);
  177. break;
  178. case 'r' : /* Remove file after printing */
  179. deletefile = 1;
  180. break;
  181. case 'P' : /* Destination printer or class */
  182. if (argv[i][2] != '\0')
  183. printer = argv[i] + 2;
  184. else
  185. {
  186. i ++;
  187. if (i >= argc)
  188. {
  189. _cupsLangPrintf(stderr,
  190. _("%s: Error - expected destination after "
  191. "\'-P\' option!\n"),
  192. argv[0]);
  193. return (1);
  194. }
  195. printer = argv[i];
  196. }
  197. if ((instance = strrchr(printer, '/')) != NULL)
  198. *instance++ = '\0';
  199. if ((dest = cupsGetNamedDest(NULL, printer, instance)) != NULL)
  200. {
  201. for (j = 0; j < dest->num_options; j ++)
  202. if (cupsGetOption(dest->options[j].name, num_options,
  203. options) == NULL)
  204. num_options = cupsAddOption(dest->options[j].name,
  205. dest->options[j].value,
  206. num_options, &options);
  207. }
  208. break;
  209. case '#' : /* Number of copies */
  210. if (argv[i][2] != '\0')
  211. num_copies = atoi(argv[i] + 2);
  212. else
  213. {
  214. i ++;
  215. if (i >= argc)
  216. {
  217. _cupsLangPrintf(stderr,
  218. _("%s: Error - expected copy count after "
  219. "\'-#\' option!\n"),
  220. argv[0]);
  221. return (1);
  222. }
  223. num_copies = atoi(argv[i]);
  224. }
  225. sprintf(buffer, "%d", num_copies);
  226. num_options = cupsAddOption("copies", buffer, num_options, &options);
  227. break;
  228. case 'C' : /* Class */
  229. case 'J' : /* Job name */
  230. case 'T' : /* Title */
  231. if (argv[i][2] != '\0')
  232. title = argv[i] + 2;
  233. else
  234. {
  235. i ++;
  236. if (i >= argc)
  237. {
  238. _cupsLangPrintf(stderr,
  239. _("%s: Error - expected name after \'-%c\' "
  240. "option!\n"), argv[0], ch);
  241. return (1);
  242. }
  243. title = argv[i];
  244. }
  245. break;
  246. default :
  247. _cupsLangPrintf(stderr,
  248. _("%s: Error - unknown option \'%c\'!\n"),
  249. argv[0], argv[i][1]);
  250. return (1);
  251. }
  252. else if (num_files < 1000)
  253. {
  254. /*
  255. * Print a file...
  256. */
  257. if (access(argv[i], R_OK) != 0)
  258. {
  259. _cupsLangPrintf(stderr,
  260. _("%s: Error - unable to access \"%s\" - %s\n"),
  261. argv[0], argv[i], strerror(errno));
  262. return (1);
  263. }
  264. files[num_files] = argv[i];
  265. num_files ++;
  266. if (title == NULL)
  267. {
  268. if ((title = strrchr(argv[i], '/')) != NULL)
  269. title ++;
  270. else
  271. title = argv[i];
  272. }
  273. }
  274. else
  275. _cupsLangPrintf(stderr,
  276. _("%s: Error - too many files - \"%s\"\n"),
  277. argv[0], argv[i]);
  278. /*
  279. * See if we have any files to print; if not, print from stdin...
  280. */
  281. if (printer == NULL)
  282. {
  283. if ((dest = cupsGetNamedDest(NULL, NULL, NULL)) != NULL)
  284. {
  285. printer = dest->name;
  286. for (j = 0; j < dest->num_options; j ++)
  287. if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
  288. num_options = cupsAddOption(dest->options[j].name,
  289. dest->options[j].value,
  290. num_options, &options);
  291. }
  292. }
  293. if (printer == NULL)
  294. {
  295. val = NULL;
  296. if ((printer = getenv("LPDEST")) == NULL)
  297. {
  298. if ((printer = getenv("PRINTER")) != NULL)
  299. {
  300. if (!strcmp(printer, "lp"))
  301. printer = NULL;
  302. else
  303. val = "PRINTER";
  304. }
  305. }
  306. else
  307. val = "LPDEST";
  308. if (printer && !cupsGetNamedDest(NULL, printer, NULL))
  309. _cupsLangPrintf(stderr,
  310. _("%s: Error - %s environment variable names "
  311. "non-existent destination \"%s\"!\n"),
  312. argv[0], val, printer);
  313. else if (cupsLastError() == IPP_NOT_FOUND)
  314. _cupsLangPrintf(stderr,
  315. _("%s: Error - no default destination available.\n"),
  316. argv[0]);
  317. else
  318. _cupsLangPrintf(stderr,
  319. _("%s: Error - scheduler not responding!\n"),
  320. argv[0]);
  321. return (1);
  322. }
  323. if (num_files > 0)
  324. {
  325. job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
  326. if (deletefile && job_id > 0)
  327. {
  328. /*
  329. * Delete print files after printing...
  330. */
  331. for (i = 0; i < num_files; i ++)
  332. unlink(files[i]);
  333. }
  334. }
  335. else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
  336. title ? title : "(stdin)",
  337. num_options, options)) > 0)
  338. {
  339. http_status_t status; /* Write status */
  340. const char *format; /* Document format */
  341. ssize_t bytes; /* Bytes read */
  342. if (cupsGetOption("raw", num_options, options))
  343. format = CUPS_FORMAT_RAW;
  344. else if ((format = cupsGetOption("document-format", num_options,
  345. options)) == NULL)
  346. format = CUPS_FORMAT_AUTO;
  347. status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
  348. format, 1);
  349. while (status == HTTP_CONTINUE &&
  350. (bytes = read(0, buffer, sizeof(buffer))) > 0)
  351. status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes);
  352. if (status != HTTP_CONTINUE)
  353. {
  354. _cupsLangPrintf(stderr,
  355. _("%s: Error - unable to queue from stdin - %s\n"),
  356. argv[0], httpStatus(status));
  357. return (1);
  358. }
  359. if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
  360. job_id = 0;
  361. }
  362. if (job_id < 1)
  363. {
  364. _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString());
  365. return (1);
  366. }
  367. return (0);
  368. }
  369. /*
  370. * End of "$Id: lpr.c 7720 2008-07-11 22:46:21Z mike $".
  371. */