2 Unix SMB/CIFS implementation.
3 printing command routines
4 Copyright (C) Andrew Tridgell 1992-2000
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.
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.
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/>.
22 #include "smbd/proto.h"
24 extern userdom_struct current_user_info
;
26 /****************************************************************************
27 Run a given print command
28 a null terminated list of value/substitute pairs is provided
29 for local substitution strings
30 ****************************************************************************/
31 static int print_run_command(int snum
, const char* printername
, bool do_sub
,
32 const char *command
, int *outfd
, ...)
34 const struct loadparm_substitution
*lp_sub
=
35 loadparm_s3_global_substitution();
39 TALLOC_CTX
*ctx
= talloc_tos();
43 /* check for a valid system printername and valid command to run */
45 if ( !printername
|| !*printername
) {
50 if (!command
|| !*command
) {
55 syscmd
= talloc_strdup(ctx
, command
);
61 DBG_DEBUG("Incoming command '%s'\n", syscmd
);
63 while ((arg
= va_arg(ap
, char *))) {
64 char *value
= va_arg(ap
,char *);
65 syscmd
= talloc_string_sub(ctx
, syscmd
, arg
, value
);
73 syscmd
= talloc_string_sub(ctx
, syscmd
, "%p", printername
);
78 syscmd
= lpcfg_substituted_string(ctx
, lp_sub
, syscmd
);
83 if (do_sub
&& snum
!= -1) {
84 syscmd
= talloc_sub_advanced(ctx
,
85 lp_servicename(talloc_tos(), lp_sub
, snum
),
86 current_user_info
.unix_name
,
88 get_current_gid(NULL
),
95 ret
= smbrun_no_sanitize(syscmd
, outfd
, NULL
);
97 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
103 /****************************************************************************
105 ****************************************************************************/
106 static int generic_job_delete( const char *sharename
, const char *lprm_command
, struct printjob
*pjob
)
110 /* need to delete the spooled entry */
111 slprintf(jobstr
, sizeof(jobstr
)-1, "%d", pjob
->sysjob
);
112 return print_run_command( -1, sharename
, False
, lprm_command
, NULL
,
114 "%T", http_timestring(talloc_tos(), pjob
->starttime
),
118 /****************************************************************************
120 ****************************************************************************/
121 static int generic_job_pause(int snum
, struct printjob
*pjob
)
123 const struct loadparm_substitution
*lp_sub
=
124 loadparm_s3_global_substitution();
127 /* need to pause the spooled entry */
128 slprintf(jobstr
, sizeof(jobstr
)-1, "%d", pjob
->sysjob
);
129 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
130 lp_lppause_command(snum
), NULL
,
135 /****************************************************************************
137 ****************************************************************************/
138 static int generic_job_resume(int snum
, struct printjob
*pjob
)
140 const struct loadparm_substitution
*lp_sub
=
141 loadparm_s3_global_substitution();
144 /* need to pause the spooled entry */
145 slprintf(jobstr
, sizeof(jobstr
)-1, "%d", pjob
->sysjob
);
146 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
147 lp_lpresume_command(snum
), NULL
,
152 /****************************************************************************
153 get the current list of queued jobs
154 ****************************************************************************/
155 static int generic_queue_get(const char *printer_name
,
156 enum printing_types printing_type
,
158 print_queue_struct
**q
,
159 print_status_struct
*status
)
163 int numlines
, i
, qcount
;
164 print_queue_struct
*queue
= NULL
;
166 /* never do substitution when running the 'lpq command' since we can't
167 get it rigt when using the background update daemon. Make the caller
168 do it before passing off the command string to us here. */
170 print_run_command(-1, printer_name
, False
, lpq_command
, &fd
, NULL
);
173 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
179 qlines
= fd_lines_load(fd
, &numlines
,0,NULL
);
182 /* turn the lpq output into a series of job structures */
184 ZERO_STRUCTP(status
);
185 if (numlines
&& qlines
) {
186 queue
= SMB_MALLOC_ARRAY(print_queue_struct
, numlines
+1);
192 memset(queue
, '\0', sizeof(print_queue_struct
)*(numlines
+1));
194 for (i
=0; i
<numlines
; i
++) {
196 if (parse_lpq_entry(printing_type
,qlines
[i
],
197 &queue
[qcount
],status
,qcount
==0)) {
208 /****************************************************************************
209 Submit a file for printing - called from print_job_end()
210 ****************************************************************************/
212 static int generic_job_submit(int snum
, struct printjob
*pjob
,
213 enum printing_types printing_type
,
217 const struct loadparm_substitution
*lp_sub
=
218 loadparm_s3_global_substitution();
219 char *current_directory
= NULL
;
220 char *print_directory
= NULL
;
223 char *jobname
= NULL
;
224 TALLOC_CTX
*ctx
= talloc_tos();
225 fstring job_page_count
, job_size
;
226 print_queue_struct
*q
;
227 print_status_struct status
;
229 /* we print from the directory path to give the best chance of
230 parsing the lpq output */
236 current_directory
= talloc_strdup(ctx
, wd
);
239 if (!current_directory
) {
242 print_directory
= talloc_strdup(ctx
, pjob
->filename
);
243 if (!print_directory
) {
246 p
= strrchr_m(print_directory
,'/');
252 if (chdir(print_directory
) != 0) {
256 jobname
= talloc_strdup(ctx
, pjob
->jobname
);
261 jobname
= talloc_string_sub(ctx
, jobname
, "'", "_");
266 slprintf(job_page_count
, sizeof(job_page_count
)-1, "%d", pjob
->page_count
);
267 slprintf(job_size
, sizeof(job_size
)-1, "%lu", (unsigned long)pjob
->size
);
269 /* send it to the system spooler */
270 ret
= print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
271 lp_print_command(snum
), NULL
,
276 "%c", job_page_count
,
284 * check the queue for the newly submitted job, this allows us to
285 * determine the backend job identifier (sysjob).
288 ret
= generic_queue_get(lp_printername(talloc_tos(), lp_sub
, snum
),
289 printing_type
, lpq_cmd
, &q
, &status
);
292 for (i
= 0; i
< ret
; i
++) {
293 if (strcmp(q
[i
].fs_file
, p
) == 0) {
294 pjob
->sysjob
= q
[i
].sysjob
;
295 DEBUG(5, ("new job %u (%s) matches sysjob %d\n",
296 pjob
->jobid
, jobname
, pjob
->sysjob
));
303 if (pjob
->sysjob
== -1) {
304 DEBUG(2, ("failed to get sysjob for job %u (%s), tracking as "
305 "Unix job\n", pjob
->jobid
, jobname
));
311 if (chdir(current_directory
) == -1) {
312 smb_panic("chdir failed in generic_job_submit");
314 TALLOC_FREE(current_directory
);
318 /****************************************************************************
320 ****************************************************************************/
321 static int generic_queue_pause(int snum
)
323 const struct loadparm_substitution
*lp_sub
=
324 loadparm_s3_global_substitution();
326 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
327 lp_queuepause_command(snum
), NULL
, NULL
);
330 /****************************************************************************
332 ****************************************************************************/
333 static int generic_queue_resume(int snum
)
335 const struct loadparm_substitution
*lp_sub
=
336 loadparm_s3_global_substitution();
338 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
339 lp_queueresume_command(snum
), NULL
, NULL
);
342 /****************************************************************************
343 * Generic printing interface definitions...
344 ***************************************************************************/
346 struct printif generic_printif
=
351 generic_queue_resume
,