s4: add SMB2_FSCTL opcodes
[Samba/gbeck.git] / source3 / printing / print_generic.c
blob14f4c6dbe79e23ff5c2e00f95435ca9b3c7c243a
1 /*
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/>.
20 #include "includes.h"
21 #include "printing.h"
23 extern struct current_user current_user;
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 char *syscmd;
35 char *arg;
36 int ret;
37 TALLOC_CTX *ctx = talloc_tos();
38 va_list ap;
39 va_start(ap, outfd);
41 /* check for a valid system printername and valid command to run */
43 if ( !printername || !*printername ) {
44 va_end(ap);
45 return -1;
48 if (!command || !*command) {
49 va_end(ap);
50 return -1;
53 syscmd = talloc_strdup(ctx, command);
54 if (!syscmd) {
55 va_end(ap);
56 return -1;
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;
67 va_end(ap);
69 syscmd = talloc_string_sub(ctx, syscmd, "%p", printername);
70 if (!syscmd) {
71 return -1;
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;
88 ret = smbrun_no_sanitize(syscmd,outfd);
90 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
92 return ret;
96 /****************************************************************************
97 delete a print job
98 ****************************************************************************/
99 static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
101 fstring jobstr;
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);
111 /****************************************************************************
112 pause a job
113 ****************************************************************************/
114 static int generic_job_pause(int snum, struct printjob *pjob)
116 fstring jobstr;
118 /* need to pause the spooled entry */
119 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
120 return print_run_command(snum, lp_printername(snum), True,
121 lp_lppausecommand(snum), NULL,
122 "%j", jobstr,
123 NULL);
126 /****************************************************************************
127 resume a job
128 ****************************************************************************/
129 static int generic_job_resume(int snum, struct printjob *pjob)
131 fstring jobstr;
133 /* need to pause the spooled entry */
134 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
135 return print_run_command(snum, lp_printername(snum), True,
136 lp_lpresumecommand(snum), NULL,
137 "%j", jobstr,
138 NULL);
141 /****************************************************************************
142 Submit a file for printing - called from print_job_end()
143 ****************************************************************************/
145 static int generic_job_submit(int snum, struct printjob *pjob)
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;
156 /* we print from the directory path to give the best chance of
157 parsing the lpq output */
158 wd = sys_getwd();
159 if (!wd) {
160 return -1;
163 current_directory = talloc_strdup(ctx, wd);
164 SAFE_FREE(wd);
166 if (!current_directory) {
167 return -1;
169 print_directory = talloc_strdup(ctx, pjob->filename);
170 if (!print_directory) {
171 return -1;
173 p = strrchr_m(print_directory,'/');
174 if (!p) {
175 return -1;
177 *p++ = 0;
179 if (chdir(print_directory) != 0) {
180 return -1;
183 jobname = talloc_strdup(ctx, pjob->jobname);
184 if (!jobname) {
185 ret = -1;
186 goto out;
188 jobname = talloc_string_sub(ctx, jobname, "'", "_");
189 if (!jobname) {
190 ret = -1;
191 goto out;
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);
196 /* send it to the system spooler */
197 ret = print_run_command(snum, lp_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);
206 out:
208 if (chdir(current_directory) == -1) {
209 smb_panic("chdir failed in generic_job_submit");
211 TALLOC_FREE(current_directory);
212 return ret;
216 /****************************************************************************
217 get the current list of queued jobs
218 ****************************************************************************/
219 static 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)
225 char **qlines;
226 int fd;
227 int numlines, i, qcount;
228 print_queue_struct *queue = NULL;
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. */
234 print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
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;
242 numlines = 0;
243 qlines = fd_lines_load(fd, &numlines,0,NULL);
244 close(fd);
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;
256 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
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++;
267 TALLOC_FREE(qlines);
268 *q = queue;
269 return qcount;
272 /****************************************************************************
273 pause a queue
274 ****************************************************************************/
275 static int generic_queue_pause(int snum)
277 return print_run_command(snum, lp_printername(snum), True,
278 lp_queuepausecommand(snum), NULL, NULL);
281 /****************************************************************************
282 resume a queue
283 ****************************************************************************/
284 static int generic_queue_resume(int snum)
286 return print_run_command(snum, lp_printername(snum), True,
287 lp_queueresumecommand(snum), NULL, NULL);
290 /****************************************************************************
291 * Generic printing interface definitions...
292 ***************************************************************************/
294 struct printif generic_printif =
296 DEFAULT_PRINTING,
297 generic_queue_get,
298 generic_queue_pause,
299 generic_queue_resume,
300 generic_job_delete,
301 generic_job_pause,
302 generic_job_resume,
303 generic_job_submit,