Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / hpps / hppsfilter.c
1 /*****************************************************************************\
2     hppsfilter.c : HP PS filter for PostScript printers
3
4     Copyright (c) 2011, Hewlett-Packard Co.
5     All rights reserved.
6
7     Redistribution and use in source and binary forms, with or without
8     modification, are permitted provided that the following conditions
9     are met:
10     1. Redistributions of source code must retain the above copyright
11        notice, this list of conditions and the following disclaimer.
12     2. Redistributions in binary form must reproduce the above copyright
13        notice, this list of conditions and the following disclaimer in the
14        documentation and/or other materials provided with the distribution.
15     3. Neither the name of the Hewlett-Packard nor the names of its
16        contributors may be used to endorse or promote products derived
17        from this software without specific prior written permission.
18
19     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24     NOT LIMITED TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR
25     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29     POSSIBILITY OF SUCH DAMAGE.
30  
31    Author: Yashwant Kumar Sahu
32 \*****************************************************************************/
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <memory.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <cups/cups.h>
41 #include <cups/ppd.h>
42 #include <sys/types.h>
43 #include <sys/stat.h>
44
45 #define PJL_HEADER "\x1B%-12345X@PJL\x0A"
46 #define BOD_PJL_FIXED "0400040101020D10100115"
47 #define BOD_PPD_ATR "HPBOD"
48 #define BOD_PJL "@PJL DMINFO ASCIIHEX=\"%s%s\"\012"
49 #define BOD_DATETIME_FORMAT "%04d%02d%02d%02d%02d%02d"
50 #define DBG_PSFILE "/tmp/hpps_job%d.out"
51
52 #define LINE_SIZE  258
53 #define FILE_NAME_SIZE 128
54
55 #define SAVE_PS_FILE      2
56
57 /*  save final output ps file: in cupsd.conf file  value #hpLogLevel 15  */
58 static int g_savepsfile = 0;
59
60 /*  final ps outfile file handle */
61 static FILE *g_fp_outdbgps = NULL;
62
63 /* get log level from the cups config file */
64 void get_LogLevel ()
65 {
66     FILE    *fp;
67     char    str[258];
68     char    *p;
69     fp = fopen ("/etc/cups/cupsd.conf", "r");
70     if (fp == NULL)
71         return;
72     while (!feof (fp))
73     {
74         if (!fgets (str, 256, fp))
75         {
76             break;
77         }
78         if ((p = strstr (str, "hpLogLevel")))
79         {
80             p += strlen ("hpLogLevel") + 1;
81             g_savepsfile = atoi (p);
82             break;
83         }
84     }
85     fclose (fp);
86 }
87
88  
89 /* create ps file for debugging purpose using job id */
90 void open_dbg_outfile(char* szjob_id)
91 {
92     g_fp_outdbgps = NULL;
93     if (g_savepsfile & SAVE_PS_FILE)
94     {
95         char    sfile_name[FILE_NAME_SIZE] = {0};
96         sprintf(sfile_name, DBG_PSFILE, szjob_id);
97         g_fp_outdbgps= fopen(sfile_name, "w");
98         chmod(sfile_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
99     }
100 }
101
102 /* Writting into out file and debug file if debug level is set to 15 */
103 int hpwrite (void *pBuffer, size_t size)
104 {
105         int ndata_written = 0;
106         if(g_fp_outdbgps)
107         {
108                 ndata_written = fwrite (pBuffer, 1, size, g_fp_outdbgps);
109         }
110         
111         ndata_written = write (STDOUT_FILENO, pBuffer, size);
112         return ndata_written;
113 }
114
115 /* Read HPBOD attribute from PPD 
116  return 1 if set as 1 */
117 int require_bod()
118 {
119     int bodRequire = 0;
120     ppd_attr_t  *pattr = NULL;
121     ppd_file_t  *pppd = NULL;   
122     pppd = ppdOpenFile(getenv("PPD"));
123     if (pppd == NULL) {
124         fprintf (stderr, "HP PS : ppdOpenFile failed for %s\n", getenv("PPD"));         
125         return 0;
126     }
127         
128     if (((pattr = ppdFindAttr(pppd, BOD_PPD_ATR, NULL)) != NULL) &&
129         (pattr && pattr->value != NULL)) {
130         bodRequire = atoi(pattr->value);
131     }
132     return bodRequire;
133 }
134
135 /* Write BOD PJL command DMINFO */
136 void emmit_bod_command()
137 {
138         struct    tm   *tgmt = NULL;
139         time_t    long_time;
140         char sBOD[100] = {0};
141     char sBOD_Var[29] = {0};
142     char sDateTime[15] = {0};
143         int index = 0;
144         
145         time(&long_time);
146         tgmt = gmtime(&long_time);
147                         
148     sprintf(sDateTime, BOD_DATETIME_FORMAT, (tgmt->tm_year + 1900),
149          (tgmt->tm_mon + 1), tgmt->tm_mday, tgmt->tm_hour, tgmt->tm_min, tgmt->tm_sec);
150         
151     for (index = 0; index < (sizeof(sDateTime) -1); index++)
152     {
153         sprintf( sBOD_Var + (index*2), "%2X", sDateTime[index ]);
154     }
155                 
156         sprintf(sBOD, BOD_PJL, BOD_PJL_FIXED, sBOD_Var);
157         fprintf (stderr, "HP PS filter sending BOD PJL:  - %s\n", sBOD);
158         hpwrite (sBOD, strlen (sBOD));
159 }
160
161 int main (int argc, char **argv)
162 {
163         cups_file_t     *fp_input =  NULL;                      /* input file: stdin or physical file */        
164     char   line[LINE_SIZE] = {0};
165         
166         get_LogLevel();
167         setbuf (stderr, NULL);
168         fprintf (stderr, "HP PS filter starting : %s \n", *argv);
169         
170         int i =  0;
171         /* Logging cups filter arguments */
172         for (   i = 0; i < argc; i++)
173         {
174                 fprintf (stderr, "DEBUG: hppsfilter: argv[%d] = %s\n", i, argv[i]);
175         }
176         
177         /* Logging debug information and creating outfile for debug */
178         if (g_savepsfile & SAVE_PS_FILE)
179         {
180                 /* opening ps debug file */
181                 open_dbg_outfile(argv[1]);
182         }
183         
184         /* Check command-line...  */
185         if (argc < 6 || argc > 7)
186         {
187                 fputs("ERROR: hppsfilter job-id user title copies options [file]\n", stderr);
188                 return (1);
189         }
190
191         /* If we have 7 arguments, print the file named on the command-line.
192         * Otherwise, send stdin instead...  */
193         if (argc == 6)
194                 fp_input = cupsFileStdin();
195         else
196         {
197                 /* Try to open the print file...    */
198                 if ((fp_input = cupsFileOpen(argv[6], "r")) == NULL)
199                 {
200                         fprintf(stderr, "ERROR: Unable to open print file \"%s\" - %s\n",
201               argv[6], strerror);
202                         return (1);
203                 }
204         }
205
206         int len  =  0;
207         int ibodwritten = 0;
208         int ireqire_bod = require_bod();
209     while ( ( len = cupsFileGetLine(fp_input, line, sizeof(line) )) > 0)
210     {
211                 hpwrite (line, len);
212                 /* if BOD is reqire, writting BOD command */
213                 if ( !ibodwritten && (!strncmp(line, "@PJL JOB NAME", 13)) && ireqire_bod)
214                 {
215                         fprintf (stderr, "HP PS filter: Matched start PJL\n");                          
216                         ibodwritten = 1;
217                         emmit_bod_command();
218                 }
219     }
220
221     if ( (argc == 7) && (fp_input != NULL) )
222         cupsFileClose (fp_input);
223         
224         if(g_fp_outdbgps != NULL)
225         {
226             fclose (g_fp_outdbgps);             
227         }
228                            
229         fprintf (stderr, "HP PS filter Ends\n");        
230     return 0;
231 }