понедельник, 27 июня 2011 г.

Простейший SMTP клиент.

Принимает ip-адрес smtp сервера, как первый и единственный аргумент, проводит элементарную сессию из сообщений "HELO", затем "QUIT", пишет всю переписку в stdout.
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <cerrno>
#include <cstdlib>
#include <cstdio>

const int port_number = 25;

void ReadFromSocket(int socket_descriptor, char *server_answer, int len) {
  int num_bytes = read(socket_descriptor, server_answer, len);
  if (num_bytes < 0) {
    perror("ERROR reading socket");
    exit(EXIT_FAILURE);
  }
}

void WriteToSocket(int socket_descriptor, const char *msg, int len) {
  int num_bytes = write(socket_descriptor, msg, len);
  if (num_bytes < 0) {
    perror("ERROR writing socket");
    exit(EXIT_FAILURE);
  }
}

void SimpleSMTPSession(int socket_descriptor) {
  char buffer[256];
  ReadFromSocket(socket_descriptor, buffer, 255);
  printf("Server: %s", buffer);

  strcpy(buffer, "HELO CLIENT\n");
  WriteToSocket(socket_descriptor, buffer, strlen(buffer));
  printf("Client: %s", buffer);

  ReadFromSocket(socket_descriptor, buffer, 255);
  printf("Server: %s", buffer);

  strcpy(buffer, "QUIT\n");
  WriteToSocket(socket_descriptor, buffer, strlen(buffer));
  printf("Client: %s", buffer);

  ReadFromSocket(socket_descriptor, buffer, 255);
  printf("Server: %s", buffer);
}

void EstablishConnection(int *socket_descriptor, char *address) {
  *socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);
  if (*socket_descriptor < 0) {
    perror("ERROR opening socket");
    exit(EXIT_FAILURE);
  }

  struct sockaddr_in server_address;
  memset(&server_address, 0, sizeof(server_address));
  server_address.sin_family = AF_INET;
  int pton_result = inet_pton(AF_INET, address, &(server_address.sin_addr));
  if (pton_result == 0) {
    printf("ERROR argument is not IP address\n");
    exit(EXIT_FAILURE);
  }
  if (pton_result < 0) {
    perror("ERROR argument is not valid IP address");
    exit(EXIT_FAILURE);
  }
  server_address.sin_port = htons(port_number);

  if (connect(*socket_descriptor,
              (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
    perror("ERROR connecting");
    exit(EXIT_FAILURE);
  }
}

void CloseConnection(int socket_descriptor) {
  if (close(socket_descriptor) < 0) {
    perror("ERROR socket closing");
    exit(EXIT_FAILURE);
  }
}

int main(int argc, char **argv) {
  if (argc != 2) {
    printf("Not enough arguments!\nUsage: %s ip_address\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  int socket_descriptor;
  EstablishConnection(&socket_descriptor, argv[1]);

  SimpleSMTPSession(socket_descriptor);

  CloseConnection(socket_descriptor);

  return 0;
}

Комментариев нет:

Отправить комментарий