Subversion Repositories tpanel

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
112 andreas 1
/*
2
 * Copyright (C) 2022 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software Foundation,
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
17
 */
18
 
19
#include <fstream>
117 andreas 20
#include <functional>
21
#include <iostream>
22
#include <cstdint>
23
#include <filesystem>
112 andreas 24
 
25
#include <sys/socket.h>
26
#include <netinet/in.h>
27
#include <string.h>
28
#include <stdio.h>
29
#include <stdlib.h>
30
#include <sys/stat.h>
31
#include <sys/sendfile.h>
32
#include <fcntl.h>
33
#include <unistd.h>
117 andreas 34
#include <sys/socket.h>
35
#include <netinet/in.h>
36
#include <netdb.h>
37
#include <arpa/inet.h>
112 andreas 38
 
39
#include "tfsfreader.h"
40
#include "tsocket.h"
41
#include "tconfig.h"
42
#include "terror.h"
43
#include "tresources.h"
113 andreas 44
#include "readtp4.h"
112 andreas 45
 
46
#define FTP_PORT    21
47
 
48
#define FTP_CMD_USER    0
49
#define FTP_CMD_PASS    1
50
#define FTP_CMD_PASV    2
51
#define FTP_CMD_TYPE    3
52
#define FTP_CMD_RETR    4
53
#define FTP_CMD_QUIT    5
54
 
55
using std::string;
56
using std::vector;
117 andreas 57
using std::bind;
112 andreas 58
 
119 andreas 59
#if __GNUC__ < 9 && !defined(__ANDROID__)
60
   #if __cplusplus < 201703L
61
      #warning "Your C++ compiler seems to have no support for C++17 standard!"
62
   #endif
63
   #include <experimental/filesystem>
64
   namespace fs = std::experimental::filesystem;
65
#else
66
#  ifdef __ANDROID__
67
#   if _LIBCPP_STD_VER >= 17
68
#       include <filesystem>
69
        namespace fs = std::__fs::filesystem;
70
#   else
71
#       include <experimental/filesystem>
72
        namespace fs = std::__fs::filesystem;
73
#   endif
74
#  else
75
#   include <filesystem>
76
    namespace fs = std::filesystem;
77
#  endif
78
#endif
117 andreas 79
 
120 andreas 80
std::function<int (off64_t xfered)> TFsfReader::_progress{nullptr};
81
 
112 andreas 82
TFsfReader::TFsfReader()
83
{
84
    DECL_TRACER("TFsfReader::TFsfReader()");
85
 
86
}
87
 
88
TFsfReader::~TFsfReader()
89
{
90
    DECL_TRACER("TFsfReader::~TFsfReader()");
91
 
117 andreas 92
    if (mFtpLib)
93
        delete mFtpLib;
112 andreas 94
}
95
 
