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