⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncbi_sendmail.c

📁 ncbi源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbi_sendmail.c,v $ * PRODUCTION Revision 1000.1  2004/02/12 21:52:59  gouriano * PRODUCTION PRODUCTION: UPGRADED [CORE_001] Dev-tree R6.22 * PRODUCTION * =========================================================================== *//*  $Id: ncbi_sendmail.c,v 1000.1 2004/02/12 21:52:59 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Author:  Anton Lavrentiev * * File Description: *   Send mail * */#include "ncbi_ansi_ext.h"#include "ncbi_priv.h"#include <connect/ncbi_sendmail.h>#include <connect/ncbi_socket.h>#include <ctype.h>#include <stdlib.h>#ifdef NCBI_OS_UNIX#include <pwd.h>#include <unistd.h>#endif#ifdef NCBI_CXX_TOOLKIT#define NCBI_SENDMAIL_TOOLKIT "C++"#else#define NCBI_SENDMAIL_TOOLKIT "C"#endif#define MX_MAGIC_NUMBER 0xBA8ADEDA#define MX_CRLF         "\r\n"#define SMTP_READERR    -1      /* Error reading from socket         */#define SMTP_REPLYERR   -2      /* Error reading reply prefix        */#define SMTP_BADCODE    -3      /* Reply code doesn't match in lines */#define SMTP_BADREPLY   -4      /* Malformed reply text              */#define SMTP_NOCODE     -5      /* No reply code detected (letters?) */#define SMTP_WRITERR    -6      /* Error writing to socket           *//* Read SMTP reply from the socket. * Return reply in the buffer provided, * and reply code (positive value) as a return value. * Return a negative code in case of problem (protocol reply * read error or protocol violations). * Return 0 in case of call error. */static int s_SockRead(SOCK sock, char* reply, size_t reply_len){    int/*bool*/ done = 0;    size_t n = 0;    int code = 0;    if (!reply  ||  !reply_len)        return 0;    do {        size_t m = 0;        char buf[4];        if (SOCK_Read(sock, buf, 4, &m, eIO_ReadPersist) != eIO_Success)            return SMTP_READERR;        if (m != 4)            return SMTP_REPLYERR;        if (buf[3] == '-'  ||  (done = isspace((unsigned char) buf[3]))) {            buf[3] = 0;            if (!code) {                if (!(code = atoi(buf)))                    return SMTP_NOCODE;            } else if (code != atoi(buf))                return SMTP_BADCODE;        } else            return SMTP_BADREPLY;        do {            m = 0;            if (SOCK_Read(sock,buf,1,&m,eIO_ReadPlain) != eIO_Success  ||  !m)                return SMTP_READERR;            if (buf[0] != '\r'  &&  n < reply_len)                reply[n++] = buf[0];        } while (buf[0] != '\n');        /* At least '\n' should sit in buffer */        assert(n);        if (done)            reply[n - 1] = 0;        else if (n < reply_len)            reply[n] = ' ';            } while (!done);    assert(code);    return code;}static int/*bool*/ s_SockReadResponse(SOCK sock, int code, int alt_code,                                      char* buf, size_t buf_size){    int c = s_SockRead(sock, buf, buf_size);    if (c <= 0) {        const char* message = 0;        switch (c) {        case SMTP_READERR:            message = "Read error";            break;        case SMTP_REPLYERR:            message = "Error reading reply prefix";            break;        case SMTP_BADCODE:            message = "Reply code doesn't match in lines";            break;        case SMTP_BADREPLY:            message = "Malformed reply text";            break;        case SMTP_NOCODE:            message = "No reply code detected";            break;        case SMTP_WRITERR:            message = "Write error";            break;        default:            message = "Unknown error";            break;        }        assert(message);        strncpy0(buf, message, buf_size - 1);    } else if (c == code  ||  (alt_code  &&  c == alt_code))        return 1/*success*/;    return 0/*failure*/;}static int/*bool*/ s_SockWrite(SOCK sock, const char* buf){    size_t len = strlen(buf);    size_t n;    if (SOCK_Write(sock, buf, len, &n, eIO_WritePersist) == eIO_Success  &&        n == len) {        return 1/*success*/;    }    return 0/*failure*/;}static char* s_ComposeFrom(char* buf, size_t buf_size){    size_t buf_len, hostname_len;#ifdef NCBI_OS_UNIX    /* Get the user login name. FIXME: not MT-safe */    const char* login_name;    CORE_LOCK_WRITE;    login_name = getlogin();    if (!login_name) {        struct passwd* pwd = getpwuid(getuid());        if (!pwd) {            if (!(login_name = getenv("USER"))  &&                !(login_name = getenv("LOGNAME"))) {                CORE_UNLOCK;                return 0;            }        } else            login_name = pwd->pw_name;    }#else    /* Temporary solution for login name */    const char* login_name = "anonymous";#  ifdef NCBI_OS_MSWIN    const char* user_name = getenv("USERNAME");    if (user_name)        login_name = user_name;#  endif#endif    strncpy0(buf, login_name, buf_size - 1);#ifdef NCBI_OS_UNIX    CORE_UNLOCK;#endif    buf_len = strlen(buf);    hostname_len = buf_size - buf_len;    if (hostname_len-- > 1) {        buf[buf_len++] = '@';        SOCK_gethostname(&buf[buf_len], hostname_len);    }    return buf;}SSendMailInfo* SendMailInfo_Init(SSendMailInfo* info){    if (info) {        info->magic_number    = MX_MAGIC_NUMBER;        info->cc              = 0;        info->bcc             = 0;        if (!s_ComposeFrom(info->from, sizeof(info->from)))            info->from[0]     = 0;        info->header          = 0;        info->body_size       = 0;        info->mx_host         = MX_HOST;        info->mx_port         = MX_PORT;        info->mx_timeout.sec  = MX_TIMEOUT;        info->mx_timeout.usec = 0;        info->mx_no_header    = 0/*false*/;    }    return info;}extern const char* CORE_SendMail(const char* to,                                 const char* subject,                                 const char* body){    return CORE_SendMailEx(to, subject, body, 0);}/* In two macros below the smartest (or, weak-minded?) Sun * C compiler warned about unreachable end-of-loop condition * (well, it thinks "a condition" is there, dumb!), if we * used 'return' right before the end of 'while' statement. * So we now added "check" and "conditional" exit, which makes * the Sun compiler much happier, and less wordy :-) */#define SENDMAIL_RETURN(reason)                                            \    do {                                                                   \        if (sock)                                                          \            SOCK_Close(sock);                                              \        CORE_LOGF(eLOG_Error, ("[SendMail]  %s", reason));                 \        if (reason/*always true, though, to trick "smart" compiler*/)      \            return reason;                                                 \    } while (0)#define SENDMAIL_RETURN2(reason, explanation)                              \    do {                                                                   \       if (sock)                                                           \           SOCK_Close(sock);                                               \       CORE_LOGF(eLOG_Error, ("[SendMail]  %s: %s", reason, explanation)); \       if (reason/*always true, though, to trick "smart" compiler*/)       \           return reason;                                                  \    } while (0)static const char* s_SendRcpt(SOCK sock, const char* to,                              char buf[], size_t buf_size,                              const char what[],                              const char write_error[],                              const char proto_error[]){    char c;    while ((c = *to++) != 0) {        char   quote = 0;        size_t k = 0;        if (isspace((unsigned char) c))            continue;        while (k < buf_size) {            if (quote) {                if (c == quote)                    quote = 0;            } else if (c == '"'  ||  c == '<'  ||  c == '\'') {                quote = c == '<' ? '>' : c;            } else if (c == ',')                break;            buf[k++] = c == '\t' ? ' ' : c;            if (!(c = *to++))                break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -