source: trunk/samba/source/libsmb/cliprint.c @ 26

Last change on this file since 26 was 26, checked in by Paul Smedley, 14 years ago

Updated source to 3.0.25rc1

File size: 9.5 KB
Line 
1/*
2   Unix SMB/CIFS implementation.
3   client print routines
4   Copyright (C) Andrew Tridgell 1994-1998
5   
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10   
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15   
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "includes.h"
22
23/*****************************************************************************
24 Convert a character pointer in a cli_call_api() response to a form we can use.
25 This function contains code to prevent core dumps if the server returns
26 invalid data.
27*****************************************************************************/
28static const char *fix_char_ptr(unsigned int datap, unsigned int converter, 
29                          char *rdata, int rdrcnt)
30{
31        if (datap == 0) {       /* turn NULL pointers into zero length strings */
32                return "";
33        } else {
34                unsigned int offset = datap - converter;
35
36                if (offset >= rdrcnt) {
37                        DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>",
38                                 datap, converter, rdrcnt));
39                        return "<ERROR>";
40                } else {
41                        return &rdata[offset];
42                }
43        }
44}
45
46
47/****************************************************************************
48call fn() on each entry in a print queue
49****************************************************************************/
50int cli_print_queue(struct cli_state *cli, 
51                    void (*fn)(struct print_job_info *))
52{
53        char *rparam = NULL;
54        char *rdata = NULL;
55        char *p;
56        unsigned int rdrcnt, rprcnt;
57        pstring param;
58        int result_code=0;
59        int i = -1;
60       
61        memset(param,'\0',sizeof(param));
62
63        p = param;
64        SSVAL(p,0,76);         /* API function number 76 (DosPrintJobEnum) */
65        p += 2;
66        pstrcpy_base(p,"zWrLeh", param);   /* parameter description? */
67        p = skip_string(param,sizeof(param),p);
68        pstrcpy_base(p,"WWzWWDDzz", param);  /* returned data format */
69        p = skip_string(param,sizeof(param),p);
70        pstrcpy_base(p,cli->share, param);    /* name of queue */
71        p = skip_string(param,sizeof(param),p);
72        SSVAL(p,0,2);   /* API function level 2, PRJINFO_2 data structure */
73        SSVAL(p,2,1000); /* size of bytes of returned data buffer */
74        p += 4;
75        pstrcpy_base(p,"", param);   /* subformat */
76        p = skip_string(param,sizeof(param),p);
77
78        DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
79
80        if (cli_api(cli, 
81                    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
82                    NULL, 0, CLI_BUFFER_SIZE,            /* data, length, maxlen */
83                    &rparam, &rprcnt,                /* return params, length */
84                    &rdata, &rdrcnt)) {               /* return data, length */
85                int converter;
86                result_code = SVAL(rparam,0);
87                converter = SVAL(rparam,2);       /* conversion factor */
88
89                if (result_code == 0) {
90                        struct print_job_info job;
91                       
92                        p = rdata; 
93
94                        for (i = 0; i < SVAL(rparam,4); ++i) {
95                                job.id = SVAL(p,0);
96                                job.priority = SVAL(p,2);
97                                fstrcpy(job.user,
98                                        fix_char_ptr(SVAL(p,4), converter, 
99                                                     rdata, rdrcnt));
100                                job.t = cli_make_unix_date3(cli, p + 12);
101                                job.size = IVAL(p,16);
102                                fstrcpy(job.name,fix_char_ptr(SVAL(p,24), 
103                                                              converter, 
104                                                              rdata, rdrcnt));
105                                fn(&job);                               
106                                p += 28;
107                        }
108                }
109        }
110
111        /* If any parameters or data were returned, free the storage. */
112        SAFE_FREE(rparam);
113        SAFE_FREE(rdata);
114
115        return i;
116}
117
118#ifdef __OS2__
119/****************************************************************************
120the same as cli_print_queue, but pass a state on each fn call
121***************************************************************************/
122int cli_print_queue_state(struct cli_state *cli, 
123                    void (*fn)(struct print_job_info *, void *), void * state)
124{
125        char *rparam = NULL;
126        char *rdata = NULL;
127        char *p;
128        unsigned int rdrcnt, rprcnt;
129        pstring param;
130        int result_code=0;
131        int i = -1;
132       
133        memset(param,'\0',sizeof(param));
134
135        p = param;
136        SSVAL(p,0,76);         /* API function number 76 (DosPrintJobEnum) */
137        p += 2;
138        pstrcpy_base(p,"zWrLeh", param);   /* parameter description? */
139        p = skip_string(param,sizeof(param),p);
140        pstrcpy_base(p,"WWzWWDDzz", param);  /* returned data format */
141        p = skip_string(param,sizeof(param),p);
142        pstrcpy_base(p,cli->share, param);    /* name of queue */
143        p = skip_string(param,sizeof(param),p);
144        SSVAL(p,0,2);   /* API function level 2, PRJINFO_2 data structure */
145        SSVAL(p,2,1000); /* size of bytes of returned data buffer */
146        p += 4;
147        pstrcpy_base(p,"", param);   /* subformat */
148        p = skip_string(param,sizeof(param),p);
149
150        DEBUG(4,("doing cli_print_queue_state for %s\n", cli->share));
151
152        if (cli_api(cli, 
153                    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
154                    NULL, 0, CLI_BUFFER_SIZE,            /* data, length, maxlen */
155                    &rparam, &rprcnt,                /* return params, length */
156                    &rdata, &rdrcnt)) {               /* return data, length */
157                int converter;
158                result_code = SVAL(rparam,0);
159                converter = SVAL(rparam,2);       /* conversion factor */
160
161                if (result_code == 0) {
162                        struct print_job_info job;
163                       
164                        p = rdata; 
165
166                        for (i = 0; i < SVAL(rparam,4); ++i) {
167                                job.id = SVAL(p,0);
168                                job.priority = SVAL(p,2);
169                                fstrcpy(job.user,
170                                        fix_char_ptr(SVAL(p,4), converter, 
171                                                     rdata, rdrcnt));
172                                job.t = srv_make_unix_date3(p + 12);
173                                job.size = IVAL(p,16);
174                                fstrcpy(job.name,fix_char_ptr(SVAL(p,24), 
175                                                              converter, 
176                                                              rdata, rdrcnt));
177                                fn(&job, state);                               
178                                p += 28;
179                        }
180                }
181        }
182
183        /* If any parameters or data were returned, free the storage. */
184        SAFE_FREE(rparam);
185        SAFE_FREE(rdata);
186
187        return i;
188}
189#endif
190
191/****************************************************************************
192  cancel a print job
193  ****************************************************************************/
194int cli_printjob_del(struct cli_state *cli, int job)
195{
196        char *rparam = NULL;
197        char *rdata = NULL;
198        char *p;
199        unsigned int rdrcnt,rprcnt;
200        int ret = -1;
201        pstring param;
202
203        memset(param,'\0',sizeof(param));
204
205        p = param;
206        SSVAL(p,0,81);          /* DosPrintJobDel() */
207        p += 2;
208        pstrcpy_base(p,"W", param);
209        p = skip_string(param,sizeof(param),p);
210        pstrcpy_base(p,"", param);
211        p = skip_string(param,sizeof(param),p);
212        SSVAL(p,0,job);     
213        p += 2;
214       
215        if (cli_api(cli, 
216                    param, PTR_DIFF(p,param), 1024,  /* Param, length, maxlen */
217                    NULL, 0, CLI_BUFFER_SIZE,            /* data, length, maxlen */
218                    &rparam, &rprcnt,                /* return params, length */
219                    &rdata, &rdrcnt)) {               /* return data, length */
220                ret = SVAL(rparam,0);
221        }
222
223        SAFE_FREE(rparam);
224        SAFE_FREE(rdata);
225
226        return ret;
227}
228
229
230/****************************************************************************
231 Open a spool file
232****************************************************************************/
233
234int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_mode)
235{
236        char *p;
237        unsigned openfn=0;
238        unsigned accessmode=0;
239
240        if (flags & O_CREAT)
241                openfn |= (1<<4);
242        if (!(flags & O_EXCL)) {
243                if (flags & O_TRUNC)
244                        openfn |= (1<<1);
245                else
246                        openfn |= (1<<0);
247        }
248
249        accessmode = (share_mode<<4);
250
251        if ((flags & O_ACCMODE) == O_RDWR) {
252                accessmode |= 2;
253        } else if ((flags & O_ACCMODE) == O_WRONLY) {
254                accessmode |= 1;
255        } 
256
257#if defined(O_SYNC)
258        if ((flags & O_SYNC) == O_SYNC) {
259                accessmode |= (1<<14);
260        }
261#endif /* O_SYNC */
262
263        if (share_mode == DENY_FCB) {
264                accessmode = 0xFF;
265        }
266
267        memset(cli->outbuf,'\0',smb_size);
268        memset(cli->inbuf,'\0',smb_size);
269
270        set_message(cli->outbuf,15,0,True);
271
272        SCVAL(cli->outbuf,smb_com,SMBsplopen);
273        SSVAL(cli->outbuf,smb_tid,cli->cnum);
274        cli_setup_packet(cli);
275
276        SSVAL(cli->outbuf,smb_vwv0,0xFF);
277        SSVAL(cli->outbuf,smb_vwv2,0);  /* no additional info */
278        SSVAL(cli->outbuf,smb_vwv3,accessmode);
279        SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
280        SSVAL(cli->outbuf,smb_vwv5,0);
281        SSVAL(cli->outbuf,smb_vwv8,openfn);
282
283        if (cli->use_oplocks) {
284                /* if using oplocks then ask for a batch oplock via
285                   core and extended methods */
286                SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)|
287                        FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK);
288                SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
289        }
290 
291        p = smb_buf(cli->outbuf);
292        p += clistr_push(cli, p, fname, -1, STR_TERMINATE);
293
294        cli_setup_bcc(cli, p);
295
296        cli_send_smb(cli);
297        if (!cli_receive_smb(cli)) {
298                return -1;
299        }
300
301        if (cli_is_error(cli)) {
302                return -1;
303        }
304
305        return SVAL(cli->inbuf,smb_vwv2);
306}
307
308/****************************************************************************
309 Close a file.
310****************************************************************************/
311
312BOOL cli_spl_close(struct cli_state *cli, int fnum)
313{
314        memset(cli->outbuf,'\0',smb_size);
315        memset(cli->inbuf,'\0',smb_size);
316
317        set_message(cli->outbuf,3,0,True);
318
319        SCVAL(cli->outbuf,smb_com,SMBsplclose);
320        SSVAL(cli->outbuf,smb_tid,cli->cnum);
321        cli_setup_packet(cli);
322
323        SSVAL(cli->outbuf,smb_vwv0,fnum);
324        SIVALS(cli->outbuf,smb_vwv1,-1);
325
326        cli_send_smb(cli);
327        if (!cli_receive_smb(cli)) {
328                return False;
329        }
330
331        return !cli_is_error(cli);
332}
333
334
Note: See TracBrowser for help on using the repository browser.