117 andreas 96
bool TFsfReader::copyOverFTP(const string& fname, const string& target)
112 andreas 97
{
117 andreas 98
    DECL_TRACER("TFsfReader::copyOverFTP(const string& fname, const string& target, const string& user, const string& pw)");
112 andreas 99
 
117 andreas 100
    if (mFtpLib)
101
        delete mFtpLib;
112 andreas 102
 
117 andreas 103
    mFtpLib = new ftplib();
112 andreas 104
 
117 andreas 105
    if (TConfig::getFtpPassive())
106
        mFtpLib->SetConnmode(ftplib::pasv);
112 andreas 107
    else
117 andreas 108
        mFtpLib->SetConnmode(ftplib::port);
112 andreas 109
 
120 andreas 110
    mFtpLib->SetCallbackLogFunction(&TFsfReader::callbackLog);      // Print some debugging messages
111
    mFtpLib->SetCallbackErrorFunction(&TFsfReader::callbackError);  // Print errors or info's
112
    mFtpLib->SetCallbackXferFunction(&TFsfReader::callbackXfer);    // This is the progress
113
    mFtpLib->SetCallbackBytes(10000L);                              // This tells the progress to be called every 10KiB
117 andreas 114
    string scon = TConfig::getController() + ":21";
115
    MSG_DEBUG("Trying to connect to " << scon);
115 andreas 116
 
117 andreas 117
    if (!mFtpLib->Connect(scon.c_str()))
115 andreas 118
    {
117 andreas 119
        delete mFtpLib;
120
        mFtpLib = nullptr;
112 andreas 121
        return false;
115 andreas 122
    }
112 andreas 123
 
117 andreas 124
    string sUser = TConfig::getFtpUser();
125
    string sPass = TConfig::getFtpPassword();
126
    MSG_DEBUG("Trying to login <" << sUser << ", " << sPass << ">");
112 andreas 127
 
117 andreas 128
    if (!mFtpLib->Login(sUser.c_str(), sPass.c_str()))
115 andreas 129
    {
117 andreas 130
        delete mFtpLib;
131
        mFtpLib = nullptr;
112 andreas 132
        return false;
115 andreas 133
    }
112 andreas 134
 
117 andreas 135
    MSG_DEBUG("Trying to download file " << fname << " to " << target);
112 andreas 136
 
117 andreas 137
    if (!mFtpLib->Get(target.c_str(), fname.c_str(), ftplib::image))
112 andreas 138
    {
117 andreas 139
        MSG_ERROR("Error downloading file " << fname);
140
        delete mFtpLib;
141
        mFtpLib = nullptr;
112 andreas 142
        return false;
143
    }
144
 
117 andreas 145
    MSG_TRACE("File " << fname << " successfully downloaded to " << target << ".");
146
    mFtpLib->Quit();
112 andreas 147
    return true;
148
}
149
 
117 andreas 150
bool TFsfReader::unpack(const string& fname, const string& path)
112 andreas 151
{
117 andreas 152
    DECL_TRACER("TFsfReader::unpack(const string& fname, const string& path)");
112 andreas 153
 
117 andreas 154
    if (fname.empty() || path.empty())
112 andreas 155
    {
117 andreas 156
        MSG_ERROR("Invalid parameters!");
112 andreas 157
        return false;
158
    }
159
 
117 andreas 160
    reader::ReadTP4 readtp4(fname, path);
115 andreas 161
 
117 andreas 162
    if (!readtp4.isReady())
112 andreas 163
        return false;
164
 
117 andreas 165
    // We must delete the old files first
166
    std::uintmax_t n = fs::remove_all(path);
167
    MSG_TRACE("Deleted " << n << " files/directories from " << path);
168
    return readtp4.doRead();
169
}
112 andreas 170
 
120 andreas 171
void TFsfReader::callbackLog(char* str, void*, bool out)
117 andreas 172
{
173
    DECL_TRACER("TFsfReader::callbackLog(char* str, void* arg, bool out)");
112 andreas 174
 
117 andreas 175
    if (!str)
176
        return;
112 andreas 177
 
117 andreas 178
    string msg = str;
116 andreas 179
    size_t pos = 0;
112 andreas 180
 
117 andreas 181
    if ((pos = msg.find("\r")) != string::npos)
182
        msg = msg.substr(0, pos);
116 andreas 183
 
117 andreas 184
    if (!out)
112 andreas 185
    {
117 andreas 186
        MSG_DEBUG("Output: " << msg);
112 andreas 187
    }
188
    else
189
    {
117 andreas 190
        MSG_DEBUG("Input: " << msg);
112 andreas 191
    }
192
}
120 andreas 193
 
194
void TFsfReader::callbackError(char* msg, void*, int err)
195
{
196
    DECL_TRACER("TFsfReader::callbackError(char* msg, void* arg, int err)");
197
 
198
    if (!msg)
199
        return;
200
 
201
    if (err)
202
    {
203
        MSG_ERROR(msg);
204
    }
205
    else if (*msg >= '0' && *msg <= '9')
206
    {
207
        MSG_INFO(msg);
208
    }
209
    else
210
    {
211
        MSG_DEBUG(msg);
212
    }
213
}
214
 
215
int TFsfReader::callbackXfer(off64_t xfered, void*)
216
{
217
    DECL_TRACER("TFsfReader::callbackXfer(off64_t xfered, void*)");
218
 
219
    if (_progress)
220
        return _progress(xfered);
221
 
222
    return 1;
223
}