Commits

Palmer, 2E0EOL committed a0067a4

Initial commit of 0.4.0 version

Comments (0)

Files changed (2)

+#
+# Makefile for killmail
+# A utility for quickly clearing out a mailbox through Post Office
+# Protocol 3.
+# Written by David Duncan Ross Palmer, Daybo Logic, all rights reserved.
+# http://www.daybologic.co.uk/
+#
+
+          WARNINGS=-Wall \
+                   -W \
+                   -Wbad-function-cast \
+                   -Wcast-qual \
+                   -Wcast-align \
+                   -Waggregate-return \
+                   -Wnested-externs \
+                   -Wpointer-arith \
+                   -Wundef \
+                   -Wshadow \
+                   -Wmissing-prototypes \
+                   -Wmissing-declarations \
+                   -Winline \
+                   -Wstrict-prototypes \
+                   -Wredundant-decls \
+                   -Wwrite-strings \
+                   -Wformat=2 \
+                   -Wformat-security \
+                   -Wformat-nonliteral
+
+ANSI=-ansi -pedantic-errors
+
+DEFINES=-D__UNIX__
+
+killmail : killmail.c
+	$(CC) $(DEFINES) $(ANSI) $(WARNINGS) -g -o killmail killmail.c
+
+clean:
+	-rm killmail
+/*
+  KillMail
+  Copyright 2004-2007 Daybo Logic, all rights reserved.
+  Written by David Duncan Ross Palmer at Daybo Logic.
+  http://www.daybologic.co.uk/
+
+  This tool is part of a collection of tools created by D.D.R. Palmer
+  to aid his work in troubleshooting. A client of mine from near Redruth
+  in Cornwall phoned me with an interesting problem. He wanted to delete
+  all of his email from a POP3 server without downloading it.
+  Fortunately, it had webmail, so deleting the whole lot at once was
+  quite possible.  I thought though that should this arise again, I
+  could be stuck.  This program allows one to log into an account and
+  delete all of the mail in one foul swoop.  It has since been extended
+  to optionally not delete the mail, but save mail to disk and have
+  support a criteron from the header, such as the sender address to
+  operate on and ignore other mail.
+
+  Incase of problems, I can be reached via this site:
+  http://www.daybologic.co.uk/mailddrp/
+*/
+
+#define VER_MAJOR (0)
+#define VER_MINOR (4)
+#define VER_PATCH (0)
+#define VER_DATE ("20070902")
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <limits.h>
+
+#ifdef __UNIX__
+# include <sys/time.h>
+# include <sys/socket.h>
+# include <sys/select.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+# include <unistd.h>
+# include <errno.h>
+
+# define SOCKET            int   /* Just use int where you can get away with it, it was always tradition and M$ must comply, SOCKET is used to avoid warnings in certain places only */
+# define SOCKETS_INIT()    true  /* Virtually return success for a non-existant function */
+# define SOCKETS_UNINIT()
+# define CLOSESOCKET(s)    close((s))
+# define ERRNO             errno
+# define SETERRNO(e)       errno = (e)
+# define RESETERRNO        errno = (0)
+# define INVALID_SOCKET    (-1)
+# define SOCKET_ERROR      (-1)
+# define SOCKET            int
+# define closesocket(s)    close((s))
+# define putch(c)          putchar((c))
+# define getch()           getchar()
+
+#elif defined(__WIN32__)
+
+# define STRICT
+# include <windows.h>
+# include <winsock.h>
+# include <conio.h> /* This doesn't exist on M$, look for DDRP's replacement lib */
+# ifdef __WATCOMC__
+#  include <i86.h> /* This is a Watcom-specific header */
+# endif /*__WATCOMC__*/
+
+# define SOCKETS_INIT()    MyWSAStartup()
+# define SOCKETS_UNINIT()  WSACleanup()
+# define CLOSESOCKET(s)    closesocket((s))
+# define ERRNO             WSAGetLastError()
+# define SETERRNO(e)       WSASetLastError((e))
+# define RESETERRNO        WSASetLastError(0)
+
+# define SYSNOTREADY WSASYSNOTREADY
+# define VERNOTSUPPORTED WSAVERNOTSUPPORTED
+# define EINPROGRESS WSAEINPROGRESS
+# define EPROCLIM WSAEPROCLIM
+# define EFAULT WSAEFAULT
+# define NOTINITIALISED WSANOTINITIALISED
+# define ENETDOWN WSAENETDOWN
+# define EACCES WSAEACCES
+# define EINTR WSAEINTR
+# define ENETRESET WSAENETRESET
+# define ENOBUFS WSAENOBUFS
+# define ENOTCONN WSAENOTCONN
+# define ENOTSOCK WSAENOTSOCK
+# define ESHUTDOWN WSAESHUTDOWN
+# define EWOULDBLOCK WSAEWOULDBLOCK
+# define EMSGSIZE WSAEMSGSIZE
+# define EINVAL WSAEINVAL
+# define ECONNABORTED WSAECONNABORTED
+# define ECONNRESET WSAECONNRESET
+# define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+# define EAFNOSUPPORT WSAEAFNOSUPPORT
+# define EDESTADDRREQ WSAEDESTADDRREQ
+# define ENETUNREACH WSAENETUNREACH
+# define ETIMEDOUT WSAETIMEDOUT
+# define ECONNREFUSED WSAECONNREFUSED
+#else
+# error ("Unknown system, use __UNIX__ or __WIN32__, for Berkely-sockets, use __UNIX__")
+#endif /*__UNIX__*/
+
+#ifdef HDRSTOP
+# pragma hdrstop
+#endif /*HDRSTOP*/
+
+/*
+  bool as stdbool.h in C99
+*/
+typedef enum {
+  false=0,
+  true=1
+} bool;
+
+#define false false
+#define true true
+
+#define POP3_PORT (110)
+
+char Pop3Host[256] = "mail.daybologic.co.uk";
+char UserName[256] = { "blah@daybologic.co.uk" };
+char Password[256] = { "blah" };
+
+/* Prototypes */
+static int mymain(const int ArgC, const char* ArgV[]);
+static void Title(void);
+static bool ProcessArguments(const int ArgC, const char* ArgV[]);
+static bool AskString(char *Buffer);
+static char* Chomp(char* Str);
+static void BeepSound(void);
+static void PrintLastSocketsError(const char *const FunctionName);
+#ifdef __WIN32__
+  static bool WinsockErrorLookup(const int ErrNum, const char** ErrMnemonic, const char** ErrMessage);
+  static bool MyWSAStartup(void);
+#endif /*__WIN32__*/
+static void PrintIP(const struct hostent *HostEntry, const int Index); /* Use -1 to print all IPs */
+static SOCKET ConnectToServer(const struct hostent *HostEntry);
+static bool KillMails(SOCKET Socket);
+static int ReceiveResponse(SOCKET S, char* Buffer, unsigned int BufferSz);
+static void DisconnectServer(SOCKET Socket); /* Sends QUIT and disconnects */
+/*-------------------------------------------------------------------------*/
+int main(const int argc, const char* argv[])
+{
+  int ret;
+
+  if ( SOCKETS_INIT() ) {
+    ret = mymain(argc, argv);
+    SOCKETS_UNINIT();
+  }
+  else
+    PrintLastSocketsError("Sockets library initialisation");
+
+  if ( ret == EXIT_SUCCESS )
+    printf("*** HIT A KEY TO EXIT ***\n");
+  else
+    printf("*** PROGRAM FAILED, HIT A KEY TO TERMINATE ***\n");
+  getch();
+
+  memset(Password, 0, sizeof(Password)); /* Security cleanup */
+  return ret;
+}
+/*-------------------------------------------------------------------------*/
+static int mymain(const int argc, const char* argv[])
+{
+  struct hostent *thread_hostEntry; /* Warning: Only one of these exists */
+  Title();
+  if ( !ProcessArguments(argc, argv) )
+    return EXIT_FAILURE;
+
+  if ( !AskString(Pop3Host) ) {
+    puts("Must supply a POP3 host, this is typically \'mail\', \'pop3\' or \'mail.daybologic.co.uk\'");
+    return EXIT_FAILURE;
+  }
+  if ( !AskString(UserName) ) {
+    puts("Must supply a valid username, this is typically an email address.\n");
+    return EXIT_FAILURE;
+  }
+  if ( !AskString(Password) )
+    puts("WARNING! Password-less account attempt.");
+
+  printf("OK, let's go.\n"
+         "Attempting to connect to %s@%s...\n"
+         "Resolving %s... [",
+         UserName,
+         Pop3Host,
+         Pop3Host
+  );
+  fflush(stdout);
+
+  thread_hostEntry = gethostbyname(Pop3Host);
+  if ( thread_hostEntry ) {
+    struct hostent hostEntry;
+    SOCKET s;
+
+    memcpy(&hostEntry, thread_hostEntry, sizeof(hostEntry)); /* Make private copy */
+    PrintIP(&hostEntry, -1);
+    printf("]\n"); /* Finish off the square-bracket */
+    s = ConnectToServer(&hostEntry);
+    if ( s != INVALID_SOCKET ) {
+      bool ok = KillMails(s);
+      DisconnectServer(s);
+      if ( !ok ) return EXIT_FAILURE;
+    }
+    else {
+      printf("Cannot connect to POP3 server\n");
+      return EXIT_FAILURE;
+    }
+  }
+  else { /* gothostbyname() failed */
+    PrintLastSocketsError("gethostbyname()");
+    return EXIT_FAILURE;
+  }
+
+  return EXIT_SUCCESS;
+}
+/*-------------------------------------------------------------------------*/
+static void Title()
+{
+  printf("KillMail - Delete all mail in a POP3-accessable inbox\n"
+         "Version %u.%u.%u (%s) (C) Daybo Logic, 2004.\n"
+         "All rights reserved. Visit www.daybologic.co.uk\n"
+         "Built %s - %s\n\n",
+         VER_MAJOR,
+         VER_MINOR,
+         VER_PATCH,
+         VER_DATE,
+         __DATE__,
+         __TIME__
+  );
+}
+/*-------------------------------------------------------------------------*/
+static bool ProcessArguments(const int ArgC, const char* ArgV[])
+{
+  if ( ArgC > 1 ) {
+    fputs("ERROR: Arguments are not yet supported\n", stderr);
+    return false;
+  }
+  return true;
+}
+/*-------------------------------------------------------------------------*/
+static bool AskString(char *Buffer)
+{
+  if ( Buffer == Pop3Host ) {
+    char tmpbuf[sizeof(Pop3Host)/sizeof(Pop3Host[0])];
+    printf("Please enter hostname of POP3 server [%s]: ", Pop3Host);
+    if ( fgets(tmpbuf, sizeof(Pop3Host)/sizeof(Pop3Host[0]), stdin) ) {
+      if ( tmpbuf[0] != '\n' )
+        strcpy(Buffer, tmpbuf);
+    }
+  }
+  else if ( Buffer == UserName ) {
+    char tmpbuf[sizeof(UserName)/sizeof(UserName[0])];
+    printf("Please enter your username as expected by the mail server [%s]: ", UserName);
+    if ( fgets(tmpbuf, sizeof(UserName)/sizeof(UserName[0]), stdin) ) {
+      if ( tmpbuf[0] != '\n' )
+        strcpy(Buffer, tmpbuf);
+    }
+  }
+  else if ( Buffer == Password ) {
+    unsigned int i;
+    printf("Please enter your password: ");
+    fflush(stdout);
+    for ( i = 0U; i < (sizeof(Password)/sizeof(Password[0]))-1; i++ ) {
+      int passchar;
+      do {
+        passchar = getch();
+        if ( passchar == EOF ) break;
+        if ( !passchar ) {
+          passchar = getch();
+          if ( passchar ) {
+            BeepSound();
+            passchar = 0;
+          }
+        }
+      } while ( !passchar );
+      if ( passchar != '\r' && passchar != '\n' ) {
+        putch('*');
+        Password[i] = (char)passchar;
+        Password[i+1] = '\0';
+      }
+      else
+        break;
+    }
+    putchar('\n');
+    fflush(stdout);
+  }
+  else
+    assert(0);
+
+  Chomp(Buffer);
+  if ( Buffer[0] ) return true;
+  return false;
+}
+/*-------------------------------------------------------------------------*/
+static char* Chomp(char* Str)
+{
+  if ( Str ) {
+    int len = strlen(Str);
+    if ( len ) {
+      if ( Str[len-1] == '\n' )
+        Str[len-1] = '\0';
+    }
+  }
+  return Str;
+}
+/*-------------------------------------------------------------------------*/
+static void BeepSound()
+{
+  #ifdef __WIN32__
+    Beep(1000, 250); /* Win32 API call */
+  #endif /*__UNIX__*/
+}
+/*-------------------------------------------------------------------------*/
+static void PrintLastSocketsError(const char *const FunctionName)
+{
+  const char *func = (FunctionName) ? (FunctionName) : ("Sockets error");
+  #ifdef __UNIX__
+    perror(func);
+  #else
+    const char *errorMsg, *errorMnemonic;
+    int err = ERRNO;
+    if ( WinsockErrorLookup(err, &errorMnemonic, &errorMsg) )
+      fprintf(stderr, "%s: %s (%s)\n", func, errorMsg, errorMnemonic);
+    else
+      fprintf(stderr, "%s: Unknown error number %u\n", func, err);
+  #endif /*__UNIX__*/
+}
+/*-------------------------------------------------------------------------*/
+#ifdef __WIN32__
+static bool WinsockErrorLookup(const int ErrNum, const char** ErrMnemonic, const char** ErrMessage)
+{
+  unsigned int i;
+  static const struct {
+    const int Number;
+    const char *const Mnemonic;
+    const char *const Message;
+  } errorTable[] = {
+    { WSANOTINITIALISED, "WSANOTINITIALISED", "Winsock not initialised." },
+    { WSAEDISCON, "WSAEDISCON", "Graceful connection shutdown in progress" },
+    { WSAHOST_NOT_FOUND, "WSAHOST_NOT_FOUND", "Hot not found" },
+    { WSAEFAULT, "WSAEFAULT", "Bad user-pointer" },
+    { WSAEINTR, "WSAEINTR", "Interrupted function call" },
+    { WSAEACCES, "WSAEACCES", "Permission denied" },
+    { WSAEINVAL, "WSAEINVAL", "Invalid argument" },
+    { WSAETIMEDOUT, "WSAETIMEDOUT", "Connection timed out" },
+    { WSAEISCONN, "WSAEISCONN", "Socket is already connected" },
+    { WSAENOBUFS, "WSAENOBUFS", "No buffer space is available" },
+    { WSAESHUTDOWN, "WSAESHUTDOWN", "Cannot send after socket shutdown" },
+    { WSAENOTCONN, "WSAENOTCONN", "Socket is not connected" },
+    { WSAECONNRESET, "WSAECONNRESET", "Connection reset by peer" },
+    { WSAENETRESET, "WSAENETRESET", "Network dropped connection on reset" },
+    { WSAECONNABORTED, "WSAECONNABORTED", "Software caused connection abort" },
+    { WSAENETUNREACH, "WSAENETUNREACH", "Network is unreachable" },
+    { WSAENETDOWN, "WSAENETDOWN", "Network is down" },
+    { WSAEADDRNOTAVAIL, "WSAEADDRNOTAVAIL", "Cannot assign requested address" },
+    { WSAEADDRINUSE, "WSAEADDRINUSE", "Address already in use" },
+    { WSAECONNREFUSED, "WSAECONNREFUSED", "Connection refused" },
+    { WSAEHOSTDOWN, "WSAEHOSTDOWN", "Host is down" },
+    { WSAEHOSTUNREACH, "WSAEHOSTUNREACH", "No route to host" },
+    { WSAEPROCLIM, "Too many processes, limit reached" },
+    { WSASYSNOTREADY, "WSASYSNOTREADY", "Network subsystem is unavailable" },
+    { WSAVERNOTSUPPORTED, "WSAVERNOTSUPPORTED", "winsock.dll is older than required for this application" },
+    { WSANO_DATA, "WSANO_DATA", "The mail server has no A record, try using the domain name rather than a hostname, if this continues to fail, contact DDRP for an update or find the IP manually with \'dig\'" }
+  };
+
+  /* Check for duplicates (source quality-control check) */
+  for ( i = 0U; i < sizeof(errorTable)/sizeof(errorTable[0]); i++ ) {
+    unsigned int j;
+    for ( j = 0U; j < sizeof(errorTable)/sizeof(errorTable[0]); j++ ) {
+      if ( i != j )
+        assert(errorTable[i].Number != errorTable[j].Number);
+    }
+  }
+
+  /* Look for the error number and return the data */
+  for ( i = 0U; i < sizeof(errorTable)/sizeof(errorTable[0]); i++ ) {
+    if ( ErrNum == errorTable[i].Number ) {
+      if ( ErrMnemonic ) *ErrMnemonic = errorTable[i].Mnemonic;
+      if ( ErrMessage ) *ErrMessage = errorTable[i].Message;
+      return true;
+    }
+  }
+  return false;
+}
+#endif /*__WIN32__*/
+/*-------------------------------------------------------------------------*/
+#ifdef __WIN32__
+static bool MyWSAStartup()
+{
+  /*
+    This crap is a copy/paste from the MSDN example at:
+    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/htm/_wcesdk_win32_wsastartup_2.asp
+  */
+  WORD wVersionRequested;
+  WSADATA wsaData;
+  int err;
+
+  wVersionRequested = MAKEWORD( (1), (1) );
+
+  err = WSAStartup( wVersionRequested, &wsaData );
+  if ( err != 0 ) {
+    /* Tell the user that we could not find a usable */
+    /* WinSock DLL.   */
+    return false;
+  }
+
+  /* Confirm that the WinSock DLL supports 1.1.*/
+  /* Note that if the DLL supports versions greater */
+  /* than 1.1 in addition to 1.1, it will still return */
+  /* 1.1 in wVersion since that is the version we */
+  /* requested.   */
+
+  if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) {
+    /* Tell the user that we could not find a usable */
+    /* WinSock DLL.   */
+    WSACleanup( );
+    return false;
+  }
+
+  /* The WinSock DLL is acceptable. Proceed. */
+  return true;
+}
+#endif /*__WIN32__*/
+/*-------------------------------------------------------------------------*/
+static void PrintIP(const struct hostent *HostEntry, const int Index)
+{
+  unsigned int addrIndex = (Index == -1) ? (0) : (Index);
+
+  if ( HostEntry->h_addrtype == AF_INET ) {
+    while ( HostEntry->h_addr_list[addrIndex] ) {
+      char* ptr = inet_ntoa(*((struct in_addr*)HostEntry->h_addr_list[addrIndex]));
+      printf("%s", ptr);
+      if ( Index != -1 ) break; /* Only printing one IP */
+      addrIndex++;
+      if ( HostEntry->h_addr_list[addrIndex] )
+        printf(", ");
+    }
+  }
+  else
+    printf("(not an IP address)");
+}
+/*-------------------------------------------------------------------------*/
+static SOCKET ConnectToServer(const struct hostent *HostEntry)
+{
+  SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
+  if ( s != INVALID_SOCKET ) {
+    unsigned int addrIndex = 0U;
+    int connectResult;
+    struct sockaddr_in ipv4serverAddress;
+
+    memset(&ipv4serverAddress, 0, sizeof(ipv4serverAddress));
+    ipv4serverAddress.sin_family = HostEntry->h_addrtype;
+    ipv4serverAddress.sin_port = htons(POP3_PORT);
+
+    while ( HostEntry->h_addr_list[addrIndex] ) {
+      printf("Attempting to connect to ");
+      PrintIP(HostEntry, addrIndex);
+      printf(":%u->", POP3_PORT);
+      memcpy(&ipv4serverAddress.sin_addr, HostEntry->h_addr_list[addrIndex], sizeof(ipv4serverAddress.sin_addr));
+      connectResult = connect(s, (const struct sockaddr*)&ipv4serverAddress, sizeof(ipv4serverAddress));
+      if ( connectResult == SOCKET_ERROR ) { /* Failed to connect */
+        printf("FAIL!\n");
+        PrintLastSocketsError("connect()");
+        if ( HostEntry->h_addr_list[++addrIndex] ) { /* More to try? */
+          continue; /* Try again on next IP */
+        }
+        else { /* Out of luck */
+          closesocket(s);
+          s = INVALID_SOCKET;
+        }
+      }
+      else {
+        printf("CONNECTED!\n");
+        break;
+      }
+    }
+  }
+  return s;
+}
+/*-------------------------------------------------------------------------*/
+static bool KillMails(SOCKET Socket)
+{
+  char buf[512]; /* For responses from server */
+  int err;
+  long int fuckover, c, i; /* The killing loop! */
+
+  /* Welcome message firstly */
+  err = ReceiveResponse(Socket, buf, sizeof(buf));
+  if ( err <= 0 ) return false;
+
+  /* Now send the username */
+  buf[0] = '\0';
+  strncat(buf, "USER ", sizeof(buf)-1);
+  strncat(buf, UserName, (sizeof(buf)-1) - strlen(buf));
+  strncat(buf, "\r\n", (sizeof(buf)-1) - strlen(buf));
+  err = send(Socket, buf, strlen(buf), 0);
+  if ( err <= 0 ) return false;
+  puts(buf);
+
+  /* Receive response again */
+  err = ReceiveResponse(Socket, buf, sizeof(buf));
+  if ( err <= 0 ) return false;
+
+  /* Now send the password */
+  buf[0] = '\0';
+  strncat(buf, "PASS ", sizeof(buf)-1);
+  strncat(buf, Password, (sizeof(buf)-1) - strlen(buf));
+  strncat(buf, "\r\n", (sizeof(buf)-1) - strlen(buf));
+  err = send(Socket, buf, strlen(buf), 0);
+  if ( err <= 0 ) return false;
+  puts(buf);
+
+  /* Receive response again */
+  err = ReceiveResponse(Socket, buf, sizeof(buf));
+  if ( err <= 0 ) return false;
+
+  /* We're in! Now let's call STAT and get some info */
+  buf[0] = '\0';
+  strncat(buf, "STAT\r\n", sizeof(buf)-1);
+  err = send(Socket, buf, strlen(buf), 0);
+  if ( err <= 0 ) return false;
+  puts(buf);
+
+  /* Get info back from STAT */
+  err = ReceiveResponse(Socket, buf, sizeof(buf));
+  if ( err <= 0 ) return false;
+
+  /* We've got STAT's output, so now we'll use it to initialise our killing loop */
+  c = strtol(buf+4, (char**)NULL, 0);
+  if ( c == LONG_MAX || c == LONG_MIN) {
+    fprintf(stderr, "Error: Out of range\n");
+    return false;
+  }
+
+  if ( c ) {
+    printf("\n\t**** WARNING****\n\tThere are %ld messages\n\t**** WARNING ****\n\n", c);
+    for ( i = 0L; i < 20; i++ )
+      BeepSound();
+  }
+
+  fuckover = 99999999;
+  for ( i = c+1; i; i-- ) {
+    char nbuf[128]; /* Temp storage of number-as-string */
+    buf[0] = '\0';
+    strncat(buf, "DELE ", sizeof(buf)-1);
+    sprintf(nbuf, "%ld", i);
+    strncat(buf, nbuf, (sizeof(buf)-1) - strlen(buf));
+    strncat(buf, "\r\n", (sizeof(buf)-1) - strlen(buf));
+    err = send(Socket, buf, strlen(buf), 0);
+    if ( err <= 0 ) return false;
+    puts(buf);
+    /* Get back status message */
+    err = ReceiveResponse(Socket, buf, sizeof(buf));
+    /*if ( err <= 0 ) return false;*/
+    fuckover--;
+    if ( !fuckover ) break;
+  }
+
+  return true;
+}
+/*-------------------------------------------------------------------------*/
+static int ReceiveResponse(SOCKET S, char* Buffer, unsigned int BufferSz)
+{
+  int err = recv(S, Buffer, BufferSz, 0);
+  if ( err > 0 ) {
+    Buffer[err] = '\0';
+    puts(Buffer);
+    if ( Buffer[0] == '-' ) return -1;
+  }
+  return err;
+}
+/*-------------------------------------------------------------------------*/
+static void DisconnectServer(SOCKET Socket)
+{
+  char buf[512];
+  int err;
+
+  /* Send QUIT and see goodbye message */
+  /* Now send the password */
+  buf[0] = '\0';
+  strncat(buf, "QUIT\r\n", sizeof(buf)-1);
+  err = send(Socket, buf, strlen(buf), 0);
+  if ( err >= 1 ) {
+    puts(buf);
+    err = recv(Socket, buf, sizeof(buf), 0);
+    if ( err > 0 ) {
+      buf[err] = '\0';
+      puts(buf);
+    }
+  }
+
+  closesocket(Socket);
+}
+/*-------------------------------------------------------------------------*/