backend, and a three-pane statusbar that shows the user and room names.
//
-// LOW LEVEL OPERATIONS
+// TRANSPORT LAYER OPERATIONS
//
// Attach to the Citadel server
// FIX (add check for not allowed to log in)
-int CitClient::attach(const wxString& host, const wxString& port) {
+int CitClient::attach(wxString host, wxString port) {
wxString ServerReady;
if (sock.is_connected())
//
-// HIGH LEVEL COMMANDS
+// SESSION LAYER OPERATIONS
//
int CitClient::serv_trans(
wxString& command,
wxString& response,
- wxStringList& xferbuf
+ wxStringList& xferbuf,
+ wxString desired_room
) {
int first_digit;
int i;
- wxString buf;
+ wxString buf, pw, junk;
bool express_messages_waiting = FALSE;
+ // If the caller specified that this transaction must take place
+ // in a particular room, make sure we're in that room.
+ if (desired_room.Length() > 0) {
+ if (desired_room.CmpNoCase(CurrentRoom) != 0) {
+ pw = "";
+ GotoRoom(desired_room, pw, junk);
+ }
+ }
+
+
+ // If a mutex is to be wrapped around this function in the future,
+ // it must begin HERE.
+
serv_puts(command);
serv_gets(response);
first_digit = (response.GetChar(0)) - '0';
serv_puts("000");
}
+ // If a mutex is to be wrapped around this function in the future,
+ // it must end HERE.
+
if (express_messages_waiting) {
download_express_messages();
}
}
// Shorter forms of serv_trans()
+int CitClient::serv_trans(
+ wxString& command,
+ wxString& response,
+ wxStringList& xferbuf
+ ) {
+ return serv_trans(command, response, xferbuf, "");
+}
+
int CitClient::serv_trans(wxString& command, wxString& response) {
wxStringList junklist;
return serv_trans(command, response, junklist);
return serv_trans(command, junkbuf);
}
+//
+// PRESENTATION LAYER OPERATIONS
+//
+
+
+void CitClient::download_express_messages(void) {
+ wxString sendcmd, recvcmd, x_user, x_sys;
+ wxStringList xferbuf;
+
+ sendcmd = "GEXP";
+ while (serv_trans(sendcmd, recvcmd, xferbuf) == 1) {
+ extract(x_user, recvcmd, 3);
+ extract(x_sys, recvcmd, 4);
+ (void)new express_message(this, x_user, x_sys, xferbuf);
+ }
+}
+
+
+
// Set up some things that we do at the beginning of every session
void CitClient::initialize_session(void) {
wxStringList info;
wxString *infoptr;
wxString infoline;
+ CurrentRoom = "";
+
sendcmd = "IDEN 0|6|001|Daphne";
serv_trans(sendcmd);
-void CitClient::download_express_messages(void) {
- wxString sendcmd, recvcmd, x_user, x_sys;
- wxStringList xferbuf;
+// Goto a room
- sendcmd = "GEXP";
- while (serv_trans(sendcmd, recvcmd, xferbuf) == 1) {
- extract(x_user, recvcmd, 3);
- extract(x_sys, recvcmd, 4);
- (void)new express_message(this, x_user, x_sys, xferbuf);
- }
+bool CitClient::GotoRoom(wxString roomname, wxString password,
+ wxString& server_response) {
+ int retval;
+ wxString sendcmd, recvcmd;
+
+ sendcmd = "GOTO " + roomname + "|" + password;
+ retval = serv_trans(sendcmd, recvcmd);
+ server_response = recvcmd;
+
+ if (retval != 2) return FALSE;
+
+ extract(CurrentRoom, recvcmd.Mid(4, 255), 0);
+ BigMDI->SetStatusText(CurrentRoom, 2);
+ return TRUE;
}
+
+
+
+
// This is a simple timer that periodically wakes up and sends a NOOP to the
// server. This accomplishes two things: it keeps the server connection
// alive by trickling some data through when it's otherwise idle, and it allows
void keepalive::Notify(void) {
if (which_sock->IsConnected()) {
- which_sock->serv_trans("NOOP");
+ wxString noop = "NOOP";
+ which_sock->serv_trans(noop);
}
}
-
-
-
-
-
-
bool is_connected(void);
private:
int serv_sock;
- int connectsock(const char *, const char *, const char *);
+ int connectsock(char *, char *, char *);
void timeout(int);
};
CitClient(void);
~CitClient(void);
- // High-level Citadel IPC methods
- int attach(const wxString& host, const wxString& port);
+ // Citadel session-layer commands
+ int attach(wxString host, wxString port);
void detach(void);
bool IsConnected(void);
+ int CitClient::serv_trans(
+ wxString& command,
+ wxString& response,
+ wxStringList& xferbuf,
+ wxString desired_room
+ );
int CitClient::serv_trans(
wxString& command,
wxString& response,
int CitClient::serv_trans(wxString& command, wxString& response);
int CitClient::serv_trans(wxString& command);
- // Various things we learn about the server
+ // Citadel presentation-layer commands
+ bool CitClient::GotoRoom(wxString roomname, wxString password,
+ wxString& server_response);
+
+ // Various things we learn about the server ...
int SessionID;
wxString NodeName;
wxString HumanNode;
wxString MorePrompt;
bool UseFloors;
int PagingLevel;
+
+ // Stuff we have to keep track of ...
+ wxString CurrentRoom;
private:
- void serv_gets(wxString& buf);
- void serv_puts(wxString buf);
- void download_express_messages(void);
- TCPsocket sock;
- void CitClient::initialize_session(void);
+ TCPsocket sock; // transport layer
+ void serv_gets(wxString& buf); // session layer
+ void serv_puts(wxString buf); // session layer
+ void download_express_messages(void); // presentation layer
+ void CitClient::initialize_session(void); // presentation layer
};
wxButton *newuser_button;
wxButton *exit_button;
void OnButtonPressed(wxCommandEvent& whichbutton);
+ void UserLogin::BeginSession(wxString serv_response);
CitClient *citsock;
wxMDIParentFrame *citMyMDI;
DECLARE_EVENT_TABLE()
SetMenuBar(menuBar);
// create a status bar just for fun (by default with 1 pane only)
- CreateStatusBar(1);
- SetStatusText("Not connected");
+ CreateStatusBar(3);
+ SetStatusText("Not connected", 0);
}
void MyFrame::OnConnect(wxCommandEvent& unused) {
int retval;
+ wxString DefaultHost, DefaultPort;
+
+ DefaultHost = "uncnsrd.mt-kisco.ny.us";
+ DefaultPort = "citadel";
if (citadel->IsConnected()) {
wxMessageBox("You are already connected to a Citadel server.",
"Oops!");
} else {
- retval = citadel->attach("uncnsrd", "citadel");
+ retval = citadel->attach(DefaultHost, DefaultPort);
if (retval == 0) {
- SetStatusText("Connected to " + citadel->HumanNode);
+ SetStatusText("Connected to " + citadel->HumanNode, 0);
new TestWindow(citadel, this);
new UserLogin(citadel, this);
} else {
serv_sock = (-1);
}
-int TCPsocket::connectsock(const char *host, const char *service,
- const char *protocol)
+int TCPsocket::connectsock(char *host, char *service,
+ char *protocol)
{
struct hostent *phe;
struct servent *pse;
}
if (whichbutton.GetId() == BUTTON_LOGIN) {
- sendbuf = "USER ";
- sendbuf += username->GetValue();
+ sendbuf = "USER " + username->GetValue();
r = citsock->serv_trans(sendbuf, recvbuf);
if (r != 3) {
wxMessageDialog nouser(this,
wxDefaultPosition);
nopass.ShowModal();
} else {
- // FIX do login procedure here
+ BeginSession(recvbuf);
delete this; // dismiss the login box
}
}
}
+
+ if (whichbutton.GetId() == BUTTON_NEWUSER) {
+ sendbuf = "NEWU " + username->GetValue();
+ r = citsock->serv_trans(sendbuf, recvbuf);
+ if (r != 2) {
+ wxMessageDialog nouser(this,
+ recvbuf.Mid(4,32767),
+ "Error",
+ wxOK | wxCENTRE | wxICON_INFORMATION,
+ wxDefaultPosition);
+ nouser.ShowModal();
+ } else {
+ sendbuf = "SETP " + password->GetValue();
+ citsock->serv_trans(sendbuf);
+ BeginSession(recvbuf);
+ delete this; // dismiss the login box
+ }
+ }
+}
+
+
+
+void UserLogin::BeginSession(wxString serv_response) {
+ wxString junk, username;
+
+ extract(username, serv_response.Mid(4, 255), 0);
+ BigMDI->SetStatusText(username, 1);
+ citsock->GotoRoom("_BASEROOM_", "", junk);
+
+ // FIX ... add code here to perform registration if necessary
}