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