--- a/src/utils/netcon.cpp
+++ b/src/utils/netcon.cpp
@@ -1,4 +1,19 @@
-/* Copyright (C) 2002 Jean-Francois Dockes */
+/* Copyright (C) 2002 J.F. Dockes
+ * 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.
+ */
// Wrapper classes for the socket interface
@@ -16,8 +31,8 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
-
#include <sys/socket.h>
+#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
@@ -25,15 +40,38 @@
#include <map>
-#ifndef NO_NAMESPACES
+
+#ifdef RECOLL_DATADIR
+#include "debuglog.h"
+
+#else
+
+#define LOGFATAL(X)
+#define LOGERR(X)
+#define LOGINFO(X)
+#define LOGDEB(X)
+#define LOGDEB0(X)
+#define LOGDEB1(X)
+#define LOGDEB2(X)
+#define LOGDEB3(X)
+#define LOGDEB4(X)
+#endif
+
+#include "netcon.h"
+
using namespace std;
-#endif
-
-#include "debuglog.h"
-#include "netcon.h"
#ifndef SOCKLEN_T
#define SOCKLEN_T socklen_t
+#endif
+
+// Size of path buffer in sockaddr_un (AF_UNIX socket
+// addr). Mysteriously it's 108 (explicit value) under linux, no
+// define accessible. Let's take a little margin as it appears that
+// some systems use 92. I believe we could also malloc a variable size
+// struct but why bother.
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 90
#endif
// Need &one, &zero for setsockopt...
@@ -72,13 +110,13 @@
FD_ZERO(&rd);
FD_SET(fd, &rd);
if (write) {
- ret = select(fd+1, 0, &rd, 0, &tv);
+ ret = select(fd+1, 0, &rd, 0, &tv);
} else {
- ret = select(fd+1, &rd, 0, 0, &tv);
+ ret = select(fd+1, &rd, 0, 0, &tv);
}
if (!FD_ISSET(fd, &rd)) {
- LOGERR(("Netcon::select1: fd not ready after select ??\n"));
- return -1;
+ LOGERR(("Netcon::select1: fd not ready after select ??\n"));
+ return -1;
}
return ret;
}
@@ -88,8 +126,9 @@
m_periodichandler = handler;
m_periodicparam = p;
m_periodicmillis = ms;
- if (m_periodicmillis > 0)
- gettimeofday(&m_lasthdlcall, 0);
+ if (m_periodicmillis > 0) {
+ gettimeofday(&m_lasthdlcall, 0);
+ }
}
// Compute the appropriate timeout so that the select call returns in
@@ -100,19 +139,20 @@
// after a very long time (we'd need to pass NULL to select for an
// infinite wait, and I'm too lazy to handle it)
if (m_periodicmillis <= 0) {
- tv->tv_sec = 10000;
- tv->tv_usec = 0;
- return;
+ tv->tv_sec = 10000;
+ tv->tv_usec = 0;
+ return;
}
struct timeval mtv;
gettimeofday(&mtv, 0);
int millis = m_periodicmillis - MILLIS(m_lasthdlcall, mtv);
- // millis <= 0 means we should have already done the thing. *dont* set the
+ // millis <= 0 means we should have already done the thing. *dont* set the
// tv to 0, which means no timeout at all !
- if (millis <= 0)
- millis = 1;
+ if (millis <= 0) {
+ millis = 1;
+ }
tv->tv_sec = millis / 1000;
tv->tv_usec = (millis % 1000) * 1000;
}
@@ -121,17 +161,19 @@
// caller if it or we return 0
int SelectLoop::maybecallperiodic()
{
- if (m_periodicmillis <= 0)
- return 1;
+ if (m_periodicmillis <= 0) {
+ return 1;
+ }
struct timeval mtv;
gettimeofday(&mtv, 0);
int millis = m_periodicmillis - MILLIS(m_lasthdlcall, mtv);
if (millis <= 0) {
- gettimeofday(&m_lasthdlcall, 0);
- if (m_periodichandler)
- return m_periodichandler(m_periodicparam);
- else
- return 0;
+ gettimeofday(&m_lasthdlcall, 0);
+ if (m_periodichandler) {
+ return m_periodichandler(m_periodicparam);
+ } else {
+ return 0;
+ }
}
return 1;
}
@@ -139,110 +181,117 @@
int SelectLoop::doLoop()
{
for (;;) {
- if (m_selectloopDoReturn) {
- m_selectloopDoReturn = false;
- LOGDEB(("Netcon::selectloop: returning on request\n"));
- return m_selectloopReturnValue;
- }
- int nfds;
- fd_set rd, wd;
- FD_ZERO(&rd);
- FD_ZERO(&wd);
-
- // Walk the netcon map and set up the read and write fd_sets
- // for select()
- nfds = 0;
- for (map<int,NetconP>::iterator it = m_polldata.begin();
- it != m_polldata.end(); it++) {
- NetconP &pll = it->second;
- int fd = it->first;
- LOGDEB2(("Selectloop: fd %d flags 0x%x\n",fd, pll->m_wantedEvents));
- if (pll->m_wantedEvents & Netcon::NETCONPOLL_READ) {
- FD_SET(fd, &rd);
- nfds = MAX(nfds, fd + 1);
- }
- if (pll->m_wantedEvents & Netcon::NETCONPOLL_WRITE) {
- FD_SET(fd, &wd);
- nfds = MAX(nfds, fd + 1);
- }
- }
-
- if (nfds == 0) {
- // This should never happen in a server as we should at least
- // always monitor the main listening server socket. For a
- // client, it's up to client code to avoid or process this
- // condition.
-
- // Just in case there would still be open fds in there
- // (with no r/w flags set). Should not be needed, but safer
- m_polldata.clear();
- LOGDEB1(("Netcon::selectloop: no fds\n"));
- return 0;
- }
-
- LOGDEB2(("Netcon::selectloop: selecting, nfds = %d\n", nfds));
-
- // Compute the next timeout according to what might need to be
- // done apart from waiting for data
- struct timeval tv;
- periodictimeout(&tv);
- // Wait for something to happen
- int ret = select(nfds, &rd, &wd, 0, &tv);
- LOGDEB2(("Netcon::selectloop: select returns %d\n", ret));
- if (ret < 0) {
- LOGSYSERR("Netcon::selectloop", "select", "");
- return -1;
- }
- if (m_periodicmillis > 0)
- if (maybecallperiodic() <= 0)
- return 1;
-
- // Timeout, do it again.
- if (ret == 0)
- continue;
-
- // We don't start the fd sweep at 0, else some fds would be advantaged.
- // Note that we do an fd sweep, not a map sweep. This is
- // inefficient because the fd array may be very sparse. Otoh, the
- // map may change between 2 sweeps, so that we'd have to be smart
- // with the iterator. As the cost per unused fd is low (just 2 bit
- // flag tests), we keep it like this for now
- if (m_placetostart >= nfds)
- m_placetostart = 0;
- int i, fd;
- for (i = 0, fd = m_placetostart; i < nfds;i++, fd++) {
- if (fd >= nfds)
- fd = 0;
-
- int canread = FD_ISSET(fd, &rd);
- int canwrite = FD_ISSET(fd, &wd);
- bool none = !canread && !canwrite;
- LOGDEB2(("Netcon::selectloop: fd %d %s %s %s\n", fd,
- none ? "blocked" : "can" , canread ? "read" : "",
- canwrite ? "write" : ""));
- if (none)
- continue;
-
- map<int,NetconP>::iterator it = m_polldata.find(fd);
- if (it == m_polldata.end()) {
- /// This should not happen actually
- LOGDEB2(("Netcon::selectloop: fd %d not found\n", fd));
- continue;
- }
-
- // Next start will be one beyond last serviced (modulo nfds)
- m_placetostart = fd + 1;
- NetconP &pll = it->second;
- if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0)
- pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
- if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0)
- pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
- if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE|Netcon::NETCONPOLL_READ))) {
- LOGDEB0(("Netcon::selectloop: fd %d has 0x%x mask, erasing\n",
- it->first, it->second->m_wantedEvents));
- m_polldata.erase(it);
- }
- } // fd sweep
+ if (m_selectloopDoReturn) {
+ m_selectloopDoReturn = false;
+ LOGDEB(("Netcon::selectloop: returning on request\n"));
+ return m_selectloopReturnValue;
+ }
+ int nfds;
+ fd_set rd, wd;
+ FD_ZERO(&rd);
+ FD_ZERO(&wd);
+
+ // Walk the netcon map and set up the read and write fd_sets
+ // for select()
+ nfds = 0;
+ for (map<int,NetconP>::iterator it = m_polldata.begin();
+ it != m_polldata.end(); it++) {
+ NetconP &pll = it->second;
+ int fd = it->first;
+ LOGDEB2(("Selectloop: fd %d flags 0x%x\n",fd, pll->m_wantedEvents));
+ if (pll->m_wantedEvents & Netcon::NETCONPOLL_READ) {
+ FD_SET(fd, &rd);
+ nfds = MAX(nfds, fd + 1);
+ }
+ if (pll->m_wantedEvents & Netcon::NETCONPOLL_WRITE) {
+ FD_SET(fd, &wd);
+ nfds = MAX(nfds, fd + 1);
+ }
+ }
+
+ if (nfds == 0) {
+ // This should never happen in a server as we should at least
+ // always monitor the main listening server socket. For a
+ // client, it's up to client code to avoid or process this
+ // condition.
+
+ // Just in case there would still be open fds in there
+ // (with no r/w flags set). Should not be needed, but safer
+ m_polldata.clear();
+ LOGDEB1(("Netcon::selectloop: no fds\n"));
+ return 0;
+ }
+
+ LOGDEB2(("Netcon::selectloop: selecting, nfds = %d\n", nfds));
+
+ // Compute the next timeout according to what might need to be
+ // done apart from waiting for data
+ struct timeval tv;
+ periodictimeout(&tv);
+ // Wait for something to happen
+ int ret = select(nfds, &rd, &wd, 0, &tv);
+ LOGDEB2(("Netcon::selectloop: select returns %d\n", ret));
+ if (ret < 0) {
+ LOGSYSERR("Netcon::selectloop", "select", "");
+ return -1;
+ }
+ if (m_periodicmillis > 0)
+ if (maybecallperiodic() <= 0) {
+ return 1;
+ }
+
+ // Timeout, do it again.
+ if (ret == 0) {
+ continue;
+ }
+
+ // We don't start the fd sweep at 0, else some fds would be advantaged.
+ // Note that we do an fd sweep, not a map sweep. This is
+ // inefficient because the fd array may be very sparse. Otoh, the
+ // map may change between 2 sweeps, so that we'd have to be smart
+ // with the iterator. As the cost per unused fd is low (just 2 bit
+ // flag tests), we keep it like this for now
+ if (m_placetostart >= nfds) {
+ m_placetostart = 0;
+ }
+ int i, fd;
+ for (i = 0, fd = m_placetostart; i < nfds; i++, fd++) {
+ if (fd >= nfds) {
+ fd = 0;
+ }
+
+ int canread = FD_ISSET(fd, &rd);
+ int canwrite = FD_ISSET(fd, &wd);
+ bool none = !canread && !canwrite;
+ LOGDEB2(("Netcon::selectloop: fd %d %s %s %s\n", fd,
+ none ? "blocked" : "can" , canread ? "read" : "",
+ canwrite ? "write" : ""));
+ if (none) {
+ continue;
+ }
+
+ map<int,NetconP>::iterator it = m_polldata.find(fd);
+ if (it == m_polldata.end()) {
+ /// This should not happen actually
+ LOGDEB2(("Netcon::selectloop: fd %d not found\n", fd));
+ continue;
+ }
+
+ // Next start will be one beyond last serviced (modulo nfds)
+ m_placetostart = fd + 1;
+ NetconP &pll = it->second;
+ if (canread && pll->cando(Netcon::NETCONPOLL_READ) <= 0) {
+ pll->m_wantedEvents &= ~Netcon::NETCONPOLL_READ;
+ }
+ if (canwrite && pll->cando(Netcon::NETCONPOLL_WRITE) <= 0) {
+ pll->m_wantedEvents &= ~Netcon::NETCONPOLL_WRITE;
+ }
+ if (!(pll->m_wantedEvents & (Netcon::NETCONPOLL_WRITE|Netcon::NETCONPOLL_READ))) {
+ LOGDEB0(("Netcon::selectloop: fd %d has 0x%x mask, erasing\n",
+ it->first, it->second->m_wantedEvents));
+ m_polldata.erase(it);
+ }
+ } // fd sweep
} // forever loop
LOGERR(("SelectLoop::doLoop: got out of loop !\n"));
@@ -252,7 +301,9 @@
// Add a connection to the monitored set.
int SelectLoop::addselcon(NetconP con, int events)
{
- if (con.isNull()) return -1;
+ if (!con) {
+ return -1;
+ }
LOGDEB1(("Netcon::addselcon: fd %d\n", con->m_fd));
con->set_nonblock(1);
con->setselevents(events);
@@ -264,12 +315,14 @@
// Remove a connection from the monitored set.
int SelectLoop::remselcon(NetconP con)
{
- if (con.isNull()) return -1;
+ if (!con) {
+ return -1;
+ }
LOGDEB1(("Netcon::remselcon: fd %d\n", con->m_fd));
map<int,NetconP>::iterator it = m_polldata.find(con->m_fd);
if (it == m_polldata.end()) {
- LOGDEB1(("Netcon::remselcon: con not found for fd %d\n", con->m_fd));
- return -1;
+ LOGDEB1(("Netcon::remselcon: con not found for fd %d\n", con->m_fd));
+ return -1;
}
con->setloop(0);
m_polldata.erase(it);
@@ -278,18 +331,19 @@
//////////////////////////////////////////////////////////
// Base class (Netcon) methods
-Netcon::~Netcon() {
+Netcon::~Netcon()
+{
closeconn();
if (m_peer) {
- free(m_peer);
- m_peer = 0;
- }
-}
-
-void Netcon::closeconn()
+ free(m_peer);
+ m_peer = 0;
+ }
+}
+
+void Netcon::closeconn()
{
if (m_ownfd && m_fd >= 0) {
- close(m_fd);
+ close(m_fd);
}
m_fd = -1;
m_ownfd = true;
@@ -302,8 +356,9 @@
void Netcon::setpeer(const char *hostname)
{
- if (m_peer)
- free(m_peer);
+ if (m_peer) {
+ free(m_peer);
+ }
m_peer = strdup(hostname);
}
@@ -311,13 +366,13 @@
{
LOGDEB2(( "Netcon::settcpnodelay\n" ));
if (m_fd < 0) {
- LOGERR(("Netcon::settcpnodelay: connection not opened\n"));
- return -1;
+ LOGERR(("Netcon::settcpnodelay: connection not opened\n"));
+ return -1;
}
char *cp = on ? (char *)&one : (char *)&zero;
if (setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, cp, sizeof(one)) < 0) {
- LOGSYSERR("NetconCli::settcpnodelay", "setsockopt", "TCP_NODELAY");
- return -1;
+ LOGSYSERR("NetconCli::settcpnodelay", "setsockopt", "TCP_NODELAY");
+ return -1;
}
return 0;
}
@@ -327,10 +382,11 @@
{
int flags = fcntl(m_fd, F_GETFL, 0);
if (flags != -1 ) {
- int newflags = onoff ? flags | O_NONBLOCK : flags & ~O_NONBLOCK;
- if (newflags != flags)
- if (fcntl(m_fd, F_SETFL, newflags)< 0)
- return -1;
+ int newflags = onoff ? flags | O_NONBLOCK : flags & ~O_NONBLOCK;
+ if (newflags != flags)
+ if (fcntl(m_fd, F_SETFL, newflags) < 0) {
+ return -1;
+ }
}
return flags;
}
@@ -338,7 +394,8 @@
/////////////////////////////////////////////////////////////////////
// Data socket (NetconData) methods
-NetconData::~NetconData() {
+NetconData::~NetconData()
+{
freeZ(m_buf);
m_bufbase = 0;
m_bufbytes = m_bufsize = 0;
@@ -349,25 +406,27 @@
LOGDEB2(("NetconData::send: fd %d cnt %d expe %d\n", m_fd, cnt, expedited));
int flag = 0;
if (m_fd < 0) {
- LOGERR(("NetconData::send: connection not opened\n"));
- return -1;
+ LOGERR(("NetconData::send: connection not opened\n"));
+ return -1;
}
if (expedited) {
- LOGDEB2(("NetconData::send: expedited data, count %d bytes\n", cnt));
- flag = MSG_OOB;
+ LOGDEB2(("NetconData::send: expedited data, count %d bytes\n", cnt));
+ flag = MSG_OOB;
}
int ret;
// There is a bug in the uthread version of sendto() in FreeBSD at
// least up to 2.2.7, so avoid using it when possible
- if (flag)
- ret = ::send(m_fd, buf, cnt, flag);
- else
- ret = ::write(m_fd, buf, cnt);
+ if (flag) {
+ ret = ::send(m_fd, buf, cnt, flag);
+ } else {
+ ret = ::write(m_fd, buf, cnt);
+ }
// Note: byte count may be different from cnt if fd is non-blocking
if (ret < 0) {
- char fdcbuf[20];sprintf(fdcbuf, "%d", m_fd);
- LOGSYSERR("NetconData::send", "send", fdcbuf);
+ char fdcbuf[20];
+ sprintf(fdcbuf, "%d", m_fd);
+ LOGSYSERR("NetconData::send", "send", fdcbuf);
}
return ret;
}
@@ -377,8 +436,8 @@
{
LOGDEB2(("NetconData::readready\n"));
if (m_fd < 0) {
- LOGERR(("NetconData::readready: connection not opened\n"));
- return -1;
+ LOGERR(("NetconData::readready: connection not opened\n"));
+ return -1;
}
return select1(m_fd, 0);
}
@@ -388,8 +447,8 @@
{
LOGDEB2(("NetconData::writeready\n"));
if (m_fd < 0) {
- LOGERR(("NetconData::writeready: connection not opened\n"));
- return -1;
+ LOGERR(("NetconData::writeready: connection not opened\n"));
+ return -1;
}
return select1(m_fd, 0, 1);
}
@@ -398,41 +457,43 @@
int NetconData::receive(char *buf, int cnt, int timeo)
{
LOGDEB2(("NetconData::receive: cnt %d timeo %d m_buf 0x%x m_bufbytes %d\n",
- cnt, timeo, m_buf, m_bufbytes));
+ cnt, timeo, m_buf, m_bufbytes));
if (m_fd < 0) {
- LOGERR(("NetconData::receive: connection not opened\n"));
- return -1;
+ LOGERR(("NetconData::receive: connection not opened\n"));
+ return -1;
}
int fromibuf = 0;
- // Get whatever might have been left in the buffer by a previous
+ // Get whatever might have been left in the buffer by a previous
// getline, except if we're called to fill the buffer of course
if (m_buf && m_bufbytes > 0 && (buf < m_buf || buf > m_buf + m_bufsize)) {
- fromibuf = MIN(m_bufbytes, cnt);
- memcpy(buf, m_bufbase, fromibuf);
- m_bufbytes -= fromibuf;
- m_bufbase += fromibuf;
- cnt -= fromibuf;
+ fromibuf = MIN(m_bufbytes, cnt);
+ memcpy(buf, m_bufbase, fromibuf);
+ m_bufbytes -= fromibuf;
+ m_bufbase += fromibuf;
+ cnt -= fromibuf;
LOGDEB2(("NetconData::receive: transferred %d from mbuf\n", fromibuf));
- if (cnt <= 0)
- return fromibuf;
+ if (cnt <= 0) {
+ return fromibuf;
+ }
}
if (timeo > 0) {
- int ret = select1(m_fd, timeo);
- if (ret == 0) {
- LOGDEB2(("NetconData::receive timed out\n"));
- m_didtimo = 1;
- return -1;
- }
- if (ret < 0) {
- LOGSYSERR("NetconData::receive", "select", "");
- return -1;
- }
+ int ret = select1(m_fd, timeo);
+ if (ret == 0) {
+ LOGDEB2(("NetconData::receive timed out\n"));
+ m_didtimo = 1;
+ return -1;
+ }
+ if (ret < 0) {
+ LOGSYSERR("NetconData::receive", "select", "");
+ return -1;
+ }
}
m_didtimo = 0;
if ((cnt = read(m_fd, buf + fromibuf, cnt)) < 0) {
- char fdcbuf[20];sprintf(fdcbuf, "%d", m_fd);
- LOGSYSERR("NetconData::receive", "read", fdcbuf);
- return -1;
+ char fdcbuf[20];
+ sprintf(fdcbuf, "%d", m_fd);
+ LOGSYSERR("NetconData::receive", "read", fdcbuf);
+ return -1;
}
LOGDEB2(("NetconData::receive: normal return, cnt %d\n", cnt));
return fromibuf + cnt;
@@ -445,16 +506,16 @@
LOGDEB2(("Netcon::doreceive: cnt %d, timeo %d\n", cnt, timeo));
cur = 0;
while (cnt > cur) {
- got = receive(buf, cnt-cur, timeo);
- LOGDEB2(("Netcon::doreceive: got %d\n", got));
- if (got < 0) {
- return -1;
- }
- if (got == 0) {
- return cur;
- }
- cur += got;
- buf += got;
+ got = receive(buf, cnt-cur, timeo);
+ LOGDEB2(("Netcon::doreceive: got %d\n", got));
+ if (got < 0) {
+ return -1;
+ }
+ if (got == 0) {
+ return cur;
+ }
+ cur += got;
+ buf += got;
}
return cur;
}
@@ -472,57 +533,58 @@
{
LOGDEB2(("NetconData::getline: cnt %d, timeo %d\n", cnt, timeo));
if (m_buf == 0) {
- if ((m_buf = (char *)malloc(defbufsize)) == 0) {
- LOGSYSERR("NetconData::getline: Out of mem", "malloc", "");
- return -1;
- }
- m_bufsize = defbufsize;
- m_bufbase = m_buf;
- m_bufbytes = 0;
+ if ((m_buf = (char *)malloc(defbufsize)) == 0) {
+ LOGSYSERR("NetconData::getline: Out of mem", "malloc", "");
+ return -1;
+ }
+ m_bufsize = defbufsize;
+ m_bufbase = m_buf;
+ m_bufbytes = 0;
}
char *cp = buf;
for (;;) {
- // Transfer from buffer. Have to take a lot of care to keep counts and
- // pointers consistant in all end cases
- int maxtransf = MIN(m_bufbytes, cnt-1);
- int nn = maxtransf;
- LOGDEB2(("Before loop, bufbytes %d, maxtransf %d, nn: %d\n",
- m_bufbytes, maxtransf, nn));
- for (nn = maxtransf; nn > 0;) {
- // This is not pretty but we want nn to be decremented for
- // each byte copied (even newline), and not become -1 if
- // we go to the end. Better ways welcome!
- nn--;
- if ((*cp++ = *m_bufbase++) == '\n')
- break;
- }
- // Update counts
- maxtransf -= nn; // Actual count transferred
- m_bufbytes -= maxtransf;
- cnt -= maxtransf;
- LOGDEB2(("After transfer: actual transf %d cnt %d, m_bufbytes %d\n",
- maxtransf, cnt, m_bufbytes));
-
- // Finished ?
- if (cnt <= 1 || (cp > buf && cp[-1] == '\n')) {
- *cp = 0;
- return cp - buf;
- }
-
- // Transfer from net
- m_bufbase = m_buf;
- m_bufbytes = receive(m_buf, m_bufsize, timeo);
- if (m_bufbytes == 0) {
- // EOF
- *cp = 0;
- return cp - buf;
- }
- if (m_bufbytes < 0) {
- m_bufbytes = 0;
- *cp = 0;
- return -1;
- }
+ // Transfer from buffer. Have to take a lot of care to keep counts and
+ // pointers consistant in all end cases
+ int maxtransf = MIN(m_bufbytes, cnt-1);
+ int nn = maxtransf;
+ LOGDEB2(("Before loop, bufbytes %d, maxtransf %d, nn: %d\n",
+ m_bufbytes, maxtransf, nn));
+ for (nn = maxtransf; nn > 0;) {
+ // This is not pretty but we want nn to be decremented for
+ // each byte copied (even newline), and not become -1 if
+ // we go to the end. Better ways welcome!
+ nn--;
+ if ((*cp++ = *m_bufbase++) == '\n') {
+ break;
+ }
+ }
+ // Update counts
+ maxtransf -= nn; // Actual count transferred
+ m_bufbytes -= maxtransf;
+ cnt -= maxtransf;
+ LOGDEB2(("After transfer: actual transf %d cnt %d, m_bufbytes %d\n",
+ maxtransf, cnt, m_bufbytes));
+
+ // Finished ?
+ if (cnt <= 1 || (cp > buf && cp[-1] == '\n')) {
+ *cp = 0;
+ return cp - buf;
+ }
+
+ // Transfer from net
+ m_bufbase = m_buf;
+ m_bufbytes = receive(m_buf, m_bufsize, timeo);
+ if (m_bufbytes == 0) {
+ // EOF
+ *cp = 0;
+ return cp - buf;
+ }
+ if (m_bufbytes < 0) {
+ m_bufbytes = 0;
+ *cp = 0;
+ return -1;
+ }
}
}
@@ -533,23 +595,23 @@
int NetconData::cando(Netcon::Event reason)
{
LOGDEB2(("NetconData::cando\n"));
- if (!m_user.isNull()) {
- return m_user->data(this, reason);
+ if (m_user) {
+ return m_user->data(this, reason);
}
// No user callback. Clean up by ourselves
if (reason & NETCONPOLL_READ) {
#define BS 200
- char buf[BS];
- int n;
- if ((n = receive(buf, BS)) < 0) {
- LOGSYSERR("NetconData::cando", "receive", "");
- return -1;
- }
- if (n == 0) {
- // EOF
- return 0;
- }
+ char buf[BS];
+ int n;
+ if ((n = receive(buf, BS)) < 0) {
+ LOGSYSERR("NetconData::cando", "receive", "");
+ return -1;
+ }
+ if (n == 0) {
+ // EOF
+ return 0;
+ }
}
clearselevents(NETCONPOLL_WRITE);
return 1;
@@ -564,73 +626,106 @@
closeconn();
- struct sockaddr_in saddr;
- memset(&saddr, 0, sizeof(saddr));
- saddr.sin_family = AF_INET;
- saddr.sin_port = htons(port);
-
- // Server name may be host name or IP address
- int addr;
- if ((addr = inet_addr(host)) != -1) {
- memcpy(&saddr.sin_addr, &addr, sizeof(addr));
+ struct sockaddr *saddr;
+ socklen_t addrsize;
+
+ struct sockaddr_in ip_addr;
+ struct sockaddr_un unix_addr;
+ if (host[0] != '/') {
+ memset(&ip_addr, 0, sizeof(ip_addr));
+ ip_addr.sin_family = AF_INET;
+ ip_addr.sin_port = htons(port);
+
+ // Server name may be host name or IP address
+ int addr;
+ if ((addr = inet_addr(host)) != -1) {
+ memcpy(&ip_addr.sin_addr, &addr, sizeof(addr));
+ } else {
+ struct hostent *hp;
+ if ((hp = gethostbyname(host)) == 0) {
+ LOGERR(("NetconCli::openconn: gethostbyname(%s) failed\n",
+ host));
+ return -1;
+ }
+ memcpy(&ip_addr.sin_addr, hp->h_addr, hp->h_length);
+ }
+
+ if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ LOGSYSERR("NetconCli::openconn", "socket", "");
+ return -1;
+ }
+ addrsize = sizeof(ip_addr);
+ saddr = (sockaddr*)&ip_addr;
} else {
- struct hostent *hp;
- if ((hp = gethostbyname(host)) == 0) {
- LOGERR(("NetconCli::openconn: gethostbyname(%s) failed\n", host));
- return -1;
- }
- memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
- }
-
- if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- LOGSYSERR("NetconCli::openconn", "socket", "");
- return -1;
- }
- if (timeo > 0)
- set_nonblock(1);
-
- if(connect(m_fd,(struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
- if (timeo > 0) {
- if (errno != EINPROGRESS)
- goto out;
- if (select1(m_fd, timeo, 1) == 1)
- goto connectok;
- }
- if (m_silentconnectfailure == 0) {
- LOGSYSERR("NetconCli", "connect", "");
- }
- goto out;
- }
- connectok:
- if (timeo > 0)
- set_nonblock(0);
+ memset(&unix_addr, 0, sizeof(unix_addr));
+ unix_addr.sun_family = AF_UNIX;
+ if (strlen(host) > UNIX_PATH_MAX - 1) {
+ LOGERR(("NetconCli::openconn: name too long: %s\n", host));
+ return -1;
+ }
+ strcpy(unix_addr.sun_path, host);
+
+ if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ LOGSYSERR("NetconCli::openconn", "socket", "");
+ return -1;
+ }
+ addrsize = sizeof(unix_addr);
+ saddr = (sockaddr*)&unix_addr;
+ }
+ if (timeo > 0) {
+ set_nonblock(1);
+ }
+
+ if (connect(m_fd, saddr, addrsize) < 0) {
+ if (timeo > 0) {
+ if (errno != EINPROGRESS) {
+ goto out;
+ }
+ if (select1(m_fd, timeo, 1) == 1) {
+ goto connectok;
+ }
+ }
+ if (m_silentconnectfailure == 0) {
+ LOGSYSERR("NetconCli", "connect", "");
+ }
+ goto out;
+ }
+connectok:
+ if (timeo > 0) {
+ set_nonblock(0);
+ }
LOGDEB2(("NetconCli::connect: setting keepalive\n"));
- if (setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE,
- (char *)&one, sizeof(one)) < 0) {
- LOGSYSERR("NetconCli::connect", "setsockopt", "KEEPALIVE");
+ if (setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE,
+ (char *)&one, sizeof(one)) < 0) {
+ LOGSYSERR("NetconCli::connect", "setsockopt", "KEEPALIVE");
}
setpeer(host);
LOGDEB2(("NetconCli::openconn: connection opened ok\n"));
ret = 0;
- out:
- if (ret < 0)
- closeconn();
+out:
+ if (ret < 0) {
+ closeconn();
+ }
return ret;
}
// Same as previous, but get the port number from services
-int NetconCli::openconn(const char *host, char *serv, int timeo)
+int NetconCli::openconn(const char *host, const char *serv, int timeo)
{
LOGDEB2(("Netconcli::openconn: host %s, serv %s\n", host, serv));
- struct servent *sp;
- if ((sp = getservbyname(serv, "tcp")) == 0) {
- LOGERR(("NetconCli::openconn: getservbyname failed for %s\n", serv));
- return -1;
- }
- // Callee expects the port number in host byte order
- return openconn(host, ntohs(sp->s_port), timeo);
+ if (host[0] != '/') {
+ struct servent *sp;
+ if ((sp = getservbyname(serv, "tcp")) == 0) {
+ LOGERR(("NetconCli::openconn: getservbyname failed for %s\n",serv));
+ return -1;
+ }
+ // Callee expects the port number in host byte order
+ return openconn(host, ntohs(sp->s_port), timeo);
+ } else {
+ return openconn(host, (unsigned int)0, timeo);
+ }
}
@@ -647,42 +742,88 @@
}
///////////////////////////////////////////////////////////////////////
-// Methods for the main (listening) server connection
-
-NetconServLis::~NetconServLis() {
+// Methods for the main (listening) server connection
+
+NetconServLis::~NetconServLis()
+{
#ifdef NETCON_ACCESSCONTROL
freeZ(okaddrs.intarray);
freeZ(okmasks.intarray);
-#endif
+#endif
}
#if 0
// code for dumping a struct servent
-static void dump_servent(struct servent *servp) {
+static void dump_servent(struct servent *servp)
+{
fprintf(stderr, "Official name %s\n", servp->s_name);
- for (char **cpp = servp->s_aliases;*cpp;cpp++)
- fprintf(stderr, "Nickname %s\n", *cpp);
+ for (char **cpp = servp->s_aliases; *cpp; cpp++) {
+ fprintf(stderr, "Nickname %s\n", *cpp);
+ }
fprintf(stderr, "Port %d\n", (int)ntohs((short)servp->s_port));
fprintf(stderr, "Proto %s\n", servp->s_proto);
}
#endif
// Set up service.
-int NetconServLis::openservice(char *serv, int backlog)
-{
- int port;
- struct servent *servp;
+int NetconServLis::openservice(const char *serv, int backlog)
+{
+ int port;
+ struct servent *servp;
+ if (!serv) {
+ LOGERR(("NetconServLis::openservice: null serv??\n"));
+ return -1;
+ }
LOGDEB1(("NetconServLis::openservice: serv %s\n", serv));
#ifdef NETCON_ACCESSCONTROL
- if (initperms(serv) < 0)
- return -1;
+ if (initperms(serv) < 0) {
+ return -1;
+ }
#endif
- if ((servp = getservbyname(serv, "tcp")) == 0) {
- LOGERR(("NetconServLis::openservice: getservbyname failed for %s\n",serv));
- return -1;
- }
- port = (int)ntohs((short)servp->s_port);
- return openservice(port, backlog);
+
+ m_serv = serv;
+ if (serv[0] != '/') {
+ if ((servp = getservbyname(serv, "tcp")) == 0) {
+ LOGERR(("NetconServLis::openservice: getservbyname failed for %s\n",
+ serv));
+ return -1;
+ }
+ port = (int)ntohs((short)servp->s_port);
+ return openservice(port, backlog);
+ } else {
+ if (strlen(serv) > UNIX_PATH_MAX - 1) {
+ LOGERR(("NetconServLis::openservice: too long for AF_UNIX: %s\n",
+ serv));
+ return -1;
+ }
+ int ret = -1;
+ struct sockaddr_un addr;
+ if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ LOGSYSERR("NetconServLis", "socket", "");
+ return -1;
+ }
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, serv);
+
+ if (::bind(m_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ LOGSYSERR("NetconServLis", "bind", "");
+ goto out;
+ }
+ if (listen(m_fd, backlog) < 0) {
+ LOGSYSERR("NetconServLis", "listen", "");
+ goto out;
+ }
+
+ LOGDEB1(("NetconServLis::openservice: service opened ok\n"));
+ ret = 0;
+ out:
+ if (ret < 0 && m_fd >= 0) {
+ close(m_fd);
+ m_fd = -1;
+ }
+ return ret;
+ }
}
// Port is a natural host integer value
@@ -690,14 +831,15 @@
{
LOGDEB1(("NetconServLis::openservice: port %d\n", port));
#ifdef NETCON_ACCESSCONTROL
- if (initperms(port) < 0)
- return -1;
+ if (initperms(port) < 0) {
+ return -1;
+ }
#endif
int ret = -1;
struct sockaddr_in ipaddr;
if ((m_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- LOGSYSERR("NetconServLis", "socket", "");
- return -1;
+ LOGSYSERR("NetconServLis", "socket", "");
+ return -1;
}
(void) setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR,(char *)&one, sizeof(one));
#ifdef SO_REUSEPORT
@@ -707,21 +849,21 @@
ipaddr.sin_family = AF_INET;
ipaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ipaddr.sin_port = htons((short)port);
- if (bind(m_fd, (struct sockaddr *)&ipaddr, sizeof(ipaddr)) < 0){
- LOGSYSERR("NetconServLis", "bind", "");
- goto out;
+ if (::bind(m_fd, (struct sockaddr *)&ipaddr, sizeof(ipaddr)) < 0) {
+ LOGSYSERR("NetconServLis", "bind", "");
+ goto out;
}
if (listen(m_fd, backlog) < 0) {
- LOGSYSERR("NetconServLis", "listen", "");
- goto out;
+ LOGSYSERR("NetconServLis", "listen", "");
+ goto out;
}
LOGDEB1(("NetconServLis::openservice: service opened ok\n"));
ret = 0;
- out:
+out:
if (ret < 0 && m_fd >= 0) {
- close(m_fd);
- m_fd = -1;
+ close(m_fd);
+ m_fd = -1;
}
return ret;
}
@@ -729,8 +871,9 @@
#ifdef NETCON_ACCESSCONTROL
int NetconServLis::initperms(int port)
{
- if (permsinit)
- return 0;
+ if (permsinit) {
+ return 0;
+ }
char sport[30];
sprintf(sport, "%d", port);
@@ -738,34 +881,35 @@
}
// Get authorized address lists from parameter file. This is disabled for now
-int NetconServLis::initperms(char *serv)
-{
- if (permsinit)
- return 0;
+int NetconServLis::initperms(const char *serv)
+{
+ if (permsinit) {
+ return 0;
+ }
if (serv == 0 || *serv == 0 || strlen(serv) > 80) {
- LOGERR(("NetconServLis::initperms: bad service name %s\n", serv));
- return -1;
+ LOGERR(("NetconServLis::initperms: bad service name %s\n", serv));
+ return -1;
}
char keyname[100];
sprintf(keyname, "%s_okaddrs", serv);
if (genparams->getparam(keyname, &okaddrs, 1) < 0) {
- serv = "default";
- sprintf(keyname, "%s_okaddrs", serv);
- if (genparams->getparam(keyname, &okaddrs) < 0) {
- LOGERR(("NetconServLis::initperms: no okaddrs found in config file\n"));
- return -1;
- }
+ serv = "default";
+ sprintf(keyname, "%s_okaddrs", serv);
+ if (genparams->getparam(keyname, &okaddrs) < 0) {
+ LOGERR(("NetconServLis::initperms: no okaddrs found in config file\n"));
+ return -1;
+ }
}
sprintf(keyname, "%s_okmasks", serv);
if (genparams->getparam(keyname, &okmasks)) {
- LOGERR(("NetconServLis::initperms: okmasks not found\n"));
- return -1;
+ LOGERR(("NetconServLis::initperms: okmasks not found\n"));
+ return -1;
}
if (okaddrs.len == 0 || okmasks.len == 0) {
- LOGERR(("NetconServLis::initperms: len 0 for okmasks or okaddrs\n"));
- return -1;
+ LOGERR(("NetconServLis::initperms: len 0 for okmasks or okaddrs\n"));
+ return -1;
}
permsinit = 1;
@@ -789,91 +933,111 @@
LOGDEB(("NetconServLis::accept\n"));
if (timeo > 0) {
- int ret = select1(m_fd, timeo);
- if (ret == 0) {
- LOGDEB2(("NetconServLis::accept timed out\n"));
- m_didtimo = 1;
- return 0;
- }
- if (ret < 0) {
- LOGSYSERR("NetconServLis::accept", "select", "");
- return 0;
- }
+ int ret = select1(m_fd, timeo);
+ if (ret == 0) {
+ LOGDEB2(("NetconServLis::accept timed out\n"));
+ m_didtimo = 1;
+ return 0;
+ }
+ if (ret < 0) {
+ LOGSYSERR("NetconServLis::accept", "select", "");
+ return 0;
+ }
}
m_didtimo = 0;
NetconServCon *con = 0;
int newfd = -1;
struct sockaddr_in who;
- SOCKLEN_T clilen = (SOCKLEN_T)sizeof(who);
- if ((newfd = ::accept(m_fd, (struct sockaddr *)&who, &clilen)) < 0) {
- LOGSYSERR("NetconServCon::accept", "accept", "");
- goto out;
- }
+ struct sockaddr_un uwho;
+ if (m_serv.empty() || m_serv[0] != '/') {
+ SOCKLEN_T clilen = (SOCKLEN_T)sizeof(who);
+ if ((newfd = ::accept(m_fd, (struct sockaddr *)&who, &clilen)) < 0) {
+ LOGSYSERR("NetconServCon::accept", "accept", "");
+ goto out;
+ }
#ifdef NETCON_ACCESSCONTROL
- if (checkperms(&who, clilen) < 0) {
- goto out;
- }
+ if (checkperms(&who, clilen) < 0) {
+ goto out;
+ }
#endif
+ } else {
+ SOCKLEN_T clilen = (SOCKLEN_T)sizeof(uwho);
+ if ((newfd = ::accept(m_fd, (struct sockaddr *)&uwho, &clilen)) < 0) {
+ LOGSYSERR("NetconServCon::accept", "accept", "");
+ goto out;
+ }
+ }
+
con = new NetconServCon(newfd);
if (con == 0) {
- LOGERR(("NetconServLis::accept: new NetconServCon failed\n"));
- goto out;
- }
+ LOGERR(("NetconServLis::accept: new NetconServCon failed\n"));
+ goto out;
+ }
+
// Retrieve peer's host name. Errors are non fatal
- struct hostent *hp;
- if ((hp = gethostbyaddr((char *)&(who.sin_addr), sizeof(struct in_addr),
- AF_INET)) == 0) {
- LOGERR(("NetconServLis::accept: gethostbyaddr failed for addr 0x%lx\n",
- who.sin_addr.s_addr));
- con->setpeer(inet_ntoa(who.sin_addr));
+ if (m_serv.empty() || m_serv[0] != '/') {
+ struct hostent *hp;
+ if ((hp = gethostbyaddr((char *) & (who.sin_addr),
+ sizeof(struct in_addr), AF_INET)) == 0) {
+ LOGERR(("NetconServLis::accept: gethostbyaddr failed for addr 0x%lx\n",
+ who.sin_addr.s_addr));
+ con->setpeer(inet_ntoa(who.sin_addr));
+ } else {
+ con->setpeer(hp->h_name);
+ }
} else {
- con->setpeer(hp->h_name);
- }
+ con->setpeer(m_serv.c_str());
+ }
+
LOGDEB2(("NetconServLis::accept: setting keepalive\n"));
- if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
- (char *)&one, sizeof(one)) < 0) {
- LOGSYSERR("NetconServLis::accept", "setsockopt", "KEEPALIVE");
+ if (setsockopt(newfd, SOL_SOCKET, SO_KEEPALIVE,
+ (char *)&one, sizeof(one)) < 0) {
+ LOGSYSERR("NetconServLis::accept", "setsockopt", "KEEPALIVE");
}
LOGDEB2(("NetconServLis::accept: got connect from %s\n", con->getpeer()));
- out:
- if (con == 0 && newfd >= 0)
- close(newfd);
+out:
+ if (con == 0 && newfd >= 0) {
+ close(newfd);
+ }
return con;
}
#ifdef NETCON_ACCESSCONTROL
-int
+int
NetconServLis::checkperms(void *cl, int)
{
// If okmasks and addrs were not initialized, the default is allow to all
- if (okmasks.len <= 0 || okaddrs.len <= 0)
- return 0;
+ if (okmasks.len <= 0 || okaddrs.len <= 0) {
+ return 0;
+ }
struct sockaddr *addr = (struct sockaddr *)cl;
unsigned long ip_addr;
if (addr->sa_family != AF_INET) {
- LOGERR(("NetconServLis::checkperms: connection from non-INET addr !\n"));
- return -1;
+ LOGERR(("NetconServLis::checkperms: connection from non-INET addr !\n"));
+ return -1;
}
ip_addr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
LOGDEB2(("checkperms: ip_addr: 0x%x\n", ip_addr));
for (int i = 0; i < okaddrs.len; i++) {
- unsigned int mask;
- if (i < okmasks.len)
- mask = okmasks.intarray[i];
- else
- mask = okmasks.intarray[okmasks.len-1];
- LOGDEB2(("checkperms: trying okaddr 0x%x, mask 0x%x\n",
- okaddrs.intarray[i], mask));
- if ((ip_addr & mask) == (okaddrs.intarray[i] & mask))
- return (0);
- }
- LOGERR(("NetconServLis::checkperm: connection from bad address 0x%x\n",
- ip_addr));
+ unsigned int mask;
+ if (i < okmasks.len) {
+ mask = okmasks.intarray[i];
+ } else {
+ mask = okmasks.intarray[okmasks.len-1];
+ }
+ LOGDEB2(("checkperms: trying okaddr 0x%x, mask 0x%x\n",
+ okaddrs.intarray[i], mask));
+ if ((ip_addr & mask) == (okaddrs.intarray[i] & mask)) {
+ return (0);
+ }
+ }
+ LOGERR(("NetconServLis::checkperm: connection from bad address 0x%x\n",
+ ip_addr));
return -1;
}
#endif /* NETCON_ACCESSCONTROL */
@@ -892,6 +1056,8 @@
#include "debuglog.h"
#include "netcon.h"
+
+using namespace std;
static char *thisprog;
static char usage[] =
@@ -900,7 +1066,7 @@
"\n"
"-s <service>: open service <service>\n"
;
-static void
+static void
Usage()
{
fprintf(stderr, "Usage : %s:\n %s", thisprog, usage);
@@ -923,49 +1089,55 @@
char *host, *serv;
thisprog = argv[0];
- argc--; argv++;
+ argc--;
+ argv++;
while (argc > 0 && **argv == '-') {
- (*argv)++;
- if (!(**argv))
- /* Cas du "adb - core" */
- Usage();
- while (**argv)
- switch (*(*argv)++) {
- case 's':
- op_flags |= OPT_s;
- break;
- case 'c':
- op_flags |= OPT_c;
- break;
- case 'n':
- op_flags |= OPT_n;
- break;
- default:
- Usage();
- break;
- }
- argc--;
- argv++;
+ (*argv)++;
+ if (!(**argv))
+ /* Cas du "adb - core" */
+ {
+ Usage();
+ }
+ while (**argv)
+ switch (*(*argv)++) {
+ case 's':
+ op_flags |= OPT_s;
+ break;
+ case 'c':
+ op_flags |= OPT_c;
+ break;
+ case 'n':
+ op_flags |= OPT_n;
+ break;
+ default:
+ Usage();
+ break;
+ }
+ argc--;
+ argv++;
}
DebugLog::setfilename("stderr");
DebugLog::getdbl()->setloglevel(DEBDEB2);
if (op_flags & OPT_c) {
- if (argc != 2) {
- Usage();
- }
- host = *argv++;argc--;
- serv = *argv++;argc--;
- exit(trycli(host, serv));
+ if (argc != 2) {
+ Usage();
+ }
+ host = *argv++;
+ argc--;
+ serv = *argv++;
+ argc--;
+ exit(trycli(host, serv));
} else if (op_flags & OPT_s) {
- if (argc != 1) {
- Usage();
- }
- serv = *argv++;argc--;
- exit(tryserv(serv));
+ if (argc != 1) {
+ Usage();
+ }
+ serv = *argv++;
+ argc--;
+ exit(tryserv(serv));
} else {
- Usage();
+ Usage();
}
}
@@ -977,47 +1149,47 @@
class CliNetconWorker : public NetconWorker {
public:
CliNetconWorker() : m_count(0) {}
- int data(NetconData *con, Netcon::Event reason)
- {
- LOGDEB(("clientdata\n"));
- if (reason & Netcon::NETCONPOLL_WRITE) {
- sprintf(fromcli, "Bonjour Bonjour client %d, count %d",
- getpid(), m_count);
- con->setselevents(Netcon::NETCONPOLL_READ);
- if (con->send(fromcli, strlen(fromcli) + 1) < 0) {
- fprintf(stderr, "send failed\n");
- return -1;
- }
- m_count++;
- }
-
- if (reason & Netcon::NETCONPOLL_READ) {
- con->setselevents(Netcon::NETCONPOLL_WRITE);
- int n;
- if ((n = con->receive(buf, buflen)) < 0) {
- fprintf(stderr, "receive failed\n");
- return -1;
- }
- if (n == 0) {
- // EOF, close connection
- return -1;
- }
- buf[n] = 0;
- fprintf(stderr, "%d received \"%s\"\n", getpid(), buf);
- if (op_flags & OPT_n) {
- pause();
- } else {
- sleep(1);
- }
- }
- if (m_count >= 10) {
- fprintf(stderr, "Did 10, enough\n");
- if (con->getloop())
- con->getloop()->loopReturn(0);
- }
- return 0;
- }
-private:
+ int data(NetconData *con, Netcon::Event reason) {
+ LOGDEB(("clientdata\n"));
+ if (reason & Netcon::NETCONPOLL_WRITE) {
+ sprintf(fromcli, "Bonjour Bonjour client %d, count %d",
+ getpid(), m_count);
+ con->setselevents(Netcon::NETCONPOLL_READ);
+ if (con->send(fromcli, strlen(fromcli) + 1) < 0) {
+ fprintf(stderr, "send failed\n");
+ return -1;
+ }
+ m_count++;
+ }
+
+ if (reason & Netcon::NETCONPOLL_READ) {
+ con->setselevents(Netcon::NETCONPOLL_WRITE);
+ int n;
+ if ((n = con->receive(buf, buflen)) < 0) {
+ fprintf(stderr, "receive failed\n");
+ return -1;
+ }
+ if (n == 0) {
+ // EOF, close connection
+ return -1;
+ }
+ buf[n] = 0;
+ fprintf(stderr, "%d received \"%s\"\n", getpid(), buf);
+ if (op_flags & OPT_n) {
+ pause();
+ } else {
+ sleep(1);
+ }
+ }
+ if (m_count >= 10) {
+ fprintf(stderr, "Did 10, enough\n");
+ if (con->getloop()) {
+ con->getloop()->loopReturn(0);
+ }
+ }
+ return 0;
+ }
+private:
int m_count;
};
@@ -1027,44 +1199,47 @@
NetconCli *clicon = new NetconCli();
NetconP con(clicon);
- if (con.isNull()) {
- fprintf(stderr, "new NetconCli failed\n");
- return 1;
- }
- if (clicon->openconn(host, serv) < 0) {
- fprintf(stderr, "openconn(%s, %s) failed\n", host, serv);
- return 1;
+ if (!con) {
+ fprintf(stderr, "new NetconCli failed\n");
+ return 1;
+ }
+ int port = atoi(serv);
+ int ret = port > 0 ?
+ clicon->openconn(host, port) : clicon->openconn(host, serv);
+ if (ret < 0) {
+ fprintf(stderr, "openconn(%s, %s) failed\n", host, serv);
+ return 1;
}
fprintf(stderr, "openconn(%s, %s) ok\n", host, serv);
#ifdef NOSELLOOP
- for (int i = 0;i < nloop;i++) {
- if (con->send(fromcli, strlen(fromcli) + 1) < 0) {
- fprintf(stderr, "%d: Send failed\n", getpid());
- return 1;
- }
- if (con->receive(buf, buflen) < 0) {
- perror("receive:");
- fprintf(stderr, "%d: Receive failed\n", getpid());
- return 1;
- }
- fprintf(stderr, "%d Received \"%s\"\n", getpid(), buf);
- if (op_flags & OPT_n) {
- pause();
- } else {
- sleep(1);
- }
+ for (int i = 0; i < nloop; i++) {
+ if (con->send(fromcli, strlen(fromcli) + 1) < 0) {
+ fprintf(stderr, "%d: Send failed\n", getpid());
+ return 1;
+ }
+ if (con->receive(buf, buflen) < 0) {
+ perror("receive:");
+ fprintf(stderr, "%d: Receive failed\n", getpid());
+ return 1;
+ }
+ fprintf(stderr, "%d Received \"%s\"\n", getpid(), buf);
+ if (op_flags & OPT_n) {
+ pause();
+ } else {
+ sleep(1);
+ }
}
#else
- RefCntr<NetconWorker> worker =
- RefCntr<NetconWorker>(new CliNetconWorker());
+ RefCntr<NetconWorker> worker =
+ RefCntr<NetconWorker>(new CliNetconWorker());
clicon->setcallback(worker);
SelectLoop myloop;
myloop.addselcon(con, Netcon::NETCONPOLL_WRITE);
fprintf(stderr, "client ready\n");
- int ret = myloop.doLoop();
+ ret = myloop.doLoop();
if (ret < 0) {
- fprintf(stderr, "selectloop failed\n");
- exit(1);
+ fprintf(stderr, "selectloop failed\n");
+ exit(1);
}
fprintf(stderr, "selectloop returned %d\n", ret);
#endif
@@ -1076,36 +1251,35 @@
class ServNetconWorker : public NetconWorker {
public:
ServNetconWorker() : m_count(0) {}
- int data(NetconData *con, Netcon::Event reason)
- {
- LOGDEB(("serverdata\n"));
- if (reason & Netcon::NETCONPOLL_WRITE) {
- con->setselevents(Netcon::NETCONPOLL_READ);
- char fromserv[200];
- sprintf(fromserv,
- "Du serveur: mon fd pour ce client est %d, mon compte %d",
- con->getfd(), ++m_count);
- if (con->send(fromserv, strlen(fromserv) + 1) < 0) {
- fprintf(stderr, "send failed\n");
- return -1;
- }
- }
- if (reason & Netcon::NETCONPOLL_READ) {
+ int data(NetconData *con, Netcon::Event reason) {
+ LOGDEB(("serverdata\n"));
+ if (reason & Netcon::NETCONPOLL_WRITE) {
+ con->setselevents(Netcon::NETCONPOLL_READ);
+ char fromserv[200];
+ sprintf(fromserv,
+ "Du serveur: mon fd pour ce client est %d, mon compte %d",
+ con->getfd(), ++m_count);
+ if (con->send(fromserv, strlen(fromserv) + 1) < 0) {
+ fprintf(stderr, "send failed\n");
+ return -1;
+ }
+ }
+ if (reason & Netcon::NETCONPOLL_READ) {
#define LL 200
- char buf[LL+1];
- int n;
- if ((n = con->receive(buf, LL)) < 0) {
- fprintf(stderr, "receive failed\n");
- return -1;
- }
- if (n == 0) {
- return -1;
- }
- buf[n] = 0;
- fprintf(stderr, "%d received \"%s\"\n", getpid(), buf);
- con->setselevents(Netcon::NETCONPOLL_READ|Netcon::NETCONPOLL_WRITE);
- }
- return 0;
+ char buf[LL+1];
+ int n;
+ if ((n = con->receive(buf, LL)) < 0) {
+ fprintf(stderr, "receive failed\n");
+ return -1;
+ }
+ if (n == 0) {
+ return -1;
+ }
+ buf[n] = 0;
+ fprintf(stderr, "%d received \"%s\"\n", getpid(), buf);
+ con->setselevents(Netcon::NETCONPOLL_READ|Netcon::NETCONPOLL_WRITE);
+ }
+ return 0;
}
private:
int m_count;
@@ -1114,19 +1288,19 @@
class MyNetconServLis : public NetconServLis {
public:
MyNetconServLis(SelectLoop &loop)
- : NetconServLis(), m_loop(loop)
- {
+ : NetconServLis(), m_loop(loop) {
}
protected:
int cando(Netcon::Event reason) {
- NetconServCon *con = accept();
- if (con == 0)
- return -1;
- RefCntr<NetconWorker> worker =
- RefCntr<NetconWorker>(new ServNetconWorker());
- con->setcallback(worker);
- m_loop.addselcon(NetconP(con), NETCONPOLL_READ);
- return 1;
+ NetconServCon *con = accept();
+ if (con == 0) {
+ return -1;
+ }
+ RefCntr<NetconWorker> worker =
+ RefCntr<NetconWorker>(new ServNetconWorker());
+ con->setcallback(worker);
+ m_loop.addselcon(NetconP(con), NETCONPOLL_READ);
+ return 1;
}
SelectLoop& m_loop;
};
@@ -1137,8 +1311,9 @@
onexit(int sig)
{
fprintf(stderr, "Onexit: ");
- if (sig == SIGQUIT)
- kill(getpid(), SIGKILL);
+ if (sig == SIGQUIT) {
+ kill(getpid(), SIGKILL);
+ }
fprintf(stderr, "Exiting\n");
exit(0);
}
@@ -1149,9 +1324,9 @@
SelectLoop myloop;
MyNetconServLis *servlis = new MyNetconServLis(myloop);
lis = NetconP(servlis);
- if (lis.isNull()) {
- fprintf(stderr, "new NetconServLis failed\n");
- return 1;
+ if (!lis) {
+ fprintf(stderr, "new NetconServLis failed\n");
+ return 1;
}
// Prepare for cleanup
@@ -1163,15 +1338,18 @@
sigaction(SIGQUIT, &sa, 0);
sigaction(SIGTERM, &sa, 0);
- if (servlis->openservice(serv) < 0) {
- fprintf(stderr, "openservice(%s) failed\n", serv);
- return 1;
+ int port = atoi(serv);
+ int ret = port > 0 ?
+ servlis->openservice(port) : servlis->openservice(serv);
+ if (ret < 0) {
+ fprintf(stderr, "openservice(%s) failed\n", serv);
+ return 1;
}
myloop.addselcon(lis, Netcon::NETCONPOLL_READ);
fprintf(stderr, "openservice(%s) Ok\n", serv);
if (myloop.doLoop() < 0) {
- fprintf(stderr, "selectloop failed\n");
- exit(1);
+ fprintf(stderr, "selectloop failed\n");
+ exit(1);
}
return 0;
}