m_threadInfo(),\r
#elif defined __WIN32__\r
m_threadInfo(NULL),\r
- m_osThreadId(0),\r
+ m_osThreadId(0),\r
#endif\r
m_shouldStop(false),\r
m_isStopped(false),\r
ReThreadPool* pool) {\r
bool rc = false;\r
if (m_pool != NULL) {\r
- ReLogger* current = masterLogger == NULL ? globalLogger() : masterLogger;\r
+ ReLogger* current =\r
+ masterLogger == NULL ? globalLogger() : masterLogger;\r
current->sayF(LOG_ERROR | CAT_LIB, LC_PREPARE_TO_RUN_1,\r
i18n("prepareToRun($1) is called multiple times")).arg(id).end();\r
} else {\r
m_threadId = id;\r
- if (m_appender != NULL){\r
+ if (m_appender != NULL) {\r
m_appender->setMasterLogger(masterLogger);\r
} else {\r
m_appender = new ReSlaveAppender(masterLogger,\r
\r
return found;\r
}\r
+/**\r
+ * Returns the number of active threads.\r
+ *\r
+ * Inactive threads will be removed.\r
+ *\r
+ * @return the number of running threads\r
+ */\r
+int ReThreadPool::countThreads() {\r
+ int count = 0;\r
+ m_mutexThreads.lock();\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ ReThread* current = m_threads[ii];\r
+ if (current != NULL) {\r
+ if (!current->m_isStopped)\r
+ count++;\r
+ else {\r
+ if (current->m_autoDelete)\r
+ delete current;\r
+ m_threads[ii] = NULL;\r
+ }\r
+ }\r
+ }\r
+ m_mutexThreads.unlock();\r
+ return count;\r
+}\r
+\r
/**\r
* Stopps all running threads.\r
*/\r
ReThreadPool(int maxThreads, ReLogger* logger);\r
virtual ~ReThreadPool();\r
public:\r
+ int countThreads();\r
void killAllThreads();\r
bool startSimpleThread(ReProcessor& processor);\r
bool startThread(ReThread* thread);\r
LC_SERVER_CONNECTION_RUN_1, // 50520\r
LC_SERVER_CONNECTION_RUN_2, // 50521\r
LC_SERVER_CONNECTION_RUN_3, // 50522\r
+ LC_HANDLE_CONNECTION_4, // 50523\r
};\r
\r
#if defined __WIN32__\r
bool ReTCPConnection::isGlobalInitialized = false;\r
#endif\r
\r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param message the description of the exception\r
+ */\r
+ReTCPException::ReTCPException(const char* message) {\r
+\r
+}\r
+;\r
+\r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param socket the socket which is disconnected\r
+ */\r
+ReTCPDisconnectException::ReTCPDisconnectException(int socket) :\r
+ ReTCPException(i18n("disconnected")),\r
+ m_socket(socket) {\r
+}\r
+\r
/**\r
* Constructor.\r
*\r
m_handleSocket(-1),\r
m_id(id),\r
m_noSent(0),\r
- m_noReceived(0) {\r
+ m_noReceived(0),\r
+ m_logSendReceive(true) {\r
#if defined __WIN32__\r
WSADATA wsaData;\r
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) {\r
*\r
* @param command OUT: the received command\r
* @param data OUT: the received data\r
+ *\r
+ * @throws ReTCPBrokenPipeException\r
*/\r
void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) {\r
command.setLength(8);\r
int received = recv(m_handleSocket, command.buffer(), 8, 0);\r
- if (received != 8) {\r
+ if (received == 0) {\r
+ // connection closed from the peer\r
+ throw ReTCPDisconnectException(m_handleSocket);\r
+ } else if (received != 8) {\r
m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_1,\r
i18n("cannot receive ($1): $2 [$3]")).arg(errno).arg(received).arg(\r
m_peerName).end();\r
m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK,\r
LC_RECEIVE_4, i18n("too few bytes read: $1/$2 [$3]")).arg(\r
readBytes).arg(received).arg(m_peerName).end();\r
- } else {\r
+ } else if (m_logSendReceive) {\r
m_loggerOwner->logger()->sayF(LOG_DEBUG | CAT_NETWORK,\r
LC_RECEIVE_5,\r
i18n("received: $1 bytes in $2 round(s) [$3]: $4")).arg(\r
// add command length:\r
int rest = length + 8;\r
m_toSend.appendInt(rest | (flags << 24), "%08x");\r
+ // we send the flag/length too:\r
+ rest += 8;\r
m_toSend.appendFix(command, -1, 8, 8, NULL);\r
m_toSend.append(data, length);\r
int sent = 0;\r
const char* buf = m_toSend.str();\r
int rounds = 0;\r
+\r
while (rest > 0) {\r
rounds++;\r
if ((sent = ::send(m_handleSocket, buf, rest, 0)) > 0) {\r
break;\r
}\r
}\r
- if (rest == 0)\r
+ if (rest == 0 && m_logSendReceive)\r
m_loggerOwner->logger()->sayF(LOG_DEBUG | CAT_NETWORK, LC_WRITE_2,\r
i18n("sent: $1 bytes in $2 round(s): $3 $4")).arg(length).arg(\r
rounds).arg(command).arg(\r
ReByteBuffer command;\r
ReNetCommandHandler::ProcessingState rc = ReNetCommandHandler::PS_UNDEF;\r
m_loggerOwner->logger()->sayF(LOG_INFO | CAT_NETWORK,\r
- LC_SERVER_CONNECTION_RUN_1, i18n("new connection to $1"))\r
- .arg(m_name).end();\r
- do {\r
- receive(command, m_received);\r
- rc = m_server->handler().handleNetCommand(command, m_received, this);\r
- if (rc == ReNetCommandHandler::PS_UNKNOWN) {\r
- logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_HANDLE_CONNECTION_1,\r
- i18n("unknown command: $1 length: $2")).arg(command).arg(\r
- m_received.length()).end();\r
- }\r
- } while (rc != ReNetCommandHandler::PS_STOP && !m_shouldStop);\r
- m_pool->setShouldStop();\r
+ LC_SERVER_CONNECTION_RUN_1, i18n("new connection to $1")).arg(m_name)\r
+ .end();\r
+ try {\r
+ do {\r
+ receive(command, m_received);\r
+ rc = m_server->handler().handleNetCommand(command, m_received,\r
+ this);\r
+ if (rc == ReNetCommandHandler::PS_UNKNOWN) {\r
+ logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_HANDLE_CONNECTION_1,\r
+ i18n("unknown command: $1 length: $2")).arg(command).arg(\r
+ m_received.length()).end();\r
+ }\r
+ } while (rc != ReNetCommandHandler::PS_STOP && !m_shouldStop);\r
+ m_pool->setShouldStop();\r
+ } catch (ReTCPDisconnectException& e) {\r
+ rc = ReNetCommandHandler::PS_CLOSED;\r
+ }\r
close();\r
- if (rc == ReNetCommandHandler::PS_STOP)\r
+ if (rc == ReNetCommandHandler::PS_CLOSED)\r
+ logger()->sayF(LOG_INFO | CAT_NETWORK, LC_HANDLE_CONNECTION_4,\r
+ i18n("connection closed by the peer $1")).arg(m_peerName).end();\r
+ else if (rc == ReNetCommandHandler::PS_STOP)\r
m_loggerOwner->logger()->sayF(LOG_INFO | CAT_NETWORK,\r
- LC_SERVER_CONNECTION_RUN_2, i18n("stop signal received from $1"))\r
- .arg(m_name).end();\r
+ LC_SERVER_CONNECTION_RUN_2, i18n("stop signal received from $1"))\r
+ .arg(m_name).end();\r
else\r
m_loggerOwner->logger()->say(LOG_INFO | CAT_NETWORK,\r
- LC_SERVER_CONNECTION_RUN_3, i18n("stop order received"));\r
+ LC_SERVER_CONNECTION_RUN_3, i18n("stop order received"));\r
m_id = -1;\r
}\r
\r
ReLogger* logger, int maxConnections) :\r
ReTCPConnection(0, this),\r
m_maxConnections(maxConnections),\r
- m_countConnections(0),\r
- m_connections(new ReTCPServerConnection*[maxConnections]),\r
m_handler(commandHandler),\r
- m_logger(logger) {\r
+ m_logger(logger),\r
+ m_threadPool(maxConnections, logger) {\r
#pragma warning( pop )\r
m_port = port;\r
- memset(m_connections, 0, maxConnections * sizeof *m_connections);\r
}\r
\r
/**\r
* Destructor.\r
*/\r
ReTCPServer::~ReTCPServer() {\r
- for (int ii = 0; ii < m_countConnections; ii++) {\r
- delete m_connections[ii];\r
- m_connections[ii] = NULL;\r
- }\r
- delete[] m_connections;\r
- m_connections = NULL;\r
+ // m_poolConnections does the things!\r
}\r
/**\r
* Creates a server connection.\r
ReTCPServerConnection* ReTCPServer::createConnection(int id, int handleSocket,\r
const struct sockaddr& address) {\r
ReTCPServerConnection* rc = NULL;\r
- for (int ii = 0; rc == NULL && ii < m_maxConnections; ii++) {\r
- if (m_connections[ii] == NULL)\r
- m_connections[ii] = rc = new ReTCPServerConnection(id, this);\r
- else if (m_connections[ii]->id() < 0) {\r
- rc = m_connections[ii];\r
- rc->setId(id);\r
- }\r
- }\r
- if (rc != NULL) {\r
+ if (m_threadPool.countThreads() < m_maxConnections) {\r
+ rc = new ReTCPServerConnection(id, this);\r
+ rc->setId(id);\r
rc->setHandleSocket(handleSocket);\r
char ip[INET6_ADDRSTRLEN];\r
inet_ntop(address.sa_family,\r
bool rc = false;\r
struct addrinfo hints;\r
struct addrinfo* addrInfo;\r
- ReThreadPool pool(m_maxConnections + 1, m_logger);\r
\r
// first, load up address structs with getaddrinfo():\r
memset(&hints, 0, sizeof hints);\r
socklen_t lengthAddr = sizeof(struct sockaddr_in);\r
while ((clientSocket = accept(m_handleSocket,\r
(struct sockaddr *) &addrClient, &lengthAddr)) != 0) {\r
- if (!pool.shouldStop()) {\r
- if (m_countConnections >= m_maxConnections) {\r
+ if (!m_threadPool.shouldStop()) {\r
+ if (m_threadPool.countThreads() >= m_maxConnections) {\r
// close the connection at once:\r
m_logger->sayF(LOG_WARNING | CAT_NETWORK,\r
LC_LISTEN_FOR_ALL_5,\r
} else {\r
ReTCPServerConnection* connection = createConnection(\r
nextId++, clientSocket, addrClient);\r
- if (!pool.startThread(connection)) {\r
+ connection->setLogSendReceive(m_logSendReceive);\r
+ if (!m_threadPool.startThread(connection)) {\r
m_logger->sayF(LOG_ERROR | CAT_PROCESS,\r
LC_LISTEN_FOR_ALL_6,\r
i18n("cannot create a thread: $1")).arg(\r
}\r
}\r
}\r
- if (pool.shouldStop()) {\r
+ if (m_threadPool.shouldStop()) {\r
m_logger->say(LOG_INFO | CAT_PROCESS, LC_LISTEN_FOR_ALL_7,\r
i18n("stop request received"));\r
}\r
#elif defined __WIN32__
# define reCloseSocket(handle) ::closesocket(handle)
#endif
+
+/**
+ * Exceptions for TCP processing.
+ */
+class ReTCPException: public ReException {
+public:
+ ReTCPException(const char* message);
+};
+
+/**
+ * Exceptions when a connection is lost.
+ */
+class ReTCPDisconnectException: ReTCPException {
+public:
+ ReTCPDisconnectException(int socket);
+public:
+ int m_socket;
+};
+
/**
* Administrates the internal data of an ip address, usable for IP4 and IP6.
*/
inline void setId(int id) {
m_id = id;
}
+ /** Sets the flag for logging sending and/or receiving.
+ * @param value <code>true</code>: the logging should be done
+ */
+ void setLogSendReceive(bool value) {
+ m_logSendReceive = value;
+ }
protected:
ReByteBuffer m_peerName;
ReByteBuffer m_received;
int m_id;
uint32_t m_noSent;
uint32_t m_noReceived;
+ bool m_logSendReceive;
#if defined __WIN32__
private:
static bool isGlobalInitialized;
#endif
public:
static void globalClose();
+
};
/**
* Implements a TCP client.
private:
ReLogger* m_logger;
};
-
class ReTCPServer;
/**
* Implements a single server connection to a client (in a single thread).
ReLogger* logger, int maxConnections = 16);
virtual ~ReTCPServer();
public:
+ ReTCPServerConnection* connectionByIndex(int index);
/** Returns the command handler.
* @return the handler for the incoming messages
*/
protected:
int m_maxConnections;
- int m_countConnections;
- ReTCPServerConnection** m_connections;
ReNetCommandHandler& m_handler;
ReLogger* m_logger;
+ ReThreadPool m_threadPool;
};
/**
PS_PROCESSED, // task has been successfully handled
PS_FAILED, // task has been handled, error occurred
PS_STOP, // no further processing should be done
+ PS_CLOSED, // connection has been closed by peer
};
public:
ReNetCommandHandler();
* @return the value (multiplied with the unit factor)\r
* @throws ReOptionExecption\r
*/\r
-time_t ReDirOptions::checkSize(const char* value) {\r
+int64_t ReDirOptions::checkSize(const char* value) {\r
int64_t rc = 0;\r
char unit = 'b';\r
switch (sscanf(value, "%lld%c", (long long int*) &rc, &unit)) {\r
m_isExe(false) {\r
// standard short options: D d O o P p T t v y Z z\r
m_programArgs.addString("first",\r
- i18n("defines the first line of the output"), '1', "first-line", true,\r
+ i18n("defines the first line of the output"), '1', "first-line", true,\r
#if defined __linux__\r
- "#! /bin/sh"\r
+ "#! /bin/sh"\r
#elif defined __WIN32__\r
- "rem this batch is created by dirtool"\r
+ "rem this batch is created by dirtool"\r
#endif\r
- );\r
+) ;\r
m_programArgs.addString("arguments", i18n("template for the output line.\n"\r
- "Possible placeholders: (e.g. e:\\data\\sample.txt)\n"\r
- " !full!: e:\\data\\sample.txt\n"\r
- " !path!: e:\\data\\\n"\r
- " !basename!: sample.txt\n"\r
- " !name!: sample\n"\r
- " !ext!: .txt\n"\r
- "example: --arguments='echo !basename! in !path! found'"), 'a',\r
- "arguments", false, NULL);\r
+ "Possible placeholders: (e.g. e:\\data\\sample.txt)\n"\r
+ " !full!: e:\\data\\sample.txt\n"\r
+ " !path!: e:\\data\\\n"\r
+ " !basename!: sample.txt\n"\r
+ " !name!: sample\n"\r
+ " !ext!: .txt\n"\r
+ "example: --arguments='echo !basename! in !path! found'"), 'a',\r
+ "arguments", false, NULL);\r
m_programArgs.addString("script",\r
- i18n("name of the script (starts each output line)"), 'c', "script",\r
- false, NULL);\r
+ i18n("name of the script (starts each output line)"), 'c', "script",\r
+ false, NULL);\r
#if defined __WIN32__\r
m_programArgs.addBool("isexe",\r
i18n("supresses the starting 'call' of each output line"\r
#elif defined __WIN32__\r
static const char* prefix = "rem ";\r
#endif\r
- printSummary (prefix);\r
+ printSummary(prefix);\r
}\r
\r
/**\r
\r
static bool isAbsoluteTime(ReFileTime_t& time) {\r
#if defined __linux__\r
- static struct tm year1980 = {0, 0, 0, 1, 1 - 1, 1980 - 1900};\r
+ static struct tm year1980 = { 0, 0, 0, 1, 1 - 1, 1980 - 1900 };\r
static time_t time1980 = mktime(&year1980);\r
return time.tv_sec >= time1980;\r
#elif defined __WIN32__\r
struct stat info;\r
if (properties == NULL) {\r
if (stat(source, &info) == 0)\r
- properties = &info;\r
+ properties = &info;\r
else {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1,\r
- i18n("could not find: $1 (errno: $2)")).arg(source).arg(\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1,\r
+ i18n("could not find: $1 (errno: $2)")).arg(source).arg(\r
errno).end();\r
}\r
}\r
FILE* fpSource = fopen(source, "rb");\r
if (fpSource == NULL) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2,\r
- i18n("cannot open $1 (errno: $2)")).arg(source).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2,\r
+ i18n("cannot open $1 (errno: $2)")).arg(source).arg(errno).end();\r
} else {\r
ReFileSize_t size =\r
- properties == NULL ? 0x7fffffff : properties->st_size;\r
+ properties == NULL ? 0x7fffffff : properties->st_size;\r
FILE* fpTarget = fopen(target, "w");\r
if (fpTarget == NULL) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3,\r
- i18n("cannot open $1 (errno: $2)")).arg(target).arg(errno)\r
- .end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3,\r
+ i18n("cannot open $1 (errno: $2)")).arg(target).arg(errno)\r
+ .end();\r
} else {\r
while (size > 0) {\r
size_t blockSize = buffer.capacity();\r
if ((int) blockSize > size)\r
- blockSize = size;\r
+ blockSize = size;\r
if (fread(buffer.buffer(), blockSize, 1, fpSource) != 1) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5,\r
- i18n("cannot read $1 (errno: $2)")).arg(source).arg(\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5,\r
+ i18n("cannot read $1 (errno: $2)")).arg(source).arg(\r
errno).end();\r
break;\r
}\r
size_t written;\r
if ((written = fwrite(buffer.buffer(), 1, blockSize, fpTarget))\r
- != blockSize) {\r
+ != blockSize) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6,\r
- i18n("cannot write $1 [$2] (errno: $3)")).arg(\r
- target).arg(written).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6,\r
+ i18n("cannot write $1 [$2] (errno: $3)")).arg(\r
+ target).arg(written).arg(errno).end();\r
break;\r
}\r
size -= blockSize;\r
rc = size == 0ll;\r
fclose(fpTarget);\r
if (properties != NULL)\r
- setProperties(target, properties, logger);\r
+ setProperties(target, properties, logger);\r
}\r
fclose(fpSource);\r
}\r
times[1].tv_usec = properties->st_mtim.tv_nsec / 1000;\r
if (utimes(fullName, times) != 0) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1,\r
- i18n("cannot change file times: $1 (errno: $2)")).arg(fullName)\r
- .arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1,\r
+ i18n("cannot change file times: $1 (errno: $2)")).arg(fullName)\r
+ .arg(errno).end();\r
rc = false;\r
}\r
int rights = properties->st_mode & (S_IRWXO | S_IRWXG | S_IRWXU);\r
if (chmod(fullName, rights) != 0) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2,\r
- i18n("cannot change file modes: $1 (errno: $2)")).arg(fullName)\r
- .arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2,\r
+ i18n("cannot change file modes: $1 (errno: $2)")).arg(fullName)\r
+ .arg(errno).end();\r
rc = false;\r
}\r
if (chown(fullName, properties->st_uid, properties->st_gid) != 0) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3,\r
- i18n("cannot change file owner: $1 (errno: $2)")).arg(fullName)\r
- .arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3,\r
+ i18n("cannot change file owner: $1 (errno: $2)")).arg(fullName)\r
+ .arg(errno).end();\r
rc = false;\r
}\r
#endif\r
ReDirTCP::ReDirTCP(ReLogger* logger) :\r
ReTool(s_tcpUsage, s_tcpExamples, 1, 0, 0, true, logger) {\r
m_hasStandardArgs = false;\r
- m_programArgs.addInt("size",\r
- i18n("size of the message to send/receive (in KiByte)"), 'b',\r
- "--buffer-size", 64);\r
+ m_programArgs.addString("size", i18n("size of the message to send/receive\n"\r
+ "<string> is a number followed by an unit\n"\r
+ "units: b(yte) k(Byte) K(iByte) m(Byte), M(iByte)\n"\r
+ "Note: maximum: 16M-32=16777184\n"\r
+ "examples: -b1m --buffer-size=512K"), 'b', "size", false, "64K");\r
m_programArgs.addInt("port", i18n("port of the server/client"), 'p',\r
"--port", 58111);\r
}\r
*/\r
void ReDirTCP::doIt() {\r
int port = m_programArgs.getInt("port");\r
- int bufferSize = m_programArgs.getInt("size") * 1024;\r
-\r
+ ReByteBuffer buffer;\r
+ int64_t bufferSize = checkSize(m_programArgs.getString("size", buffer));\r
+ // the protocol does not allow more than 16 MiByte because of the flags:\r
+ if (bufferSize > 16LL * 1024 * 1024 - 64LL)\r
+ help(i18n("buffersize exceeds 16777184 = 16MiByte - 32: "),\r
+ buffer.str());\r
ReByteBuffer command = m_programArgs.arg(0);\r
if (command.isPrefixOf("server", -1, true)) {\r
ReTCPEchoServer server(port, m_logger);\r
+ server.setLogSendReceive(false);\r
server.listenForAll();\r
} else if (command.isPrefixOf("client", -1, true)) {\r
const char* ip = m_programArgs.arg(1);\r
if (m_programArgs.argCount() > 4)\r
interval = atoi(m_programArgs.arg(4));\r
if (tolower(direction.at(0)) == 'm')\r
- runMixedClient(ip, port, rounds, interval, bufferSize);\r
+ runMixedClient(ip, port, rounds, interval, (int) bufferSize);\r
else\r
- runOneThreadClient(ip, port, rounds, interval, bufferSize,\r
+ runOneThreadClient(ip, port, rounds, interval, (int) bufferSize,\r
tolower(direction.at(0)) == 'u');\r
} else\r
help("unknown subcommand: $1", command.str());\r
int64_t size = 0;\r
int duration = 0;\r
ReByteBuffer answer, data;\r
+ client.setLogSendReceive(false);\r
for (int ii = 0; ii < rounds; ii++) {\r
client.send(command, message.str(), message.length());\r
client.receive(answer, data);\r
if (duration == 0)\r
duration = 1;\r
printf("%2d: %9.3f MiByte %8.3f kiByte %s/sec %s\n", rounds,\r
- size / 1024.0 / 1024, (double) size / duration / 1024, upload ? "up" : "down");\r
+ size / 1024.0 / 1024, (double) size / duration / 1024,\r
+ upload ? "up" : "down");\r
\r
}\r
}\r
false,\r
NULL);\r
m_programArgs.addString("separator",\r
- i18n("separator between the path elements"), 's', "separator", false,\r
+ i18n("separator between the path elements"), 's', "separator", false,\r
#if defined __linux__\r
- ":"\r
+ ":"\r
#elif defined __WIN32__\r
- ";"\r
+ ";"\r
#endif\r
- );\r
+) ;\r
m_programArgs.addString("variable", i18n("variable with the path list"),\r
'v', "variable", false, "PATH");\r
m_hasStandardArgs = false;\r