Removed version number from file header.
[kamenim/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
150         /* we print from the directory path to give the best chance of
151            parsing the lpq output */
152         wd = sys_getwd(current_directory);
153         if (!wd)
154                 return 0;
155
156         pstrcpy(print_directory, pjob->filename);
157         p = strrchr_m(print_directory,'/');
158         if (!p)
159                 return 0;
160         *p++ = 0;
161
162         if (chdir(print_directory) != 0)
163                 return 0;
164
165         pstrcpy(jobname, pjob->jobname);
166         pstring_sub(jobname, "'", "_");
167
168         /* send it to the system spooler */
169         ret = print_run_command(snum, 
170                           lp_printcommand(snum), NULL,
171                           "%s", p,
172                           "%J", jobname,
173                           "%f", p,
174                           NULL);
175
176         chdir(wd);
177
178         return ret;
179 }
180
181
182 /****************************************************************************
183 get the current list of queued jobs
184 ****************************************************************************/
185 static int generic_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
186 {
187         char **qlines;
188         int fd;
189         int numlines, i, qcount;
190         print_queue_struct *queue = NULL;
191         fstring printer_name;
192               
193         fstrcpy(printer_name, lp_servicename(snum));
194         
195         print_run_command(snum, lp_lpqcommand(snum), &fd, NULL);
196
197         if (fd == -1) {
198                 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
199                         printer_name ));
200                 return 0;
201         }
202         
203         numlines = 0;
204         qlines = fd_lines_load(fd, &numlines);
205         close(fd);
206
207         /* turn the lpq output into a series of job structures */
208         qcount = 0;
209         ZERO_STRUCTP(status);
210         if (numlines)
211                 queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
212
213         if (queue) {
214                 for (i=0; i<numlines; i++) {
215                         /* parse the line */
216                         if (parse_lpq_entry(snum,qlines[i],
217                                             &queue[qcount],status,qcount==0)) {
218                                 qcount++;
219                         }
220                 }               
221         }
222         file_lines_free(qlines);
223
224         *q = queue;
225         return qcount;
226 }
227
228 /****************************************************************************
229  pause a queue
230 ****************************************************************************/
231 static int generic_queue_pause(int snum)
232 {
233         return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL);
234 }
235
236 /****************************************************************************
237  resume a queue
238 ****************************************************************************/
239 static int generic_queue_resume(int snum)
240 {
241         return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL);
242 }