Newer
Older
SLC 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; version 2 of the License.
SLC 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 SLC; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include "screen.hh"
#include "error.hh"
Connection::Connection() : socket_(0) {}
// make connection
connect_(O.server.c_str(), O.port);
// send login info
// send pass info
// Start reader thread
pthread_create(&g_thread_reader, 0, thread_reader, 0);
void Connection::connect_(const char *addr, int port) {
struct sockaddr_in daddr;
struct hostent *h;
// Check no existing connexion
assert(socket_ == 0);
// retrieve remote host info
h = gethostbyname(addr);
if (h == 0) {
S << "Unable to resolve: " << addr << ": " << hstrerror(h_errno) << ".\n";
return;
}
socket_ = socket(PF_INET, SOCK_STREAM, 0);
if (socket_ == -1) {
S << "Unable to create socket: " << strerror(errno) << ".\n";
socket_ = 0;
daddr.sin_family = AF_INET;
daddr.sin_port = htons(port);
daddr.sin_addr = *((struct in_addr *) h->h_addr);
memset(daddr.sin_zero, '\0', sizeof daddr.sin_zero);
S << "Connecting to " << h->h_name << " (" << inet_ntoa(*(struct in_addr*)h->h_addr)
<< ") on port " << port << "...\n";
// connect
pthread_mutex_lock(&mtx_socket);
int con = connect(socket_, (struct sockaddr *) &daddr, sizeof daddr);
pthread_mutex_unlock(&mtx_socket);
if (con == -1) {
disconnect_();
S << "Unable to connect: " << strerror(errno) << ".\n";
S << "Connected to " << h->h_name << " (" << inet_ntoa(*(struct in_addr*)h->h_addr)
}
void Connection::disconnect_() {
void Connection::send(const string &data) {
send(data.c_str(), data.length());
}
void Connection::send(const char* buf, size_t len) {
}
void Connection::sendln(const string &data) {
sendln(data.c_str(), data.length());
}
void Connection::sendln(const char* buf, size_t len) {
assert(socket_ > 0);
pthread_mutex_lock(&mtx_socket);
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
do {
// check EOL char
size_t offset = rbuf_.find('\n');
if (offset != string::npos) {
string s = rbuf_.substr(0, offset);
rbuf_.erase(0, offset + 1);
return s;
}
// wait incoming data
static struct pollfd spfd[1] = {{socket_, POLLIN|POLLPRI|POLLHUP|POLLERR, 0}};
poll(spfd, 1, -1);
// lock before read
pthread_mutex_lock(&mtx_socket);
// read data
static char local_buf[MAX_LINE_SIZE];
int ret = ::recv(socket_, local_buf, MAX_LINE_SIZE, MSG_DONTWAIT);
// unlock
pthread_mutex_unlock(&mtx_socket);
if (ret == -1) {
disconnect_();
*local_buf = 0;
}
else local_buf[ret] = 0;
// add read data in buffer
rbuf_ += local_buf;
} while (1);
assert(1);