/*--------------------------------------------------------------------------
Copyright 1999, Dan Kegel http://www.kegel.com/
See the file COPYING
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--------------------------------------------------------------------------*/
#ifndef robouser_h
#define robouser_h
#include "eclock.h" /* for clock_t - should be eclock_t */
#include "ftp_client_pipe.h"
#include "Sked.h"
#include <stddef.h>
#include <stdio.h>
class Platoon;
/**--------------------------------------------------------------------------
Module to simulate FTP users.
--------------------------------------------------------------------------*/
class robouser_t : public ftp_client_pipe_datainterface_t, public SkedClient {
public:
/** stages in a robot's life cycle.
* Order is extremely important; see Platoon::sumInState() and
* Platoon::startUser(), which assume any state between CONNECT and
* GETTING (numerically) is alive...
*/
enum state_t {UNINIT,CONNECT,CONNECTING,START_TYPE,FINISH_TYPE,GET,GETTING,
STOPPED};
/// number of possible values of state_t
static const int NUMSTATES = (((int) STOPPED)+1);
private:
/* Private data members - all start with m_ */
/// this struct's index in outer container
int m_user;
/** The Platoon to which this robot belongs */
Platoon *m_platoon;
/** where the robot is in its life cycle */
state_t m_state;
/* variables to support statistics gathering */
/** when current fetch started */
clock_t m_startedAt;
/** so far from current file */
size_t m_bytesFetched;
/** number of 'packets' read so far */
int m_reads;
/** The FTP connection to the server. */
ftp_client_pipe_t m_fcp;
/// cached value of eclock_hertz()
static int s_hertz;
/* Public instance methods (needed by Platoon) */
public:
/**----------------------------------------------------------------------
Constructor is public, but only Platoon::startUser should call it.
----------------------------------------------------------------------*/
robouser_t(Platoon *platoon) { m_state = UNINIT; m_platoon = platoon; }
/**----------------------------------------------------------------------
Start an already-allocated robouser on its tiny-brained way.
usernum is the index of this object in an outer container.
Returns 0 on success, Unix error code on failure.
----------------------------------------------------------------------*/
int start(int usernum);
/**----------------------------------------------------------------------
Shut down the fcp connection.
----------------------------------------------------------------------*/
void shutDown() { m_fcp.shutdown(); }
int getUser() { return m_user; }
/* Private instance methods */
private:
/**----------------------------------------------------------------------
Pick a random file from the set we know are on the server.
For now, a bogus implementation.
Later on, we will probably expand m_filename as a template.
----------------------------------------------------------------------*/
void pick_random_file(char *fname);
/**----------------------------------------------------------------------
Jump to the given state.
Adjust counts.
----------------------------------------------------------------------*/
void gotoState(state_t newstate);
/**----------------------------------------------------------------------
Shut down one user. Opposite of start().
Call after QUIT succeeds, or connection-fatal error detected.
----------------------------------------------------------------------*/
void stop();
/* Callback functions - called by Sked and ftp_client_proto only */
/**----------------------------------------------------------------------
When the time specified by addClient() has elapsed, Sked calls this method.
----------------------------------------------------------------------*/
void skedCallback(clock_t now);
/**----------------------------------------------------------------------
Callback function.
Called internally by ftp_client_pipe_t::notifyPollEvent().
The operating system has told us that our data file descriptor
is ready for I/O. This function performs the desired I/O.
----------------------------------------------------------------------*/
int handle_data_io(int fd, short revents, clock_t now);
/**----------------------------------------------------------------------
Callback function. When any command (cd, ls, get, put, ...) finishes,
ftp_client_pipe_t::notifyPollEvent() calls this function called to alert us.
----------------------------------------------------------------------*/
void ftpCmdDone(int xerr, int status, const char *buf);
/// Get an integer that identifies this object. Used in log messages.
int getID(void) { return m_user; }
};
#endif
syntax highlighted by Code2HTML, v. 0.9.1