`
23号
  • 浏览: 138161 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

send mail command

阅读更多

/*
 * Copyright 2008 N23 <No.0023@gmail.com>
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 * Author:
 *   N23 <No.0023@gmail.com>
 *   Blog: http://n23.appspot.com/blog/
 *
 * compile: cc -Wall -W $(pkg-config --cflags --libs glib-2.0) -o $HOME/bin/run
 *
 * vi $HOME/.LoginAccount.txt
 * [mail]
 * host = smtp.qq.com
 * port = 25
 * user = ***
 * pass = ***
 * fr = No.0023@qq.com
 * to = No.0023@gmail.com
 *
 *
 * $Id: mail.c 51 2008-07-16 15:03:37Z No.0023 $
 */

#include <glib.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

#include <netdb.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

static const char *config_filename = ".LoginAccount.txt";
static const char *config_label = "mail";
static const char *end_flag = "\r\n";
static const char *email_flag = "===== Baby, I love you. ^-^ =====";

const char *log_time();
int sendCmd(const int, const char*);
int fetchCmd(const int, const char *);
int conn(const char *, const int *);
int login(const int, const char *, const char *, const char *);
int sendmail_head (const int, const char *, const char *, const char *);
void sendmail_file(const int, const char *);
int sendmail_tail(const int);
const char *get_sub_string(const char *, const gsize, const gsize);
const void split_base64(const int, const char *, const gsize);
void sendmail_data(const int, const char *);

static void error_func(GOptionContext *context,
                       GOptionGroup *group,
                       gpointer data,
                       GError **error) {
    if (*error && (*error)->message) {
        gchar *progname = g_get_prgname();
        g_print("%s: %s\nTry '%s --help' for more information.\n",
                progname,
                (*error)->message,
                progname);
        exit(1);
    }
}

int
main (int argc, char *argv[])
{
    GKeyFile *config;
    gchar *path = g_build_filename(g_get_home_dir(), config_filename, NULL);
    config = g_key_file_new();
    g_key_file_load_from_file(config, path, 0, NULL);
    gchar *host = g_key_file_get_string(config, config_label, "host", NULL);
    gint   port = g_key_file_get_integer(config, config_label, "port", NULL);
    gchar *user = g_key_file_get_string(config, config_label, "user", NULL);
    gchar *pass = g_key_file_get_string(config, config_label, "pass", NULL);
    gchar *fr = g_key_file_get_string(config, config_label, "fr", NULL);
    gchar *to = g_key_file_get_string(config, config_label, "to", NULL);

    gchar           *addr = NULL;
    gboolean        flag = FALSE;
    GOptionEntry    entries[] =
    {
        {"addr", 'e', 0, G_OPTION_ARG_FILENAME, &addr,
         "mail address", "ADDR"},
        { "atta", 'a', 0, G_OPTION_ARG_NONE, &flag,
          "attachment flag", NULL },
        {NULL}
    };
    GOptionContext *context;
    GError         *error = NULL;

    context = g_option_context_new("[args]");
    g_option_context_add_main_entries(context, entries, NULL);
    g_option_context_set_help_enabled(context, TRUE);
    g_option_group_set_error_hook(g_option_context_get_main_group(context),
                                  (GOptionErrorFunc)error_func);
    g_option_context_parse(context, &argc, &argv, &error);

    if (error) {
        perror(error->message);
        return error->code;
    }
    g_option_context_free(context);

    if (argc == 1) g_error("No file to Send");
    gint fd = conn(host, port);
    if (addr) g_stpcpy(to, addr);
    if ((login(fd, host, user, pass)) == -1) g_error("Login failed");
    for (argv++; *argv != NULL; argv++) {
        if (sendmail_head(fd, fr, to, *argv) == -1)
            g_error("Sendmail header failed");
        if (flag) sendmail_atta(fd, *argv);
        else sendmail_file(fd, *argv);
        if (sendmail_tail(fd) == -1)
            g_error("Sendmail header failed");
    }
    close(fd);
    return 0;
}


int
sendCmd(const int fd, const char* s)
{
    int             bytes;
    g_printf("%s%s%s%s%s",
             "Send: [",
             log_time(),
             "] ",
             "CMD=",
             s);
    if ((bytes = send(fd, s, strlen(s), 0)) == -1) {
        perror("send error");
        return -1;
    }

    return bytes;
}

int
fetchCmd(const int fd, const char *cmd)
{
    char            buff[1024];
    int             bytes;
    char            *tmp;

    if ((bytes = recv(fd, buff, 1024, 0)) == -1) {
        perror("recv error");
        return(-1);
    }
    buff[bytes] = '\0';
    g_printf("%s%s%s%s%s",
             "Recv: [",
             log_time(),
             "] ",
             "Result=",
             buff);
    tmp = g_strndup(buff, 3);
    if (strcmp(tmp, cmd) != 0)
        return -1;
    else
        return 0;
}

const char *log_time()
{
    char           *ct;
    time_t          t;
    t = time(NULL);
    ct = ctime(&t);
    *(strchr(ct, '\n')) = '\0';
    return ct;
}

int
conn(const char *host, const int *port)
{
    int             sockfd;
    struct sockaddr_in server_addr;
    struct hostent *server_ip;
    while ((server_ip = gethostbyname(host)) == NULL) {
        herror("gethostbyname error");
        sleep(30);
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        return -1;
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr = *((struct in_addr *) server_ip->h_addr);
    bzero(&(server_addr.sin_zero), 8);
    if (connect(sockfd, (struct sockaddr *)
        & server_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect error");
        return -1;
    }
    if (fetchCmd(sockfd, "220") == -1)
        return -1;

    return sockfd;
}

int
login(const int fd, const char *host, const char *user, const char *pass)
{
    GString *s = g_string_new("");
    g_string_append(s, "EHLO ");
    g_string_append(s, host);
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "250") == -1)
        return -1;

    g_string_erase(s, 0, -1);
    g_string_append(s, "AUTH LOGIN");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "334") == -1)
        return -1;

    g_string_erase(s, 0, -1);
    g_string_append(s,  g_base64_encode(user, strlen(user)));
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "334") == -1)
        return -1;

    g_string_erase(s, 0, -1);
    g_string_append(s,  g_base64_encode(pass, strlen(pass)));
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "235") == -1)
        return -1;

    g_string_free(s, TRUE);
    return 0;
}

int sendmail_head (const int fd,
                   const char *fr,
                   const char *to,
                   const char *subject)
{
    GString *s = g_string_new("");
    g_string_append(s, "MAIL FROM:");
    g_string_append(s, "<");
    g_string_append(s, fr);
    g_string_append(s, ">");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "250") == -1)
        return -1;

    g_string_erase(s, 0, -1);
    g_string_append(s, "RCPT TO:");
    g_string_append(s, "<");
    g_string_append(s, to);
    g_string_append(s, ">");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "250") == -1)
        return -1;

    g_string_erase(s, 0, -1);
    g_string_append(s, "DATA");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "354") == -1)
        return -1;

    g_string_erase(s, 0, -1);
    g_string_append(s, "From:");
    g_string_append(s, fr);
    g_string_append(s, end_flag);
    g_string_append(s, "To:");
    g_string_append(s, to);
    g_string_append(s, end_flag);

    g_string_append(s, "Subject:");
    g_string_append(s, subject);
    g_string_append(s, end_flag);
    g_string_append(s, "Mime-Version: 1.0");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);

    g_string_erase(s, 0, -1);
    g_string_append(s, "Content-Type: multipart/mixed;Boundary=\"");
    g_string_append(s, email_flag);
    g_string_append(s, "\"");
    g_string_append(s, end_flag);
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);

    g_string_free(s, TRUE);
    return 0;
}

void
sendmail_file(const int fd, const char *file)
{
    GString *s = g_string_new("");
    g_string_append(s, "--");
    g_string_append(s, email_flag);
    g_string_append(s, end_flag);
    g_string_append(s, "Content-Type: text/plain; charset=\"utf-8\";");
    g_string_append(s, end_flag);
    g_string_append(s, "Content-Transfer-Encoding: base64");
    g_string_append(s, end_flag);
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    g_string_free(s, TRUE);

    sendmail_data(fd, file);
}

void
sendmail_atta(const int fd, const char *file)
{
    GString *s = g_string_new("");
    g_string_append(s, "--");
    g_string_append(s, email_flag);
    g_string_append(s, end_flag);
    g_string_append(s, "Content-Type:application/octet-stream;name=\"");
    g_string_append(s, file);
    g_string_append(s, "\"");
    g_string_append(s, end_flag);
    g_string_append(s, "Content-Transfer-Encoding: base64");
    g_string_append(s, end_flag);
    g_string_append(s, "Content-Disposition:attachment;filename=\"");
    g_string_append(s, file);
    g_string_append(s, "\"");
    g_string_append(s, end_flag);
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    g_string_free(s, TRUE);

    sendmail_data(fd, file);
}

int sendmail_tail(const int fd)
{
    GString *s = g_string_new("");
    g_string_append(s, end_flag);
    g_string_append(s, end_flag);
    g_string_append(s, "--");
    g_string_append(s, email_flag);
    g_string_append(s, "--");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);

    g_string_erase(s, 0, -1);
    g_string_append(s, end_flag);
    g_string_append(s, ".");
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);
    if (fetchCmd(fd, "250") == -1)
        return -1;

    g_string_free(s, TRUE);
    return 0;
}

const char           *
get_sub_string(const char *str, const gsize start, const gsize end)
{
    gsize        n = end - start;
    static char     stbuf[256];
    if (start >= strlen(str)) {
        return NULL;
    } else {
        strncpy(stbuf, str + start, n);
        stbuf[n] = '\0';
        return stbuf;
    }
}

const void
split_base64(const int fd, const char *text, const gsize len)
{
    gchar *code = g_base64_encode(text, len);
    GString *s = g_string_new("");
    gsize l = strlen(code);
    guint start = 0, end = 0;
    g_printf("split_base64 ...start\n");
    int             bytes;
    for(end = 78; start < l; start +=78, end += 78) {
        g_string_append(s, get_sub_string(code, start, end));
        g_string_append(s, "\n");
        if ((bytes = send(fd, s->str, s->len, 0)) == -1)
            g_error("send error in split_base64");
        g_string_erase(s, 0, -1);
    }
    g_printf("split_base64 ...done\n");
    g_free(code);
    g_string_free(s, TRUE);
}

void sendmail_data(const int fd, const char *file)
{
    GString *s = g_string_new("");
    g_string_append(s, end_flag);
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);

    gchar *text;
    GError *err = NULL;
    gsize len;
    if (g_file_get_contents(file, &text, &len, &err))
        split_base64(fd, text, len);

    g_string_erase(s, 0, -1);
    g_string_append(s, end_flag);
    g_string_append(s, end_flag);
    sendCmd(fd, s->str);

    g_free(text);
    g_string_free(s, TRUE);
}

分享到:
评论

相关推荐

    biee案例开发

    针对在BIEE开发过程中可能遇到的问题,如“OracleBISchedulerError:nQSError:68019Authentication Failed.”、“[nQSError:75006]Failed to send MAIL command. Authentication required”等,文档提供了详细的错误...

    OBIEE 学习资料(内容介绍参见简介信息)

    - **[nQSError:75006] Failed to send MAIL command. Authentication required:** 邮件发送失败时的处理方法。 以上是根据提供的文档概览整理出来的OBIEE学习资料的知识点总结。这些知识点覆盖了OBIEE的基础概念...

    Biee_入门讲座

    - **[nQSError:75006]Failed to send MAIL command. Authentication required**:解决发送邮件命令时出现的身份验证问题。 以上是对BIEE入门讲座中的知识点进行了详细的解析和总结,涵盖了从安装配置到具体使用的...

    BIEE详细入门

    - **[nQSError: 75006] Failed to send MAIL command. Authentication required**:发送邮件命令失败的解决办法。 #### 8. Open and Closed Issues for this Deliverable 这部分列出了项目的开放和已关闭问题,以...

    send_mail.zip

    同时,“send_mail.sln”是Visual Studio的解决方案文件,包含整个项目的配置信息。“send_mail.csproj”是项目文件,定义了项目的构建设置。“Program.cs”可能是主程序入口,而“Properties”目录下的“App.config...

    Send Email under Windows Command Line

    在Windows操作系统中,通过命令行发送电子邮件是一种便捷的方式,尤其适用于自动化脚本或者批处理任务。这个场景中,我们可以利用`sendEmail.exe`这个可执行文件来实现这一功能。`sendEmail.pl`则可能是一个Perl脚本...

    Laravel开发-laravel-worker-command

    Mail::to($this-&gt;user-&gt;email)-&gt;send(new WelcomeEmail()); } } ``` ### 4. 发布和调度队列任务 要将任务添加到队列,使用`dispatch`函数: ```php SendEmailJob::dispatch($user); ``` ### 5. Laravel Worker...

    C.SMTPe-mail.zip_STMP服务器_stmp c

    - 发送SMTP命令的函数,如`send_command()`,可能包含一个循环来处理服务器的响应。 - 处理身份验证的函数,如果需要的话。 - 将邮件内容格式化并发送的函数,如`send_email_data()`。 - 最后,关闭连接的函数,如`...

    Laravel开发-command-center

    Mail::to($user)-&gt;send(new WelcomeEmail()); } ``` 最后,在`app/Events/EventServiceProvider.php`的`listen`数组中注册监听器。 通过这种方式,Laravel的命令中心和域事件系统可以帮助开发者更好地组织代码,...

    VB E_MAIL 有关内容

    然后,调用`MAPIMessages1.Compose`启动新邮件的创建过程,并最终使用`MAPIMessages1.Send`发送邮件。 `Command4_Click`是回复邮件的函数,它同样设置邮件会话ID,并通过`MAPIMessages1.MsgIndex`指定要回复的邮件...

    Java邮件开发Fundamentals of the JavaMail API

    * Send and read mail using the JavaMail API * Deal with sending and receiving attachments * Work with HTML messages * Use search terms to search for messages Prerequisites Instructions on how to...

    oracle发邮件功能代码编写

    CREATE OR REPLACE PROCEDURE send_mail(p_recipient VARCHAR2, p_subject VARCHAR2, p_message VARCHAR2) IS v_mailhost VARCHAR2(30) := 'mail.itpub.net'; v_user VARCHAR2(30) := 'yangtingkun@itpub...

    Laravel开发-postman

    例如,我们可以创建一个新的命令类`SendEmails`,通过`Artisan::command()`注册,并使用`email:send`命令调度这个任务: ```php protected function schedule(Schedule $schedule) { $schedule-&gt;command('email:...

    Windows下C语言实现MAIL邮件发送小工具--含源代码

    在实际应用中,为了提高代码的可读性和可维护性,可以将各个步骤封装成单独的函数,如`init_socket`、`connect_to_server`、`send_smtp_command`等。此外,考虑到安全因素,源代码可能还涉及到加密技术,如SSL/TLS,...

    PyLineMail:命令行电子邮件发送客户端,可以签名和登录,在mongo db中搜索

    #PyLineMail 文档包括零件在本地 mongo db 中搜索将联系人添加到 mongo db 将电子邮件记录到数据库py.rsa 使用的签名邮件介绍 this can send mail in command line ,include signature安装 install mongodb ,python...

    MATLAB 遗传算法程序

    This directory contains the Genetic Algorithm Optimization Toolbox for ...send mail to jjoine@eos.ncsu.edu. For a list of the files in the tool box get help on gaot. Thanks for trying the toolbox.

    windows下命令行发送邮件

    Blat is useful for creating s cripts where mail has to be sent automatically (CGI, backups, etc.), or just as a quick way to send a file or message quickly from the command line. It will store ...

    php多种形式发送邮件(mail qmail邮件系统 phpmailer类)

    function send_check_mail($email, $subject, $uid, $buffer) { $command = "/var/qmail/bin/qmail-inject " . $email; $handle = popen($command, "w"); if (!$handle) { return false; } // 写入邮件头和...

Global site tag (gtag.js) - Google Analytics