1 /*****************************************************************************\
2 hppsfilter.c : HP PS filter for PostScript printers
4 Copyright (c) 2011, Hewlett-Packard Co.
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
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.
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.
31 Author: Yashwant Kumar Sahu
32 \*****************************************************************************/
40 #include <cups/cups.h>
42 #include <sys/types.h>
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"
53 #define FILE_NAME_SIZE 128
55 #define SAVE_PS_FILE 2
57 /* save final output ps file: in cupsd.conf file value #hpLogLevel 15 */
58 static int g_savepsfile = 0;
60 /* final ps outfile file handle */
61 static FILE *g_fp_outdbgps = NULL;
63 /* get log level from the cups config file */
69 fp = fopen ("/etc/cups/cupsd.conf", "r");
74 if (!fgets (str, 256, fp))
78 if ((p = strstr (str, "hpLogLevel")))
80 p += strlen ("hpLogLevel") + 1;
81 g_savepsfile = atoi (p);
89 /* create ps file for debugging purpose using job id */
90 void open_dbg_outfile(char* szjob_id)
93 if (g_savepsfile & SAVE_PS_FILE)
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);
102 /* Writting into out file and debug file if debug level is set to 15 */
103 int hpwrite (void *pBuffer, size_t size)
105 int ndata_written = 0;
108 ndata_written = fwrite (pBuffer, 1, size, g_fp_outdbgps);
111 ndata_written = write (STDOUT_FILENO, pBuffer, size);
112 return ndata_written;
115 /* Read HPBOD attribute from PPD
116 return 1 if set as 1 */
120 ppd_attr_t *pattr = NULL;
121 ppd_file_t *pppd = NULL;
122 pppd = ppdOpenFile(getenv("PPD"));
124 fprintf (stderr, "HP PS : ppdOpenFile failed for %s\n", getenv("PPD"));
128 if (((pattr = ppdFindAttr(pppd, BOD_PPD_ATR, NULL)) != NULL) &&
129 (pattr && pattr->value != NULL)) {
130 bodRequire = atoi(pattr->value);
135 /* Write BOD PJL command DMINFO */
136 void emmit_bod_command()
138 struct tm *tgmt = NULL;
140 char sBOD[100] = {0};
141 char sBOD_Var[29] = {0};
142 char sDateTime[15] = {0};
146 tgmt = gmtime(&long_time);
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);
151 for (index = 0; index < (sizeof(sDateTime) -1); index++)
153 sprintf( sBOD_Var + (index*2), "%2X", sDateTime[index ]);
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));
161 int main (int argc, char **argv)
163 cups_file_t *fp_input = NULL; /* input file: stdin or physical file */
164 char line[LINE_SIZE] = {0};
167 setbuf (stderr, NULL);
168 fprintf (stderr, "HP PS filter starting : %s \n", *argv);
171 /* Logging cups filter arguments */
172 for ( i = 0; i < argc; i++)
174 fprintf (stderr, "DEBUG: hppsfilter: argv[%d] = %s\n", i, argv[i]);
177 /* Logging debug information and creating outfile for debug */
178 if (g_savepsfile & SAVE_PS_FILE)
180 /* opening ps debug file */
181 open_dbg_outfile(argv[1]);
184 /* Check command-line... */
185 if (argc < 6 || argc > 7)
187 fputs("ERROR: hppsfilter job-id user title copies options [file]\n", stderr);
191 /* If we have 7 arguments, print the file named on the command-line.
192 * Otherwise, send stdin instead... */
194 fp_input = cupsFileStdin();
197 /* Try to open the print file... */
198 if ((fp_input = cupsFileOpen(argv[6], "r")) == NULL)
200 fprintf(stderr, "ERROR: Unable to open print file \"%s\" - %s\n",
208 int ireqire_bod = require_bod();
209 while ( ( len = cupsFileGetLine(fp_input, line, sizeof(line) )) > 0)
212 /* if BOD is reqire, writting BOD command */
213 if ( !ibodwritten && (!strncmp(line, "@PJL JOB NAME", 13)) && ireqire_bod)
215 fprintf (stderr, "HP PS filter: Matched start PJL\n");
221 if ( (argc == 7) && (fp_input != NULL) )
222 cupsFileClose (fp_input);
224 if(g_fp_outdbgps != NULL)
226 fclose (g_fp_outdbgps);
229 fprintf (stderr, "HP PS filter Ends\n");