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