AIX calling WINSOCK during e-mail - normal?


 
Thread Tools Search this Thread
Top Forums Programming AIX calling WINSOCK during e-mail - normal?
# 43  
Old 01-25-2011
Great, thanks for the help. I'll keep debugging that - I figure we're very close to figuring out these segfaults. We might actually rewrite the whole component.
We just got word from our client that fixing the socket resolved their email issues - the segfaults are only happening in our baseline environments.

Not sure how much they're going to want me to keep working on this now - so if you don't hear from me for a week or so, that's why. Just wanted to say thanks so much for helping with this - there are a lot of happy people here.
# 44  
Old 01-25-2011
Quote:
Originally Posted by ctote
We might actually rewrite the whole component.
From the looks of it... that might be a good idea. It's not too bad when you look at small bits but when you see how it's put together, the code you've posted is Smilie after Smilie after Smilie
This User Gave Thanks to Corona688 For This Post:
# 45  
Old 01-25-2011
I agree.

So I did
Code:
*pst = (void *)conn;

because just 'pst' wouldn't compile. But I'm still getting the problem where pst stay 0 the whole time. Any idea what else to try?
# 46  
Old 01-25-2011
Do fprintf(stderr, "sizeof(void *)=%d, sizeof(int)=%d\n", sizeof(void *), sizeof(int)); somewhere. If they're anything but identical that code is in serious trouble.

Given how badly pointers have been treated elsewhere in this code, I suspect that pointer's been corrupted somehow, but I can't say for sure since I don't see any code for what's calling gensock_connect(), what's calling the thing that calls it, etc etc etc until we get to the point the actual pointer gets passed in.
# 47  
Old 01-25-2011
I guess I'm a little confused - why can I do '*pst = conn;' in windows but not in AIX?

The typedef in windows is:
typedef void FAR * socktag;

And in AIX its:
typedef void * socktag;

---------- Post updated at 04:36 PM ---------- Previous update was at 04:03 PM ----------

btw, my print statements aren't being output to the cmd prompt. Not sure why.

---------- Post updated at 04:39 PM ---------- Previous update was at 04:36 PM ----------

I should also mention that *pst = conn; compiles fine. But like the rest of my tries, it completely skips over the line as if it doesn't exist. It might stop at the line, but nothing changes after execution. Is there a command in dbx to print the line of execution you're at?
# 48  
Old 01-25-2011
Quote:
Originally Posted by ctote
I guess I'm a little confused - why can I do '*pst = conn;' in windows but not in AIX?
It's not that. It's this:

Code:
int gensock_getchar (int st, int wait, char * ch)
{
   int retval = 0;
   connection *conn;

   conn = (connection *)st;

   if ((retval = conn->cc_getchar(wait, ch)))
      return (retval);
   else
      return (0);
}

In windows 32-bit, that's works, because an "int" contains enough bits to hold a "void *". They're in fact the same, 32 bits. This is a bad habit because it's never safe to assume that an int is large enough everywhere. On many 64-bit platforms, including Linux and Windows and maybe AIX(what did that code print? are int and void * different sizes or not?), an int would be 32-bit and a pointer would be 64-bit. Cramming a pointer into an integer would mangle it beyond use.

This code was obviously written with the assumption that sizeof(int) == sizeof(void *). I suspect this isn't true anymore, but yog only knows what depended on it!

I think some pointers elsewhere must have already been mangled, and you're only noticing strange things happening long after the actual mistake. This is why you're getting weird crashes in harmless places -- that pointer got mangled, so when you try to read or modify a member, it tries to use invalid memory and crashes. Variables not doing what you expect -- what is it truly pointing to now? etc.

Of course, I could be wrong, and there could be other reasons.

None of which I can tell without seeing the code. I can't answer definitively until you post the parts I asked for, and maybe not even then.

Last edited by Corona688; 01-25-2011 at 06:16 PM..
# 49  
Old 01-25-2011
I think the easiest thing for me to do at this point is post both of my files. I've already posted a large chunk, and those are probably outdated now.

Flow begins at prepare_smtp_message()
Code:
//mail_un.cpp


#ifdef OC_UNIX
#include <stdio.h>
#include <stdlib.h>

#include <amsios.h>
#include <string.h>
#include <time.h>
#include <amsdefs.h>
#include <mail.h> 
/* generic socket DLL support */
#include "gensocks.h"

#define MAXOUTLINE 255


socktag SMTPSock;


#define SERVER_SIZE    256     // #defines (bleah!) from Beverly Brown "beverly@datacube.com"
#define SENDER_SIZE    256
#define MAX_PATH    256
enum BOOL { FALSE1, TRUE1};

char SMTPHost[SERVER_SIZE];
char Sender[SENDER_SIZE];
char *Recipients;
char my_hostname[1024];
char *destination = "";
char *cc_list = "";
char *bcc_list = "";
char *loginname = "";
char *senderid = "";
char *subject = "";
int mime = 0;
int quiet = 0;


