+++ /dev/null
-
-#include "includes.hpp"
-#include <unistd.h>
-
-
-//
-// TRANSPORT LAYER OPERATIONS
-//
-
-// Attach to the Citadel server
-// FIX (add check for not allowed to log in)
-int CitClient::attach(wxString host, wxString port) {
- wxString ServerReady;
-
- if (sock.is_connected())
- sock.detach();
- if (sock.attach(host, port)==0) {
- serv_gets(ServerReady);
- initialize_session();
-
- curr_host = host; // Remember host and port, in case
- curr_port = port; // we need to auto-reconnect later
-
- return(0);
- }
- else return(1);
-
-}
-
-
-// constructor
-CitClient::CitClient(void) {
- (void)new keepalive(this);
-}
-
-
-// destructor
-CitClient::~CitClient(void) {
- // Be nice and log out from the server if it's still connected
- sock.detach();
-}
-
-void CitClient::detach(void) {
- wxString buf;
-
- if (sock.is_connected()) {
- serv_puts("QUIT");
- serv_gets(buf);
- sock.detach();
- }
-}
-
-
-// Is this client connected? Simply return the IsConnected status of sock.
-bool CitClient::IsConnected(void) {
- return sock.is_connected();
-}
-
-
-
-// Read a line of text from the server
-void CitClient::serv_gets(wxString& buf) {
- char charbuf[256];
-
- sock.serv_gets(charbuf);
- buf = charbuf;
-}
-
-
-// Write a line of text to the server
-void CitClient::serv_puts(wxString buf) {
- sock.serv_puts(buf);
-}
-
-
-//
-// SESSION LAYER OPERATIONS
-//
-
-
-// Server transaction (returns first digit of server response code)
-int CitClient::serv_trans(
- wxString& command,
- wxString& response,
- wxString& xferbuf,
- wxString desired_room
- ) {
-
- int first_digit, i, pos;
- 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);
-
- if (IsConnected() == FALSE) {
- reconnect_session();
- serv_puts(command);
- }
-
- serv_gets(response);
-
- first_digit = (response.GetChar(0)) - '0';
-
- if (response.GetChar(3) == '*')
- express_messages_waiting = TRUE;
-
- if (first_digit == 1) { // LISTING_FOLLOWS
- xferbuf.Empty();
- while (serv_gets(buf), buf != "000") {
- xferbuf.Append(buf + "\n");
- }
- } else if (first_digit == 4) { // SEND_LISTING
- buf = xferbuf;
- while (buf.Length() > 0) {
- pos = buf.Find('\n', FALSE);
- if ((pos < 0) && (buf.Length() < 250)) {
- serv_puts(buf + "\n");
- buf.Empty();
- } else if ((pos < 250) && (pos >= 0)) {
- serv_puts(buf.Left(pos+1));
- buf = buf.Mid(pos+1);
- } else {
- pos = buf.Left(250).Find(' ', TRUE);
- if ((pos < 250) && (pos >= 0)) {
- serv_puts(buf.Left(pos) + "\n");
- buf = buf.Mid(pos+1);
- } else {
- serv_puts(buf.Left(250) + "\n");
- buf = buf.Mid(pos);
- }
- }
- }
- 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();
- }
-
- return first_digit;
-}
-
-// Shorter forms of serv_trans()
-int CitClient::serv_trans(
- wxString& command,
- wxString& response,
- wxString& xferbuf
- ) {
- return serv_trans(command, response, xferbuf, "");
-}
-
-int CitClient::serv_trans(wxString& command, wxString& response) {
- wxString junklist;
- return serv_trans(command, response, junklist);
-}
-
-int CitClient::serv_trans(wxString& command) {
- wxString junkbuf;
- return serv_trans(command, junkbuf);
-}
-
-//
-// PRESENTATION LAYER OPERATIONS
-//
-
-
-void CitClient::download_express_messages(void) {
- wxString sendcmd, recvcmd, x_user, x_sys;
- wxString 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) {
- wxString info;
- wxString sendcmd;
- wxString recvcmd;
- int i, pos;
- wxString *infoptr;
- wxString infoline;
-
- CurrentRoom = "";
-
- sendcmd = "IDEN 0|6|001|Daphne";
- serv_trans(sendcmd);
-
- sendcmd = "INFO";
- if (serv_trans(sendcmd, recvcmd, info)==1) {
- i = 0;
- while (pos = info.Find('\n', FALSE), (pos >= 0) ) {
- infoline = info.Left(pos);
- info = info.Mid(pos+1);
- switch(i) {
-
- case 0: SessionID = atoi(infoline);
- case 1: NodeName = infoline;
- case 2: HumanNode = infoline;
- case 3: FQDN = infoline;
- case 4: ServerSoftware = infoline;
- case 5: ServerRev = atoi(infoline);
- case 6: GeoLocation = infoline;
- case 7: SysAdmin = infoline;
- case 8: ServerType = atoi(infoline);
- case 9: MorePrompt = infoline;
- case 10: UseFloors = ((atoi(infoline)>0)
- ? TRUE : FALSE);
- case 11: PagingLevel = atoi(infoline);
-
- ++i;
- }
- }
- }
-}
-
-
-
-// Goto a room
-
-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), 0);
- BigMDI->SetStatusText(CurrentRoom, 2);
- return TRUE;
-}
-
-
-
-// Reconnect a broken session
-
-void CitClient::reconnect_session(void) {
- wxString sendcmd;
-
- CurrentRoom = "__ This is not the name of any valid room __";
-
- // Give a crashed server some time to restart
- sleep(5);
-
- if (attach(curr_host, curr_port) != 0) {
- // FIX do this more elegantly
- cout << "Could not re-establish session (1)\n";
- }
-
- sendcmd = "USER " + curr_user;
- if (serv_trans(sendcmd) != 3) {
- // FIX do this more elegantly
- cout << "Could not re-establish session (2)\n";
- }
-
- sendcmd = "PASS " + curr_pass;
- if (serv_trans(sendcmd) != 2) {
- // FIX do this more elegantly
- cout << "Could not re-establish session (3)\n";
- }
-}
-
-
-
-
-
-
-// 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
-// the "check for express messages" loop to activate if it has to.
-
-keepalive::keepalive(CitClient *sock)
- : wxTimer() {
-
- which_sock = sock; // Know which instance to refresh
- Start(15000, FALSE); // Call every 15 seconds
-}
-
-
-void keepalive::Notify(void) {
- if (which_sock->IsConnected()) {
- wxString noop = "NOOP";
- which_sock->serv_trans(noop);
- }
-}
+++ /dev/null
-#include "includes.hpp"
-
-//
-// TRANSPORT LAYER OPERATIONS
-//
-
-
-
-// Attach to the Citadel server
-// FIX (add check for not allowed to log in)
-int CitClient::attach(wxString host, wxString port) {
- wxString ServerReady;
- wxIPV4address addr;
-
- if (sock->IsConnected())
- sock->Close();
-
- addr.Hostname(host);
- addr.Service(port);
- sock->SetNotify(0);
- sock->Connect(addr, TRUE);
- if (sock->IsConnected()) {
- cout << "Connect succeeded\n" ;
- serv_gets(ServerReady);
- initialize_session();
- curr_host = host; // Remember host and port, in case
- curr_port = port; // we need to auto-reconnect later
- return(0);
- } else {
- cout << "Connect failed\n" ;
- return(1);
- }
-}
-
-
-// constructor
-CitClient::CitClient(void) {
-
- wxSocketHandler::Master();
- sock = new wxSocketClient();
-
- // The WAITALL flag causes reads to block. Don't use it.
- //sock->SetFlags(wxSocketBase::WAITALL);
- sock->SetFlags(wxSocketBase::NONE);
-
- wxSocketHandler::Master().Register(sock);
- sock->SetNotify(wxSocketBase::REQ_LOST);
-
- (void)new keepalive(this);
-}
-
-
-// destructor
-CitClient::~CitClient(void) {
- // Be nice and log out from the server if it's still connected
- sock->Close();
-}
-
-
-
-void CitClient::detach(void) {
- wxString buf;
-
- if (sock->IsConnected()) {
- serv_puts("QUIT");
- serv_gets(buf);
- sock->Close();
- }
-}
-
-
-
-// Is this client connected? Simply return the IsConnected status of sock.
-bool CitClient::IsConnected(void) {
- return sock->IsConnected();
-}
-
-
-
-
-
-// Read a line of text from the server
-void CitClient::serv_gets(wxString& buf) {
- static char charbuf[512];
- static size_t nbytes = 0;
- int i;
- int nl_pos = (-1);
-
-
- do {
- sock->Read(&charbuf[nbytes], (sizeof(charbuf)-nbytes) );
- nbytes += sock->LastCount();
- for (i=nbytes; i>=0; --i)
- if (charbuf[i] == 10) nl_pos = i;
- } while (nl_pos < 0);
-
- charbuf[nbytes] = 0;
- charbuf[nl_pos] = 0;
-
- buf = charbuf;
- strcpy(charbuf, &charbuf[nl_pos + 1]);
- nbytes = nbytes - (nl_pos + 1);
-
- cout << "> " << buf << "(len=" << nl_pos << ")\n";
-}
-
-
-
-
-
-
-// Write a line of text to the server
-void CitClient::serv_puts(wxString buf) {
-
- cout << "< " << buf << "\n" ;
- sock->Write((const char *)buf, buf.Len());
- sock->Write("\n", 1);
-}
-
-
-
-
-
-
-
-
-
-//
-// SESSION LAYER OPERATIONS
-//
-
-
-// Server transaction (returns first digit of server response code)
-int CitClient::serv_trans(
- wxString& command,
- wxString& response,
- wxString& xferbuf,
- wxString desired_room
- ) {
-
- int first_digit, i, pos;
- 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.
- cout << "Beginning transaction\n";
- wxBeginBusyCursor();
- Critter.Enter();
-
- serv_puts(command);
-
- if (IsConnected() == FALSE) {
- wxSleep(5); // Give a crashed server some time to restart
- cout << "Reconnecting session\n";
- reconnect_session();
- serv_puts(command);
- }
-
- serv_gets(response);
-
- first_digit = (response.GetChar(0)) - '0';
-
- if (response.GetChar(3) == '*')
- express_messages_waiting = TRUE;
-
- if (first_digit == 1) { // LISTING_FOLLOWS
- xferbuf.Empty();
- while (serv_gets(buf), buf != "000") {
- xferbuf.Append(buf + "\n");
- }
- } else if (first_digit == 4) { // SEND_LISTING
- buf = xferbuf;
- while (buf.Length() > 0) {
- pos = buf.Find('\n', FALSE);
- if ((pos < 0) && (buf.Length() < 250)) {
- serv_puts(buf + "\n");
- buf.Empty();
- } else if ((pos < 250) && (pos >= 0)) {
- serv_puts(buf.Left(pos+1));
- buf = buf.Mid(pos+1);
- } else {
- pos = buf.Left(250).Find(' ', TRUE);
- if ((pos < 250) && (pos >= 0)) {
- serv_puts(buf.Left(pos) + "\n");
- buf = buf.Mid(pos+1);
- } else {
- serv_puts(buf.Left(250) + "\n");
- buf = buf.Mid(pos);
- }
- }
- }
- serv_puts("000");
- }
-
- // If a mutex is to be wrapped around this function in the future,
- // it must end HERE.
- cout << "Ending transaction...\n";
- Critter.Leave();
- wxEndBusyCursor();
- cout << "...done.\n";
-
- if (express_messages_waiting) {
- download_express_messages();
- }
-
- cout << "serv_trans() returning " << first_digit << "\n";
- return first_digit;
-}
-
-// Shorter forms of serv_trans()
-int CitClient::serv_trans(
- wxString& command,
- wxString& response,
- wxString& xferbuf
- ) {
- return serv_trans(command, response, xferbuf, "");
-}
-
-int CitClient::serv_trans(wxString& command, wxString& response) {
- wxString junklist;
- return serv_trans(command, response, junklist);
-}
-
-int CitClient::serv_trans(wxString& command) {
- wxString junkbuf;
- return serv_trans(command, junkbuf);
-}
-
-//
-// PRESENTATION LAYER OPERATIONS
-//
-
-
-void CitClient::download_express_messages(void) {
- wxString sendcmd, recvcmd, x_user, x_sys;
- wxString 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) {
- wxString info;
- wxString sendcmd;
- wxString recvcmd;
- int i, pos;
- wxString *infoptr;
- wxString infoline;
-
- CurrentRoom = "";
-
- sendcmd = "IDEN 0|6|001|Daphne";
- serv_trans(sendcmd);
-
- sendcmd = "INFO";
- if (serv_trans(sendcmd, recvcmd, info)==1) {
- i = 0;
- while (pos = info.Find('\n', FALSE), (pos >= 0) ) {
- infoline = info.Left(pos);
- info = info.Mid(pos+1);
- switch(i) {
-
- case 0: SessionID = atoi(infoline);
- case 1: NodeName = infoline;
- case 2: HumanNode = infoline;
- case 3: FQDN = infoline;
- case 4: ServerSoftware = infoline;
- case 5: ServerRev = atoi(infoline);
- case 6: GeoLocation = infoline;
- case 7: SysAdmin = infoline;
- case 8: ServerType = atoi(infoline);
- case 9: MorePrompt = infoline;
- case 10: UseFloors = ((atoi(infoline)>0)
- ? TRUE : FALSE);
- case 11: PagingLevel = atoi(infoline);
-
- ++i;
- }
- }
- }
-}
-
-
-
-// Goto a room
-
-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), 0);
- BigMDI->SetStatusText(CurrentRoom, 2);
- return TRUE;
-}
-
-
-
-// Reconnect a broken session
-
-void CitClient::reconnect_session(void) {
- wxString sendcmd;
-
- CurrentRoom = "__ This is not the name of any valid room __";
-
- if (attach(curr_host, curr_port) != 0) {
- // FIX do this more elegantly
- cout << "Could not re-establish session (1)\n";
- }
-
- sendcmd = "USER " + curr_user;
- if (serv_trans(sendcmd) != 3) {
- // FIX do this more elegantly
- cout << "Could not re-establish session (2)\n";
- }
-
- sendcmd = "PASS " + curr_pass;
- if (serv_trans(sendcmd) != 2) {
- // FIX do this more elegantly
- cout << "Could not re-establish session (3)\n";
- }
-}
-
-
-
-
-
-
-// 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
-// the "check for express messages" loop to activate if it has to.
-
-keepalive::keepalive(CitClient *sock)
- : wxTimer() {
-
- which_sock = sock; // Know which instance to refresh
- Start(15000, FALSE); // Call every 15 seconds
-}
-
-
-void keepalive::Notify(void) {
- if (which_sock->IsConnected()) {
- wxString noop = "NOOP";
- which_sock->serv_trans(noop);
- }
-}
// it must begin HERE.
cout << "Beginning transaction\n";
Critter.Enter();
- wxBeginBusyCursor();
+ // wxBeginBusyCursor();
serv_puts(command);
// If a mutex is to be wrapped around this function in the future,
// it must end HERE.
cout << "Ending transaction...\n";
- wxEndBusyCursor();
+ // wxEndBusyCursor();
Critter.Leave();
cout << "...done.\n";
+++ /dev/null
-/*
- * tcp_sockets.c
- *
- * TCP socket module for WebCit
- *
- * $Id$
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <string.h>
-#include <stdarg.h>
-#include <errno.h>
-#include "includes.hpp"
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
-
-TCPsocket::TCPsocket(void) {
- serv_sock = (-1);
-}
-
-void TCPsocket::timeout(int signum) {
- fprintf(stderr, "Connection timed out.\n");
- citadel->sock.serv_sock = (-1);
-}
-
-int TCPsocket::connectsock(const char *host, const char *service,
- const char *protocol)
-{
- struct hostent *phe;
- struct servent *pse;
- struct protoent *ppe;
- struct sockaddr_in sin;
- int s,type;
-
- bzero((char *)&sin,sizeof(sin));
- sin.sin_family = AF_INET;
-
- pse=getservbyname(service,protocol);
- if (pse) {
- sin.sin_port = pse->s_port;
- }
- else if ((sin.sin_port = htons((u_short)atoi(service))) == 0) {
- fprintf(stderr, "Can't get %s service entry\n", service);
- return(-1);
- }
-
- phe=gethostbyname(host);
- if (phe) {
- bcopy(phe->h_addr,(char *)&sin.sin_addr,phe->h_length);
- }
- else if ((sin.sin_addr.s_addr = inet_addr(host))==INADDR_NONE) {
- fprintf(stderr, "Can't get %s host entry: %s\n",
- host,strerror(errno));
- return(-1);
- }
-
- if ((ppe=getprotobyname(protocol))==0) {
- fprintf(stderr, "Can't get %s protocol entry: %s\n",
- protocol,strerror(errno));
- return(-1);
- }
-
- if (!strcmp(protocol,"udp"))
- type = SOCK_DGRAM;
- else
- type = SOCK_STREAM;
-
- s = socket(PF_INET,type,ppe->p_proto);
- if (s<0) {
- fprintf(stderr, "Can't create socket: %s\n", strerror(errno));
- return(-1);
- }
-
-
- signal(SIGALRM, &timeout);
- alarm(30);
-
- if (connect(s,(struct sockaddr *)&sin,sizeof(sin))<0) {
- fprintf(stderr,"can't connect to %s.%s: %s\n",
- host,service,strerror(errno));
- return(-1);
- }
-
- alarm(0);
- signal(SIGALRM,SIG_IGN);
-
- serv_sock = s;
- return(s);
- }
-
-
-
-
-/*
- * Input binary data from socket
- */
-void TCPsocket::serv_read(char *buf, int bytes)
-{
- int len,rlen;
-
- len = 0;
- while(len<bytes) {
- rlen = read(serv_sock,&buf[len],bytes-len);
- if (rlen<1) {
- fprintf(stderr, "Server connection broken: %s\n",
- strerror(errno));
- serv_sock = (-1);
- return;
- }
- len = len + rlen;
- }
- }
-
-
-/*
- * input string from pipe
- */
-void TCPsocket::serv_gets(char *strbuf)
-{
- int ch,len;
- char buf[2];
-
- len = 0;
- strcpy(strbuf,"");
- do {
- serv_read(&buf[0], 1);
- ch = buf[0];
- strbuf[len++] = ch;
- } while((ch!=10)&&(ch!=13)&&(ch!=0)&&(len<255));
- strbuf[len-1] = 0;
- /* fprintf(stderr, ">%s\n", strbuf); */
- }
-
-
-
-/*
- * send binary to server
- */
-void TCPsocket::serv_write(char *buf, int nbytes)
-{
- int bytes_written = 0;
- int retval;
- while (bytes_written < nbytes) {
- retval = write(serv_sock, &buf[bytes_written],
- nbytes - bytes_written);
- if (retval < 1) {
- fprintf(stderr, "Server connection broken: %s\n",
- strerror(errno));
- serv_sock = (-1);
- return;
- }
- bytes_written = bytes_written + retval;
- }
- }
-
-
-/*
- * send line to server
- */
-void TCPsocket::serv_puts(const char *string)
-{
- char buf[256];
-
- sprintf(buf,"%s\n", string);
- serv_write(buf, strlen(buf));
- }
-
-
-int TCPsocket::attach(const char *host, const char *port) {
- serv_sock = connectsock(host, port, "tcp");
- if (serv_sock >= 0) return 0;
- else return (-1);
-}
-
-void TCPsocket::detach() {
- close(serv_sock);
- serv_sock = (-1);
-}
-
-bool TCPsocket::is_connected(void) {
- if (serv_sock >= 0) return TRUE;
- else return FALSE;
- }