~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/libcli/clireadwrite.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
   client file read/write routines
 
4
   Copyright (C) Andrew Tridgell 1994-1998
 
5
   Copyright (C) James Myers 2003
 
6
   
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
 
11
   
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
   
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
*/
 
20
 
 
21
#include "includes.h"
 
22
#include "libcli/raw/libcliraw.h"
 
23
#include "libcli/raw/raw_proto.h"
 
24
#include "libcli/libcli.h"
 
25
 
 
26
/****************************************************************************
 
27
  Read size bytes at offset offset using SMBreadX.
 
28
****************************************************************************/
 
29
ssize_t smbcli_read(struct smbcli_tree *tree, int fnum, void *_buf, off_t offset, 
 
30
                 size_t size)
 
31
{
 
32
        uint8_t *buf = (uint8_t *)_buf;
 
33
        union smb_read parms;
 
34
        int readsize;
 
35
        ssize_t total = 0;
 
36
        
 
37
        if (size == 0) {
 
38
                return 0;
 
39
        }
 
40
 
 
41
        parms.readx.level = RAW_READ_READX;
 
42
        parms.readx.in.file.fnum = fnum;
 
43
 
 
44
        /*
 
45
         * Set readsize to the maximum size we can handle in one readX,
 
46
         * rounded down to a multiple of 1024.
 
47
         */
 
48
        readsize = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32));
 
49
        if (readsize > 0xFFFF) readsize = 0xFFFF;
 
50
 
 
51
        while (total < size) {
 
52
                NTSTATUS status;
 
53
 
 
54
                readsize = MIN(readsize, size-total);
 
55
 
 
56
                parms.readx.in.offset    = offset;
 
57
                parms.readx.in.mincnt    = readsize;
 
58
                parms.readx.in.maxcnt    = readsize;
 
59
                parms.readx.in.remaining = size - total;
 
60
                parms.readx.in.read_for_execute = false;
 
61
                parms.readx.out.data     = buf + total;
 
62
                
 
63
                status = smb_raw_read(tree, &parms);
 
64
                
 
65
                if (!NT_STATUS_IS_OK(status)) {
 
66
                        return -1;
 
67
                }
 
68
 
 
69
                total += parms.readx.out.nread;
 
70
                offset += parms.readx.out.nread;
 
71
 
 
72
                /* If the server returned less than we asked for we're at EOF */
 
73
                if (parms.readx.out.nread < readsize)
 
74
                        break;
 
75
        }
 
76
 
 
77
        return total;
 
78
}
 
79
 
 
80
 
 
81
/****************************************************************************
 
82
  write to a file
 
83
  write_mode: 0x0001 disallow write cacheing
 
84
              0x0002 return bytes remaining
 
85
              0x0004 use raw named pipe protocol
 
86
              0x0008 start of message mode named pipe protocol
 
87
****************************************************************************/
 
88
ssize_t smbcli_write(struct smbcli_tree *tree,
 
89
                     int fnum, uint16_t write_mode,
 
90
                     const void *_buf, off_t offset, size_t size)
 
91
{
 
92
        const uint8_t *buf = (const uint8_t *)_buf;
 
93
        union smb_write parms;
 
94
        int block = (tree->session->transport->negotiate.max_xmit - (MIN_SMB_SIZE+32));
 
95
        ssize_t total = 0;
 
96
 
 
97
        if (size == 0) {
 
98
                return 0;
 
99
        }
 
100
 
 
101
        if (block > 0xFFFF) block = 0xFFFF;
 
102
 
 
103
 
 
104
        parms.writex.level = RAW_WRITE_WRITEX;
 
105
        parms.writex.in.file.fnum = fnum;
 
106
        parms.writex.in.wmode = write_mode;
 
107
        parms.writex.in.remaining = 0;
 
108
        
 
109
        while (total < size) {
 
110
                NTSTATUS status;
 
111
 
 
112
                block = MIN(block, size - total);
 
113
 
 
114
                parms.writex.in.offset = offset;
 
115
                parms.writex.in.count = block;
 
116
                parms.writex.in.data = buf;
 
117
 
 
118
                status = smb_raw_write(tree, &parms);
 
119
 
 
120
                if (!NT_STATUS_IS_OK(status)) {
 
121
                        return -1;
 
122
                }
 
123
 
 
124
                offset += parms.writex.out.nwritten;
 
125
                total += parms.writex.out.nwritten;
 
126
                buf += parms.writex.out.nwritten;
 
127
        }
 
128
 
 
129
        return total;
 
130
}
 
131
 
 
132
/****************************************************************************
 
133
  write to a file using a SMBwrite and not bypassing 0 byte writes
 
134
****************************************************************************/
 
135
ssize_t smbcli_smbwrite(struct smbcli_tree *tree,
 
136
                     int fnum, const void *_buf, off_t offset, size_t size1)
 
137
{
 
138
        const uint8_t *buf = (const uint8_t *)_buf;
 
139
        union smb_write parms;
 
140
        ssize_t total = 0;
 
141
 
 
142
        parms.write.level = RAW_WRITE_WRITE;
 
143
        parms.write.in.remaining = 0;
 
144
        
 
145
        do {
 
146
                size_t size = MIN(size1, tree->session->transport->negotiate.max_xmit - 48);
 
147
                if (size > 0xFFFF) size = 0xFFFF;
 
148
                
 
149
                parms.write.in.file.fnum = fnum;
 
150
                parms.write.in.offset = offset;
 
151
                parms.write.in.count = size;
 
152
                parms.write.in.data = buf + total;
 
153
 
 
154
                if (NT_STATUS_IS_ERR(smb_raw_write(tree, &parms)))
 
155
                        return -1;
 
156
 
 
157
                size = parms.write.out.nwritten;
 
158
                if (size == 0)
 
159
                        break;
 
160
 
 
161
                size1 -= size;
 
162
                total += size;
 
163
                offset += size;
 
164
        } while (size1);
 
165
 
 
166
        return total;
 
167
}