char *usage[] =
   {
      "Blat v1.5: WinNT console utility to mail a file via SMTP",
      "",
      "syntax:",
      "Blat <filename> -t <recipient> [optional switches (see below)]",
      "Blat -install <server addr> <sender's addr> [-q]",
      "Blat -h [-q]",
      "",
      "-install <server addr> <sender's addr>: set's default SMTP server and sender",
      "",
      "<filename>    : file with the message body ('-' for console input, end with ^Z)",
      "-t <recipient>: recipient list (comma separated)",
      "-s <subj>     : subject line",
      "-f <sender>   : overrides the default sender address (must be known to server)",
      "-i <addr>     : a 'From:' address, not necessarily known to the SMTP server.",
      "-c <recipient>: carbon copy recipient list (comma separated)",
      "-b <recipient>: blind carbon copy recipient list (comma separated)",
      "-h            : displays this help.",
      "-mime         : MIME Quoted-Printable Content-Transfer-Encoding.",
      "-q            : supresses *all* output.",
      "-server <addr>: overrides the default SMTP server to be used.",
      "",
      "Note that if the '-i' option is used, <sender> is included in 'Reply-to:'",
      "and 'Sender:' fields in the header of the message."
   };
const NMLINES = 22;

void
gensock_error (char * function, int retval)
{
   if ( ! quiet )
   {
      switch ( retval )
      {
         case 4001:
         cout << "Error: Malloc failed (possibly out of memory).";
         break;
         case 4002:
         cout << "Error: Error sending data.";
         break;
         case 4003:
         cout << "Error: Error initializing gensock.dll.";
         break;
         case 4004:
         cout << "Error: Version not supported.";
         break;
         case 4005:
         cout << "Error: The winsock version specified by gensock is not supported by this winsock.dll.";
         break;
         case 4006:
         cout << "Error: Network not ready.";
         break;
         case 4007:
         cout << "Error: Can't resolve (mailserver) hostname.";
         break;
         case 4008:
         cout << "Error: Can't create a socket (too many simultaneous links?)";
         break;
         case 4009:
         cout << "Error: Error reading socket.";
         break;
         case 4010:
         cout << "Error: Not a socket.";
         break;
         case 4011:
         cout << "Error: Busy.";
         break;
         case 4012:
         cout << "Error: Error closing socket.";
         break;
         case 4013:
         cout << "Error: Wait a bit (possible timeout).";
         break;
         case 4014:
         cout << "Error: Can't resolve service.";
         break;
         case 4015:
         cout << "Error: Can't connect to mailserver (timed out if winsock.dll error 10060)";
         break;
         case 4016:
         cout << "Error: Connection to mailserver was dropped.";
         break;
         case 4017:
         cout << "Error: Mail server refused connection.";
         break;
         default:
         cout << "error " << retval << " in function '" << function;
      }
   }
}




int open_smtp_socket( void )
{
   int retval;


   retval = gensock_connect ( SMTPHost, "smtp", &SMTPSock);

   if (retval)
   {
      if (retval == ERR_CANT_RESOLVE_SERVICE)
      {
         retval = gensock_connect (SMTPHost,
                                   "25",
                                   &SMTPSock);
         if (retval)
         {
            gensock_error ("gensock_connect", retval);
            return -1;
         }
      }
      // error other than can't resolve service
      else
      {
         gensock_error ("gensock_connect", retval);
         return -1;
      }
   }

   return 0;
}


int close_smtp_socket( void )
{
   int retval;

   if ( (retval = gensock_close (SMTPSock)) )
   {
      gensock_error ("gensock_close", retval);
      return -1;
   }

   return (0);
}

int get_smtp_line( void )
{
   char ch = '.';
   char in_data [MAXOUTLINE];
   char * index;
   int retval = 0;

   index = in_data;

   cout << "Before while...\n";
   while (ch != '\n')
   {
      if ( (retval = gensock_getchar (SMTPSock, 0, &ch) ) )
      {
          cout << "In if...\n";
         gensock_error ("gensock_getchar", retval);
         return -1;
      }
      else
      {
         cout << "In else...\n";
         cout << "index:  " << *index << endl ;
         *index = ch;
         index++;
      }
   }


   cout << "returning\n";
   return atoi(in_data);
}

int put_smtp_line( socktag sock, char * line, unsigned int nchars )
{
   int retval;

   if ( (retval = gensock_put_data (sock, line, (unsigned long) nchars)))
   {
      gensock_error ("gensock_put_data", retval);
      return -1;
   }
   return (0);
}

int putline_internal (socktag sock, char * line, unsigned int nchars)
{
   int retval;

   if ((retval =
            gensock_put_data (sock,
                              (char *) line,
                              (unsigned long) nchars)))
   {
      switch (retval)
      {
         case ERR_NOT_CONNECTED:
         gensock_error( "SMTP server has closed the connection", retval );
         break;

         default:
         gensock_error ("gensock_put_data", retval);
      }
      return -1;
   }
   return (0);
}

