~ubuntu-filemanager-dev/ubuntu-filemanager-app/trunk

« back to all changes in this revision

Viewing changes to src/plugin/folderlistmodel/smb/qsambaclient/src/smblocationitemfile.cpp

  • Committer: Bileto Bot
  • Date: 2017-04-04 17:06:41 UTC
  • mfrom: (588.1.19 fix-desktop-file)
  • Revision ID: ci-train-bot@canonical.com-20170404170641-1p15lmx8wodlx2ut
* Rename binary file to ubuntu-filemanager-app
* Join plugin packages into the main package 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2015 Canonical Ltd.
4
 
 * Copyright 2015 Carlos J Mazieri <carlos.mazieri@gmail.com>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU Lesser General Public License as published by
8
 
 * the Free Software Foundation; version 3.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU Lesser General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU Lesser General Public License
16
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
 *
18
 
 * File: smblocationitemfile.cpp
19
 
 * Date: 20/04/2015
20
 
 */
21
 
 
22
 
#include "smblocationitemfile.h"
23
 
#include "smbiteminfo.h"
24
 
 
25
 
#include <sys/stat.h>
26
 
#include <sys/statfs.h>
27
 
#include <errno.h>
28
 
 
29
 
#include <QDebug>
30
 
 
31
 
 
32
 
SmbLocationItemFile::SmbLocationItemFile(QObject *parent, Const_SmbUtil_Ptr  smb)
33
 
  : LocationItemFile(parent)
34
 
  , SmbObject(QLatin1String(0), smb)
35
 
  , m_fd(0)
36
 
  , m_context(0)
37
 
  , m_curReadPosition(0)
38
 
  , m_openMode(0)
39
 
{
40
 
 
41
 
}
42
 
 
43
 
SmbLocationItemFile::SmbLocationItemFile(const QString &name, QObject *parent,  Const_SmbUtil_Ptr  smb)
44
 
  : LocationItemFile(parent)
45
 
  , SmbObject(name, smb)
46
 
  , m_fd(0)
47
 
  , m_context(0)
48
 
  , m_curReadPosition(0)
49
 
  , m_openMode(0)
50
 
{
51
 
 
52
 
}
53
 
 
54
 
 
55
 
SmbLocationItemFile::~SmbLocationItemFile()
56
 
{
57
 
    close();
58
 
    if (m_context)
59
 
    {
60
 
        SmbObject::smbObj()->deleteContext(m_context);
61
 
        m_context = 0;
62
 
    }
63
 
}
64
 
 
65
 
 
66
 
QString SmbLocationItemFile::fileName() const
67
 
{
68
 
    return cleanUrl();
69
 
}
70
 
 
71
 
 
72
 
bool SmbLocationItemFile::rename(const QString& newName)
73
 
{
74
 
    bool ret = false;
75
 
    if (!cleanUrl().isEmpty())
76
 
    {
77
 
        close();
78
 
        ret = rename(cleanUrl(), newName);
79
 
    }
80
 
    return ret;
81
 
}
82
 
 
83
 
 
84
 
bool SmbLocationItemFile::rename(const QString& oldname, const QString& newName)
85
 
{  
86
 
    createContext();
87
 
    Smb::Context  nContext =  SmbObject::smbObj()->createContext();
88
 
    int ret = smbc_getFunctionRename(m_context)
89
 
                                    (m_context,
90
 
                                     oldname.toLocal8Bit().constData(),
91
 
                                     nContext,
92
 
                                     newName.toLocal8Bit().constData()
93
 
                                    );
94
 
    SmbObject::smbObj()->deleteContext(nContext);
95
 
    return ret == 0;
96
 
}
97
 
 
98
 
 
99
 
bool SmbLocationItemFile::remove()
100
 
{
101
 
    return private_remove(cleanUrl());
102
 
}
103
 
 
104
 
 
105
 
bool SmbLocationItemFile::remove(const QString& name)
106
 
{
107
 
   CleanUrl otherUrl(name);
108
 
   if (otherUrl.hasAuthenticationData())
109
 
   {
110
 
       qWarning() << Q_FUNC_INFO
111
 
                  << "Authentication in the form smb://user:password@pathname is not supported" ;
112
 
   }
113
 
   return private_remove(name) ;
114
 
}
115
 
 
116
 
 
117
 
