r23779: Change from v2 or later to v3 or later.
[sfrench/samba-autobuild/.git] / source3 / printing / print_generic.c
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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "printing.h"
23
24 extern struct current_user current_user;
25 extern userdom_struct current_user_info;
26
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, ...)
34 {
35         pstring syscmd;
36         char *arg;
37         int ret;
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                 return -1;
45
46         if (!command || !*command) 
47                 return -1;
48
49         pstrcpy(syscmd, command);
50
51         while ((arg = va_arg(ap, char *))) {
52                 char *value = va_arg(ap,char *);
53                 pstring_sub(syscmd, arg, value);
54         }
55         va_end(ap);
56   
57         pstring_sub( syscmd, "%p", printername );
58
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));
66                 
67         ret = smbrun_no_sanitize(syscmd,outfd);
68
69         DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
70
71         return ret;
72 }
73
74
75 /****************************************************************************
76 delete a print job
77 ****************************************************************************/
78 static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
79 {
80         fstring jobstr;
81
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);
88 }
89
90 /****************************************************************************
91 pause a job
92 ****************************************************************************/
93 static int generic_job_pause(int snum, struct printjob *pjob)
94 {
95         fstring jobstr;
96         
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);
103 }
104
105 /****************************************************************************
106 resume a job
107 ****************************************************************************/
108 static int generic_job_resume(int snum, struct printjob *pjob)
109 {
110         fstring jobstr;
111         
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);
118 }
119
120 /****************************************************************************
121  Submit a file for printing - called from print_job_end()
122 ****************************************************************************/
123
124 static int generic_job_submit(int snum, struct printjob *pjob)
125 {
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;
132
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;
138
139         pstrcpy(print_directory, pjob->filename);
140         p = strrchr_m(print_directory,'/');
141         if (!p)
142                 return 0;
143         *p++ = 0;
144
145         if (chdir(print_directory) != 0)
146                 return 0;
147
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);
152
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);
162
163         chdir(wd);
164
165         return ret;
166 }
167
168
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)
177 {
178         char **qlines;
179         int fd;
180         int numlines, i, qcount;
181         print_queue_struct *queue = NULL;
182         
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. */
186
187         print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
188
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;
193         }
194         
195         numlines = 0;
196         qlines = fd_lines_load(fd, &numlines,0);
197         close(fd);
198
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;
208                 }
209                 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
210
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++;
216                         }
217                 }               
218         }
219
220         file_lines_free(qlines);
221         *q = queue;
222         return qcount;
223 }
224
225 /****************************************************************************
226  pause a queue
227 ****************************************************************************/
228 static int generic_queue_pause(int snum)
229 {
230         return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
231 }
232
233 /****************************************************************************
234  resume a queue
235 ****************************************************************************/
236 static int generic_queue_resume(int snum)
237 {
238         return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
239 }
240
241 /****************************************************************************
242  * Generic printing interface definitions...
243  ***************************************************************************/
244
245 struct printif  generic_printif =
246 {
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,
255 };
256