Commit 5c50702c 5c50702cdf6552db0098564009f3b49c3ce80df1 by Sergey Poznyakoff

Added to the repository

1 parent c36e5d80
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #include <mh.h>
19
20 struct recipient {
21 char *addr;
22 int isbcc;
23 };
24
25 static list_t local_rcp; /* Local recipients */
26 static list_t network_rcp; /* Network recipients */
27
28 static void
29 addrcp (list_t *list, char *addr, int isbcc)
30 {
31 int rc;
32 struct recipient *p = xmalloc (sizeof (*p));
33 p->addr = addr;
34 p->isbcc = isbcc;
35 if (!*list && (rc = list_create (list)))
36 {
37 mh_error (_("can't create list: %s"), mu_strerror (rc));
38 exit (1);
39 }
40 list_append (*list, p);
41 }
42
43 static int
44 ismydomain (char *p)
45 {
46 char *domain;
47 if (!p)
48 return 1;
49 mu_get_user_email_domain (&domain);
50 return strcasecmp (domain, p + 1) == 0;
51 }
52
53 static void
54 scan_addrs (char *str, int isbcc)
55 {
56 address_t addr;
57 size_t i, count;
58
59 address_create (&addr, str);
60 address_get_count (addr, &count);
61 for (i = 1; i <= count; i++)
62 {
63 char *buf, *p;
64 int rc;
65 rc = address_aget_email (addr, i, &buf);
66 if (rc)
67 {
68 mh_error ("address_aget_email: %s", mu_strerror (rc));
69 continue;
70 }
71 p = strchr (buf, '@');
72 if (ismydomain (p))
73 addrcp (&local_rcp, buf, isbcc);
74 else
75 addrcp (&network_rcp, buf, isbcc);
76 }
77 address_destroy (&addr);
78 free (str); /* FIXME: This will disappear. Note comment to
79 mh_context_get_value! */
80 }
81
82 static int
83 _destroy_recipient (void *item, void *unused_data)
84 {
85 struct recipient *p = item;
86 free (p->addr);
87 free (p);
88 return 0;
89 }
90
91 static void
92 destroy_addrs (list_t *list)
93 {
94 if (!*list)
95 return;
96 list_do (*list, _destroy_recipient, NULL);
97 list_destroy (list);
98 }
99
100 /* Print an email in more readable form: localpart + "at" + domain */
101 static void
102 print_readable (char *email, int islocal)
103 {
104 printf (" ");
105 for (; *email && *email != '@'; email++)
106 putchar (*email);
107
108 if (!*email || islocal)
109 return;
110
111 printf (_(" at %s"), email+1);
112 }
113
114 static int
115 _print_recipient (void *item, void *data)
116 {
117 struct recipient *p = item;
118 size_t *count = data;
119
120 print_readable (p->addr, 0);
121 if (p->isbcc)
122 printf ("[BCC]");
123 printf ("\n");
124 (*count)++;
125 return 0;
126 }
127
128 static int
129 _print_local_recipient (void *item, void *data)
130 {
131 struct recipient *p = item;
132 size_t *count = data;
133
134 print_readable (p->addr, 1);
135 if (p->isbcc)
136 printf ("[BCC]");
137 printf ("\n");
138 (*count)++;
139 return 0;
140 }
141
142 int
143 mh_whom (char *filename, int check)
144 {
145 int rc = 0;
146 mh_context_t *ctx;
147
148 ctx = mh_context_create (filename, 1);
149 if (mh_context_read (ctx))
150 {
151 mh_error (_("malformed message"));
152 rc = -1;
153 }
154 else
155 {
156 size_t count = 0;
157
158 scan_addrs (mh_context_get_value (ctx, MU_HEADER_TO, NULL), 0);
159 scan_addrs (mh_context_get_value (ctx, MU_HEADER_CC, NULL), 0);
160 scan_addrs (mh_context_get_value (ctx, MU_HEADER_BCC, NULL), 1);
161
162 if (local_rcp)
163 {
164 printf (" %s\n", _("-- Local Recipients --"));
165 list_do (local_rcp, _print_local_recipient, &count);
166 }
167
168 if (network_rcp)
169 {
170 printf (" %s\n", _("-- Network Recipients --"));
171 list_do (network_rcp, _print_recipient, &count);
172 }
173
174 if (count == 0)
175 {
176 mh_error(_("No recipients"));
177 rc = -1;
178 }
179 }
180 free (ctx);
181 destroy_addrs (&network_rcp);
182 destroy_addrs (&local_rcp);
183 return rc;
184 }
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2003 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 #include <mh.h>
19
20 const char *argp_program_version = "whom (" PACKAGE_STRING ")";
21 static char doc[] = N_("GNU MH whom\v"
22 "Use -help to obtain the list of traditional MH options.");
23 static char args_doc[] = "[file]";
24
25 /* GNU options */
26 static struct argp_option options[] = {
27 {"alias", ARG_ALIAS, N_("FILE"), 0,
28 N_("* Specify additional alias file") },
29 {"draft", ARG_DRAFT, NULL, 0,
30 N_("Use prepared draft") },
31 {"draftfolder", ARG_DRAFTFOLDER, N_("FOLDER"), 0,
32 N_("Specify the folder for message drafts") },
33 {"draftmessage", ARG_DRAFTMESSAGE, NULL, 0,
34 N_("Treat the arguments as a list of messages from the draftfolder") },
35 {"nodraftfolder", ARG_NODRAFTFOLDER, NULL, 0,
36 N_("Undo the effect of the last --draftfolder option") },
37 {"check", ARG_CHECK, N_("BOOL"), OPTION_ARG_OPTIONAL,
38 N_("Check if addresses are deliverable") },
39 {"nocheck", ARG_NOCHECK, NULL, OPTION_HIDDEN, "" },
40 {NULL}
41 };
42
43 /* Traditional MH options */
44 struct mh_option mh_option[] = {
45 {"alias", 1, 0, "aliasfile" },
46 {"draft", 5, 0, NULL },
47 {"draftfolder", 6, 0, "folder" },
48 {"draftmessage", 6, 0, "message"},
49 {"nodraftfolder", 3, 0, NULL },
50 {"check", 1, 0, MH_OPT_BOOL, NULL},
51 {NULL}
52 };
53
54 static int check_recipients;
55 static int use_draft; /* Use the prepared draft */
56 static char *draft_folder; /* Use this draft folder */
57
58 static int
59 opt_handler (int key, char *arg, void *unused, struct argp_state *state)
60 {
61 switch (key)
62 {
63 case ARG_ALIAS:
64 return 1;
65
66 case ARG_DRAFT:
67 use_draft = 1;
68 break;
69
70 case ARG_DRAFTFOLDER:
71 draft_folder = arg;
72 break;
73
74 case ARG_NODRAFTFOLDER:
75 draft_folder = NULL;
76 break;
77
78 case ARG_DRAFTMESSAGE:
79 if (!draft_folder)
80 draft_folder = mh_global_profile_get ("Draft-Folder",
81 mu_path_folder_dir);
82 break;
83
84 case ARG_CHECK:
85 check_recipients = is_true (arg);
86 break;
87
88 case ARG_NOCHECK:
89 check_recipients = 0;
90 break;
91
92 default:
93 return 1;
94 }
95 return 0;
96 }
97
98 int
99 main (int argc, char **argv)
100 {
101 int index;
102 char *name = "draft";
103
104 mu_init_nls ();
105
106 mh_argp_parse (argc, argv, 0, options, mh_option, args_doc, doc,
107 opt_handler, NULL, &index);
108
109 argc -= index;
110 argv += index;
111
112 if (!use_draft && argc > 1)
113 name = argv[0];
114
115 if (!draft_folder)
116 draft_folder = mh_global_profile_get ("Draft-Folder",
117 mu_path_folder_dir);
118 return mh_whom (mh_expand_name (draft_folder, name, 0), check_recipients) ?
119 1 : 0;
120 }