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