void smtp_error (char * message)
{
   if ( ! quiet )
      cout << message << "\n";
   put_smtp_line (SMTPSock, "QUIT\r\n", 6);
   close_smtp_socket();
}


// 'destination' is the address the message is to be sent to
// 'message' is a pointer to a null-terminated 'string' containing the
// entire text of the message.

int prepare_smtp_message(char * MailAddress, char * destination)
{
   char out_data[MAXOUTLINE];
   char str[1024];
   char *ptr;
   int len, startLen;

   if ( open_smtp_socket() )
      return -1;

   if ( get_smtp_line() != 220 )
   {
      smtp_error ("SMTP server error");
      return ( -1);
   }

   sprintf( out_data, "HELO %s\r\n", my_hostname);
   put_smtp_line( SMTPSock, out_data, strlen (out_data) );

   if ( get_smtp_line() != 250 )
   {
      smtp_error ("SMTP server error");
      return -1;
   }

   sprintf (out_data, "MAIL From:<%s>\r\n", loginname);
   put_smtp_line( SMTPSock, out_data, strlen (out_data) );

   if (get_smtp_line() != 250)
   {
      smtp_error ("The mail server doesn't like the sender name,\nhave you set your mail address correctly?");
      return -1;
   }

   // do a series of RCPT lines for each name in address line
   for (ptr = destination; *ptr; ptr += len + 1)
   {
      // if there's only one token left, then len will = startLen,
      // and we'll iterate once only
      startLen = strlen (ptr);
      if ((len = strcspn (ptr, " ,\n\t\r")) != startLen)
      {
         ptr[len] = '\0';            // replace delim with NULL char
         while (strchr (" ,\n\t\r", ptr[len + 1]))    // eat white space
            ptr[len++] = '\0';
      }

      sprintf (out_data, "RCPT To: <%s>\r\n", ptr);
      putline_internal( SMTPSock, out_data, strlen (out_data) );

      if (get_smtp_line() != 250)
      {
         sprintf (str, "The mail server doesn't like the name %s.\nHave you set the 'To: ' field correctly?", ptr);
         smtp_error (str);
         return -1;
      }

      if (len == startLen)    // last token, we're done
         break;
   }

   sprintf (out_data, "DATA\r\n");
   put_smtp_line (SMTPSock, out_data, strlen (out_data));

   if (get_smtp_line() != 354)
   {
      smtp_error ("Mail server error accepting message data");
      return -1;
   }

   return (0);

}

int transform_and_send_edit_data( socktag sock, char * editptr )
{
   char *index;
   char *header_end;
   char previous_char = 'x';
   unsigned int send_len;
   int retval;
   BOOL done = FALSE1;

   send_len = strlen(editptr);
   index = editptr;

   header_end = strstr (editptr, "\r\n\r\n");

   while (!done)
   {
      // room for extra char for double dot on end case
      while ((unsigned int) (index - editptr) < send_len)
      {
         switch (*index)
         {
            case '.':
            if (previous_char == '\n')
               /* send _two_ dots... */
               if ((retval = gensock_put_data_buffered (sock, index, 1)))
                  return (retval);
            if ((retval = gensock_put_data_buffered (sock, index, 1)))
               return (retval);
            break;
            case '\r':
            // watch for soft-breaks in the header, and ignore them
            if (index < header_end && (strncmp (index, "\r\r\n", 3) == 0))
               index += 2;
            else
               if (previous_char != '\r')
                  if ((retval = gensock_put_data_buffered (sock, index, 1)))
                     return (retval);
            // soft line-break (see EM_FMTLINES), skip extra CR */
            break;
            default:
            if ((retval = gensock_put_data_buffered (sock, index, 1)))
               return (retval);
         }
         previous_char = *index;
         index++;
      }
      if ( (unsigned int) (index - editptr) == send_len)
         done = TRUE1;
   }

   // this handles the case where the user doesn't end the last
   // line with a <return>

   if (editptr[send_len - 1] != '\n')
   {
      if ((retval = gensock_put_data_buffered (sock, "\r\n.\r\n", 5)))
         return (retval);
   }
   else
      if ((retval = gensock_put_data_buffered (sock, ".\r\n", 3)))
         return (retval);

   /* now make sure it's all sent... */
   if ((retval = gensock_put_data_flush(sock)))
      return (retval);
   return (TRUE);
}



int send_smtp_edit_data (char * message)
{
   transform_and_send_edit_data( SMTPSock, message );

   if (get_smtp_line() != 250)
   {
      smtp_error ("Message not accepted by server");
      return -1;
   }
   return (0);
}


int finish_smtp_message( void )
{
   return put_smtp_line( SMTPSock, "QUIT\r\n", 6 );
}





