s3-libsmb: Fix possible comparsion problems.
[kai/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 "libsmb/libsmb.h"
27 #include "libsmbclient.h"
28 #include "libsmb_internal.h"
29
30
31 /*
32  * Open a print file to be written to by other calls
33  */
34
35 SMBCFILE *
36 SMBC_open_print_job_ctx(SMBCCTX *context,
37                         const char *fname)
38 {
39         char *server = NULL;
40         char *share = NULL;
41         char *user = NULL;
42         char *password = NULL;
43         char *path = NULL;
44         TALLOC_CTX *frame = talloc_stackframe();
45
46         if (!context || !context->internal->initialized) {
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 smbc_getFunctionOpen(context)(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         smbc_open_fn f_open1;
97         smbc_open_print_job_fn f_open_pj2;
98         int bytes;
99         int saverr;
100         int tot_bytes = 0;
101         char buf[4096];
102         TALLOC_CTX *frame = talloc_stackframe();
103
104         if (!c_file || !c_file->internal->initialized ||
105             !c_print || !c_print->internal->initialized) {
106                 errno = EINVAL;
107                 TALLOC_FREE(frame);
108                 return -1;
109         }
110
111         if (!fname && !printq) {
112                 errno = EINVAL;
113                 TALLOC_FREE(frame);
114                 return -1;
115         }
116
117         /* Try to open the file for reading ... */
118         f_open1 = smbc_getFunctionOpen(c_file);
119         if (f_open1 == NULL) {
120                 errno = EINVAL;
121                 TALLOC_FREE(frame);
122                 return -1;
123         }
124
125         fid1 = f_open1(c_file, fname, O_RDONLY, 0666);
126         if (fid1 < 0) {
127                 DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
128                 TALLOC_FREE(frame);
129                 return -1;  /* smbc_open sets errno */
130         }
131
132         /* Now, try to open the printer file for writing */
133         f_open_pj2 = smbc_getFunctionOpenPrintJob(c_print);
134         if (f_open_pj2 == NULL) {
135                 errno = EINVAL;
136                 TALLOC_FREE(frame);
137                 return -1;
138         }
139
140         fid2 = f_open_pj2(c_print, printq);
141         if (fid2 < 0) {
142                 saverr = errno;  /* Save errno */
143                 smbc_getFunctionClose(c_file)(c_file, fid1);
144                 errno = saverr;
145                 TALLOC_FREE(frame);
146                 return -1;
147         }
148
149         while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1,
150                                                      buf, sizeof(buf))) > 0) {
151                 tot_bytes += bytes;
152
153                 if ((smbc_getFunctionWrite(c_print)(c_print, fid2,
154                                                     buf, bytes)) < 0) {
155                         saverr = errno;
156                         smbc_getFunctionClose(c_file)(c_file, fid1);
157                         smbc_getFunctionClose(c_print)(c_print, fid2);
158                         errno = saverr;
159                 }
160         }
161
162         saverr = errno;
163
164         smbc_getFunctionClose(c_file)(c_file, fid1);
165         smbc_getFunctionClose(c_print)(c_print, fid2);
166
167         if (bytes < 0) {
168                 errno = saverr;
169                 TALLOC_FREE(frame);
170                 return -1;
171         }
172
173         TALLOC_FREE(frame);
174         return tot_bytes;
175 }
176
177 /*
178  * Routine to list print jobs on a printer share ...
179  */
180
181 int
182 SMBC_list_print_jobs_ctx(SMBCCTX *context,
183                          const char *fname,
184                          smbc_list_print_job_fn fn)
185 {
186         SMBCSRV *srv = NULL;
187         char *server = NULL;
188         char *share = NULL;
189         char *user = NULL;
190         char *password = NULL;
191         char *workgroup = NULL;
192         char *path = NULL;
193         TALLOC_CTX *frame = talloc_stackframe();
194
195         if (!context || !context->internal->initialized) {
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, smbc_getUser(context));
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  * Delete a print job from a remote printer share
254  */
255
256 int
257 SMBC_unlink_print_job_ctx(SMBCCTX *context,
258                           const char *fname,
259                           int id)
260 {
261         SMBCSRV *srv = NULL;
262         char *server = NULL;
263         char *share = NULL;
264         char *user = NULL;
265         char *password = NULL;
266         char *workgroup = NULL;
267         char *path = NULL;
268         int err;
269         TALLOC_CTX *frame = talloc_stackframe();
270
271         if (!context || !context->internal->initialized) {
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, smbc_getUser(context));
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                 TALLOC_FREE(frame);
314                 return -1;  /* errno set by SMBC_server */
315         }
316
317         if ((err = cli_printjob_del(srv->cli, id)) != 0) {
318                 if (err < 0)
319                         errno = SMBC_errno(context, srv->cli);
320                 else if (err == ERRnosuchprintjob)
321                         errno = EINVAL;
322                 TALLOC_FREE(frame);
323                 return -1;
324         }
325
326         TALLOC_FREE(frame);
327         return 0;
328 }
329