Tizen 2.1 base
[platform/upstream/hplip.git] / prnt / filters / hplipjs.c
1 /*****************************************************************************\
2     hplipjs.c : HP CUPS filter for PostScript printers
3
4     Copyright (c) 2008, 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
32 #include <stdio.h>
33 #include <string.h>
34 #include <memory.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <cups/cups.h>
39 #include <sys/types.h>
40 #include <pwd.h>
41
42
43 #ifdef TESTING
44 FILE    *HPFp;
45 int HPWrite (int fd, void *pBuffer, int len)
46 {
47     fwrite (pBuffer, 1, len, HPFp);
48     return len;
49 }
50 #else
51 #define HPWrite write
52 #endif
53
54 static char    *szJSStrings[] = {"HOLDKEY", "USERNAME", "JOBNAME", "HOLDTYPE", "DUPLICATEJOB"};
55
56 void SendJobHoldCommands (char *szJSOptions, int fd)
57 {
58     int     i, k;
59     int     iJS;
60     char    *p;
61     char    szStr[256];
62     p = strstr (szJSOptions, "HOLD");
63     if (!(strncmp (p+5, "OFF", 3)))
64         return;
65     while (*p && *p != '=')
66         p++;
67     p++;
68     k = 14;
69     memset (szStr, 0, sizeof (szStr));
70     strcpy (szStr, "@PJL SET HOLD=");
71     while (*p && *p > ' ' && k < 254)
72     {
73         szStr[k++] = *p++;
74     }
75     szStr[k] = '\x0A';
76     HPWrite (fd, szStr, strlen (szStr));
77
78     p = szJSOptions;
79     iJS = sizeof (szJSStrings) / sizeof (szJSStrings[0]);
80     for (i = 0; i < iJS; i++)
81     {
82             if ((p = strstr (szJSOptions, szJSStrings[i])))
83             {
84                 memset (szStr, 0, sizeof (szStr));
85                 sprintf (szStr, "@PJL SET %s=", szJSStrings[i]);
86                 while (*p && *p != '=')
87                         p++;
88                 p++;
89                 k = strlen (szStr);
90                 if (i < 3)
91                     szStr[k++] = '"';
92                 while (*p && *p > ' ' && k < 254)
93                 {
94                         szStr[k] = *p++;
95                         if (szStr[k] == '_')
96                             szStr[k] = ' ';
97                         k++;
98                 }
99                 if (i < 3)
100                     szStr[k++] = '"';
101                 szStr[k] = '\x0A';
102                 HPWrite (fd, szStr, strlen (szStr));
103             }
104     }
105     return;
106 }
107
108 void GetOptionStringFromCups (char *pPrinter, int fd, char *user)
109 {
110     struct    passwd    *pwd;
111     char      szlpOptionsFile[1024];
112     FILE      *fp;
113     char      szLine[1024];
114     pwd = getpwnam (user);
115     if (pwd == NULL)
116     {
117         fprintf (stderr, "DEBUG: getpwnam failed for user %s\n", user);
118         return;
119     }
120     sprintf (szlpOptionsFile, "%s/.cups/lpoptions", pwd->pw_dir);
121     fp = fopen (szlpOptionsFile, "r");
122     if (fp == NULL)
123     {
124         fprintf (stderr, "DEBUG: Unable to open lpoptions file %s\n", szlpOptionsFile);
125         return;
126     }
127     while (!feof (fp))
128     {
129         fgets (szLine, 1020, fp);
130         if (strstr (szLine, pPrinter))
131         {
132             fprintf (stderr, "DEBUG: Got %s from lpoptions file\n", szLine);
133             SendJobHoldCommands (szLine + strlen (pPrinter) + 5, fd);
134             break;
135         }
136     }
137     fclose (fp);
138 }
139
140 #if 0
141 void GetOptionStringFromCups (char *pPrinter, int fd)
142 {
143     int            i, j;
144     int            iJS;
145     int            num_dests;
146     cups_dest_t    *dests;
147     cups_dest_t    *dest;
148     char           *opt;
149     char           *ppdFileName;
150     ppd_file_t     *ppdFile;
151     char           szJSOptionString[1024];
152
153 fprintf (stderr, "DEBUG: In GetOption.... printer = %s, fd = %d\n", pPrinter, fd);
154     ppdFileName = (char *) cupsGetPPD (pPrinter);
155     if (!ppdFileName)
156     {
157 fprintf (stderr, "DEBUG: did not get ppdfilename\n");
158         return;
159     }
160 fprintf (stderr, "DEBUG: ppdFileName = %s\n", ppdFileName);
161     ppdFile = ppdOpenFile (ppdFileName);
162 fprintf (stderr, "DEBUG: ppdFileName = %s\n", ppdFileName);
163     if (ppdFile == NULL)
164     {
165 fprintf (stderr, "DEBUG: unable to open ppdfile, %s\n", ppdFileName);
166         return;
167     }
168     num_dests = cupsGetDests (&dests);
169     if (num_dests == 0)
170     {
171 fprintf (stderr, "DEBUG: num_dests is zero\n");
172         ppdClose (ppdFile);
173         return;
174     }
175     dest = cupsGetDest (pPrinter, NULL, num_dests, dests);
176     if (dest == NULL)
177     {
178 fprintf (stderr, "DEBUG: did not get dest for printer %s\n", pPrinter);
179         ppdClose (ppdFile);
180         return;
181     }
182     ppdMarkDefaults (ppdFile);
183     cupsMarkOptions (ppdFile, dest->num_options, dest->options);
184     iJS = sizeof (szJSStrings) / sizeof (szJSStrings[0]);
185     if ((opt = (char *) cupsGetOption ("HOLD", dest->num_options, dest->options)) == NULL)
186     {
187 fprintf (stderr, "DEBUG: did not see HOLD option\nOptions in the list are:\n");
188 for (i = 0; i < dest->num_options; i++)
189 {
190     fprintf (stderr, "DEBUG: Option = %s : value = %s\n", dest->options[i].name, dest->options[i].value);
191 }
192
193         ppdClose (ppdFile);
194         return;
195     }
196     memset (szJSOptionString, 0, sizeof (szJSOptionString));
197     j = sprintf (szJSOptionString, "HOLD=%s", opt);
198     for (i = 0; i < iJS; i++)
199     {
200         if ((opt = (char *) cupsGetOption (szJSStrings[i], dest->num_options, dest->options)))
201         {
202 fprintf (stderr, "DEBUG: cupsGetOption returned %s = %s\n", szJSStrings[i], opt);
203             j += sprintf (szJSOptionString + j, " %s=%s", szJSStrings[i], opt);
204         }
205     }
206     ppdClose (ppdFile);
207     cupsFreeDests (num_dests, dests);
208 fprintf (stderr, "DEBUG: Calling SendJobHoldCommands with %s\n", szJSOptionString);
209     SendJobHoldCommands (szJSOptionString, fd);
210 }
211 #endif
212
213 int main (int argc, char **argv)
214 {\r
215 #ifdef TESTING
216     int    i;\r
217 #endif
218     int    n;
219     int    fd;
220     int    Outfd;
221     char   pBuffer[260];
222     char   *szStartJob = "\x1B%-12345X@PJL JOBNAME=";
223     char   *szUEL = "@PJL ENTER LANGUAGE=POSTSCRIPT\x0A";
224     char   *szEndJob = "\x1B%-12345X@PJL EOJ\x0A\x1B%-12345X";
225
226 /*
227  *  Job storage command strings
228  *
229  *  @PJL SET HOLD=ON | OFF | STORE | REPRINT
230  *                hold in memory, regular job, store to hdd, reprint from memory
231  *  @PJL SET HOLDTYPE=PRIVATE | PUBLIC
232  *  @PJL SET HOLDKEY=1234
233  *  @PJL SET USERNAME="user_name"
234  *  @PJL SET JOBNAME="job_name"
235  *  @PJL SET DUPLICATEJOB=APPEND | REPLACE
236  */
237
238     setbuf (stderr, NULL);
239     if (argc < 6 || argc > 7)
240     {
241         fprintf (stderr, "ERROR: Uage - %s JobId UserName Title NCopies OptionList [InputFile]\n", *argv);
242         return 1;
243     }\r
244
245 //  Doesn't really work\r
246 //    cupsSetUser (argv[2]);
247
248 #ifdef TESTING
249     for (i = 0; i < argc; i++)
250     {
251         fprintf (stderr, "DEBUG: HPLIPJS: argv[%d] = %s\n", i, argv[i]);
252     }
253
254     HPFp = fopen ("/tmp/output.ps", "w");
255 #endif
256     fd = 0;        // read from stdin
257     Outfd = 1;     // HPWrite to stdout
258     if (argc == 7)
259     {
260         if ((fd = open (argv[6], O_RDONLY)) == -1)
261         {
262             fprintf (stderr, "ERROR: Unable to open input file %s for reading\n", argv[6]);
263             return 1;
264         }
265     }
266
267     HPWrite (Outfd, szStartJob, strlen (szStartJob));
268     sprintf (pBuffer, "hplip-%s\x0A", argv[1]);
269     HPWrite (Outfd, pBuffer, strlen (pBuffer));
270
271 /*
272  *  Check if job storage option is selected. If so, send the PJL header and
273  *  job storage commands.
274  */
275
276     if ((strstr (argv[5], "HOLD")))
277     {
278         fprintf (stderr, "DEBUG: found HOLD option\n");
279         SendJobHoldCommands (argv[5], Outfd);
280     }
281     else
282     {
283         fprintf (stderr, "DEBUG: did not find HOLD option, calling GetOption....\n");
284         GetOptionStringFromCups (argv[0], Outfd, argv[2]);
285     }
286
287     HPWrite (Outfd, szUEL, strlen (szUEL));
288
289     while ((n = read (fd, pBuffer, 256)) > 0)
290     {
291         HPWrite (Outfd, pBuffer, n);
292     }
293
294     HPWrite (Outfd, szEndJob, strlen (szEndJob));
295
296     if (fd != 0)
297         close (fd);
298 #ifdef TESTING
299     fclose (HPFp);
300 #endif
301     return 0;
302 }
303