// MIME Quoted-Printable Content-Transfer-Encoding
#define MimeHexChar "0123456789ABCDEF";
void ConvertToQuotedPrintable(char ThisChar, int * CurrPos, char * buffer)
{
   int ThisValue;
   div_t result;
   // char buffer[8];
   char HexTable[17] = MimeHexChar;

   ThisValue = (256 + (unsigned int) ThisChar) % 256;

   if (ThisValue == 13)
   {
      sprintf( buffer, "%s", "\0" );
      return ;
   }
   else if (ThisValue == 10)
   {
      sprintf( buffer, "%s", "\r\n" );
      (*CurrPos) = 0;
      return ;
   }
   else if ((ThisValue < 33) |
            (ThisValue == 61) |
            (ThisValue > 126))
   {
      result = div(ThisValue, 16);
      buffer[0] = '=';
      (*CurrPos)++;
      buffer[1] = HexTable[result.quot];
      (*CurrPos)++;
      buffer[2] = HexTable[result.rem];
      (*CurrPos)++;
      buffer[3] = '\0';
   }
   else
   {
      buffer[0] = ThisChar;
      (*CurrPos)++;
      buffer[1] = '\0';
   }

   if (*CurrPos > 71)
   {
      strcat(buffer, "=\r\n");     /* Add soft line break */
      (*CurrPos) = 0;
   }
}


int send_mail ( char * in_buffer,
                char * in_recipients,
                char * in_subject,
                char * in_sender,
                char * in_copy_recipients,
                char * in_blind_recipients,
                char * in_server,
                char * in_hostname,
                char * in_loginname,
                char * error
              )    /* Array of environment variable strings    */
{

   int impersonating = 0;
   int penguin = 0;
   int i, j;
   int retcode;
   int hours, minutes;
   int dest_len, cc_len, bcc_len;


   // by default Blat is very noisy!
   quiet = 0;

   // by default Blat does not use mime Quoted-Printable Content-Transfer-Encoding!
   mime = 0;


   Sender[0] = '\0';
   SMTPHost[0] = '\0';


   // thanks to Beverly Brown "beverly@datacube.com" for
   // fixing the argument parsing, I "fixed" the brackets
   // to conform approximately to our "style"  :-)
   // Starts here

   subject = in_subject;

   cc_list = in_copy_recipients;

   bcc_list = in_blind_recipients;

   destination = in_recipients;

   strcpy(SMTPHost, in_server);

   loginname = in_loginname;

   //IR-GSAFX0569 set the senderid to in_sender rather than loginname
   senderid = in_sender;
   //senderid = loginname;

   strcpy(my_hostname, in_hostname);
   if ((SMTPHost[0] == '\0') || (loginname[0] == '\0'))
   {
      if ( ! quiet )
      {
         printf( "to set the SMTP server's address and the user name at that address do:\nblat -install server username\n");
         printf( "or use '-server <server name>' and '-f <user name>'\n");
         printf( "aborting, nothing sent\n" );
      }
      return 12;
   }

   if (destination)
      dest_len = strlen(destination);
   else
      dest_len = 0;

   if (cc_list)
      cc_len = strlen(cc_list);
   else
      cc_len = 0;

   if (bcc_list)
      bcc_len = strlen(bcc_list);
   else
      bcc_len = 0;

   char *temp = new char [ dest_len + \
                           cc_len + bcc_len + 4 ];
   // build the recipients list
   Recipients = new char [ dest_len + \
                           cc_len + bcc_len + 4 ];

   // Parse the "To:" line
   for (i = j = 0; i < (int) strlen(destination); i++)
   {
      // strip white space
      while (destination[i] == ' ')
         i++;
      // look for comments in brackets, and omit
      if (destination[i] == '(')
      {
         while (destination[i] != ')')
            i++;
         i++;
      }
      // look for comments in quotes, and omit
      if (destination[i] == '\'')
      {
         i++;
         while (destination[i] != '\'')
            i++;
         i++;
      }

      temp[j++] = destination[i];
   }
   temp[j] = '\0';               // End of list added!
   strcpy( Recipients, temp);

   // Parse the "Cc:" line
   for (i = j = 0; i < cc_len; i++)
   {
      // strip white space
      while (cc_list[i] == ' ')
         i++;
      // look for comments in brackets, and omit
      if (cc_list[i] == '(')
      {
         while (cc_list[i] != ')')
            i++;
         i++;
      }
      // look for comments in quotes, and omit
      if (cc_list[i] == '\'')
      {
         i++;
         while (cc_list[i] != '\'')
            i++;
         i++;
      }
      temp[j++] = cc_list[i];
   }
   temp[j] = '\0';               // End of list added!
   if ( cc_len > 0 )
   {
      strcat(Recipients, "," );
      strcat(Recipients, temp);
   }

   // Parse the "Bcc:" line
   for (i = j = 0; i < bcc_len; i++)
   {
      // strip white space
      while (bcc_list[i] == ' ')
         i++;
      // look for comments in brackets, and omit
      if (bcc_list[i] == '(')
      {
         while (bcc_list[i] != ')')
            i++;
         i++;
      }
      // look for comments in quotes, and omit
      if (bcc_list[i] == '\'')
      {
         i++;
         while (bcc_list[i] != '\'')
            i++;
         i++;
      }
      temp[j++] = bcc_list[i];
   }
   temp[j] = '\0';               // End of list added!
   if ( bcc_len > 0 )
   {
      strcat(Recipients, "," );
      strcat(Recipients, temp);
   }


   // create a header for the message
   char tmpstr[256];
   char header[2048];
   int headerlen;

   sprintf( tmpstr, "From: %s\r\n", senderid );
   strcat( header, tmpstr );
   if ( impersonating )
   {
      sprintf( tmpstr, "Sender: %s\r\n", loginname );
      strcat( header, tmpstr );
      if (!(penguin == 1))
      {
         sprintf( tmpstr, "Reply-to: %s\r\n", loginname );
         strcat( header, tmpstr );
      }
   }
   if ( subject )
   {
      sprintf( tmpstr, "Subject: %s\r\n", subject );
      strcat( header, tmpstr );
   }

   sprintf( tmpstr, "To: %s\r\n", destination );
   strcat( header, tmpstr );
   if ( cc_list )
   {
      // Add line for the Carbon Copies
      sprintf( tmpstr, "Cc: %s\r\n", cc_list );
      strcat( header, tmpstr );
   }


   strcat( header, "X-Mailer: <WinNT's Blat ver 1.5>\r\n" );

   strcat (header, "\r\n");

   headerlen = strlen (header);

   long filesize = strlen(in_buffer);

   char *buffer = new char[(3 * (filesize + filesize / 72)) + headerlen + 1];
   char *tmpptr;

   // put the header at the top...
   strcpy ( buffer, header);
   // point to the end of header
   tmpptr = buffer + headerlen;

   strcpy (tmpptr, in_buffer);

   // make some noise about what we are doing
   if ( ! quiet )
   {
      if (subject)
         cout << "Subject:" << subject << '\n';
      if (loginname)
         cout << "Login name is " << loginname << '\n';
   }

   // send the message to the SMTP server!
   retcode = prepare_smtp_message( loginname, Recipients );
   if ( !retcode )
   {

      retcode = send_smtp_edit_data( buffer );
      if ( !retcode )
         finish_smtp_message();
      close_smtp_socket();
   }


   delete [] temp;
   delete [] buffer;
   delete [] Recipients;


   return (retcode);
}
#endif

