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