545225cae4c63af48bde559698cabc19b25b8763
[samba.git] / source3 / libsmb / libsmb_printjob.c
1 /* 
2    Unix SMB/Netbios implementation.
3    SMB client library implementation
4    Copyright (C) Andrew Tridgell 1998
5    Copyright (C) Richard Sharpe 2000, 2002
6    Copyright (C) John Terpstra 2000
7    Copyright (C) Tom Jansen (Ninja ISD) 2002 
8    Copyright (C) Derrell Lipman 2003-2008
9    Copyright (C) Jeremy Allison 2007, 2008
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "libsmbclient.h"
27 #include "libsmb_internal.h"
28
29
30 /*
31  * Open a print file to be written to by other calls
32  */
33
34 SMBCFILE *
35 SMBC_open_print_job_ctx(SMBCCTX *context,
36                         const char *fname)
37 {
38         char *server = NULL;
39         char *share = NULL;
40         char *user = NULL;
41         char *password = NULL;
42         char *path = NULL;
43         TALLOC_CTX *frame = talloc_stackframe();
44         
45         if (!context || !context->internal->initialized) {
46                 
47                 errno = EINVAL;
48                 TALLOC_FREE(frame);
49                 return NULL;
50         }
51         
52         if (!fname) {
53                 errno = EINVAL;
54                 TALLOC_FREE(frame);
55                 return NULL;
56         }
57         
58         DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname));
59         
60         if (SMBC_parse_path(frame,
61                             context,
62                             fname,
63                             NULL,
64                             &server,
65                             &share,
66                             &path,
67                             &user,
68                             &password,
69                             NULL)) {
70                 errno = EINVAL;
71                 TALLOC_FREE(frame);
72                 return NULL;
73         }
74         
75         /* What if the path is empty, or the file exists? */
76         
77         TALLOC_FREE(frame);
78         return (context->posix_emu.open_fn)(context, fname, O_WRONLY, 666);
79 }
80
81 /*
82  * Routine to print a file on a remote server ...
83  *
84  * We open the file, which we assume to be on a remote server, and then
85  * copy it to a print file on the share specified by printq.
86  */
87
88 int
89 SMBC_print_file_ctx(SMBCCTX *c_file,
90                     const char *fname,
91                     SMBCCTX *c_print,
92                     const char *printq)
93 {
94         SMBCFILE *fid1;
95         SMBCFILE *fid2;
96         int bytes;
97         int saverr;
98         int tot_bytes = 0;
99         char buf[4096];
100         TALLOC_CTX *frame = talloc_stackframe();
101         
102         if (!c_file || !c_file->internal->initialized ||
103             !c_print || !c_print->internal->initialized) {
104                 
105                 errno = EINVAL;
106                 TALLOC_FREE(frame);
107                 return -1;
108                 
109         }
110         
111         if (!fname && !printq) {
112                 
113                 errno = EINVAL;
114                 TALLOC_FREE(frame);
115                 return -1;
116                 
117         }
118         
119         /* Try to open the file for reading ... */
120         
121         if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname,
122                                                        O_RDONLY, 0666)) < 0) {
123                 DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
124                 TALLOC_FREE(frame);
125                 return -1;  /* smbc_open sets errno */
126         }
127         
128         /* Now, try to open the printer file for writing */
129         
130         if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print,
131                                                                 printq)) < 0) {
132                 
133                 saverr = errno;  /* Save errno */
134                 smbc_getFunctionClose(c_file)(c_file, fid1);
135                 errno = saverr;
136                 TALLOC_FREE(frame);
137                 return -1;
138                 
139         }
140         
141         while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1,
142                                                      buf, sizeof(buf))) > 0) {
143                 
144                 tot_bytes += bytes;
145                 
146                 if ((smbc_getFunctionWrite(c_print)(c_print, fid2,
147                                                     buf, bytes)) < 0) {
148                         
149                         saverr = errno;
150                         smbc_getFunctionClose(c_file)(c_file, fid1);
151                         smbc_getFunctionClose(c_print)(c_print, fid2);
152                         errno = saverr;
153                         
154                 }
155                 
156         }
157         
158         saverr = errno;
159         
160         smbc_getFunctionClose(c_file)(c_file, fid1);
161         smbc_getFunctionClose(c_print)(c_print, fid2);
162         
163         if (bytes < 0) {
164                 
165                 errno = saverr;
166                 TALLOC_FREE(frame);
167                 return -1;
168                 
169         }
170         
171         TALLOC_FREE(frame);
172         return tot_bytes;
173         
174 }
175
176 /*
177  * Routine to list print jobs on a printer share ...
178  */
179
180 int
181 SMBC_list_print_jobs_ctx(SMBCCTX *context,
182                          const char *fname,
183                          smbc_list_print_job_fn fn)
184 {
185         SMBCSRV *srv = NULL;
186         char *server = NULL;
187         char *share = NULL;
188         char *user = NULL;
189         char *password = NULL;
190         char *workgroup = NULL;
191         char *path = NULL;
192         TALLOC_CTX *frame = talloc_stackframe();
193         
194         if (!context || !context->internal->initialized) {
195                 
196                 errno = EINVAL;
197                 TALLOC_FREE(frame);
198                 return -1;
199         }
200         
201         if (!fname) {
202                 errno = EINVAL;
203                 TALLOC_FREE(frame);
204                 return -1;
205         }
206         
207         DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
208         
209         if (SMBC_parse_path(frame,
210                             context,
211                             fname,
212                             &workgroup,
213                             &server,
214                             &share,
215                             &path,
216                             &user,
217                             &password,
218                             NULL)) {
219                 errno = EINVAL;
220                 TALLOC_FREE(frame);
221                 return -1;
222         }
223         
224         if (!user || user[0] == (char)0) {
225                 user = talloc_strdup(frame, context->config.user);
226                 if (!user) {
227                         errno = ENOMEM;
228                         TALLOC_FREE(frame);
229                         return -1;
230                 }
231         }
232         
233         srv = SMBC_server(frame, context, True,
234                           server, share, &workgroup, &user, &password);
235         
236         if (!srv) {
237                 TALLOC_FREE(frame);
238                 return -1;  /* errno set by SMBC_server */
239         }
240         
241         if (cli_print_queue(srv->cli,
242                             (void (*)(struct print_job_info *))fn) < 0) {
243                 errno = SMBC_errno(context, srv->cli);
244                 TALLOC_FREE(frame);
245                 return -1;
246         }
247         
248         TALLOC_FREE(frame);
249         return 0;
250         
251 }
252
253 /*
254  * Delete a print job from a remote printer share
255  */
256
257 int
258 SMBC_unlink_print_job_ctx(SMBCCTX *context,
259                           const char *fname,
260                           int id)
261 {
262         SMBCSRV *srv = NULL;
263         char *server = NULL;
264         char *share = NULL;
265         char *user = NULL;
266         char *password = NULL;
267         char *workgroup = NULL;
268         char *path = NULL;
269         int err;
270         TALLOC_CTX *frame = talloc_stackframe();
271         
272         if (!context || !context->internal->initialized) {
273                 
274                 errno = EINVAL;
275                 TALLOC_FREE(frame);
276                 return -1;
277         }
278         
279         if (!fname) {
280                 errno = EINVAL;
281                 TALLOC_FREE(frame);
282                 return -1;
283         }
284         
285         DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
286         
287         if (SMBC_parse_path(frame,
288                             context,
289                             fname,
290                             &workgroup,
291                             &server,
292                             &share,
293                             &path,
294                             &user,
295                             &password,
296                             NULL)) {
297                 errno = EINVAL;
298                 TALLOC_FREE(frame);
299                 return -1;
300         }
301         
302         if (!user || user[0] == (char)0) {
303                 user = talloc_strdup(frame, context->config.user);
304                 if (!user) {
305                         errno = ENOMEM;
306                         TALLOC_FREE(frame);
307                         return -1;
308                 }
309         }
310         
311         srv = SMBC_server(frame, context, True,
312                           server, share, &workgroup, &user, &password);
313         
314         if (!srv) {
315                 
316                 TALLOC_FREE(frame);
317                 return -1;  /* errno set by SMBC_server */
318                 
319         }
320         
321         if ((err = cli_printjob_del(srv->cli, id)) != 0) {
322                 
323                 if (err < 0)
324                         errno = SMBC_errno(context, srv->cli);
325                 else if (err == ERRnosuchprintjob)
326                         errno = EINVAL;
327                 TALLOC_FREE(frame);
328                 return -1;
329                 
330         }
331         
332         TALLOC_FREE(frame);
333         return 0;
334         
335 }
336