import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / 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 2 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
25 /*
26  * Generic printing interface definitions...
27  */
28
29 static int generic_job_delete(int snum, struct printjob *pjob);
30 static int generic_job_pause(int snum, struct printjob *pjob);
31 static int generic_job_resume(int snum, struct printjob *pjob);
32 static int generic_job_submit(int snum, struct printjob *pjob);
33 static int generic_queue_get(int snum, print_queue_struct **q,
34                              print_status_struct *status);
35 static int generic_queue_pause(int snum);
36 static int generic_queue_resume(int snum);
37
38
39 struct printif  generic_printif =
40                 {
41                   generic_queue_get,
42                   generic_queue_pause,
43                   generic_queue_resume,
44                   generic_job_delete,
45                   generic_job_pause,
46                   generic_job_resume,
47                   generic_job_submit,
48                 };
49
50 /****************************************************************************
51 run a given print command 
52 a null terminated list of value/substitute pairs is provided
53 for local substitution strings
54 ****************************************************************************/
55 static int print_run_command(int snum,char *command, int *outfd, ...)
56 {
57
58         pstring syscmd;
59         char *arg;
60         int ret;
61         va_list ap;
62         va_start(ap, outfd);
63
64         if (!command || !*command) return -1;
65
66         if (!VALID_SNUM(snum)) {
67                 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
68                 return -1;
69         }
70
71         pstrcpy(syscmd, command);
72
73         while ((arg = va_arg(ap, char *))) {
74                 char *value = va_arg(ap,char *);
75                 pstring_sub(syscmd, arg, value);
76         }
77         va_end(ap);
78   
79         pstring_sub(syscmd, "%p", PRINTERNAME(snum));
80         standard_sub_snum(snum,syscmd,sizeof(syscmd));
81
82         ret = smbrun(syscmd,outfd);
83
84         DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
85
86         return ret;
87 }
88
89
90 /****************************************************************************
91 delete a print job
92 ****************************************************************************/
93 static int generic_job_delete(int snum, struct printjob *pjob)
94 {
95         fstring jobstr;
96
97         /* need to delete the spooled entry */
98         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
99         return print_run_command(
100                    snum, 
101                    lp_lprmcommand(snum), 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, 
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, 
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;
144         pstring current_directory;
145         pstring print_directory;
146         char *wd, *p;
147         pstring jobname;
148         fstring job_page_count, job_size;
149
150         /* we print from the directory path to give the best chance of
151            parsing the lpq output */
152         wd = sys_getwd(current_directory);
153         if (!wd)
154                 return 0;
155
156         pstrcpy(print_directory, pjob->filename);
157         p = strrchr_m(print_directory,'/');
158         if (!p)
159                 return 0;
160         *p++ = 0;
161
162         if (chdir(print_directory) != 0)
163                 return 0;
164
165         pstrcpy(jobname, pjob->jobname);
166         pstring_sub(jobname, "'", "_");
167         slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
168         slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
169
170         /* send it to the system spooler */
171         ret = print_run_command(snum, 
172                         lp_printcommand(snum), NULL,
173                         "%s", p,
174                         "%J", jobname,
175                         "%f", p,
176                         "%z", job_size,
177                         "%c", job_page_count,
178                         NULL);
179
180         chdir(wd);
181
182         return ret;
183 }
184
185
186 /****************************************************************************
187 get the current list of queued jobs
188 ****************************************************************************/
189 static int generic_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
190 {
191         char **qlines;
192         int fd;
193         int numlines, i, qcount;
194         print_queue_struct *queue = NULL;
195         fstring printer_name;
196               
197         fstrcpy(printer_name, lp_servicename(snum));
198         
199         print_run_command(snum, lp_lpqcommand(snum), &fd, NULL);
200
201         if (fd == -1) {
202                 DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
203                         printer_name ));
204                 return 0;
205         }
206         
207         numlines = 0;
208         qlines = fd_lines_load(fd, &numlines);
209         close(fd);
210
211         /* turn the lpq output into a series of job structures */
212         qcount = 0;
213         ZERO_STRUCTP(status);
214         if (numlines)
215                 queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
216
217         if (queue) {
218                 memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
219                 for (i=0; i<numlines; i++) {
220                         /* parse the line */
221                         if (parse_lpq_entry(snum,qlines[i],
222                                             &queue[qcount],status,qcount==0)) {
223                                 qcount++;
224                         }
225                 }               
226         }
227         file_lines_free(qlines);
228
229         *q = queue;
230         return qcount;
231 }
232
233 /****************************************************************************
234  pause a queue
235 ****************************************************************************/
236 static int generic_queue_pause(int snum)
237 {
238         return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL);
239 }
240
241 /****************************************************************************
242  resume a queue
243 ****************************************************************************/
244 static int generic_queue_resume(int snum)
245 {
246         return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL);
247 }