Exemple #1
0
/* Skeletons for the socket i/o test:
 *   TEST__client(...)
 *   TEST__server(...)
 *   establish and close connection;  call test i/o functions like
 *     TEST__[client|server]_[1|2|...] (...)
 */
static void TEST__client(const char*     server_host,
                         unsigned short  server_port,
                         const STimeout* timeout)
{
    SOCK       sock;
    EIO_Status status;
    char       tmo[80];

    if ( timeout )
        sprintf(tmo, "%u.%06u", timeout->sec, timeout->usec);
    else
        strcpy(tmo, "INFINITE");
    CORE_LOGF(eLOG_Note,
              ("TEST__client(host = \"%s\", port = %hu, timeout = %s",
               server_host, server_port, tmo));

    /* Connect to server */
    status = SOCK_Create(server_host, server_port, timeout, &sock);
    assert(status == eIO_Success);
    verify(SOCK_SetTimeout(sock, eIO_ReadWrite, timeout) == eIO_Success);
    verify(SOCK_SetTimeout(sock, eIO_Close,     timeout) == eIO_Success);

    /* Test the simplest randezvous(plain request-reply)
     * The two peer functions are:
     *      "TEST__[client|server]_1(SOCK sock)"
     */
    TEST__client_1(sock);

    /* Test a more complex case
     * The two peer functions are:
     *      "TEST__[client|server]_2(SOCK sock)"
     */
    TEST__client_2(sock);

    /* Close connection and exit */
    status = SOCK_Close(sock);
    assert(status == eIO_Success  ||  status == eIO_Closed);

    CORE_LOG(eLOG_Note, "TEST completed successfully");
}
Exemple #2
0
const char* CORE_SendMailEx(const char*          to,
                            const char*          subject,
                            const char*          body,
                            const SSendMailInfo* uinfo)
{
    static const STimeout zero = {0, 0};
    const SSendMailInfo* info;
    SSendMailInfo ainfo;
    char buffer[1024];
    SOCK sock = 0;

    info = uinfo ? uinfo : SendMailInfo_Init(&ainfo);
    if (info->magic_number != MX_MAGIC_NUMBER)
        SENDMAIL_RETURN(6, "Invalid magic number");

    if ((!to         ||  !*to)        &&
        (!info->cc   ||  !*info->cc)  &&
        (!info->bcc  ||  !*info->bcc)) {
        SENDMAIL_RETURN(7, "At least one message recipient must be specified");
    }

    /* Open connection to sendmail */
    if (SOCK_Create(info->mx_host, info->mx_port, &info->mx_timeout, &sock)
        != eIO_Success) {
        SENDMAIL_RETURN(8, "Cannot connect to sendmail");
    }
    SOCK_SetTimeout(sock, eIO_ReadWrite, &info->mx_timeout);

    /* Follow the protocol conversation, RFC821 */
    if (!SENDMAIL_READ_RESPONSE(220, 0, buffer))
        SENDMAIL_RETURN2(9, "Protocol error in connection init", buffer);

    if ((!(info->mx_options & fSendMail_StripNonFQDNHost)  ||
         !SOCK_gethostbyaddr(0, buffer, sizeof(buffer)))  &&
        SOCK_gethostname(buffer, sizeof(buffer)) != 0) {
        SENDMAIL_RETURN(10, "Unable to get local host name");
    }
    if (!s_SockWrite(sock, "HELO ", 0)  ||
        !s_SockWrite(sock, buffer, 0)   ||
        !s_SockWrite(sock, MX_CRLF, 2)) {
        SENDMAIL_RETURN(11, "Write error in HELO command");
    }
    if (!SENDMAIL_READ_RESPONSE(250, 0, buffer))
        SENDMAIL_RETURN2(12, "Protocol error in HELO command", buffer);

    if (!s_SockWrite(sock, "MAIL FROM: <", 0)             ||
        !s_SockWrite(sock, info->from, s_FromSize(info))  ||
        !s_SockWrite(sock, ">" MX_CRLF, 1 + 2)) {
        SENDMAIL_RETURN(13, "Write error in MAIL command");
    }
    if (!SENDMAIL_READ_RESPONSE(250, 0, buffer))
        SENDMAIL_RETURN2(14, "Protocol error in MAIL command", buffer);

    if (to && *to) {
        const char* error = SENDMAIL_SENDRCPT("To", to, buffer);
        if (error)
            return error;
    }

    if (info->cc && *info->cc) {
        const char* error = SENDMAIL_SENDRCPT("Cc", info->cc, buffer);
        if (error)
            return error;
    }

    if (info->bcc && *info->bcc) {
        const char* error = SENDMAIL_SENDRCPT("Bcc", info->bcc, buffer);
        if (error)
            return error;
    }

    if (!s_SockWrite(sock, "DATA" MX_CRLF, 0))
        SENDMAIL_RETURN(15, "Write error in DATA command");
    if (!SENDMAIL_READ_RESPONSE(354, 0, buffer))
        SENDMAIL_RETURN2(16, "Protocol error in DATA command", buffer);

    if (!(info->mx_options & fSendMail_NoMxHeader)) {
        /* Follow RFC822 to compose message headers. Note that
         * 'Date:'and 'From:' are both added by sendmail automagically.
         */ 
        if (!s_SockWrite(sock, "Subject: ", 0)             ||
            (subject  &&  !s_SockWrite(sock, subject, 0))  ||
            !s_SockWrite(sock, MX_CRLF, 2))
            SENDMAIL_RETURN(17, "Write error in sending subject");

        if (to  &&  *to) {
            if (!s_SockWrite(sock, "To: ", 0)              ||
                !s_SockWrite(sock, to, 0)                  ||
                !s_SockWrite(sock, MX_CRLF, 2))
                SENDMAIL_RETURN(18, "Write error in sending To");
        }

        if (info->cc  &&  *info->cc) {
            if (!s_SockWrite(sock, "Cc: ", 0)              ||
                !s_SockWrite(sock, info->cc, 0)            ||
                !s_SockWrite(sock, MX_CRLF, 2))
                SENDMAIL_RETURN(19, "Write error in sending Cc");
        }
    } else if (subject && *subject)
        CORE_LOG_X(2, eLOG_Warning,
                   "[SendMail]  Subject ignored in as-is messages");

    if (!s_SockWrite(sock, "X-Mailer: CORE_SendMail (NCBI "
                     NCBI_SENDMAIL_TOOLKIT " Toolkit)" MX_CRLF, 0)) {
        SENDMAIL_RETURN(20, "Write error in sending mailer information");
    }

    assert(sizeof(buffer) > sizeof(MX_CRLF) && sizeof(MX_CRLF) >= 3);

    if (info->header && *info->header) {
        size_t n = 0, m = strlen(info->header);
        int/*bool*/ newline = 0/*false*/;
        while (n < m) {
            size_t k = 0;
            if (SOCK_Wait(sock, eIO_Read, &zero) != eIO_Timeout)
                break;
            while (k < sizeof(buffer) - sizeof(MX_CRLF)) {
                if (info->header[n] == '\n') {
                    memcpy(&buffer[k], MX_CRLF, sizeof(MX_CRLF) - 1);
                    k += sizeof(MX_CRLF) - 1;
                    newline = 1/*true*/;
                } else {
                    if (info->header[n] != '\r'  ||  info->header[n+1] != '\n')
                        buffer[k++] = info->header[n];
                    newline = 0/*false*/;
                }
                if (++n >= m)
                    break;
            }
            buffer[k] = '\0'/*just in case*/;
            if (!s_SockWrite(sock, buffer, k))
                SENDMAIL_RETURN(21, "Write error while sending custom header");
        }
        if (n < m)
            SENDMAIL_RETURN(22, "Header write error");
        if (!newline && !s_SockWrite(sock, MX_CRLF, 2))
            SENDMAIL_RETURN(23, "Write error while finalizing custom header");
    }

    if (body) {
        size_t n = 0, m = info->body_size ? info->body_size : strlen(body);
        int/*bool*/ newline = 0/*false*/;
        if (!(info->mx_options & fSendMail_NoMxHeader)  &&  m) {
            if (!s_SockWrite(sock, MX_CRLF, 2))
                SENDMAIL_RETURN(24, "Write error in message body delimiter");
        }
        while (n < m) {
            size_t k = 0;
            if (SOCK_Wait(sock, eIO_Read, &zero) != eIO_Timeout)
                break;
            while (k < sizeof(buffer) - sizeof(MX_CRLF)) {
                if (body[n] == '\n') {
                    memcpy(&buffer[k], MX_CRLF, sizeof(MX_CRLF) - 1);
                    k += sizeof(MX_CRLF) - 1;
                    newline = 1/*true*/;
                } else {
                    if (body[n] != '\r'  ||  (n+1 < m  &&  body[n+1] != '\n')){
                        if (body[n] == '.'  &&  (newline  ||  !n)) {
                            buffer[k++] = '.';
                            buffer[k++] = '.';
                        } else
                            buffer[k++] = body[n];
                    }
                    newline = 0/*false*/;
                }
                if (++n >= m)
                    break;
            }
            buffer[k] = '\0'/*just in case*/;
            if (!s_SockWrite(sock, buffer, k))
                SENDMAIL_RETURN(25, "Write error while sending message body");
        }
        if (n < m)
            SENDMAIL_RETURN(26, "Body write error");
        if ((!newline  &&  m  &&  !s_SockWrite(sock, MX_CRLF, 2))
            ||  !s_SockWrite(sock, "." MX_CRLF, 1 + 2)) {
            SENDMAIL_RETURN(27, "Write error while finalizing message body");
        }
    } else if (!s_SockWrite(sock, "." MX_CRLF, 1 + 2))
        SENDMAIL_RETURN(28, "Write error while finalizing message");

    if (!SENDMAIL_READ_RESPONSE(250, 0, buffer))
        SENDMAIL_RETURN2(29, "Protocol error in sending message", buffer);

    if (!s_SockWrite(sock, "QUIT" MX_CRLF, 0))
        SENDMAIL_RETURN(30, "Write error in QUIT command");
    if (!SENDMAIL_READ_RESPONSE(221, 0, buffer))
        SENDMAIL_RETURN2(31, "Protocol error in QUIT command", buffer);

    SOCK_Close(sock);
    return 0;
}
Exemple #3
0
static NI_HandPtr s_GenericGetService
(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
 CharPtr defService, Boolean hasResource)
{
  NI_HandPtr result;
  SOCK       sock;
  Char       srv_host[64];
  Uint2      srv_port;
  Uint4      conn_try;

  /* get the server host name */
  NI_GetEnvParam(configFile, configSection, ENV_DEBUG_HOST,
                 srv_host, sizeof(srv_host), "");
  if ( !srv_host[0] ) {
    ErrPostEx(SEV_ERROR, 0, 0, ENV_DEBUG_HOST ": undefined");
    return 0;
  }

  {{ /* get the server port */
    Char str[32];
    int  val;
    NI_GetEnvParam(configFile, configSection, ENV_DEBUG_PORT,
                   str, sizeof(str), "");
    val = atoi(str);
    if (val <= 0) {
      ErrPostEx(SEV_ERROR, 0, 0, ENV_DEBUG_PORT ": bad(%d) or undefined", val);
      return 0;
    }
    srv_port = (Uint2)val;
  }}

  {{ /* alternate the max. number of attemts to establish a connection */
    Char str[32];
    int  val;
    NI_GetEnvParam(configFile, configSection, ENV_DEBUG_TRY,
                   str, sizeof(str), "");
    val = atoi(str);
    conn_try = (Uint4)((val > 0) ? val : DEF_DEBUG_TRY);
  }}

  /* establish connection to the server */
  for (sock = 0;  !sock  &&  conn_try;  conn_try--) {
    if (SOCK_Create(srv_host, srv_port, 0, &sock) != eIO_Success) {
      ErrPostEx(SEV_WARNING, 0, 1,
                "[Debug NI Client]  Cannot connect to host \"%s\", port %d;",
                srv_host, (int)srv_port);
    }
  }
  if ( !sock ) {
    ErrPostEx(SEV_ERROR, 0, 1,
              "[Debug NI Client]  Failed to connect to host \"%s\", port %d;",
              srv_host, (int)srv_port);
    return 0;
  }

  /* open ASN i/o, etc. */
  result = (NI_HandPtr)MemNew(sizeof(NI_Handle));
  result->extra_proc_info = sock;
  result->raip = AsnIoNew((ASNIO_BIN | ASNIO_IN),  (FILE *)0,
                          (void *)sock, s_AsnRead,  (IoFuncType)0);
  result->waip = AsnIoNew((ASNIO_BIN | ASNIO_OUT), (FILE *)0,
                          (void *)sock, (IoFuncType)0, s_AsnWrite);

  AsnIoSetErrorMsg(result->raip, s_AsnErrorFunc);
  AsnIoSetErrorMsg(result->waip, s_AsnErrorFunc);
  result->hostname = StringSave("");
  result->disp = disp;
  disp->referenceCount++;

  return result;
}