• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source3/printing/
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(talloc_tos(), 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	if (chdir(wd) == -1) {
209		smb_panic("chdir failed in generic_job_submit");
210	}
211	TALLOC_FREE(current_directory);
212        return ret;
213}
214
215
216/****************************************************************************
217get the current list of queued jobs
218****************************************************************************/
219static int generic_queue_get(const char *printer_name,
220                             enum printing_types printing_type,
221                             char *lpq_command,
222                             print_queue_struct **q,
223                             print_status_struct *status)
224{
225	char **qlines;
226	int fd;
227	int numlines, i, qcount;
228	print_queue_struct *queue = NULL;
229
230	/* never do substitution when running the 'lpq command' since we can't
231	   get it rigt when using the background update daemon.  Make the caller
232	   do it before passing off the command string to us here. */
233
234	print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
235
236	if (fd == -1) {
237		DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
238			printer_name ));
239		return 0;
240	}
241
242	numlines = 0;
243	qlines = fd_lines_load(fd, &numlines,0,NULL);
244	close(fd);
245
246	/* turn the lpq output into a series of job structures */
247	qcount = 0;
248	ZERO_STRUCTP(status);
249	if (numlines && qlines) {
250		queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1);
251		if (!queue) {
252			TALLOC_FREE(qlines);
253			*q = NULL;
254			return 0;
255		}
256		memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
257
258		for (i=0; i<numlines; i++) {
259			/* parse the line */
260			if (parse_lpq_entry(printing_type,qlines[i],
261					    &queue[qcount],status,qcount==0)) {
262				qcount++;
263			}
264		}
265	}
266
267	TALLOC_FREE(qlines);
268        *q = queue;
269	return qcount;
270}
271
272/****************************************************************************
273 pause a queue
274****************************************************************************/
275static int generic_queue_pause(int snum)
276{
277	return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
278}
279
280/****************************************************************************
281 resume a queue
282****************************************************************************/
283static int generic_queue_resume(int snum)
284{
285	return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
286}
287
288/****************************************************************************
289 * Generic printing interface definitions...
290 ***************************************************************************/
291
292struct printif	generic_printif =
293{
294	DEFAULT_PRINTING,
295	generic_queue_get,
296	generic_queue_pause,
297	generic_queue_resume,
298	generic_job_delete,
299	generic_job_pause,
300	generic_job_resume,
301	generic_job_submit,
302};
303
304