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


Geoff Hutchison (Geoffrey.R.Hutchison@williams.edu)
Wed, 07 Oct 1998 14:32:16 -0400


Several people asked for the patch for Connection.cc on Alphas. Here's the
patch from Paul Meyer (thanks Paul!)
-Geoff

>Date: Thu, 24 Sep 1998 07:55:15 -0500
>From: "Paul J. Meyer" <pmeyer@rimeice.msfc.nasa.gov>
>Subject: Re: htdig: making ht://Dig 3.1.0b1 in Digital Unix 4.0D
>Sender: owner-htdig@sdsu.edu
>To: Michael Boer <boerm@u.washington.edu>
>Cc: htdig@sdsu.edu
>Reply-to: "Paul J. Meyer" <pmeyer@rimeice.msfc.nasa.gov>
>
>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/
>
>
>X-Zm-Content-Name: Connection.cc
>Content-Description: Text
>Content-Type: text/plain ; name="Connection.cc" ; charset=us-ascii
>
>//
>// 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;
>}
>
>
>X-Zm-Content-Name: Connection.h
>Content-Description: Text
>Content-Type: text/plain ; name="Connection.h" ; charset=us-ascii
>
>//
>// 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:28:29 PST