Merge JohnR's fix.
[kai/samba.git] / source3 / printing / print_generic.c
1 /* 
2    Unix SMB/CIFS implementation.
3    printing command routines
4    Copyright (C) Andrew Tridgell 1992-2000
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; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "printing.h"
22
23
24 /*
25  * Generic printing interface definitions...
26  */
27
28 static int generic_job_delete(int snum, struct printjob *pjob);
29 static int generic_job_pause(int snum, struct printjob *pjob);
30 static int generic_job_resume(int snum, struct printjob *pjob);
31 static int generic_job_submit(int snum, struct printjob *pjob);
32 static int generic_queue_get(int snum, print_queue_struct **q,
33                              print_status_struct *status);
34 static int generic_queue_pause(int snum);
35 static int generic_queue_resume(int snum);
36
37
38 struct printif  generic_printif =
39                 {
40                   generic_queue_get,
41                   generic_queue_pause,
42                   generic_queue_resume,
43                   generic_job_delete,
44                   generic_job_pause,
45                   generic_job_resume,
46                   generic_job_submit,
47                 };
48
49 /****************************************************************************
50 run a given print command 
51 a null terminated list of value/substitute pairs is provided
52 for local substitution strings
53 ****************************************************************************/
54 static int print_run_command(int snum,char *command, int *outfd, ...)
55 {
56
57         pstring syscmd;
58         char *p, *arg;
59         int ret;
60         va_list ap;
61         va_start(ap, outfd);
62
63         if (!command || !*command) return -1;
64
65         if (!VALID_SNUM(snum)) {
66                 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
67                 return -1;
68         }
69
70         pstrcpy(syscmd, command);
71
72         while ((arg = va_arg(ap, char *))) {
73                 char *value = va_arg(ap,char *);
74                 pstring_sub(syscmd, arg, value);
75         }
76         va_end(ap);
77   
78         p = PRINTERNAME(snum);
79   
80         pstring_sub(syscmd, "%p", p);
81         standard_sub_snum(snum,syscmd);
82
83         ret = smbrun(syscmd,outfd);
84
85         DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
86
87         return ret;
88 }
89
90
91 /****************************************************************************
92 delete a print job
93 ****************************************************************************/
94 static int generic_job_delete(int snum, struct printjob *pjob)
95 {
96         fstring jobstr;
97
98         /* need to delete the spooled entry */
99         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
100         return print_run_command(
101                    snum, 
102                    lp_lprmcommand(snum), NULL,
103                    "%j", jobstr,
104                    "%T", http_timestring(pjob->starttime),
105                    NULL);
106 }
107
108 /****************************************************************************
109 pause a job
110 ****************************************************************************/
111 static int generic_job_pause(int snum, struct printjob *pjob)
112 {
113         fstring jobstr;
114         
115         /* need to pause the spooled entry */
116         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
117         return print_run_command(snum, 
118                                  lp_lppausecommand(snum), NULL,
119                                  "%j", jobstr,
120                                  NULL);
121 }
122
123 /****************************************************************************
124 resume a job
125 ****************************************************************************/
126 static int generic_job_resume(int snum, struct printjob *pjob)
127 {
128         fstring jobstr;
129         
130         /* need to pause the spooled entry */
131         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
132         return print_run_command(snum, 
133                                  lp_lpresumecommand(snum), NULL,
134                                  "%j", jobstr,
135                                  NULL);
136 }
137
138 /****************************************************************************
139  Submit a file for printing - called from print_job_end()
140 ****************************************************************************/
141
142 static int generic_job_submit(int snum, struct printjob *pjob)
143 {
144         int ret;
145         pstring current_directory;
146         pstring print_directory;
147         char *wd, *p;
148         pstring jobname;
149         fstring job_page_count, job_size;
150
151         /* we print from the directory path to give the best chance of
152            parsing the lpq output */
153         wd = sys_getwd(current_directory);
154         if (!wd)
155                 return 0;
156
157         pstrcpy(print_directory, pjob->filename);
158         p = strrchr_m(print_directory,'/');
159         if (!p)
160                 return 0;
161         *p++ = 0;
162
163         if (chdir(print_directory) != 0)
164                 return 0;
165
166         pstrcpy(jobname, pjob->jobname);
167         pstring_sub(jobname, "'", "_");
168         slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
169         slprintf(job_size, sizeof(job_size)-1, "%d", pjob->size);
170
171         /* send it to the system spooler */
172         ret = print_run_command(snum, 
173                         lp_printcommand(snum), NULL,
174                         "%s", p,
175                         "%J", jobname,
176                         "%f", p,
177                         "%z", job_size,
178                         "%c", job_page_count,
179                         NULL);
180
181         chdir(wd);
182
183         return ret;
184 }
185
186
187 /****************************************************************************
188 get the current list of queued jobs
189 ****************************************************************************/
190 static int generic_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
191 {
192         char **qlines;
193         int fd;
194         int numlines, i, qcount;
195         print_queue_struct *queue = NULL;
196         fstring printer_name;
197               
198         fstrcpy(printer_name, lp_servicename(snum));
199         
200         print_run_command(snum, lp_lpqcommand(snum), &fd, NULL);
201
202         if (fd == -1) {
203                 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
204                         printer_name ));
205                 return 0;
206         }
207         
208         numlines = 0;
209         qlines = fd_lines_load(fd, &numlines);
210         close(fd);
211
212         /* turn the lpq output into a series of job structures */
213         qcount = 0;
214         ZERO_STRUCTP(status);
215         if (numlines)
216                 queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
217
218         if (queue) {
219                 for (i=0; i<numlines; i++) {
220                         /* parse the line */
221                         if (parse_lpq_entry(snum,qlines[i],
222                                             &queue[qcount],status,qcount==0)) {
223                                 qcount++;
224                         }
225                 }               
226         }
227         file_lines_free(qlines);
228
229         *q = queue;
230         return qcount;
231 }
232
233 /****************************************************************************
234  pause a queue
235 ****************************************************************************/
236 static int generic_queue_pause(int snum)
237 {
238         return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL);
239 }
240
241 /****************************************************************************
242  resume a queue
243 ****************************************************************************/
244 static int generic_queue_resume(int snum)
245 {
246         return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL);
247 }