Code:
//gensocks_un.cpp

#ifdef OC_UNIX 
// -*- C++ -*-
// generic socket DLL, winsock version
// disclaimer:  a C programmer wrote this.

// $Id: gensocks_un.cpp,v 1.12 2002/10/17 11:21:36Z aahamm Exp $

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>


extern "C"
{
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <fcntl.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stropts.h>
#ifndef OC_LINUX_GCC
#ifndef OC_HPUX
#include <sys/conf.h>
#endif
#endif
#include <sys/time.h>
#include "gensocks.h"
}

#define SOCKET_BUFFER_SIZE    512
#ifdef OC_AIX_VACPP
#undef INADDR_NONE
#endif
#define INADDR_NONE        0
#define INVALID_SOCKET        -1
#define SOCKET_ERROR        -1
#define  _XOPEN_SOURCE_EXTENDED 1

//
// ---------------------------------------------------------------------------
// container for a buffered SOCK_STREAM.

class connection
{
private:
   int    the_socket;
   char *in_buffer;
   char *out_buffer;
   unsigned int    in_index;
   unsigned int    out_index;
   unsigned int    in_buffer_total;
   unsigned int    out_buffer_total;
   unsigned int    last_winsock_error;
   fd_set    fds;
   struct timeval    timeout;

public:

   connection (void);
   ~connection (void);

   int get_connected (char * hostname, char * service);
   int get_socket(void)
   {
      return (the_socket);
   }
   int    get_buffer(int wait);
   int    close_conn (void);
   int    cc_getchar (int wait, char * ch);
   int    put_data (char * data, unsigned long length);
   int    put_data_buffered (char * data, unsigned long length);
   int    put_data_flush (void);
};

connection::connection (void)
{
   the_socket = 0;
   in_index = 0;
   out_index = 0;
   in_buffer_total = 0;
   out_buffer_total = 0;
   in_buffer = 0;

   in_buffer = new char[SOCKET_BUFFER_SIZE];
   out_buffer = new char[SOCKET_BUFFER_SIZE];

   last_winsock_error = 0;
}

connection::~connection (void)
{
   delete [] in_buffer;
   delete [] out_buffer;
}

