Re: htdig: making ht://Dig 3.1.0b1 in Digital Unix 4.0D


Paul J. Meyer (pmeyer@rimeice.msfc.nasa.gov)
Thu, 24 Sep 1998 07:55:15 -0500


Michael,

    I had a similar problem on my Dec alpha running Redhat 5.1. I think the
fundamental problem is the use of size_t as unsigned long instead of unsigned
int. Due to some of these type mismatches etc. (Alphas are 64 bit processors,
not 32 bit, so longs are 8 bytes and not 4!), the libht.a is not being created,
so you have the problem you encountered. There may have been something else in
there that I corrected. But these should hopefully give you a jumpstart. I'm
including a Connection.cc, and Connection.h from the htlib directory from my
setup. Also, note that one of the network address comparisons, the ~0L is
replaced by ~0 This statement change was fundamentally necessary to make htdig
operate - compiled fairly clean - but wouldn't work.

Paul

On Sep 23, 3:43pm, Michael Boer wrote:
> Subject: htdig: making ht://Dig 3.1.0b1 in Digital Unix 4.0D
> There have been a few questions on making ht://Dig in Digital Unix
> recently, but no answers. Since I'm now in the position of wanting to
> do this, I will share a few observations, hoping that someone will find
> sense and a solution in what is a mystery to me.
>
> I have fresh installations of gcc 2.8.1, gmake 3.77, libstdc++ 2.8.1
> (with the libg++ 2.8.1.1a compatibility thing), and I have compiled c++
> in what I believe is the recommended fashion.
>
> Since the normal ht://Dig make process fails, I've tried to approach it
> a step at a time.
> ........
> -L../rx-1.5/rx -L/usr/lib Document.o HTML.o Images.o Parsable.o
> Plaintext.o Postscript.o Retriever.o SGMLEntities.o Server.o URLRef.o
> main.o ExternalParser.o PDF.o -lcommon -lht -ldb -lrx
> collect2: ld returned 1 exit status
> /usr/bin/ld:
> Can't locate file for: -lht
> gmake: *** [htdig] Error 1
>
> This is the essential failure, I think. So, friends, what's up with
> ld's errors here? (Is it an issue that it uses Digital's /usr/bin/ld
> rather than the gnu ld which located elsewhere? Or is it something
> more fundamental than an ld problem?)
>
 End of excerpt from Michael Boer

-- 
__
Paul J. Meyer
Global Hydrology and Climate Center
NASA/MSFC code HR20     |  pmeyer@rimeice.msfc.nasa.gov (SMTP)
Huntsville, AL 35812    |  paul.meyer@msfc.nasa.gov    (X.500)
     Voice: (256) 922-5892  Fax: (256) 922-5723
           http://wwwghcc.msfc.nasa.gov/

// // Connection.cc // // (c) Copyright 1993, San Diego State University -- College of Sciences // (See the COPYRIGHT file for more Copyright information) // // Implementation of the Connection class // // $Log: Connection.cc,v $ // Revision 1.7 1998/06/22 04:33:20 turtle // New Berkeley database stuff // // Revision 1.6 1998/05/26 03:58:06 turtle // Got rid of compiler warnings. // // Revision 1.5 1998/01/05 05:18:18 turtle // Fix by Pontus Borg for AIX. Changed 'size_t' to 'unsigned long' for // the length parameter for getpeername() // // Revision 1.4 1997/10/23 18:01:10 turtle // Fix by Pontus Borg for AIX. Changed 'size_t' to 'unsigned long' for // the length parameter for getpeername() // // Revision 1.3 1997/03/24 04:33:19 turtle // Renamed the String.h file to htString.h to help compiling under win32 // // Revision 1.2 1997/02/10 17:32:47 turtle // Applied AIX specific patches supplied by Lars-Owe Ivarsson // <lars-owe.ivarsson@its.uu.se> // // Revision 1.1.1.1 1997/02/03 17:11:04 turtle // Initial CVS // //

#include "Connection.h" #include "Object.h" #include "htString.h" #include "List.h"

#include <errno.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <sys/ioctl.h> #include <sys/uio.h> #include <sys/file.h> #include <unistd.h> #include <fcntl.h> #include <netdb.h> #include <stdlib.h>

extern "C" { int rresvport(int *); }

List all_connections;

Connection::Connection() { sock = -1; connected = 0; peer = 0; server_name = 0; all_connections.Add(this); }

//************************************************************************* // Connection::Connection(int socket) // PURPOSE: // Create a connection from just a socket. // PARAMETERS: // int socket: obvious!!!! // Connection::Connection(int socket) { sock = socket; connected = 0; unsigned int length = sizeof(server); if (getpeername(socket, (struct sockaddr *)&server, &length) < 0) { perror("getpeername"); } peer = 0; server_name = 0; all_connections.Add(this); }

