Remove pstring from printing/*.c except for the
[ira/wip.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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "printing.h"
22
23 extern struct current_user current_user;
24 extern 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 ****************************************************************************/
31 static 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                 return -1;
45         }
46
47         if (!command || !*command) {
48                 return -1;
49         }
50
51         syscmd = talloc_strdup(ctx, command);
52         if (!syscmd) {
53                 return -1;
54         }
55
56         while ((arg = va_arg(ap, char *))) {
57                 char *value = va_arg(ap,char *);
58                 syscmd = talloc_string_sub(ctx, syscmd, arg, value);
59                 if (!syscmd) {
60                         return -1;
61                 }
62         }
63         va_end(ap);
64
65         syscmd = talloc_string_sub(ctx, syscmd, "%p", printername);
66         if (!syscmd) {
67                 return -1;
68         }
69
70         if (do_sub && snum != -1) {
71                 syscmd = talloc_sub_advanced(ctx,
72                                 lp_servicename(snum),
73                                 current_user_info.unix_name,
74                                 "",
75                                 current_user.ut.gid,
76                                 get_current_username(),
77                                 current_user_info.domain,
78                                 syscmd);
79                 if (!syscmd) {
80                         return -1;
81                 }
82         }
83
84         ret = smbrun_no_sanitize(syscmd,outfd);
85
86         DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
87
88         return ret;
89 }
90
91
92 /****************************************************************************
93 delete a print job
94 ****************************************************************************/
95 static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
96 {
97         fstring jobstr;
98
99         /* need to delete the spooled entry */
100         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
101         return print_run_command( -1, sharename, False, lprm_command, NULL,
102                    "%j", jobstr,
103                    "%T", http_timestring(pjob->starttime),
104                    NULL);
105 }
106
107 /****************************************************************************
108 pause a job
109 ****************************************************************************/
110 static int generic_job_pause(int snum, struct printjob *pjob)
111 {
112         fstring jobstr;
113         
114         /* need to pause the spooled entry */
115         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
116         return print_run_command(snum, PRINTERNAME(snum), True,
117                                  lp_lppausecommand(snum), NULL,
118                                  "%j", jobstr,
119                                  NULL);
120 }
121
122 /****************************************************************************
123 resume a job
124 ****************************************************************************/
125 static int generic_job_resume(int snum, struct printjob *pjob)
126 {
127         fstring jobstr;
128
129         /* need to pause the spooled entry */
130         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
131         return print_run_command(snum, PRINTERNAME(snum), True,
132                                  lp_lpresumecommand(snum), NULL,
133                                  "%j", jobstr,
134                                  NULL);
135 }
136
137 /****************************************************************************
138  Submit a file for printing - called from print_job_end()
139 ****************************************************************************/
140
141 static int generic_job_submit(int snum, struct printjob *pjob)
142 {
143         int ret = -1;
144         char *current_directory = NULL;
145         char *print_directory = NULL;
146         char *wd = NULL;
147         char *p = NULL;
148         char *jobname = NULL;
149         TALLOC_CTX *ctx = talloc_tos();
150         fstring job_page_count, job_size;
151
152         /* we print from the directory path to give the best chance of
153            parsing the lpq output */
154         current_directory = TALLOC_ARRAY(ctx,
155                                         char,
156                                         PATH_MAX+1);
157         if (!current_directory) {
158                 return -1;
159         }
160         wd = sys_getwd(current_directory);
161         if (!wd) {
162                 return -1;
163         }
164
165         print_directory = talloc_strdup(ctx, pjob->filename);
166         if (!print_directory) {
167                 return -1;
168         }
169         p = strrchr_m(print_directory,'/');
170         if (!p) {
171                 return -1;
172         }
173         *p++ = 0;
174
175         if (chdir(print_directory) != 0) {
176                 return -1;
177         }
178
179         jobname = talloc_strdup(ctx, pjob->jobname);
180         if (!jobname) {
181                 ret = -1;
182                 goto out;
183         }
184         jobname = talloc_string_sub(ctx, jobname, "'", "_");
185         if (!jobname) {
186                 ret = -1;
187                 goto out;
188         }
189         slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
190         slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
191
192         /* send it to the system spooler */
193         ret = print_run_command(snum, PRINTERNAME(snum), True,
194                         lp_printcommand(snum), NULL,
195                         "%s", p,
196                         "%J", jobname,
197                         "%f", p,
198                         "%z", job_size,
199                         "%c", job_page_count,
200                         NULL);
201
202  out:
203
204         chdir(wd);
205         TALLOC_FREE(current_directory);
206         return ret;
207 }
208
209
210 /****************************************************************************
211 get the current list of queued jobs
212 ****************************************************************************/
213 static int generic_queue_get(const char *printer_name, 
214                              enum printing_types printing_type,
215                              char *lpq_command,
216                              print_queue_struct **q, 
217                              print_status_struct *status)
218 {
219         char **qlines;
220         int fd;
221         int numlines, i, qcount;
222         print_queue_struct *queue = NULL;
223         
224         /* never do substitution when running the 'lpq command' since we can't
225            get it rigt when using the background update daemon.  Make the caller 
226            do it before passing off the command string to us here. */
227
228         print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
229
230         if (fd == -1) {
231                 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
232                         printer_name ));
233                 return 0;
234         }
235         
236         numlines = 0;
237         qlines = fd_lines_load(fd, &numlines,0);
238         close(fd);
239
240         /* turn the lpq output into a series of job structures */
241         qcount = 0;
242         ZERO_STRUCTP(status);
243         if (numlines && qlines) {
244                 queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1);
245                 if (!queue) {
246                         file_lines_free(qlines);
247                         *q = NULL;
248                         return 0;
249                 }
250                 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
251
252                 for (i=0; i<numlines; i++) {
253                         /* parse the line */
254                         if (parse_lpq_entry(printing_type,qlines[i],
255                                             &queue[qcount],status,qcount==0)) {
256                                 qcount++;
257                         }
258                 }               
259         }
260
261         file_lines_free(qlines);
262         *q = queue;
263         return qcount;
264 }
265
266 /****************************************************************************
267  pause a queue
268 ****************************************************************************/
269 static int generic_queue_pause(int snum)
270 {
271         return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
272 }
273
274 /****************************************************************************
275  resume a queue
276 ****************************************************************************/
277 static int generic_queue_resume(int snum)
278 {
279         return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
280 }
281
282 /****************************************************************************
283  * Generic printing interface definitions...
284  ***************************************************************************/
285
286 struct printif  generic_printif =
287 {
288         DEFAULT_PRINTING,
289         generic_queue_get,
290         generic_queue_pause,
291         generic_queue_resume,
292         generic_job_delete,
293         generic_job_pause,
294         generic_job_resume,
295         generic_job_submit,
296 };
297