int
gensock_is_a_number (char * string)
{
   while (*string)
   {
      if (!isdigit (*string))
      {
         return (0);
      }
      string++;
   }
   return (1);
}

//
// ---------------------------------------------------------------------------
//

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int
connection::get_connected (char * hostname, char * service)
{

    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    struct servent *s;

    if(service == NULL)
        return(ERR_CANT_RESOLVE_SERVICE);

    // We read it in as local order
    if(sscanf(service, "%d", &portno) == 1);
    else if(s = getservbyname(service, "tcp"))
        portno=htons(s->s_port); // Convert from network to LOCAL order
    else
        return(ERR_CANT_RESOLVE_SERVICE);

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd < 0) 
        error("ERROR opening socket");

    server = gethostbyname(hostname);

    if (server == NULL) 
    {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    
    // fill the area of memory taken by serv_addr structure with zeros
    bzero((char *) &serv_addr, sizeof(serv_addr));
    
    // set the sin_family member of serv_addr to AF_INET (IP Address Family)
    serv_addr.sin_family = AF_INET;
    
    // copy the address returned by gethostbyname() into the s_addr member of serv_addr
    // s_addr contains the integer representation of the IP address
    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
    
    // set the sin_port member of serv_addr to the port number
    // htons converts a u_short from host to IP network byte order (which is big-endian).    
    serv_addr.sin_port = htons(portno);

    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");

#ifdef HA
    // Make this a non-blocking socket
    fcntl (sockfd, F_SETFL, O_NDELAY);
    // make the FD_SET and timeout structures for later operations...
#endif

    the_socket = sockfd;

    FD_ZERO (&fds);
    FD_SET (sockfd, &fds);

    // normal timeout, can be changed by the wait option.
    timeout.tv_sec = 0;
    timeout.tv_usec = 0;

    return 0;

    /*
   struct hostent *    hostentry; // from gethostbyname 
   struct servent *    serventry; // from getservbyname
   unsigned long ip_address;
   struct sockaddr_in    sa_in;
   int    our_port;
   struct linger NoLinger;
   int    retval, err_code;
   unsigned long    ioctl_blocking = 1;
   char    message[512];

   // if the ctor couldn't get a buffer
   if (!in_buffer || !out_buffer)
      return (ERR_CANT_MALLOC);

   // --------------------------------------------------
   // resolve the service name
   //

   // If they've specified a number, just use it.
   if (gensock_is_a_number (service))
   {
      char * tail;
      our_port = (int) strtol (service, &tail, 10);
      if (tail == service)
      {
         return (ERR_CANT_RESOLVE_SERVICE);
      }
      else
      {
         our_port = htons (our_port);
      }
   }
   else
   {
      // we have a name, we must resolve it.
      serventry = getservbyname (service, "tcp");

      if (serventry)
         our_port = serventry->s_port;
      else
         return (ERR_CANT_RESOLVE_SERVICE);
   }

   // --------------------------------------------------
   // resolve the hostname/ipaddress
   //
   // Assume only hostname
   //  if ((ip_address = inet_addr (hostname)) != INADDR_NONE) {
   //    sa_in.sin_addr.s_addr = ip_address;
   // }
   //  else {
   if ((hostentry = gethostbyname(hostname)) == NULL)
   {
      return (ERR_CANT_RESOLVE_HOSTNAME);
   }
   sa_in.sin_addr.s_addr = *(long *)hostentry->h_addr;
   // }


   // --------------------------------------------------
   // get a socket
   //

   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
   {
      return (ERR_CANT_GET_SOCKET);
   }

   sa_in.sin_family = AF_INET;
   sa_in.sin_port = our_port;

   // set socket options.  DONTLINGER will give us a more graceful disconnect

   NoLinger.l_onoff = 0;
   setsockopt(sockfd,
              SOL_SOCKET,
              SO_LINGER,
              (char *) &NoLinger, sizeof(NoLinger));

   // get a connection

   memset(&sa_in, 0, sizeof(sa_in));
   memcpy(&sa_in.sin_addr.s_addr, hostentry->h_addr, hostentry->h_length);
   sa_in.sin_port=htons(our_port);
   retval = connect (sockfd, (struct sockaddr *) & sa_in,
                     sizeof(sa_in));

   if (retval == SOCKET_ERROR)
   {
      return (ERR_CANT_CONNECT);
   }

#ifdef HA
   // Make this a non-blocking socket
   fcntl (sockfd, F_SETFL, O_NDELAY);
   // make the FD_SET and timeout structures for later operations...
#endif

   FD_ZERO (&fds);
   FD_SET (the_socket, &fds);

   // normal timeout, can be changed by the wait option.
   timeout.tv_sec = 0;
   timeout.tv_usec = 0;

   return (0);
   
   */
}


//
//---------------------------------------------------------------------------
//
// The 'wait' parameter, if set, says to return WAIT_A_BIT
// if there's no data waiting to be read.