//***************************************************************************** // Connection::~Connection() // Connection::~Connection() { all_connections.Remove(this); this->close(); delete peer; delete server_name; }

//***************************************************************************** // int Connection::open(int priv) // int Connection::open(int priv) { if (priv) { int aport = IPPORT_RESERVED - 1;

sock = rresvport(&aport); } else sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock == NOTOK) return NOTOK;

int on = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)); server.sin_family = AF_INET;

return OK; }

//***************************************************************************** // int Connection::ndelay() // int Connection::ndelay() { return fcntl(sock, F_SETFL, FNDELAY); }

//***************************************************************************** // int Connection::nondelay() // int Connection::nondelay() { return fcntl(sock, F_SETFL, 0); }

//***************************************************************************** // int Connection::close() // int Connection::close() { connected = 0; if (sock >= 0) { int ret = ::close(sock); sock = -1; return ret; } return NOTOK; }

//***************************************************************************** // int Connection::assign_port(int port) // int Connection::assign_port(int port) { server.sin_port = htons(port); return OK; }

//***************************************************************************** // int Connection::assign_port(char *service) // int Connection::assign_port(char *service) { struct servent *sp;

sp = getservbyname(service, "tcp"); if (sp == NULL) { return NOTOK; } server.sin_port = sp->s_port; return OK; }

//***************************************************************************** // int Connection::assign_server(unsigned int addr) // int Connection::assign_server(unsigned int addr) { server.sin_addr.s_addr = addr; return OK; }

extern "C" unsigned int inet_addr(char *);

//***************************************************************************** // int Connection::assign_server(char *name) // int Connection::assign_server(char *name) { struct hostent *hp; unsigned int addr;

addr = inet_addr(name); if (addr == ~0/*L*/) /* PJM MOD */ { hp = gethostbyname(name); if (hp == NULL) { return NOTOK; } memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length); } else { memcpy((char *)&server.sin_addr, (char *)&addr, sizeof(addr)); }

delete server_name; server_name = strdup(name);

return OK; }

//***************************************************************************** // int Connection::connect(int allow_EINTR) // int Connection::connect(int allow_EINTR) { int status;

for (;;) { status = ::connect(sock, (struct sockaddr *)&server, sizeof(server)); if (status < 0 && errno == EINTR && !allow_EINTR) { ::close(sock); open(); continue; } break; } if (status == 0 || errno == EALREADY || errno == EISCONN) { connected = 1; return OK; } #if 0 if (status == ECONNREFUSED) { // // For the case where the connection attempt is refused, we need // to close the socket and create a new one in order to do any // more with it. // ::close(sock); open(); } #else ::close(sock); open(0); #endif

connected = 0; return NOTOK; }

//***************************************************************************** // int Connection::bind() // int Connection::bind() { if (::bind(sock, (struct sockaddr *)&server, sizeof(server)) == NOTOK) { return NOTOK; } return OK; }

//***************************************************************************** // int Connection::get_port() // int Connection::get_port() { unsigned int length = sizeof(server); if (getsockname(sock, (struct sockaddr *)&server, &length) == NOTOK) { return NOTOK; } return ntohs(server.sin_port); }

//***************************************************************************** // int Connection::listen(int n) // int Connection::listen(int n) { return ::listen(sock, n); }

//***************************************************************************** // Connection *Connection::accept(int priv) // Connection *Connection::accept(int priv) { int newsock;

while (1) { newsock = ::accept(sock, (struct sockaddr *)0, (unsigned int *)0); if (newsock == NOTOK && errno == EINTR) continue; break; } if (newsock == NOTOK) return (Connection *)0;

Connection *newconnect = new Connection; newconnect->sock = newsock;

unsigned int length = sizeof(newconnect->server); getpeername(newsock, (struct sockaddr *)&newconnect->server, &length);

if (priv && newconnect->server.sin_port >= IPPORT_RESERVED) { delete newconnect; return (Connection *)0; }

return newconnect; }

//************************************************************************* // Connection *Connection::accept_privileged() // PURPOSE: // Accept in incoming connection but only if it is from a // privileged port // Connection * Connection::accept_privileged() { return accept(1); }

//************************************************************************* // int Connection::read_partial(char *buffer, int maxlength) // PURPOSE: // Read at most <maxlength> from the current TCP connection. // This is equivalent to the workings of the standard read() // system call // PARAMETERS: // char *buffer: Buffer to read the data into // int maxlength: Maximum number of bytes to read into the buffer // RETURN VALUE: // The actual number of bytes read in. // ASSUMPTIONS: // The connection has been previously established. // FUNCTIONS USED: // read() // int Connection::read_partial(char *buffer, int maxlength) { int count;

