1 /*-------------------------------------------------------------------------- 2 Copyright 1999, Dan Kegel http://www.kegel.com/ 3 See the file COPYING 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 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 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 --------------------------------------------------------------------------*/ 19 20 #ifndef robouser_h 21 #define robouser_h 22 23 #include "eclock.h" /* for clock_t - should be eclock_t */ 24 #include "ftp_client_pipe.h" 25 #include "Sked.h" 26 #include <stddef.h> 27 #include <stdio.h> 28 29 class Platoon; 30 /**-------------------------------------------------------------------------- 31 Module to simulate FTP users. 32 --------------------------------------------------------------------------*/ 33 class robouser_t : public ftp_client_pipe_datainterface_t, public SkedClient { 34 35 public: 36 /** stages in a robot's life cycle. 37 * Order is extremely important; see Platoon::sumInState() and 38 * Platoon::startUser(), which assume any state between CONNECT and 39 * GETTING (numerically) is alive... 40 */ 41 enum state_t {UNINIT,CONNECT,CONNECTING,START_TYPE,FINISH_TYPE,GET,GETTING, 42 STOPPED}; 43 /// number of possible values of state_t 44 static const int NUMSTATES = (((int) STOPPED)+1); 45 46 private: 47 /* Private data members - all start with m_ */ 48 /// this struct's index in outer container 49 int m_user; 50 51 /** The Platoon to which this robot belongs */ 52 Platoon *m_platoon; 53 54 /** where the robot is in its life cycle */ 55 state_t m_state; 56 57 /* variables to support statistics gathering */ 58 /** when current fetch started */ 59 clock_t m_startedAt; 60 /** so far from current file */ 61 size_t m_bytesFetched; 62 /** number of 'packets' read so far */ 63 int m_reads; 64 65 /** The FTP connection to the server. */ 66 ftp_client_pipe_t m_fcp; 67 68 69 /// cached value of eclock_hertz() 70 static int s_hertz; 71 /* Public instance methods (needed by Platoon) */ 72 public: 73 /**---------------------------------------------------------------------- 74 Constructor is public, but only Platoon::startUser should call it. 75 ----------------------------------------------------------------------*/ robouser_t(Platoon * platoon)76 robouser_t(Platoon *platoon) { m_state = UNINIT; m_platoon = platoon; } 77 78 /**---------------------------------------------------------------------- 79 Start an already-allocated robouser on its tiny-brained way. 80 usernum is the index of this object in an outer container. 81 82 Returns 0 on success, Unix error code on failure. 83 ----------------------------------------------------------------------*/ 84 int start(int usernum); 85 86 /**---------------------------------------------------------------------- 87 Shut down the fcp connection. 88 ----------------------------------------------------------------------*/ shutDown()89 void shutDown() { m_fcp.shutdown(); } 90 getUser()91 int getUser() { return m_user; } 92 93 /* Private instance methods */ 94 private: 95 /**---------------------------------------------------------------------- 96 Pick a random file from the set we know are on the server. 97 For now, a bogus implementation. 98 Later on, we will probably expand m_filename as a template. 99 ----------------------------------------------------------------------*/ 100 void pick_random_file(char *fname); 101 102 /**---------------------------------------------------------------------- 103 Jump to the given state. 104 Adjust counts. 105 ----------------------------------------------------------------------*/ 106 void gotoState(state_t newstate); 107 108 /**---------------------------------------------------------------------- 109 Shut down one user. Opposite of start(). 110 Call after QUIT succeeds, or connection-fatal error detected. 111 ----------------------------------------------------------------------*/ 112 void stop(); 113 114 /* Callback functions - called by Sked and ftp_client_proto only */ 115 116 /**---------------------------------------------------------------------- 117 When the time specified by addClient() has elapsed, Sked calls this method. 118 ----------------------------------------------------------------------*/ 119 void skedCallback(clock_t now); 120 121 /**---------------------------------------------------------------------- 122 Callback function. 123 Called internally by ftp_client_pipe_t::notifyPollEvent(). 124 The operating system has told us that our data file descriptor 125 is ready for I/O. This function performs the desired I/O. 126 ----------------------------------------------------------------------*/ 127 int handle_data_io(int fd, short revents, clock_t now); 128 129 /**---------------------------------------------------------------------- 130 Callback function. When any command (cd, ls, get, put, ...) finishes, 131 ftp_client_pipe_t::notifyPollEvent() calls this function called to alert us. 132 ----------------------------------------------------------------------*/ 133 void ftpCmdDone(int xerr, int status, const char *buf); 134 135 /// Get an integer that identifies this object. Used in log messages. getID(void)136 int getID(void) { return m_user; } 137 }; 138 139 #endif 140