r20124: clean up nested extern declaration warnings
[Samba.git] / source3 / printing / print_generic.c
blob1e55f712c5395fb57738d992f340586d7f0bfabd
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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
22 #include "printing.h"
24 extern struct current_user current_user;
25 extern userdom_struct current_user_info;
27 /****************************************************************************
28 run a given print command
29 a null terminated list of value/substitute pairs is provided
30 for local substitution strings
31 ****************************************************************************/
32 static int print_run_command(int snum, const char* printername, BOOL do_sub,
33 const char *command, int *outfd, ...)
35 pstring syscmd;
36 char *arg;
37 int ret;
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 return -1;
46 if (!command || !*command)
47 return -1;
49 pstrcpy(syscmd, command);
51 while ((arg = va_arg(ap, char *))) {
52 char *value = va_arg(ap,char *);
53 pstring_sub(syscmd, arg, value);
55 va_end(ap);
57 pstring_sub( syscmd, "%p", printername );
59 if ( do_sub && snum != -1 )
60 standard_sub_advanced(lp_servicename(snum),
61 current_user_info.unix_name, "",
62 current_user.ut.gid,
63 get_current_username(),
64 current_user_info.domain,
65 syscmd, sizeof(syscmd));
67 ret = smbrun(syscmd,outfd);
69 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
71 return ret;
75 /****************************************************************************
76 delete a print job
77 ****************************************************************************/
78 static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
80 fstring jobstr;
82 /* need to delete the spooled entry */
83 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
84 return print_run_command( -1, sharename, False, lprm_command, NULL,
85 "%j", jobstr,
86 "%T", http_timestring(pjob->starttime),
87 NULL);
90 /****************************************************************************
91 pause a job
92 ****************************************************************************/
93 static int generic_job_pause(int snum, struct printjob *pjob)
95 fstring jobstr;
97 /* need to pause the spooled entry */
98 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
99 return print_run_command(snum, PRINTERNAME(snum), True,
100 lp_lppausecommand(snum), NULL,
101 "%j", jobstr,
102 NULL);
105 /****************************************************************************
106 resume a job
107 ****************************************************************************/
108 static int generic_job_resume(int snum, struct printjob *pjob)
110 fstring jobstr;
112 /* need to pause the spooled entry */
113 slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
114 return print_run_command(snum, PRINTERNAME(snum), True,
115 lp_lpresumecommand(snum), NULL,
116 "%j", jobstr,
117 NULL);
120 /****************************************************************************
121 Submit a file for printing - called from print_job_end()
122 ****************************************************************************/
124 static int generic_job_submit(int snum, struct printjob *pjob)
126 int ret;
127 pstring current_directory;
128 pstring print_directory;
129 char *wd, *p;
130 pstring jobname;
131 fstring job_page_count, job_size;
133 /* we print from the directory path to give the best chance of
134 parsing the lpq output */
135 wd = sys_getwd(current_directory);
136 if (!wd)
137 return 0;
139 pstrcpy(print_directory, pjob->filename);
140 p = strrchr_m(print_directory,'/');
141 if (!p)
142 return 0;
143 *p++ = 0;
145 if (chdir(print_directory) != 0)
146 return 0;
148 pstrcpy(jobname, pjob->jobname);
149 pstring_sub(jobname, "'", "_");
150 slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
151 slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
153 /* send it to the system spooler */
154 ret = print_run_command(snum, PRINTERNAME(snum), True,
155 lp_printcommand(snum), NULL,
156 "%s", p,
157 "%J", jobname,
158 "%f", p,
159 "%z", job_size,
160 "%c", job_page_count,
161 NULL);
163 chdir(wd);
165 return ret;
169 /****************************************************************************
170 get the current list of queued jobs
171 ****************************************************************************/
172 static int generic_queue_get(const char *printer_name,
173 enum printing_types printing_type,
174 char *lpq_command,
175 print_queue_struct **q,
176 print_status_struct *status)
178 char **qlines;
179 int fd;
180 int numlines, i, qcount;
181 print_queue_struct *queue = NULL;
183 /* never do substitution when running the 'lpq command' since we can't
184 get it rigt when using the background update daemon. Make the caller
185 do it before passing off the command string to us here. */
187 print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
189 if (fd == -1) {
190 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
191 printer_name ));
192 return 0;
195 numlines = 0;
196 qlines = fd_lines_load(fd, &numlines,0);
197 close(fd);
199 /* turn the lpq output into a series of job structures */
200 qcount = 0;
201 ZERO_STRUCTP(status);
202 if (numlines && qlines) {
203 queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1);
204 if (!queue) {
205 file_lines_free(qlines);
206 *q = NULL;
207 return 0;
209 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
211 for (i=0; i<numlines; i++) {
212 /* parse the line */
213 if (parse_lpq_entry(printing_type,qlines[i],
214 &queue[qcount],status,qcount==0)) {
215 qcount++;
220 file_lines_free(qlines);
221 *q = queue;
222 return qcount;
225 /****************************************************************************
226 pause a queue
227 ****************************************************************************/
228 static int generic_queue_pause(int snum)
230 return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
233 /****************************************************************************
234 resume a queue
235 ****************************************************************************/
236 static int generic_queue_resume(int snum)
238 return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
241 /****************************************************************************
242 * Generic printing interface definitions...
243 ***************************************************************************/
245 struct printif generic_printif =
247 DEFAULT_PRINTING,
248 generic_queue_get,
249 generic_queue_pause,
250 generic_queue_resume,
251 generic_job_delete,
252 generic_job_pause,
253 generic_job_resume,
254 generic_job_submit,