source: branches/samba-3.2.x/source/printing/print_generic.c

Last change on this file was 133, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0pre3

File size: 7.9 KB
Line 
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 3 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, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "includes.h"
21#include "printing.h"
22
23extern struct current_user current_user;
24extern userdom_struct current_user_info;
25
26/****************************************************************************
27 Run a given print command
28 a null terminated list of value/substitute pairs is provided
29 for local substitution strings
30****************************************************************************/
31static int print_run_command(int snum, const char* printername, bool do_sub,
32 const char *command, int *outfd, ...)
33{
34 char *syscmd;
35 char *arg;
36 int ret;
37 TALLOC_CTX *ctx = talloc_tos();
38 va_list ap;
39 va_start(ap, outfd);
40
41 /* check for a valid system printername and valid command to run */
42
43 if ( !printername || !*printername ) {
44 va_end(ap);
45 return -1;
46 }
47
48 if (!command || !*command) {
49 va_end(ap);
50 return -1;
51 }
52
53 syscmd = talloc_strdup(ctx, command);
54 if (!syscmd) {
55 va_end(ap);
56 return -1;
57 }
58
59 while ((arg = va_arg(ap, char *))) {
60 char *value = va_arg(ap,char *);
61 syscmd = talloc_string_sub(ctx, syscmd, arg, value);
62 if (!syscmd) {
63 va_end(ap);
64 return -1;
65 }
66 }
67 va_end(ap);
68
69 syscmd = talloc_string_sub(ctx, syscmd, "%p", printername);
70 if (!syscmd) {
71 return -1;
72 }
73
74 if (do_sub && snum != -1) {
75 syscmd = talloc_sub_advanced(ctx,
76 lp_servicename(snum),
77 current_user_info.unix_name,
78 "",
79 current_user.ut.gid,
80 get_current_username(),
81 current_user_info.domain,
82 syscmd);
83 if (!syscmd) {
84 return -1;
85 }
86 }
87
88 ret = smbrun_no_sanitize(syscmd,outfd);
89
90 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
91
92 return ret;
93}
94
95
96/****************************************************************************
97delete a print job
98****************************************************************************/
99static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
100{
101 fstring jobstr;
102
103 /* need to delete the spooled entry */
104 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
105 return print_run_command( -1, sharename, False, lprm_command, NULL,
106 "%j", jobstr,
107 "%T", http_timestring(pjob->starttime),
108 NULL);
109}
110
111/****************************************************************************
112pause a job
113****************************************************************************/
114static int generic_job_pause(int snum, struct printjob *pjob)
115{
116 fstring jobstr;
117
118 /* need to pause the spooled entry */
119 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
120 return print_run_command(snum, PRINTERNAME(snum), True,
121 lp_lppausecommand(snum), NULL,
122 "%j", jobstr,
123 NULL);
124}
125
126/****************************************************************************
127resume a job
128****************************************************************************/
129static int generic_job_resume(int snum, struct printjob *pjob)
130{
131 fstring jobstr;
132
133 /* need to pause the spooled entry */
134 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
135 return print_run_command(snum, PRINTERNAME(snum), True,
136 lp_lpresumecommand(snum), NULL,
137 "%j", jobstr,
138 NULL);
139}
140
141/****************************************************************************
142 Submit a file for printing - called from print_job_end()
143****************************************************************************/
144
145static int generic_job_submit(int snum, struct printjob *pjob)
146{
147 int ret = -1;
148 char *current_directory = NULL;
149 char *print_directory = NULL;
150 char *wd = NULL;
151 char *p = NULL;
152 char *jobname = NULL;
153 TALLOC_CTX *ctx = talloc_tos();
154 fstring job_page_count, job_size;
155
156 /* we print from the directory path to give the best chance of
157 parsing the lpq output */
158 current_directory = TALLOC_ARRAY(ctx,
159 char,
160 PATH_MAX+1);
161 if (!current_directory) {
162 return -1;
163 }
164 wd = sys_getwd(current_directory);
165 if (!wd) {
166 return -1;
167 }
168
169 print_directory = talloc_strdup(ctx, pjob->filename);
170 if (!print_directory) {
171 return -1;
172 }
173 p = strrchr_m(print_directory,'/');
174 if (!p) {
175 return -1;
176 }
177 *p++ = 0;
178
179 if (chdir(print_directory) != 0) {
180 return -1;
181 }
182
183 jobname = talloc_strdup(ctx, pjob->jobname);
184 if (!jobname) {
185 ret = -1;
186 goto out;
187 }
188 jobname = talloc_string_sub(ctx, jobname, "'", "_");
189 if (!jobname) {
190 ret = -1;
191 goto out;
192 }
193 slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
194 slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
195
196 /* send it to the system spooler */
197 ret = print_run_command(snum, PRINTERNAME(snum), True,
198 lp_printcommand(snum), NULL,
199 "%s", p,
200 "%J", jobname,
201 "%f", p,
202 "%z", job_size,
203 "%c", job_page_count,
204 NULL);
205
206 out:
207
208 chdir(wd);
209 TALLOC_FREE(current_directory);
210 return ret;
211}
212
213
214/****************************************************************************
215get the current list of queued jobs
216****************************************************************************/
217static int generic_queue_get(const char *printer_name,
218 enum printing_types printing_type,
219 char *lpq_command,
220 print_queue_struct **q,
221 print_status_struct *status)
222{
223 char **qlines;
224 int fd;
225 int numlines, i, qcount;
226 print_queue_struct *queue = NULL;
227
228 /* never do substitution when running the 'lpq command' since we can't
229 get it rigt when using the background update daemon. Make the caller
230 do it before passing off the command string to us here. */
231
232 print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
233
234 if (fd == -1) {
235 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
236 printer_name ));
237 return 0;
238 }
239
240 numlines = 0;
241 qlines = fd_lines_load(fd, &numlines,0);
242 close(fd);
243
244 /* turn the lpq output into a series of job structures */
245 qcount = 0;
246 ZERO_STRUCTP(status);
247 if (numlines && qlines) {
248 queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1);
249 if (!queue) {
250 file_lines_free(qlines);
251 *q = NULL;
252 return 0;
253 }
254 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
255
256 for (i=0; i<numlines; i++) {
257 /* parse the line */
258 if (parse_lpq_entry(printing_type,qlines[i],
259 &queue[qcount],status,qcount==0)) {
260 qcount++;
261 }
262 }
263 }
264
265 file_lines_free(qlines);
266 *q = queue;
267 return qcount;
268}
269
270/****************************************************************************
271 pause a queue
272****************************************************************************/
273static int generic_queue_pause(int snum)
274{
275 return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
276}
277
278/****************************************************************************
279 resume a queue
280****************************************************************************/
281static int generic_queue_resume(int snum)
282{
283 return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
284}
285
286/****************************************************************************
287 * Generic printing interface definitions...
288 ***************************************************************************/
289
290struct printif generic_printif =
291{
292 DEFAULT_PRINTING,
293 generic_queue_get,
294 generic_queue_pause,
295 generic_queue_resume,
296 generic_job_delete,
297 generic_job_pause,
298 generic_job_resume,
299 generic_job_submit,
300};
301
Note: See TracBrowser for help on using the repository browser.