int
connection::get_buffer(int wait)
{
   int retval;
   int bytes_read = 0;
   unsigned long ready_to_read = 0;

   // Use select to see if data is waiting...

   FD_ZERO (&fds);
   FD_SET (the_socket, &fds);

   // if wait is set, we are polling, return immediately
   if (wait)
   {
      timeout.tv_sec = 0;
   }
   else
   {
      timeout.tv_sec = 0;
   }
#ifdef HA
   if ((retval = select (0, &fds, NULL, NULL, &timeout))
         == SOCKET_ERROR)
   {
      //printf ( "connection::get_buffer() unexpected error from select\n");
   }

   // if we don't want to wait


   if (!retval && wait)
   {
      return (WAIT_A_BIT);
   }
#endif
   // we have data waiting...
   bytes_read = recv (the_socket,
                      in_buffer,
                      SOCKET_BUFFER_SIZE,
                      0);

   // just in case.

   if (bytes_read == 0)
   {
      // connection terminated (semi-) gracefully by the other side
      return (ERR_NOT_CONNECTED);
   }

   if (bytes_read == SOCKET_ERROR)
   {
      //printf ("connection::get_buffer() unexpected error\n");

   }

   // reset buffer indices.


   in_buffer_total = bytes_read;
   in_index = 0;
   return (0);

}

//
//---------------------------------------------------------------------------
// get a character from this connection.
//

int
connection::cc_getchar(int wait, char * ch)
{
   int retval;

   if (in_index >= in_buffer_total)
   {
      if ((retval = get_buffer(wait)))
         return (retval);
   }
   *ch = in_buffer[in_index++];
   return (0);
}


//
//---------------------------------------------------------------------------
// FIXME: should try to handle the fact that send can only take
// an int, not an unsigned long.

int
connection::put_data (char * data, unsigned long length)
{
   int num_sent;
   int retval;

   FD_ZERO (&fds);
   FD_SET (the_socket, &fds);

   timeout.tv_sec = 0;
   while (length > 0)
   {
#ifdef HA
      if ((retval = select (0, NULL, &fds, NULL, &timeout)) == SOCKET_ERROR)
      {
         //printf ("connection::put_data() unexpected error from select \n");
      }
#endif

      num_sent = send (the_socket,
                       data,
                       length > 1024 ? 1024 : (int)length,
                       0);

      if (num_sent == SOCKET_ERROR)
      {
         //printf ( "connection::put_data() unexpected error from send()\n");
         return (ERR_SENDING_DATA);

      }
      else
      {
         length -= num_sent;
         data += num_sent;
      }
   }

   return (0);
}

//
//
// buffered output
//

int
connection::put_data_buffered (char * data, unsigned long length)
{
   unsigned int sorta_sent = 0;
   int retval;

   while (length)
   {
      if ((out_index + length) < SOCKET_BUFFER_SIZE)
      {
         // we won't overflow, simply copy into the buffer
         memcpy (out_buffer + out_index, data, (size_t) length);
         out_index += (unsigned int) length;
         length = 0;
      }
      else
      {
         unsigned int orphaned_chunk = SOCKET_BUFFER_SIZE - out_index;
         // we will overflow, handle it
         memcpy (out_buffer + out_index, data, orphaned_chunk);
         // send this buffer...
         if ((retval = put_data (out_buffer, SOCKET_BUFFER_SIZE)))
         {
            return (retval);
         }
         length -= orphaned_chunk;
         out_index = 0;
         data += orphaned_chunk;
      }
   }

   return (0);
}

int
connection::put_data_flush (void)
{
   int retval;

   if ((retval = put_data (out_buffer, out_index)))
      return (retval);
   else
      out_index = 0;

   return (0);
}

//
//---------------------------------------------------------------------------
//

int connection::close_conn (void)
{
   if ( close(the_socket) == SOCKET_ERROR)
      return (ERR_CLOSING);
   else
      return (0);
}



// ---------------------------------------------------------------------------
// C/DLL interface
//
int gensock_connect (char * hostname,
                     char * service,
                     socktag * pst)
{

   int retval;

   connection * conn = new connection;

   if ((retval = conn->get_connected (hostname, service)))
   {
      gensock_close(0);
      *pst = 0;
      return (0);
   }
   fprintf(stderr, "sizeof(void *)=%d, sizeof(int)=%d\n", sizeof(void *), sizeof(int));
   *pst = conn;

   return (retval);
}

//
//
//

int gensock_getchar (int st, int wait, char * ch)
{
   int retval = 0;
   connection *conn;

   conn = (connection *)st;

   if ((retval = conn->cc_getchar(wait, ch)))
      return (retval);
   else
      return (0);
}


//---------------------------------------------------------------------------
//
//

int gensock_put_data (int st, char * data, unsigned long length)
{
   connection *conn;
   int retval = 0;

   conn = (connection *)st;
   if ((retval = conn->put_data(data, length)))
      return (retval);

   return (0);
}

