email.c
上传用户:knt0001
上传日期:2022-01-28
资源大小:264k
文件大小:9k
源码类别:

Email客户端

开发平台:

C/C++

  1. /**
  2.     eMail is a command line SMTP client.
  3.     Copyright (C) 2001 - 2008 email by Dean Jones
  4.     Software supplied and written by http://www.cleancode.org
  5.     This file is part of eMail.
  6.     eMail is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.     eMail is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with eMail; if not, write to the Free Software
  16.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. **/
  18. #if HAVE_CONFIG_H
  19. # include "config.h"
  20. #endif
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <signal.h>
  25. #include "getopt.h"
  26. #include "email.h"
  27. #include "conf.h"
  28. #include "utils.h"
  29. #include "addy_book.h"
  30. #include "file_io.h"
  31. #include "message.h"
  32. #include "error.h"
  33. #include "mimeutils.h"
  34. static void
  35. defaultDestr(void *ptr)
  36. {
  37. xfree(ptr);
  38. }
  39. static struct option Gopts[] = {
  40. {"attach", 1, 0, 'a'},
  41. {"attachment", 1, 0, 'a'},
  42. {"verbose", 0, 0, 'v'},
  43. {"high-priority", 0, 0, 'o'},
  44. {"encrypt", 0, 0, 'e'},
  45. {"subject", 1, 0, 's'},
  46. {"sub", 1, 0, 's'},
  47. {"smtp-server", 1, 0, 'r'},
  48. {"smtp-port", 1, 0, 'p'},
  49. {"conf-file", 1, 0, 'c'},
  50. {"check-config", 0, 0, 't'},
  51. {"version", 0, 0, 'v'},
  52. {"blank-mail", 0, 0, 'b'},
  53. {"smtp-user", 1, 0, 'u'},
  54. {"smtp-username", 1, 0, 'u'},
  55. {"smtp-pass", 1, 0, 'i'},
  56. {"smtp-password", 1, 0, 'i'},
  57. {"smtp-auth", 1, 0, 'm'},
  58. {"gpg-pass", 1, 0, 'g'},
  59. {"gpg-password", 1, 0, 'g'},
  60. {"from-addr", 1, 0, 'f'},
  61. {"from-name", 1, 0, 'n'},
  62. {"header", 1, 0, 'H'},
  63. {"timeout", 1, 0, 'x'},
  64. {"html", 0, 0, 1},
  65. {"sign", 0, 0, 2},
  66. {"clearsign", 0, 0, 2},
  67. {"cc", 1, 0, 3},
  68. {"bcc", 1, 0, 4},
  69. {"to-name", 1, 0, 5},
  70. {"tls", 0, 0, 6},
  71. {"no-encoding", 0, 0, 7},
  72. {NULL, 0, NULL, 0 }
  73. };
  74. /**
  75.  * Usage prints helpful usage information,
  76. **/
  77. void
  78. usage(void)
  79. {
  80. fprintf(stderr,
  81.     "Options information is as followsn"
  82.     "email [options] recipient1,recipient2,...nn"
  83.     "    -h, -help module          Print this message or specify one of the "
  84.     "below optionsn"
  85.     "    -V, -verbose              Display mailing progress.n"
  86.     "    -f, -from-addr            Senders mail addressn"
  87.     "    -n, -from-name            Senders namen"
  88.     "    -b, -blank-mail           Allows you to send a blank emailn"
  89.     "    -e, -encrypt              Encrypt the e-mail for first recipient before "
  90.     "sendingn"
  91.     "    -s, -subject subject      Subject of messagen"
  92.     "    -r, -smtp-server server   Specify a temporary SMTP server for sendingn"
  93.     "    -p, -smtp-port port       Specify the SMTP port to connect ton"
  94.     "    -a, -attach file          Attach file and base64 encoden"
  95.     "    -c, -conf-file file       Path to non-default configuration filen"
  96.     "    -t, -check-config         Simply parse the email.conf file for errorsn"
  97.     "    -x, -timeout              Set socket timeout.n"
  98.     "        -cc email,email,...   Copy recipientsn"
  99.     "        -bcc email,email,...  Blind Copy recipientsn"
  100.     "        -sign                 Sign the email with GPGn"
  101.     "        -html                 Send message in HTML format "
  102.     "( Make your own HTML! )n"
  103.     "        -tls                  Use TLS/SSLn"
  104.     "    -m, -smtp-auth type       Set the SMTP AUTH type (plain or login)n"
  105.     "    -u, -smtp-user username   Specify your username for SMTP AUTHn"
  106.     "    -i, -smtp-pass password   Specify your password for SMTP AUTHn"
  107.     "    -g, -gpg-pass             Specify your password for GPGn"
  108.     "    -H, -header string        Add header (can be used multiple times)n"
  109.     "        -high-priority        Send the email with high priorityn"
  110.     "        -no-encoding          Don't use UTF-8 encodingn");
  111. exit(EXIT_SUCCESS);
  112. }
  113. char *
  114. getConfValue(const char *tok)
  115. {
  116. return (char *)dhGetItem(table, tok);
  117. }
  118. void
  119. setConfValue(const char *tok, const char *val)
  120. {
  121. dhInsert(table, tok, val);
  122. }
  123. /**
  124.  * ModuleUsage will take an argument for the specified 
  125.  * module and print out help information on the topic.  
  126.  * information is stored in a written file in the location 
  127.  * in Macro EMAIL_DIR. and also specified with EMAIL_HELP_FILE
  128.  */
  129. static void
  130. moduleUsage(const char *module)
  131. {
  132. FILE *help=NULL;
  133. short found=0;
  134. char *moduleptr=NULL;
  135. dstrbuf *buf = DSB_NEW;
  136. dstrbuf *help_file = expandPath(EMAIL_HELP_FILE);
  137. if (!(help = fopen(help_file->str, "r"))) {
  138. fatal("Could not open help file: %s", help_file->str);
  139. dsbDestroy(help_file);
  140. properExit(ERROR);
  141. }
  142. dsbDestroy(help_file);
  143. while (!feof(help)) {
  144. dsbReadline(buf, help);
  145. if ((buf->str[0] == '#') || (buf->str[0] == 'n')) {
  146. continue;
  147. }
  148. chomp(buf->str);
  149. moduleptr = strtok(buf->str, "|");
  150. if (strcasecmp(moduleptr, module) != 0) {
  151. while ((moduleptr = strtok(NULL, "|")) != NULL) {
  152. if (strcasecmp(moduleptr, module) == 0) {
  153. found = 1;
  154. break;
  155. }
  156. }
  157. } else {
  158. found = 1;
  159. }
  160. if (!found) {
  161. continue;
  162. }
  163. while (!feof(help)) {
  164. dsbReadline(buf, help);
  165. if (!strcmp(buf->str, "EOHn")) {
  166. break;
  167. }
  168. printf("%s", buf->str);
  169. }
  170. break;
  171. }
  172. if (feof(help)) {
  173. printf("There is no help in the module: %sn", module);
  174. usage();
  175. }
  176. dsbDestroy(buf);
  177. fclose(help);
  178. exit(0);
  179. }
  180. int
  181. main(int argc, char **argv)
  182. {
  183. int get;
  184. int opt_index = 0;          /* for getopt */
  185. char *cc_string = NULL;
  186. char *bcc_string = NULL;
  187. const char *opts = "f:n:a:p:oVedvtb?c:s:r:u:i:g:m:H:x:";
  188. /* Set certian global options to NULL */
  189. conf_file = NULL;
  190. global_msg = NULL;
  191. memset(&Mopts, 0, sizeof(struct mailer_options));
  192. Mopts.encoding = true;
  193. /* Check if they need help */
  194. if ((argc > 1) && (!strcmp(argv[1], "-h") ||
  195. !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help"))) {
  196. if (argc == 3) {
  197. moduleUsage(argv[2]);
  198. } else if (argc == 2) {
  199. usage();
  200. } else {
  201. fprintf(stderr, "Only specify one option with %s: n", argv[1]);
  202. usage();
  203. }
  204. }
  205. table = dhInit(28, defaultDestr);
  206. if (!table) {
  207. fprintf(stderr, "ERROR: Could not initialize Hash table.n");
  208. exit(0);
  209. }
  210. while ((get = getopt_long_only(argc, argv, opts, Gopts, &opt_index)) > EOF) {
  211. switch (get) {
  212. case 'n':
  213. setConfValue("MY_NAME", xstrdup(optarg));
  214. break;
  215. case 'f':
  216. setConfValue("MY_EMAIL", xstrdup(optarg));
  217. break;
  218. case 'a':
  219. if (!Mopts.attach) {
  220. Mopts.attach = dlInit(defaultDestr);
  221. }
  222. dlInsertTop(Mopts.attach, xstrdup(optarg));
  223. break;
  224. case 'V':
  225. Mopts.verbose = true;
  226. break;
  227. case 'p':
  228. setConfValue("SMTP_PORT", xstrdup(optarg));
  229. break;
  230. case 'o':
  231. Mopts.priority = 1;
  232. break;
  233. case 'e':
  234. Mopts.gpg_opts |= GPG_ENC;
  235. break;
  236. case 's':
  237. Mopts.subject = optarg;
  238. break;
  239. case 'r':
  240. setConfValue("SMTP_SERVER", xstrdup(optarg));
  241. break;
  242. case 'c':
  243. conf_file = optarg;
  244. break;
  245. case 't':
  246. checkConfig();
  247. printf("Configuration file is proper.n");
  248. dhDestroy(table);
  249. return (0);
  250. break;
  251. case 'v':
  252. printf("email - By: Dean Jones. Email: deanjones@cleancode.org.n"
  253. "Version %s - Date %s n", EMAIL_VERSION, COMPILE_DATE);
  254. dhDestroy(table);
  255. exit(EXIT_SUCCESS);
  256. break;
  257. case 'b':
  258. Mopts.blank = 1;
  259. break;
  260. case 'u':
  261. setConfValue("SMTP_AUTH_USER", xstrdup(optarg));
  262. break;
  263. case 'i':
  264. setConfValue("SMTP_AUTH_PASS", xstrdup(optarg));
  265. break;
  266. case 'm':
  267. setConfValue("SMTP_AUTH", xstrdup(optarg));
  268. break;
  269. case 'g':
  270. setConfValue("GPG_PASS", xstrdup(optarg));
  271. break;
  272. case 'H':
  273. if (!Mopts.headers) {
  274. Mopts.headers = dlInit(defaultDestr);
  275. }
  276. dlInsertTop(Mopts.headers, xstrdup(optarg));
  277. break;
  278. case 'x':
  279. setConfValue("TIMEOUT", xstrdup(optarg));
  280. break;
  281. case '?':
  282. usage();
  283. break;
  284. case 1:
  285. Mopts.html = 1;
  286. break;
  287. case 2:
  288. Mopts.gpg_opts |= GPG_SIG;
  289. break;
  290. case 3:
  291. cc_string = optarg;
  292. break;
  293. case 4:
  294. bcc_string = optarg;
  295. break;
  296. case 5:
  297. /* To name? */
  298. break;
  299. case 6:
  300. setConfValue("USE_TLS", xstrdup("true"));
  301. break;
  302. case 7:
  303. Mopts.encoding = false;
  304. break;
  305. default:
  306. /* Print an error message here  */
  307. usage();
  308. break;
  309. }
  310. }
  311. /* first let's check to make sure they specified some recipients */
  312. if (optind == argc) {
  313. usage();
  314. }
  315. configure();
  316. /* Check to see if we need to attach a vcard. */
  317. if (getConfValue("VCARD")) {
  318. dstrbuf *vcard = expandPath(getConfValue("VCARD"));
  319. if (!Mopts.attach) {
  320. Mopts.attach = dlInit(defaultDestr);
  321. }
  322. dlInsertTop(Mopts.attach, xstrdup(vcard->str));
  323. dsbDestroy(vcard);
  324. }
  325. /* set to addresses if argc is > 1 */
  326. if (!(Mopts.to = getNames(argv[optind]))) {
  327. fatal("You must specify at least one recipient!n");
  328. properExit(ERROR);
  329. }
  330. /* Set CC and BCC addresses */
  331. if (cc_string) {
  332. Mopts.cc = getNames(cc_string);
  333. }
  334. if (bcc_string) {
  335. Mopts.bcc = getNames(bcc_string);
  336. }
  337. signal(SIGTERM, properExit);
  338. signal(SIGINT, properExit);
  339. signal(SIGPIPE, properExit);
  340. signal(SIGHUP, properExit);
  341. signal(SIGQUIT, properExit);
  342. createMail();
  343. properExit(0);
  344. /* We never get here, but gcc will whine if i don't return something */
  345. return 0;
  346. }