bool SmbLocationItemFile::link(const QString& linkName)
118
 
{
119
 
    Q_UNUSED(linkName);
120
 
    qWarning() << Q_FUNC_INFO << "Smbclient does not provide link() function";
121
 
    return false;
122
 
}
123
 
 
124
 
 
125
 
bool SmbLocationItemFile::open(QIODevice::OpenMode mode)
126
 
{
127
 
    bool ret = false;   
128
 
    QString smb_path = cleanUrl();    
129
 
    if (!smb_path.isEmpty() && !isOpen())
130
 
    {       
131
 
        int openFlags   = 0;
132
 
        m_openMode      = mode;
133
 
        createContext();
134
 
        if (mode & QFile::ReadOnly)
135
 
        {
136
 
            openFlags = mode & QFile::WriteOnly ? O_RDWR : O_RDONLY;
137
 
        }
138
 
        else
139
 
        {
140
 
            if (mode & QFile::WriteOnly)
141
 
            {
142
 
                openFlags = O_CREAT | O_WRONLY;
143
 
            }
144
 
            if (mode & QFile::Append)
145
 
            {
146
 
                openFlags =  O_APPEND | O_CREAT | O_WRONLY;
147
 
            }
148
 
            if ((mode & QFile::Truncate) || !(mode & QFile::Append))
149
 
            {
150
 
               openFlags |=  O_TRUNC;
151
 
            }          
152
 
        }
153
 
        int creationMode = LocationItemFile::getUmaskFilesCreation();
154
 
        /*
155
 
         *  it looks like SMB open() does set the permission properly
156
 
         *  does not matter what value "creationMode" has, libsmbclient always creates files with the following permission:
157
 
         *     -rwxr--r-- 1 nobody    nogroup  0 Mai 30 14:04 second_item.txt
158
 
         *  SMB chmod() does not work either
159
 
         *
160
 
         *  It depends on Samba configuration: force user; force group; force create mode; force directory mode
161
 
         */
162
 
        m_fd = SmbObject::smbObj()->openFile(m_context, smb_path, openFlags, creationMode);
163
 
        ret = m_fd ? true : false;
164
 
    }   
165
 
    return ret;
166
 
}
167
 
 
168
 
 
169
 
qint64 SmbLocationItemFile::read(char * buffer, qint64 bytes)
170
 
{
171
 
    qint64 ret = -1;
172
 
    if (isOpen())
173
 
    {
174
 
        size_t to_write = static_cast<size_t> (bytes);
175
 
        void *buf   = static_cast<void*> (buffer);
176
 
        ssize_t wr = smbc_getFunctionRead(m_context)(m_context, m_fd, buf, to_write);
177
 
        ret = static_cast<qint64> (wr);
178
 
    }
179
 
    if (ret > 0)
180
 
    {
181
 
        m_curReadPosition += ret;
182
 
    }
183
 
    return ret;
184
 
}
185
 
 
186
 
 
187
 
qint64 SmbLocationItemFile::write(const char * buffer, qint64 bytes)
188
 
{
189
 
    qint64 ret = -1;
190
 
    if (isOpen())
191
 
    {
192
 
        size_t to_read = static_cast<size_t> (bytes);
193
 
        const void * const_buf = static_cast<const void*> (buffer);
194
 
        void *buf   = const_cast<void*> (const_buf);
195
 
        ssize_t rd = smbc_getFunctionWrite(m_context)(m_context, m_fd, buf, to_read);
196
 
        ret = static_cast<qint64> (rd);
197
 
    }
198
 
    return ret;
199
 
}
200
 
 
201
 
 
202
 
void SmbLocationItemFile::close()
203
 
{
204
 
    if (isOpen())
205
 
    {
206
 
       SmbObject::smbObj()->closeHandle(m_context, m_fd);
207
 
       m_fd = 0;
208
 
    }
209
 
    m_curReadPosition = 0;
210
 
}
211
 
 
212
 
 
213
 
bool SmbLocationItemFile::atEnd() const
214
 
