Guest User

bjcups.c

a guest
Jan 19th, 2014
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.74 KB | None | 0 0
  1. /*
  2. * CUPS add-on module for Canon Inkjet Printer.
  3. * Copyright CANON INC. 2001-2013
  4. * All Rights Reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #if HAVE_CONFIG_H
  21. #include <config.h>
  22. #endif // HAVE_CONFIG_H
  23.  
  24. #include <cups/cups.h>
  25. #include <cups/language.h>
  26. #include <cups/ppd.h>
  27. #include <cups/ipp.h>
  28. #include <unistd.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <popt.h>
  32. #include <sys/types.h>
  33. #include <sys/wait.h>
  34.  
  35. #include "cncl.h"
  36. #include "cncldef.h"
  37. #include "cncl2def.h"
  38. #include "cncludef.h"
  39. #include "cnclucom.h"
  40.  
  41. #include "paramlist.h"
  42. #include "bjipc.h"
  43. #include "bjcups.h"
  44. #include "bjutil.h"
  45.  
  46. #define BJCUPS_VERSION "cngpij Ver.3.90 Copyright CANON INC. 2002-2013\n"
  47. #define BJCUPS_INTVER "cngpij Internal Version : 3.90.01.001\n"
  48.  
  49. #define BJ_SOCKET "/tmp/ijui"
  50.  
  51. #define UI_PATH PROG_PATH
  52. //#define UI_PATH "/usr/local/bin/"
  53. #define UI_SLASH "/"
  54. #define UI_NAME "printui"
  55.  
  56. #define UI_OPT_VERSION 1
  57. #define UI_OPT_PRINTER 2
  58. #define UI_OPT_OTHERS 4
  59. #define UI_OPT_INTVER 8
  60. #define UI_OPT_CHECKENTRY 16
  61.  
  62. #define LINE_BUF_SIZE 1024
  63. #define CNPPD_SETTINGS_SUPPORT_DEVURI_OPT "EnableDEVURIOption"
  64. #define CNPPD_SETTINGS_SUPPORT_FRONTEND_OPT "EnableFrontEnd" /* Ver.3.80 */
  65. #define TRUE 1
  66. #define FALSE 0
  67.  
  68. char* g_printer_name = NULL;
  69.  
  70.  
  71. extern int GetIPCData(LPIPCU pipc, char *sname);
  72. static short getDeviceURI( const char *pDestName, char *pDeviceURI, short bufSize);
  73.  
  74.  
  75. int get_value_and_param_array(short id, short** value, char*** param)
  76. {
  77. int count;
  78.  
  79. switch( id )
  80. {
  81. case CNCL_MEDIATYPE: // Media Type.
  82. *value = g_media_value;
  83. *param = g_media_param;
  84. count = sizeof(g_media_value) / sizeof(short);
  85. break;
  86.  
  87. case CNCL_MEDIASUPPLY: // Media Supply.
  88. *value = g_supply_value;
  89. *param = g_supply_param;
  90. count = sizeof(g_supply_value) / sizeof(short);
  91. break;
  92.  
  93. case CNCL_PAPERSIZE: // Paper Size.
  94. *value = g_size_value;
  95. *param = g_size_param;
  96. count = sizeof(g_size_value) / sizeof(short);
  97. break;
  98.  
  99. case CNCL_DITHER_PAT: // Halftoning.
  100. *value = g_halftoning_value;
  101. *param = g_halftoning_param;
  102. count = sizeof(g_halftoning_value) / sizeof(short);
  103. break;
  104.  
  105. case CNCL_CARTRIDGE: // Cartridge.
  106. *value = g_cartridge_value;
  107. *param = g_cartridge_param;
  108. count = sizeof(g_cartridge_value) / sizeof(short);
  109. break;
  110.  
  111. case CNCL_PRINTQUALITY: // Print quality.
  112. *value = g_quality_value;
  113. *param = g_quality_param;
  114. count = sizeof(g_quality_value) / sizeof(short);
  115. break;
  116.  
  117. case CNCL_INPUT_GAMMA: // Input gamma.
  118. *value = g_input_gamma_value;
  119. *param = g_input_gamma_param;
  120. count = sizeof(g_input_gamma_value) / sizeof(short);
  121. break;
  122.  
  123. case CNCL_GRAYSCALE: // Grayscale.
  124. *value = g_grayscale_value;
  125. *param = g_grayscale_param;
  126. count = sizeof(g_grayscale_value) / sizeof(short);
  127. break;
  128.  
  129. case CNCL_PAPERGAP_COMMAND: // Paper gap.
  130. *value = g_paper_gap_value;
  131. *param = g_paper_gap_param;
  132. count = sizeof(g_paper_gap_value) / sizeof(short);
  133. break;
  134.  
  135. case CNCL_DUPLEX_PRINTING: // Duplex printing.
  136. *value = g_duplex_value;
  137. *param = g_duplex_param;
  138. count = sizeof(g_duplex_value) / sizeof(short);
  139. break;
  140.  
  141. case EXT_CNCL_INTENT: // Intent.
  142. *value = g_intent_value;
  143. *param = g_intent_param;
  144. count = sizeof(g_intent_value) / sizeof(short);
  145. break;
  146.  
  147. case EXT_CNCL_LOCATION: // Location.
  148. *value = g_location_value;
  149. *param = g_location_param_lpr; /* Ver.3.00 */
  150. count = sizeof(g_location_value) / sizeof(short);
  151. break;
  152.  
  153. case EXT_CNCL_STAPLESIDE: // Staple side.
  154. *value = g_staple_side_value;
  155. *param = g_staple_side_param;
  156. count = sizeof(g_staple_side_value) / sizeof(short);
  157. break;
  158.  
  159. case CNCL_INKCARTRIDGESETTINGS: // InkCartridgeSettings.
  160. *value = g_cartridge_value;
  161. *param = g_cartridge_param;
  162. count = sizeof(g_cartridge_value) / sizeof(short);
  163. break;
  164.  
  165. default:
  166. *value = NULL;
  167. *param = NULL;
  168. count = 0;
  169. break;
  170. }
  171.  
  172. return count;
  173. }
  174.  
  175. char *value_to_param(short id, short value)
  176. {
  177. short *value_array;
  178. char **key_array;
  179. int count;
  180. int i;
  181.  
  182. count = get_value_and_param_array(id, &value_array, &key_array);
  183.  
  184. for( i = 0 ; i < count ; i++ )
  185. {
  186. if( value_array[i] == value )
  187. break;
  188. }
  189. return (i < count)? key_array[i] : "";
  190. }
  191.  
  192. void add_option_param(ParamList **pp_list, char *key, int id, int value)
  193. {
  194. char param[1024];
  195.  
  196. snprintf(param, 1023, "%s=%s", key, value_to_param(id, value));
  197. param_list_add_multi(pp_list, "-o", param, strlen(param) + 1, 1);
  198. }
  199.  
  200. /* Ver.3.00 */
  201. void add_option_param_bl(ParamList **pp_list, char *key, int id, int value)
  202. {
  203. char param[1024];
  204.  
  205. snprintf(param, 1023, "%s=%s.bl", key, value_to_param(id, value));
  206. param_list_add_multi(pp_list, "-o", param, strlen(param) + 1, 1);
  207. }
  208.  
  209.  
  210. void add_option_value(ParamList **pp_list, char *key, int value)
  211. {
  212. char param[1024];
  213.  
  214. snprintf(param, 1023, "%s=%d", key, value);
  215. param_list_add_multi(pp_list, "-o", param, strlen(param) + 1, 1);
  216. }
  217.  
  218. void add_option_string(ParamList **pp_list, char *key, char *str)
  219. {
  220. char param[1024];
  221.  
  222. snprintf(param, 1023, "%s=%s", key, str);
  223. param_list_add_multi(pp_list, "-o", param, strlen(param) + 1, 1);
  224. }
  225.  
  226.  
  227. /* Ver.3.20 */
  228. static void char_lower( char *string, short len )
  229. {
  230. short count;
  231. short dis;
  232. char *current_char = string;
  233.  
  234. dis='a'-'A';
  235.  
  236. for( count = 0; count < len ; count++ )
  237. {
  238. if( (*current_char >= 'A') && (*current_char <= 'Z') ) *current_char += dis;
  239. current_char++;
  240. }
  241. }
  242.  
  243.  
  244. /* Ver.3.20:check entry exist or not (use cupsGetDests2) */
  245. static short check_entry_name(const char *printer_name)
  246. {
  247. http_t *pHTTP = NULL; // Pointer to HTTP connection.
  248. int num = 0;
  249. int count;
  250. cups_dest_t *dests = NULL;
  251. cups_dest_t *current_dests;
  252. char target_name[256];
  253. char compare_name[256];
  254. short target_name_len;
  255. short result = 1; /* not exist */
  256. char devURIBuf[10224];
  257.  
  258. getDeviceURI( printer_name, devURIBuf, sizeof(devURIBuf) );
  259.  
  260. target_name_len = strlen( printer_name );
  261. if( target_name_len > 255 )
  262. {
  263. fputs("ERROR: too long name\n", stderr);
  264. goto onErr;
  265. }
  266.  
  267. memset( target_name , 0x00 , 256 );
  268. strncpy( target_name , printer_name , target_name_len );
  269. char_lower( target_name , target_name_len );
  270.  
  271.  
  272. pHTTP = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
  273. if( pHTTP == NULL){
  274. fputs("ERROR: IPP ERROR\n", stderr);
  275. goto onErr;
  276. }
  277. else
  278. {
  279. num = cupsGetDests2( pHTTP , &dests );
  280. current_dests = dests;
  281. for( count = 0; count < num ; count++ )
  282. {
  283. memset( compare_name , 0x00 , 256 );
  284.  
  285. if( strlen(current_dests->name) == target_name_len ) /* length compare first */
  286. {
  287. strncpy( compare_name , current_dests->name , strlen( current_dests->name ) );
  288. char_lower( compare_name , strlen( compare_name ) );
  289.  
  290.  
  291. if( !strncmp( target_name , compare_name , target_name_len ) )
  292. {
  293. result = 0; /* exist */
  294. goto onErr;
  295. }
  296. }
  297. else
  298. {
  299. }
  300. current_dests++;
  301. }
  302. }
  303.  
  304. onErr:
  305. if( pHTTP != NULL ) httpClose(pHTTP);
  306. if( dests != NULL ) cupsFreeDests(num,dests);
  307.  
  308. return result;
  309. }
  310.  
  311.  
  312.  
  313. int init_option(ParamList **pp_list, int argc, char* argv[])
  314. {
  315. static struct poptOption option_table[] =
  316. {
  317. {"version", 'v', 0, NULL, UI_OPT_VERSION},
  318. {"internalversion", 0, POPT_ARG_NONE, NULL, UI_OPT_INTVER }, /* Ver.2.70 */
  319. {"checkentryexist", 0, POPT_ARG_STRING, NULL, UI_OPT_CHECKENTRY }, /* Ver.3.20 */
  320. {NULL, 'P', POPT_ARG_STRING, NULL, UI_OPT_PRINTER},
  321. {NULL, 'o', POPT_ARG_STRING, NULL, UI_OPT_OTHERS },
  322. {NULL, 0, 0, NULL, 0}
  323. };
  324.  
  325. poptContext context
  326. = poptGetContext("cngpij", argc, (const char**)argv, option_table, 0);
  327. int rc;
  328.  
  329. while( (rc = poptGetNextOpt(context)) > 0 )
  330. {
  331. switch( rc )
  332. {
  333. case UI_OPT_VERSION:
  334. fputs(BJCUPS_VERSION, stderr);
  335. exit(1);
  336.  
  337. case UI_OPT_CHECKENTRY:
  338. {
  339. g_printer_name = strdup(poptGetOptArg(context));
  340. if( check_entry_name(g_printer_name) == 1 )
  341. {
  342. fputs("ERROR: Illegal printer name.\n", stderr);
  343. exit(1);
  344. }
  345. else{
  346. fputs("Exist\n", stderr);
  347. exit(0);
  348. }
  349. }
  350. case UI_OPT_PRINTER:
  351. g_printer_name = strdup(poptGetOptArg(context));
  352. break;
  353.  
  354. case UI_OPT_OTHERS:
  355. {
  356. const char *option = poptGetOptArg(context);
  357. param_list_add(pp_list, "-o", option, strlen(option) + 1);
  358. break;
  359. }
  360. case UI_OPT_INTVER:
  361. {
  362. fputs(BJCUPS_INTVER, stderr);
  363. exit(1);
  364. }
  365. default:
  366. break;
  367. }
  368. }
  369.  
  370. if( rc < -1 )
  371. {
  372. fprintf(stderr, "Unknown switch, %s\n",
  373. poptBadOption(context, POPT_BADOPTION_NOALIAS));
  374.  
  375. return rc;
  376. }
  377. return 0;
  378. }
  379.  
  380. static
  381. char *parse_product_name(char *ppd_product, char *product, int len)
  382. {
  383. char *p_product = product;
  384. char *p_cc;
  385. int count = 0;
  386.  
  387. memset(product, 0, len);
  388. p_cc = ppd_product;
  389.  
  390. while( *p_cc == '(' )
  391. p_cc++;
  392.  
  393. while( *p_cc != ')' && *p_cc != '\0' && count < len - 1 )
  394. {
  395. *p_product++ = *p_cc++;
  396. count++;
  397. }
  398. *p_product = '\0';
  399.  
  400. return product;
  401. }
  402.  
  403. char *get_product_name(const char *printer_name, char *product_name, int len)
  404. {
  405. const char *ppd_name = cupsGetPPD(printer_name);
  406. char *p_product = NULL;
  407. static char product[256];
  408.  
  409. if( len < 1 )
  410. return NULL;
  411.  
  412. if( ppd_name != NULL )
  413. {
  414. ppd_file_t *p_ppd;
  415.  
  416. if( (p_ppd = ppdOpenFile(ppd_name)) != NULL )
  417. {
  418. if( !strcmp(p_ppd->manufacturer, "Canon") )
  419. {
  420. p_product = parse_product_name(p_ppd->product, product, 256);
  421. strncpy(product_name, product, len - 1);
  422. }
  423. ppdClose(p_ppd);
  424. }
  425. unlink( ppd_name ); /* Ver.3.00 : You should remove the copy of the PPD file. */
  426.  
  427. }
  428. return p_product;
  429. }
  430.  
  431. void get_paper_dimension_points(IPCU *p_ipc, double *p_pw, double* p_ph)
  432. {
  433. BJFLTDEVICE *p_fltdev = &p_ipc->parm.bjfltdev;
  434. CNCLPAPERSIZE *p_papersize = &p_ipc->parm.papersize;
  435. double pw_pt = (double)p_fltdev->bjfltPaperWidth * 72.0 / 2540.0;
  436. double ph_pt = (double)p_fltdev->bjfltPaperHeight * 72.0 / 2540.0;
  437. long rw_mm = (long)(pw_pt * 2540.0 / 72.0);
  438. long rh_mm = (long)(ph_pt * 2540.0 / 72.0);
  439. long minw_mm = p_papersize->nMinCustomWidth;
  440. long maxw_mm = p_papersize->nMaxCustomWidth;
  441. long minh_mm = p_papersize->nMinCustomLength;
  442. long maxh_mm = p_papersize->nMaxCustomLength;
  443. long dw = 0;
  444. long dh = 0;
  445.  
  446. while( rw_mm < minw_mm )
  447. {
  448. dw++;
  449. pw_pt = (double)(p_fltdev->bjfltPaperWidth + dw) * 72.0 / 2540.0;
  450. rw_mm = (long)(pw_pt * 2540.0 / 72.0);
  451. }
  452. while( rw_mm > maxw_mm )
  453. {
  454. dw--;
  455. pw_pt = (double)(p_fltdev->bjfltPaperWidth + dw) * 72.0 / 2540.0;
  456. rw_mm = (long)(pw_pt * 2540.0 / 72.0);
  457. }
  458. while( rh_mm < minh_mm )
  459. {
  460. dh++;
  461. ph_pt = (double)(p_fltdev->bjfltPaperHeight + dh) * 72.0 / 2540.0;
  462. rh_mm = (long)(ph_pt * 2540.0 / 72.0);
  463. }
  464. while( rh_mm > maxh_mm )
  465. {
  466. dh--;
  467. ph_pt = (double)(p_fltdev->bjfltPaperHeight + dh) * 72.0 / 2540.0;
  468. rh_mm = (long)(ph_pt * 2540.0 / 72.0);
  469. }
  470.  
  471. *p_pw = pw_pt;
  472. *p_ph = ph_pt;
  473. }
  474.  
  475. char **make_lpr_param(ParamList **pp_list, char *printer,
  476. IPCU *p_ipc, char *print_file)
  477. {
  478. BJFLTDEVICE *p_fltdev = &p_ipc->parm.bjfltdev;
  479. BJFLTCOLORSYSTEM *p_fltcol = &p_ipc->parm.bjfltcolor;
  480. BJFLT_UISETUP *p_uiset = &p_ipc->parm.bjflt_uisetup;
  481. CNCLPAPERSIZE *p_papersize = &p_ipc->parm.papersize;
  482. char **cmd_buf;
  483. int cmd_buf_index;
  484. int cmd_num;
  485.  
  486. add_option_param(pp_list, "CNCartridge",
  487. CNCL_CARTRIDGE, p_fltdev->bjfltInkType);
  488.  
  489. add_option_param(pp_list, "MediaType",
  490. CNCL_MEDIATYPE, p_fltdev->bjfltMediaType);
  491.  
  492. if( p_fltdev->bjfltPaperSize == CND_SIZE_USER )
  493. {
  494. double pw, ph;
  495. char custom_size[256];
  496.  
  497. get_paper_dimension_points(p_ipc, &pw, &ph);
  498. snprintf(custom_size, 255, "Custom.%lfx%lf", pw, ph);
  499.  
  500. add_option_string(pp_list, "PageSize", custom_size);
  501. }
  502. else
  503. {
  504. /* If Borderless Printing is ON, add ".bl" to PageSize parameter. (Ver.3.00) */
  505. if( p_fltdev->bjfltMarginType == CND_MARGIN_MINUS )
  506. {
  507. add_option_param_bl(pp_list, "PageSize",
  508. CNCL_PAPERSIZE, p_fltdev->bjfltPaperSize);
  509. }else{
  510. add_option_param(pp_list, "PageSize",
  511. CNCL_PAPERSIZE, p_fltdev->bjfltPaperSize);
  512. }
  513. }
  514.  
  515. add_option_param(pp_list, "InputSlot",
  516. CNCL_MEDIASUPPLY, p_fltdev->bjfltMediaSupply);
  517.  
  518. /* Ver.3.60: disable CNHalftoning */
  519. if ( p_fltdev->bjfltBinMethod != CND_UIBIN_NA ){
  520. add_option_param(pp_list, "CNHalftoning",
  521. CNCL_DITHER_PAT, p_fltdev->bjfltBinMethod);
  522. }
  523.  
  524. add_option_param(pp_list, "CNGrayscale",
  525. CNCL_GRAYSCALE, p_fltdev->bjfltGrayScale);
  526.  
  527. add_option_param(pp_list, "CNQuality",
  528. CNCL_PRINTQUALITY, p_fltdev->bjfltPrintQuality);
  529.  
  530. add_option_param(pp_list, "CNGamma",
  531. CNCL_INPUT_GAMMA, p_fltcol->bjfltGamma);
  532.  
  533. if( p_fltdev->bjfltPaperGap != CND_PGAP_CMD_NA )
  534. {
  535. add_option_param(pp_list, "CNPaperGap",
  536. CNCL_PAPERGAP_COMMAND, p_fltdev->bjfltPaperGap);
  537. }
  538.  
  539. add_option_param(pp_list, "CNRenderIntent",
  540. EXT_CNCL_INTENT, p_fltcol->bjfltIntent);
  541.  
  542. /* Use "position" instead of "CNLocation" (Ver.3.00) */
  543. add_option_param(pp_list, "position",
  544. EXT_CNCL_LOCATION, p_uiset->bjflt_location);
  545.  
  546. if( p_fltdev->bjfltDuplex == CND_DUPLEX_AUTO )
  547. {
  548. add_option_param(pp_list, "Duplex",
  549. CNCL_DUPLEX_PRINTING, p_fltdev->bjfltDuplex);
  550.  
  551. add_option_param(pp_list, "CNStapleSide",
  552. EXT_CNCL_STAPLESIDE, p_uiset->bjflt_stapleside);
  553. }
  554.  
  555. if( p_fltdev->bjfltInkcartridgesettings != CND_CARTRIDGE_NA )
  556. {
  557. add_option_param(pp_list, "CNInkCartridgeSettings",
  558. CNCL_INKCARTRIDGESETTINGS, p_fltdev->bjfltInkcartridgesettings);
  559. }
  560.  
  561. add_option_value(pp_list, "CNBalanceC", p_fltcol->bjfltBalanceC);
  562. add_option_value(pp_list, "CNBalanceM", p_fltcol->bjfltBalanceM);
  563. add_option_value(pp_list, "CNBalanceY", p_fltcol->bjfltBalanceY);
  564.  
  565. /* Ver.2.70 */
  566. if( p_fltcol->bjfltBalanceK != 0 ) /* 0...option not supported or default value */
  567. {
  568. if( p_fltcol->bjfltBalanceK >= -50 && p_fltcol->bjfltBalanceK <= 50 ){
  569. add_option_value(pp_list, "CNBalanceK", p_fltcol->bjfltBalanceK);
  570. }
  571. }
  572.  
  573. if( p_fltcol->bjfltContrast != 0 ) /* 0...option not supported or default value */
  574. {
  575. if( p_fltcol->bjfltContrast >= -50 && p_fltcol->bjfltContrast <= 50 ){
  576. add_option_value(pp_list, "CNContrast", p_fltcol->bjfltContrast);
  577. }
  578. }
  579.  
  580. add_option_value(pp_list, "CNDensity", p_fltcol->bjfltDensity);
  581.  
  582. /* Ver.3.00 */
  583. /* Fit-to-Page Printing and Scaled Printing cannot be specified at the same time. */
  584. if( p_uiset->bjflt_fit == FIT_SHORT)
  585. {
  586. add_option_value(pp_list, "scaling", 100 ); //scaling=100
  587. }
  588. else if( p_uiset->bjflt_percent != 100)
  589. {
  590. /* If bjflt_percent is "100", "Scaled Printing" is not selected. */
  591. add_option_value(pp_list, "natural-scaling", p_uiset->bjflt_percent);
  592. }
  593.  
  594.  
  595.  
  596. /* Ver.3.00 */
  597. /* If Borderless Printing is ON, add CNExtension. */
  598. if( p_fltdev->bjfltMarginType == CND_MARGIN_MINUS )
  599. {
  600. add_option_value(pp_list, "CNExtension", p_uiset->bjflt_extension);
  601. }
  602.  
  603. /* Ver.3.40 */
  604. if( p_fltcol->bjfltMonochromeTone != 0 ){ /* 0...option not supported or default value */
  605. if( p_fltcol->bjfltMonochromeTone >= -50 && p_fltcol->bjfltMonochromeTone <= 50 ){
  606. add_option_value(pp_list, "CNTone", p_fltcol->bjfltMonochromeTone);
  607. }
  608. }
  609.  
  610. add_option_value(pp_list, "CNCopies", p_uiset->bjflt_copies);
  611.  
  612. add_option_value(pp_list, "CNMinWidth", p_papersize->nMinCustomWidth);
  613. add_option_value(pp_list, "CNMaxWidth", p_papersize->nMaxCustomWidth);
  614. add_option_value(pp_list, "CNMinLength", p_papersize->nMinCustomLength);
  615. add_option_value(pp_list, "CNMaxLength", p_papersize->nMaxCustomLength);
  616.  
  617. #ifdef DEBUG_PARAM_LIST
  618. param_list_print(*pp_list);
  619. #endif
  620. cmd_num = param_list_num(*pp_list);
  621. cmd_buf = (char**)malloc((cmd_num * 2 + 5) * sizeof(char*));
  622.  
  623. if( cmd_buf )
  624. {
  625. ParamList *curs;
  626.  
  627. cmd_buf[0] = "lpr";
  628. cmd_buf[1] = "-P";
  629. cmd_buf[2] = printer;
  630.  
  631. cmd_buf_index = 3;
  632.  
  633. for( curs = *pp_list ; curs != NULL ; curs = curs->next )
  634. {
  635. cmd_buf[cmd_buf_index++] = curs->key;
  636. cmd_buf[cmd_buf_index++] = curs->value;
  637. }
  638. cmd_buf[cmd_buf_index++] = print_file;
  639. cmd_buf[cmd_buf_index] = NULL;
  640. }
  641.  
  642. return cmd_buf;
  643. }
  644.  
  645. void exec_lpr(char **lpr_param)
  646. {
  647. int pid = fork();
  648.  
  649. if( pid == -1 )
  650. return;
  651.  
  652. if( pid == 0 )
  653. {
  654. execv("/usr/bin/lpr", lpr_param);
  655. fputs("ERROR: Can't execute lpr command.\n", stderr);
  656. }
  657. else
  658. {
  659. waitpid(pid, NULL, 0);
  660. }
  661. }
  662.  
  663.  
  664.  
  665. static cups_lang_t * bjcupsLangDefault( )
  666. {
  667. cups_lang_t *pLanguage;
  668. char *tLang;
  669.  
  670. if( (tLang = getenv("LC_ALL"))==NULL)
  671. tLang = getenv("LANG");
  672.  
  673. pLanguage = cupsLangDefault();
  674. setlocale(LC_ALL,tLang);
  675.  
  676. return pLanguage;
  677. }
  678.  
  679.  
  680.  
  681. static short getDeviceURI( const char *pDestName, char *pDeviceURI, short bufSize)
  682. {
  683. /*** Parameters start ***/
  684. http_t *pHTTP; // Pointer to HTTP connection.
  685. ipp_t *pRequest, // Pointer to CUPS IPP request.
  686. *pResponse; // Pointer to CUPS IPP response.
  687. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes.
  688. cups_lang_t *pLanguage; // Pointer to language.
  689. char *pPrinter = NULL; // Pointer to printer name.
  690. char *pDUri = NULL; // Pointer to Device uri.
  691. short retVal = -1; // Return value.
  692. /*** Parameters end ***/
  693.  
  694. // CUPS http connect.
  695. if ((pHTTP = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) {
  696. fputs("ERROR: IPP ERROR\n", stderr);
  697. goto onErr;
  698. }
  699. else {
  700. pRequest = ippNew();
  701.  
  702. pRequest->request.op.operation_id = CUPS_GET_PRINTERS;
  703. pRequest->request.op.request_id = 1;
  704.  
  705. pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19
  706.  
  707. ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage));
  708. ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language);
  709. ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, NULL);
  710.  
  711. if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) {
  712. if (pResponse->request.status.status_code > IPP_OK_CONFLICT) {
  713. fputs("ERROR: IPP ERROR\n", stderr);
  714. goto onErr;
  715. }
  716. else {
  717. pAttribute = pResponse->attrs;
  718.  
  719. while (pAttribute != NULL) {
  720. while (pAttribute != NULL && pAttribute->group_tag != IPP_TAG_PRINTER) {
  721. pAttribute = pAttribute->next;
  722. }
  723. if (pAttribute == NULL) {
  724. break;
  725. }
  726.  
  727. while (pAttribute != NULL && pAttribute->group_tag == IPP_TAG_PRINTER) {
  728. if (strcmp(pAttribute->name, "printer-name") == 0 && pAttribute->value_tag == IPP_TAG_NAME) {
  729. pPrinter = pAttribute->values[0].string.text;
  730. }
  731. if (strcmp(pAttribute->name, "device-uri") == 0 && pAttribute->value_tag == IPP_TAG_URI) {
  732. pDUri = pAttribute->values[0].string.text;
  733. }
  734. pAttribute = pAttribute->next;
  735. }
  736.  
  737. if (strcasecmp(pDestName, pPrinter) == 0) {
  738. strncpy(pDeviceURI, pDUri, bufSize);
  739. break;
  740. }
  741.  
  742. if (pAttribute != NULL)
  743. pAttribute = pAttribute->next;
  744. }
  745. }
  746.  
  747. ippDelete(pResponse);
  748. }
  749. else {
  750. pDeviceURI = '\0';
  751. goto onErr;
  752. }
  753.  
  754. cupsLangFree(pLanguage);
  755. httpClose(pHTTP);
  756. }
  757.  
  758. onErr:
  759. return(retVal);
  760. }// End getDeviceURI
  761.  
  762.  
  763. static int read_line(FILE *fp, char *buf, int buf_size)
  764. {
  765. int cc = EOF;
  766. int i = 0;
  767.  
  768. if( buf != NULL && buf_size > 0 )
  769. {
  770. while( (cc = fgetc(fp)) != EOF )
  771. {
  772. if( cc == 0x0d || cc == 0x0a )
  773. break;
  774. if( i < buf_size - 1 )
  775. buf[i++] = cc;
  776. }
  777. buf[i] = 0;
  778. }
  779.  
  780. return (cc == EOF)? -1 : i;
  781. }
  782.  
  783.  
  784. static int ParseCNPpdOption( int *value, char *key )
  785. {
  786. const char *p_ppd_name = cupsGetPPD( g_printer_name );
  787. char *keyStr;
  788. FILE *fp = NULL;
  789. char line_buf[LINE_BUF_SIZE];
  790. int result = -1;
  791.  
  792. if ( (value == NULL) || (key == NULL) ) goto onErr1;
  793. *value = 0;
  794.  
  795. if ( (fp = fopen( p_ppd_name, "r" )) == NULL ) goto onErr1;
  796.  
  797. while( read_line( fp, line_buf, LINE_BUF_SIZE ) >= 0 ){
  798. if( line_buf[0] == '*' && line_buf[1] == '%' ){
  799. keyStr = strtok(line_buf, " ");
  800. if ( (keyStr != NULL) && (!strcmp(keyStr, "*%CNPpdOptions")) ){
  801. keyStr = strtok(NULL, " ");
  802. while ( keyStr != NULL ){
  803. if ( !strcmp(keyStr, key) ){
  804. *value = 1;
  805. break;
  806. }
  807. keyStr = strtok(NULL, " ");
  808. }
  809. }
  810. }
  811. }
  812.  
  813. result = 0;
  814. if ( fp != NULL ) fclose( fp );
  815. onErr1:
  816. return result;
  817. }
  818.  
  819. static int isSupportMSI( void )
  820. {
  821. int value;
  822. int result = FALSE;
  823.  
  824. if ( ParseCNPpdOption( &value, CNPPD_SETTINGS_SUPPORT_DEVURI_OPT ) < 0 ) goto onErr;
  825.  
  826. if ( value == 1 ) {
  827. result = TRUE;
  828. }
  829. else {
  830. result = FALSE;
  831. }
  832.  
  833. onErr:
  834. return result;
  835. }
  836.  
  837. /* Ver.3.80 */
  838. static int isSupportFrontEnd( void )
  839. {
  840. int value;
  841. int result = FALSE;
  842.  
  843. if ( ParseCNPpdOption( &value, CNPPD_SETTINGS_SUPPORT_FRONTEND_OPT ) < 0 ) goto onErr;
  844.  
  845. if ( value == 1 ) {
  846. result = TRUE;
  847. }
  848. else {
  849. result = FALSE;
  850. }
  851.  
  852. onErr:
  853. return result;
  854. }
  855.  
  856.  
  857. int main(int argc, char* argv[])
  858. {
  859. ParamList *p_list = NULL;
  860. int ui_pid;
  861. char *print_file;
  862. char product_name[64];
  863. // char ui_path[256];
  864. char *ui_path = NULL;
  865. char ui_name[256];
  866. char socket_name[64];
  867. char *ui_arg[8];
  868.  
  869. /* Ver.3.20 */
  870. short ret=-1;
  871. char device_uri_buf[1024];
  872. short device_uri_buf_len = 1024;
  873. char *canon_usb_backend_str = "cnijusb:";
  874. char *canon_net_backend_str = "cnijnet:";
  875. short canon_backend_flag = 0;
  876. short add_bidi = 0;
  877. short add_direct = 0;
  878. const char *p_ppd_name;
  879. ppd_file_t *p_ppd;
  880.  
  881. /* Ver.3.70 */
  882. int arg_num;
  883.  
  884. if( argc == 1 )
  885. {
  886. fputs(BJCUPS_VERSION, stderr);
  887. fputs("Usage: cngpij [-P printer name] <file name>\n", stderr);
  888. exit(1);
  889. }
  890.  
  891. print_file = argv[argc - 1];
  892.  
  893. if( init_option(&p_list, argc, argv) < 0 )
  894. exit(1);
  895.  
  896. if( g_printer_name == NULL )
  897. {
  898. const char *printer_name;
  899.  
  900. if( (printer_name = cupsGetDefault()) != NULL )
  901. g_printer_name = strdup(printer_name);
  902. else
  903. {
  904. fputs("ERROR: Can't get default printer name.\n", stderr);
  905. exit(1);
  906. }
  907. }
  908.  
  909. if( get_product_name(g_printer_name, product_name, 64) == NULL )
  910. {
  911. fputs("ERROR: Illegal printer name.\n", stderr);
  912. exit(1);
  913. }
  914.  
  915. /* Ver.3.80 */
  916. if( isSupportFrontEnd() == TRUE )
  917. {
  918. fputs("ERROR: The specified printer is not supported.\n", stderr);
  919. exit(1);
  920. }
  921.  
  922. /* Ver.3.20: Set canon_backend_flag. */
  923. {
  924. memset( device_uri_buf , 0x00 , device_uri_buf_len );
  925. ret = getDeviceURI( g_printer_name , device_uri_buf , device_uri_buf_len );
  926. if( ret < -1 )
  927. {
  928. fputs("ERROR: Can't get device URI.\n", stderr);
  929. exit(1);
  930. }
  931.  
  932. if( !strncmp( device_uri_buf , canon_usb_backend_str , strlen( canon_usb_backend_str ) ) ) canon_backend_flag = 1;
  933. else if( !strncmp( device_uri_buf , canon_net_backend_str , strlen( canon_net_backend_str ) ) ) canon_backend_flag = 1;
  934.  
  935.  
  936. /* PPD open and check cupsModelNumber */
  937. p_ppd_name = cupsGetPPD( g_printer_name );
  938. if( p_ppd_name ==NULL ){
  939. fputs("ERROR: Can't get PPD name.\n", stderr);
  940. exit(1);
  941. }
  942. p_ppd = ppdOpenFile(p_ppd_name);
  943. if( p_ppd ==NULL ){
  944. fputs("ERROR: Can't open PPD file.\n", stderr);
  945. unlink( p_ppd_name ); /* You should remove the copy of the PPD file. */
  946. exit(1);
  947. }
  948.  
  949. add_bidi = canon_backend_flag;
  950. if( p_ppd->model_number < 356 ) add_bidi = 0;
  951.  
  952. ppdClose(p_ppd);
  953. unlink( p_ppd_name ); /* You should remove the copy of the PPD file. */
  954.  
  955. }
  956.  
  957.  
  958. ui_path = (char *)malloc(strlen(UI_PATH) + strlen(UI_SLASH) + strlen(UI_NAME) + strlen(product_name) + 1);
  959. strcpy(ui_path, UI_PATH);
  960. strcat(ui_path, UI_SLASH);
  961. strcat(ui_path, UI_NAME);
  962. strcat(ui_path, product_name);
  963.  
  964. strcpy(ui_name, UI_NAME);
  965. strcat(ui_name, product_name);
  966.  
  967. snprintf(socket_name, 63, "%s%d", BJ_SOCKET, getpid());
  968.  
  969.  
  970. for ( arg_num=0; arg_num<sizeof(ui_arg)/sizeof(char*); arg_num++ ) {
  971. ui_arg[arg_num] = NULL;
  972. }
  973.  
  974. arg_num = 0;
  975. ui_arg[arg_num] = ui_name; arg_num++;
  976. ui_arg[arg_num] = "-s"; arg_num++;
  977. ui_arg[arg_num] = socket_name; arg_num++;
  978. ui_arg[arg_num] = "--cups"; arg_num++;
  979.  
  980. /* Ver.3.20 */
  981. if( add_bidi ) {
  982. ui_arg[arg_num] = "--bidi"; arg_num++;
  983. }
  984.  
  985. /* Ver.3.70 */
  986. if ( canon_backend_flag ) {
  987. if ( isSupportMSI() == 1 ) {
  988. ui_arg[arg_num] = "--devuri"; arg_num++;
  989. ui_arg[arg_num] = device_uri_buf; arg_num++;
  990. }
  991. }
  992.  
  993.  
  994.  
  995. #if 0
  996. /* for debug */
  997. {
  998. short i=0;
  999. while( ui_arg[i]!=NULL )
  1000. {
  1001. fprintf(stderr,"ui_arg[%d]=%s\n",i,ui_arg[i]);
  1002. i++;
  1003. }
  1004. }
  1005. #endif
  1006.  
  1007. ui_pid = fork();
  1008.  
  1009. if( ui_pid == 0 )
  1010. {
  1011. execv(ui_path, ui_arg);
  1012. }
  1013. else
  1014. {
  1015. while(1){
  1016. IPCU ipc;
  1017. int ret;
  1018. memset(&ipc, 0, sizeof(IPCU));
  1019.  
  1020. ret = GetIPCData(&ipc, socket_name);
  1021.  
  1022. if( ret == RET_PRINT )
  1023. {
  1024. char **lpr_param
  1025. = make_lpr_param(&p_list, g_printer_name, &ipc, print_file);
  1026. if( lpr_param )
  1027. {
  1028. exec_lpr(lpr_param);
  1029. free(lpr_param);
  1030. }
  1031. break;
  1032. }
  1033. else if( ret == RET_PDATA ){ // For Maintenance
  1034. char **lpr_param;
  1035. /* Ver.3.20 */
  1036. /* If canon backend is NOT used, add "CNBjDirect" */
  1037. if( canon_backend_flag ) add_direct = 0;
  1038. else add_direct = 1;
  1039.  
  1040. lpr_param = make_pdata_lpr_param( g_printer_name, &ipc, add_direct );
  1041.  
  1042. if( lpr_param )
  1043. {
  1044. exec_lpr(lpr_param);
  1045. free_util_cmd_param( lpr_param );
  1046. }
  1047.  
  1048. }
  1049. else if( ret == RET_FDATA ){ // For Maintenance i250/i255
  1050. char **lpr_param
  1051. = make_fdata_lpr_param( g_printer_name, &ipc );
  1052.  
  1053. if( lpr_param )
  1054. {
  1055. exec_lpr(lpr_param);
  1056. free_util_cmd_param(lpr_param);
  1057. lpr_param = NULL;
  1058. }
  1059. }
  1060. else if( ret == RET_WDATA ){ // For Maintenance i250/i255
  1061. char **lpr_param
  1062. = make_wdata_lpr_param( g_printer_name, &ipc);
  1063. if( lpr_param )
  1064. {
  1065. exec_lpr(lpr_param);
  1066. free_util_cmd_param(lpr_param);
  1067. lpr_param = NULL;
  1068. }
  1069. }
  1070. /* Ver.3.20 for PowerOFF */
  1071. else if( ret == RET_POWEROFF ){
  1072. char **lpr_param
  1073. = make_pdata_lpr_param( g_printer_name, &ipc, 1); /* PowerOFF -> always add "--CNBjDirect" */
  1074.  
  1075. if( lpr_param )
  1076. {
  1077. exec_lpr(lpr_param);
  1078. free_util_cmd_param( lpr_param );
  1079. }
  1080. }
  1081. else if( ret == RET_CANCEL ){
  1082. break;
  1083.  
  1084. }
  1085. else if ( ret == RET_ERROR ){
  1086. break;
  1087. }
  1088. }
  1089.  
  1090. if( p_list != NULL )
  1091. param_list_free(p_list);
  1092.  
  1093. waitpid(ui_pid, NULL, 0);
  1094. }
  1095.  
  1096. free(g_printer_name);
  1097. return 0;
  1098. }
Advertisement
Add Comment
Please, Sign In to add comment