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/>.
21 #include "lib/util/util_file.h"
23 #include "smbd/proto.h"
24 #include "source3/lib/substitute.h"
26 extern userdom_struct current_user_info
;
28 /****************************************************************************
29 Run a given print command
30 a null terminated list of value/substitute pairs is provided
31 for local substitution strings
32 ****************************************************************************/
33 static int print_run_command(int snum
, const char* printername
, bool do_sub
,
34 const char *command
, int *outfd
, ...)
36 const struct loadparm_substitution
*lp_sub
=
37 loadparm_s3_global_substitution();
41 TALLOC_CTX
*ctx
= talloc_tos();
45 /* check for a valid system printername and valid command to run */
47 if ( !printername
|| !*printername
) {
52 if (!command
|| !*command
) {
57 syscmd
= talloc_strdup(ctx
, command
);
63 DBG_DEBUG("Incoming command '%s'\n", syscmd
);
65 while ((arg
= va_arg(ap
, char *))) {
66 char *value
= va_arg(ap
,char *);
67 syscmd
= talloc_string_sub(ctx
, syscmd
, arg
, value
);
75 syscmd
= talloc_string_sub(ctx
, syscmd
, "%p", printername
);
80 syscmd
= lpcfg_substituted_string(ctx
, lp_sub
, syscmd
);
85 if (do_sub
&& snum
!= -1) {
86 syscmd
= talloc_sub_advanced(ctx
,
87 lp_servicename(talloc_tos(), lp_sub
, snum
),
88 current_user_info
.unix_name
,
90 get_current_gid(NULL
),
97 ret
= smbrun_no_sanitize(syscmd
, outfd
, NULL
);
99 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
105 /****************************************************************************
107 ****************************************************************************/
108 static int generic_job_delete( const char *sharename
, const char *lprm_command
, struct printjob
*pjob
)
112 /* need to delete the spooled entry */
113 fstr_sprintf(jobstr
, "%d", pjob
->sysjob
);
114 return print_run_command( -1, sharename
, False
, lprm_command
, NULL
,
116 "%T", http_timestring(talloc_tos(), pjob
->starttime
),
120 /****************************************************************************
122 ****************************************************************************/
123 static int generic_job_pause(int snum
, struct printjob
*pjob
)
125 const struct loadparm_substitution
*lp_sub
=
126 loadparm_s3_global_substitution();
129 /* need to pause the spooled entry */
130 fstr_sprintf(jobstr
, "%d", pjob
->sysjob
);
131 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
132 lp_lppause_command(snum
), NULL
,
137 /****************************************************************************
139 ****************************************************************************/
140 static int generic_job_resume(int snum
, struct printjob
*pjob
)
142 const struct loadparm_substitution
*lp_sub
=
143 loadparm_s3_global_substitution();
146 /* need to pause the spooled entry */
147 fstr_sprintf(jobstr
, "%d", pjob
->sysjob
);
148 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
149 lp_lpresume_command(snum
), NULL
,
154 /****************************************************************************
155 get the current list of queued jobs
156 ****************************************************************************/
157 static int generic_queue_get(const char *printer_name
,
158 enum printing_types printing_type
,
160 print_queue_struct
**q
,
161 print_status_struct
*status
)
165 int numlines
, i
, qcount
;
166 print_queue_struct
*queue
= NULL
;
168 /* never do substitution when running the 'lpq command' since we can't
169 get it right when using the background update daemon. Make the caller
170 do it before passing off the command string to us here. */
172 print_run_command(-1, printer_name
, False
, lpq_command
, &fd
, NULL
);
175 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
181 qlines
= fd_lines_load(fd
, &numlines
,0,NULL
);
184 /* turn the lpq output into a series of job structures */
186 ZERO_STRUCTP(status
);
187 if (numlines
&& qlines
) {
188 queue
= SMB_MALLOC_ARRAY(print_queue_struct
, numlines
+1);
194 memset(queue
, '\0', sizeof(print_queue_struct
)*(numlines
+1));
196 for (i
=0; i
<numlines
; i
++) {
198 if (parse_lpq_entry(printing_type
,qlines
[i
],
199 &queue
[qcount
],status
,qcount
==0)) {
210 /****************************************************************************
211 Submit a file for printing - called from print_job_end()
212 ****************************************************************************/
214 static int generic_job_submit(int snum
, struct printjob
*pjob
,
215 enum printing_types printing_type
,
219 const struct loadparm_substitution
*lp_sub
=
220 loadparm_s3_global_substitution();
221 char *current_directory
= NULL
;
222 char *print_directory
= NULL
;
225 char *jobname
= NULL
;
226 TALLOC_CTX
*ctx
= talloc_tos();
227 fstring job_page_count
, job_size
;
228 print_queue_struct
*q
;
229 print_status_struct status
;
231 /* we print from the directory path to give the best chance of
232 parsing the lpq output */
238 current_directory
= talloc_strdup(ctx
, wd
);
241 if (!current_directory
) {
244 print_directory
= talloc_strdup(ctx
, pjob
->filename
);
245 if (!print_directory
) {
248 p
= strrchr_m(print_directory
,'/');
254 if (chdir(print_directory
) != 0) {
258 jobname
= talloc_strdup(ctx
, pjob
->jobname
);
263 jobname
= talloc_string_sub(ctx
, jobname
, "'", "_");
268 fstr_sprintf(job_page_count
, "%d", pjob
->page_count
);
269 fstr_sprintf(job_size
, "%zu", pjob
->size
);
271 /* send it to the system spooler */
272 ret
= print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
273 lp_print_command(snum
), NULL
,
278 "%c", job_page_count
,
286 * check the queue for the newly submitted job, this allows us to
287 * determine the backend job identifier (sysjob).
290 ret
= generic_queue_get(lp_printername(talloc_tos(), lp_sub
, snum
),
291 printing_type
, lpq_cmd
, &q
, &status
);
294 for (i
= 0; i
< ret
; i
++) {
295 if (strcmp(q
[i
].fs_file
, p
) == 0) {
296 pjob
->sysjob
= q
[i
].sysjob
;
297 DEBUG(5, ("new job %u (%s) matches sysjob %d\n",
298 pjob
->jobid
, jobname
, pjob
->sysjob
));
305 if (pjob
->sysjob
== -1) {
306 DEBUG(2, ("failed to get sysjob for job %u (%s), tracking as "
307 "Unix job\n", pjob
->jobid
, jobname
));
313 if (chdir(current_directory
) == -1) {
314 smb_panic("chdir failed in generic_job_submit");
316 TALLOC_FREE(current_directory
);
320 /****************************************************************************
322 ****************************************************************************/
323 static int generic_queue_pause(int snum
)
325 const struct loadparm_substitution
*lp_sub
=
326 loadparm_s3_global_substitution();
328 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
329 lp_queuepause_command(snum
), NULL
, NULL
);
332 /****************************************************************************
334 ****************************************************************************/
335 static int generic_queue_resume(int snum
)
337 const struct loadparm_substitution
*lp_sub
=
338 loadparm_s3_global_substitution();
340 return print_run_command(snum
, lp_printername(talloc_tos(), lp_sub
, snum
), True
,
341 lp_queueresume_command(snum
), NULL
, NULL
);
344 /****************************************************************************
345 * Generic printing interface definitions...
346 ***************************************************************************/
348 struct printif generic_printif
=
353 generic_queue_resume
,