do { count = ::read(sock, buffer, maxlength); } while (count < 0 && errno == EINTR && !need_io_stop); need_io_stop = 0;

return count; }

//************************************************************************* // int Connection::write_partial(char *buffer, int maxlength) // int Connection::write_partial(char *buffer, int maxlength) { int count;

do { count = ::write(sock, buffer, maxlength); } while (count < 0 && errno == EINTR && !need_io_stop); need_io_stop = 0;

return count; }

//************************************************************************* // char * Connection::socket_as_string() // PURPOSE: // Return the numeric ASCII equivalent of the socket number. // This is needed to pass the socket to another program // char * Connection::socket_as_string() { char *buffer = new char[20];

sprintf(buffer, "%d", sock); return buffer; }

extern "C" char *inet_ntoa(struct in_addr);

//************************************************************************* // char *Connection::get_peername() // char *Connection::get_peername() { if (!peer) { struct sockaddr_in p; unsigned int length = sizeof(p); struct hostent *hp; if (getpeername(sock, (struct sockaddr *) &p, &length) < 0) { return 0; } length = sizeof(p.sin_addr); hp = gethostbyaddr((const char *) &p.sin_addr, length, AF_INET); if (hp) peer = strdup((char *) hp->h_name); else peer = strdup((char *) inet_ntoa(p.sin_addr)); } return peer; }

//************************************************************************* // char *Connection::get_peerip() // char *Connection::get_peerip() { struct sockaddr_in peer; unsigned int length = sizeof(peer); if (getpeername(sock, (struct sockaddr *) &peer, &length) < 0) { return 0; } return inet_ntoa(peer.sin_addr); }

#if defined(__sun__) extern "C" int gethostname(char *name, int namelen); #endif

//************************************************************************* // unsigned int gethostip(char *ip, int length) // unsigned int gethostip(char *ip, int length) { char hostname[100]; if (gethostname(hostname, sizeof(hostname)) == NOTOK) return 0;

struct hostent *ent = gethostbyname(hostname); if (!ent) return 0;

struct in_addr addr; memcpy((char *) &addr.s_addr, ent->h_addr, sizeof(addr)); if (ip) strncpy(ip, inet_ntoa(addr), length); return addr.s_addr; }

// // Connection.h // // (c) Copyright 1993, San Diego State University -- College of Sciences // (See the COPYRIGHT file for more Copyright information) // // This class forms a easy to use interface to the berkeley tcp socket library. // All the calls are basically the same, but the parameters do not have any // stray _addr or _in mixed in... // // $Id: Connection.h,v 1.1.1.1 1997/02/03 17:11:04 turtle Exp $ // // $Log: Connection.h,v $ // Revision 1.1.1.1 1997/02/03 17:11:04 turtle // Initial CVS // //

#if !defined(_Connection_h_) # define _Connection_h_

#include "io.h"

#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h>

class String;

class Connection : public io { public: // Constructors & Destructors Connection(); Connection(int socket); ~Connection();

// (De)initialization int open(int priv = 0); int close(); int ndelay(); int nondelay();

// Port stuff int assign_port(int port = 0); int assign_port(char *service); int get_port(); int is_privileged();

// Host stuff int assign_server(char *name); int assign_server(unsigned int addr = INADDR_ANY); char *get_server() {return server_name;}

// Connection establishment int connect(int allow_EINTR = 0); Connection *accept(int priv = 0); Connection *accept_privileged();

// Registration things int bind(); int listen(int n = 5);

// IO int read_partial(char *buffer, int maxlength); int write_partial(char *buffer, int maxlength); void stop_io() {need_io_stop = 1;}

// Access to socket number char *socket_as_string(); int get_socket() {return sock;} int isopen() {return sock >= 0;} int isconnected() {return connected;}

// Access to info about remote socket char *get_peerip(); char *get_peername();

private: int sock; struct sockaddr_in server; int connected; char *peer; char *server_name; int need_io_stop; };

//************************************************************************* // inline int Connection::is_privileged() // PURPOSE: // Return whether the port is priveleged or not. // inline int Connection::is_privileged() { return server.sin_port < 1023; }

// // Get arround the lack of gethostip() library call... There is a gethostname() // call but we want the IP address, not the name! // The call will put the ASCII string representing the IP address in the supplied // buffer and it will also return the 4 byte unsigned long equivalent of it. // The ip buffer can be null... // unsigned int gethostip(char *ip = 0, int length = 0);

#endif

---------------------------------------------------------------------- To unsubscribe from the htdig mailing list, send a message to htdig-request@sdsu.edu containing the single word "unsubscribe" in the body of the message.



This archive was generated by hypermail 2.0b3 on Sat Jan 02 1999 - 16:27:51 PST