{
215
 
    bool ret = true;  //closed files are at end, aren't they?
216
 
    if (isOpen())
217
 
    {
218
 
        struct stat  st;
219
 
        if (smbObj()->getFstat(m_context,m_fd, &st) == SmbUtil::StatDone)
220
 
        {
221
 
            ret = m_curReadPosition >= st.st_size;
222
 
        }
223
 
    }
224
 
    return ret;
225
 
}
226
 
 
227
 
 
228
 
qint64 SmbLocationItemFile::size() const
229
 
{
230
 
    qint64 size = 0;
231
 
    struct stat  st;
232
 
    bool ok = isOpen() ? smbObj()->getFstat(m_context,m_fd,&st) == 0 : false;
233
 
    if (!isOpen())
234
 
    {
235
 
        ok = m_context != 0 ? smbObj()->getStat(m_context,cleanUrl(),&st) == 0 :
236
 
                              smbObj()->getStatInfo(cleanUrl(),&st) == SmbUtil::StatDone;
237
 
    }
238
 
    if(ok)
239
 
    {
240
 
        size = static_cast<qint64> (st.st_size);
241
 
    }
242
 
    return size;
243
 
}
244
 
 
245
 
 
246
 
bool SmbLocationItemFile::isOpen() const
247
 
{
248
 
    return m_fd != 0 && m_context != 0 ? true : false;
249
 
}
250
 
 
251
 
 
252
 
bool SmbLocationItemFile::setPermissions(QFileDevice::Permissions perm)
253
 
{
254
 
    return setPermissions(cleanUrl(), perm);
255
 
}
256
 
 
257
 
 
258
 
bool SmbLocationItemFile::setPermissions(const QString &filename, QFileDevice::Permissions perm)
259
 
{
260
 
    bool ret = false;
261
 
    if (!filename.isEmpty())
262
 
    {
263
 
        createContextIfNotExists();
264
 
        ret = smbObj()->changePermissions(m_context, filename, LocationItemFile::unixPermissions(perm));
265
 
        /*
266
 
         *  fake the return in case the file exists becase chmod() on libsmbclient does not work,
267
 
         *  the same comment is present in the \ref open()
268
 
         */
269
 
        if (!ret)
270
 
        {
271
 
            struct stat  st;
272
 
            ret = smbObj()->getStat(m_context,filename, &st) == SmbUtil::StatDone;
273
 
        }
274
 
    }
275
 
    return ret;
276
 
}
277
 
 
278
 
 
279
 
QFile::Permissions SmbLocationItemFile::permissions() const
280
 
{
281
 
    SmbItemInfo info(cleanUrl(), m_smb);
282
 
    return info.permissions();
283
 
}
284
 
 
285
 
 
286
 
bool SmbLocationItemFile::private_remove(const QString& smb_path)
287
 
{
288
 
    bool ret = false;
289
 
    if (!smb_path.isEmpty())
290
 
    {
291
 
         close();
292
 
         createContextIfNotExists();
293
 
         if (smbc_getFunctionUnlink(m_context)(m_context, smb_path.toLocal8Bit().constData()) == 0)
294
 
         {
295
 
             ret = true;
296
 
         }
297
 
    }
298
 
    return ret;
299
 
}
300
 
 
301
 
 
302
 
/*!
303
 
 * \brief SmbLocationItemFile::createContext() Always creates a new context, if a context already exists it is deleted.
304
 
 */
305
 
void SmbLocationItemFile::createContext()
306
 
{
307
 
    if (m_context != 0)
308
 
    {
309
 
        SmbObject::smbObj()->deleteContext(m_context);
310
 
    }
311
 
    m_context = SmbObject::smbObj()->createContext();
312
 
    Q_ASSERT(m_context);
313
 
}
314
 
 
315
 
 
316
 
/*!
317
 
 * \brief SmbLocationItemFile::createContextIfNotExists() Creates a new context when the current context is null
318
 
 *
319
 
 *  It tries to reuse an existent context
320
 
 */
321
 
void SmbLocationItemFile::createContextIfNotExists()
322
 
{
323
 
    if (m_context == 0)
324
 
    {
325
 
        m_context = SmbObject::smbObj()->createContext();
326
 
        Q_ASSERT(m_context);
327
 
    }
328
 
}
329
 
 
330