//---------------------------------------------------------------------------
//
//

int gensock_put_data_buffered (int st, char * data, unsigned long length)
{

   int retval;
   connection *conn;

   conn = (connection *) st;
   if ((retval = conn->put_data_buffered (data, length)))
      return (retval);

   return (0);
}

//---------------------------------------------------------------------------
//
//

int gensock_put_data_flush (int st)
{

   int retval = 0;
   connection *conn;

   conn = (connection *) st;

   if ((retval = conn->put_data_flush() ))
      return (retval);

   return (0);
}

//---------------------------------------------------------------------------
//
//
int gensock_gethostname (char * name, int namelen)
{
   int retval;
   //  if ((retval = gethostname(name, namelen))) {
   //   return (retval - 5000);
   //  }
   // else return (0);
   return (0);
}

//---------------------------------------------------------------------------
//
//

int gensock_close (int st)
{

   int retval;
   connection *conn;

   conn = (connection *) st;
   if ((retval = conn->close_conn()))
      return (retval);

   return (0);
}

#endif


Also, my print statments aren't working. Nothing is output to the dbx cmd window.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. AIX

Unable to set ACLs on sulog - need to grant read permission to a normal user on AIX 6.1

Hi, I need to grant read permission to a normal user on sulog file on AIX 6.1. As root I did acledit sulog and aclget shows "extended permissions" as "enabled" and normal user "splunk" has read permissions. When I try to access sulog as splunk user it won't allow and aclget for splunk user... (6 Replies)
Discussion started by: prvnrk
6 Replies

2. Shell Programming and Scripting

AIX : Need to convert UNIX Timestamp to normal timestamp

Hello , I am working on AIX. I have to convert Unix timestamp to normal timestamp. Below is the file. The Unix timestamp will always be preceded by EFFECTIVE_TIME as first field as shown and there could be multiple EFFECTIVE_TIME in the file : 3.txt Contents of... (6 Replies)
Discussion started by: rahul2662
6 Replies

3. Shell Programming and Scripting

Send mail from AIX 7.1

Hi, My OS version is AIX 7.1. I am trying to send an email with a file to my mail address. sendmail or uuencode does not work. Can someone give me the correct format ? I use: uuencode <file name> | mail -s "subject" emailaddress Thanks Use code tags, thanks. (3 Replies)
Discussion started by: Nagesh_1985
3 Replies

4. Shell Programming and Scripting

AIX mail notification

plzzz help me, I want to send emails for exchange group members when the used file-system % gets more than 90%, this notification must include df -g, netstat -i,and errpt with the hostname thx in advance (0 Replies)
Discussion started by: majd_ece
0 Replies

5. Shell Programming and Scripting

Calling SQL script from ksh job and send mail on some error.

Hi, I am trying to call sql script from ksh job with parameters.The parameters passed from ksh job will be used in SELECT query in sql file to SPOOL the data in extract file.My questions are: 1) How to call a sql script from ksh job with parameters? 2) How to use the parameter in sql file to... (1 Reply)
Discussion started by: anil029
1 Replies

6. UNIX for Advanced & Expert Users

Oracle (11gr2) calling unix commands (aix)

I have an Oracle database running on AIX, and I have a procedure that is calling OS commands from an oracle (and it's not working anymore)... so, there was an Java stored proc in Oracle CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED COMMON."Host" as import java.io.*; public class Host {... (1 Reply)
Discussion started by: bongo
1 Replies

7. UNIX for Dummies Questions & Answers

Forwarding Mail in AIX 5.3

Hello everyone, I am trying to create a forwarding scenario, and I do not seem to get it right! I created a .forward file in the directory where my personal mailbox resides. In the file is the full address to deliver email to ... yet the emails do not seem to get forwarded. Is there something... (3 Replies)
Discussion started by: gio001
3 Replies

8. AIX

Normal User Unable to Login Through AIX CDE

When we as normal user try to login, the session startup terminates and we are presented with the login screen.The root user is able to login without any problem.I can log in to the Aix server as normal user through telnet & using xmanager but not directly through server terminal .The Aix version... (1 Reply)
Discussion started by: ranadeep
1 Replies

9. AIX

To find RAM Size in AIX as normal user?

Hi, Am jus trying to find the Total RAM Size of a AIX m/c (in MB)..svmon works perfectly for a superuser...But i want to achive this as a normal user...Please help me out with correct command.. Best Regards, Muthukumaran.M (3 Replies)
Discussion started by: muthukumaran13
3 Replies

10. AIX

Calling All Aix Experts

I am new to the world of AIX. I want to get certified in AIX and learn it but fast. with in 3 months Could you give me some advise of a good site that with teach you or a bootcamp that is reasonable. I am really in need I am in atlanta (0 Replies)
Discussion started by: Courtney3216
0 Replies
Login or Register to Ask a Question