Initial revamp of the libsmbclient interface.
[samba.git] / source / 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->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->initialized ||
103             !c_print || !c_print->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, O_RDONLY, 0666)) < 0) {
122                 DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
123                 TALLOC_FREE(frame);
124                 return -1;  /* smbc_open sets errno */
125         }
126
127         /* Now, try to open the printer file for writing */
128
129         if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, printq)) < 0) {
130
131                 saverr = errno;  /* Save errno */
132                 smbc_getFunctionClose(c_file)(c_file, fid1);
133                 errno = saverr;
134                 TALLOC_FREE(frame);
135                 return -1;
136
137         }
138
139         while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1,
140                                                      buf, sizeof(buf))) > 0) {
141
142                 tot_bytes += bytes;
143
144                 if ((smbc_getFunctionWrite(c_print)(c_print, fid2,
145                                                     buf, bytes)) < 0) {
146
147                         saverr = errno;
148                         smbc_getFunctionClose(c_file)(c_file, fid1);
149                         smbc_getFunctionClose(c_print)(c_print, fid2);
150                         errno = saverr;
151
152                 }
153
154         }
155
156         saverr = errno;
157
158         smbc_getFunctionClose(c_file)(c_file, fid1);  /* We have to close these anyway */
159         smbc_getFunctionClose(c_print)(c_print, fid2);
160
161         if (bytes < 0) {
162
163                 errno = saverr;
164                 TALLOC_FREE(frame);
165                 return -1;
166
167         }
168
169         TALLOC_FREE(frame);
170         return tot_bytes;
171
172 }
173
174 /*
175  * Routine to list print jobs on a printer share ...
176  */
177
178 int
179 SMBC_list_print_jobs_ctx(SMBCCTX *context,
180                          const char *fname,
181                          smbc_list_print_job_fn fn)
182 {
183         SMBCSRV *srv = NULL;
184         char *server = NULL;
185         char *share = NULL;
186         char *user = NULL;
187         char *password = NULL;
188         char *workgroup = NULL;
189         char *path = NULL;
190         TALLOC_CTX *frame = talloc_stackframe();
191
192         if (!context || !context->initialized) {
193
194                 errno = EINVAL;
195                 TALLOC_FREE(frame);
196                 return -1;
197         }
198
199         if (!fname) {
200                 errno = EINVAL;
201                 TALLOC_FREE(frame);
202                 return -1;
203         }
204
205         DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname));
206
207         if (SMBC_parse_path(frame,
208                                 context,
209                                 fname,
210                                 &workgroup,
211                                 &server,
212                                 &share,
213                                 &path,
214                                 &user,
215                                 &password,
216                                 NULL)) {
217                 errno = EINVAL;
218                 TALLOC_FREE(frame);
219                 return -1;
220         }
221
222         if (!user || user[0] == (char)0) {
223                 user = talloc_strdup(frame, context->user);
224                 if (!user) {
225                         errno = ENOMEM;
226                         TALLOC_FREE(frame);
227                         return -1;
228                 }
229         }
230
231         srv = SMBC_server(frame, context, True,
232                           server, share, &workgroup, &user, &password);
233
234         if (!srv) {
235                 TALLOC_FREE(frame);
236                 return -1;  /* errno set by SMBC_server */
237         }
238
239         if (cli_print_queue(srv->cli,
240                             (void (*)(struct print_job_info *))fn) < 0) {
241                 errno = SMBC_errno(context, srv->cli);
242                 TALLOC_FREE(frame);
243                 return -1;
244         }
245
246         TALLOC_FREE(frame);
247         return 0;
248
249 }
250
251 /*
252  * Delete a print job from a remote printer share
253  */
254
255 int
256 SMBC_unlink_print_job_ctx(SMBCCTX *context,
257                           const char *fname,
258                           int id)
259 {
260         SMBCSRV *srv = NULL;
261         char *server = NULL;
262         char *share = NULL;
263         char *user = NULL;
264         char *password = NULL;
265         char *workgroup = NULL;
266         char *path = NULL;
267         int err;
268         TALLOC_CTX *frame = talloc_stackframe();
269
270         if (!context || !context->initialized) {
271
272                 errno = EINVAL;
273                 TALLOC_FREE(frame);
274                 return -1;
275         }
276
277         if (!fname) {
278                 errno = EINVAL;
279                 TALLOC_FREE(frame);
280                 return -1;
281         }
282
283         DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname));
284
285         if (SMBC_parse_path(frame,
286                                 context,
287                                 fname,
288                                 &workgroup,
289                                 &server,
290                                 &share,
291                                 &path,
292                                 &user,
293                                 &password,
294                                 NULL)) {
295                 errno = EINVAL;
296                 TALLOC_FREE(frame);
297                 return -1;
298         }
299
300         if (!user || user[0] == (char)0) {
301                 user = talloc_strdup(frame, context->user);
302                 if (!user) {
303                         errno = ENOMEM;
304                         TALLOC_FREE(frame);
305                         return -1;
306                 }
307         }
308
309         srv = SMBC_server(frame, context, True,
310                           server, share, &workgroup, &user, &password);
311
312         if (!srv) {
313
314                 TALLOC_FREE(frame);
315                 return -1;  /* errno set by SMBC_server */
316
317         }
318
319         if ((err = cli_printjob_del(srv->cli, id)) != 0) {
320
321                 if (err < 0)
322                         errno = SMBC_errno(context, srv->cli);
323                 else if (err == ERRnosuchprintjob)
324                         errno = EINVAL;
325                 TALLOC_FREE(frame);
326                 return -1;
327
328         }
329
330         TALLOC_FREE(frame);
331         return 0;
332
333 }
334