Guest User

Untitled

a guest
Jan 19th, 2014
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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