The big character set handling changeover!
[jra/samba/.git] / source3 / printing / print_generic.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing command routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
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 extern int DEBUGLEVEL;
51
52 /****************************************************************************
53 run a given print command 
54 a null terminated list of value/substitute pairs is provided
55 for local substitution strings
56 ****************************************************************************/
57 static int print_run_command(int snum,char *command, int *outfd, ...)
58 {
59
60         pstring syscmd;
61         char *p, *arg;
62         int ret;
63         va_list ap;
64         va_start(ap, outfd);
65
66         if (!command || !*command) return -1;
67
68         if (!VALID_SNUM(snum)) {
69                 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
70                 return -1;
71         }
72
73         pstrcpy(syscmd, command);
74
75         while ((arg = va_arg(ap, char *))) {
76                 char *value = va_arg(ap,char *);
77                 pstring_sub(syscmd, arg, value);
78         }
79         va_end(ap);
80   
81         p = PRINTERNAME(snum);
82   
83         pstring_sub(syscmd, "%p", p);
84         standard_sub_snum(snum,syscmd);
85
86         ret = smbrun(syscmd,outfd);
87
88         DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
89
90         return ret;
91 }
92
93
94 /****************************************************************************
95 delete a print job
96 ****************************************************************************/
97 static int generic_job_delete(int snum, struct printjob *pjob)
98 {
99         fstring jobstr;
100
101         /* need to delete the spooled entry */
102         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
103         return print_run_command(
104                    snum, 
105                    lp_lprmcommand(snum), NULL,
106                    "%j", jobstr,
107                    "%T", http_timestring(pjob->starttime),
108                    NULL);
109 }
110
111 /****************************************************************************
112 pause a job
113 ****************************************************************************/
114 static int generic_job_pause(int snum, struct printjob *pjob)
115 {
116         fstring jobstr;
117         
118         /* need to pause the spooled entry */
119         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
120         return print_run_command(snum, 
121                                  lp_lppausecommand(snum), NULL,
122                                  "%j", jobstr,
123                                  NULL);
124 }
125
126 /****************************************************************************
127 resume a job
128 ****************************************************************************/
129 static int generic_job_resume(int snum, struct printjob *pjob)
130 {
131         fstring jobstr;
132         
133         /* need to pause the spooled entry */
134         slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
135         return print_run_command(snum, 
136                                  lp_lpresumecommand(snum), NULL,
137                                  "%j", jobstr,
138                                  NULL);
139 }
140
141 /****************************************************************************
142  Submit a file for printing - called from print_job_end()
143 ****************************************************************************/
144
145 static int generic_job_submit(int snum, struct printjob *pjob)
146 {
147         int ret;
148         pstring current_directory;
149         pstring print_directory;
150         char *wd, *p;
151         pstring jobname;
152
153         /* we print from the directory path to give the best chance of
154            parsing the lpq output */
155         wd = sys_getwd(current_directory);
156         if (!wd)
157                 return 0;
158
159         pstrcpy(print_directory, pjob->filename);
160         p = strrchr(print_directory,'/');
161         if (!p)
162                 return 0;
163         *p++ = 0;
164
165         if (chdir(print_directory) != 0)
166                 return 0;
167
168         pstrcpy(jobname, pjob->jobname);
169         pstring_sub(jobname, "'", "_");
170
171         /* send it to the system spooler */
172         ret = print_run_command(snum, 
173                           lp_printcommand(snum), NULL,
174                           "%s", p,
175                           "%J", jobname,
176                           "%f", p,
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 }