2
* Heirloom mailx - a mail user agent derived from Berkeley Mail.
4
* Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany.
8
* Gunnar Ritter. All rights reserved.
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
* 3. All advertising materials mentioning features or use of this software
19
* must display the following acknowledgement:
20
* This product includes software developed by Gunnar Ritter
21
* and his contributors.
22
* 4. Neither the name of Gunnar Ritter nor the names of his contributors
23
* may be used to endorse or promote products derived from this software
24
* without specific prior written permission.
26
* THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND
27
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
* ARE DISCLAIMED. IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE
30
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41
static char sccsid[] = "@(#)macro.c 1.13 (gritter) 3/4/06";
51
* Mail -- a mail program
65
struct macro *ma_next;
67
struct line *ma_contents;
74
static struct macro *macros[MAPRIME];
75
static struct macro *accounts[MAPRIME];
77
#define mahash(cp) (pjw(cp) % MAPRIME)
78
static void undef1(const char *name, struct macro **table);
79
static int maexec(struct macro *mp);
80
static int closingangle(const char *cp);
81
static struct macro *malook(const char *name, struct macro *data,
82
struct macro **table);
83
static void freelines(struct line *lp);
84
static void list0(FILE *fp, struct line *lp);
85
static int list1(FILE *fp, struct macro **table);
92
if (args[0] == NULL) {
93
fprintf(stderr, "Missing macro name to define.\n");
96
if (args[1] == NULL || strcmp(args[1], "{") || args[2] != NULL) {
97
fprintf(stderr, "Syntax is: define <name> {\n");
100
return define1(args[0], 0);
104
define1(const char *name, int account)
107
struct line *lp, *lst = NULL, *lnd = NULL;
108
char *linebuf = NULL;
111
mp = scalloc(1, sizeof *mp);
112
mp->ma_name = sstrdup(name);
114
mp->ma_flags |= MA_ACCOUNT;
118
n = readline_restart(input, &linebuf, &linesize, n);
121
if (n == 0 || linebuf[n-1] != '\\')
126
fprintf(stderr, "Unterminated %s definition: \"%s\".\n",
127
account ? "account" : "macro",
135
if (closingangle(linebuf))
137
lp = scalloc(1, sizeof *lp);
138
lp->l_linesize = n+1;
139
lp->l_line = smalloc(lp->l_linesize);
140
memcpy(lp->l_line, linebuf, lp->l_linesize);
141
lp->l_line[n] = '\0';
148
mp->ma_contents = lst;
149
if (malook(mp->ma_name, mp, account ? accounts : macros) != NULL) {
152
"A macro named \"%s\" already exists.\n",
154
freelines(mp->ma_contents);
159
undef1(mp->ma_name, accounts);
160
malook(mp->ma_name, mp, accounts);
171
fprintf(stderr, "Missing macro name to undef.\n");
175
undef1(*args, macros);
181
undef1(const char *name, struct macro **table)
185
if ((mp = malook(name, NULL, table)) != NULL) {
186
freelines(mp->ma_contents);
198
if (args[0] == NULL || args[1] != NULL && args[2] != NULL) {
199
fprintf(stderr, "Syntax is: call <name>\n");
202
if ((mp = malook(*args, NULL, macros)) == NULL) {
203
fprintf(stderr, "Undefined macro called: \"%s\"\n", *args);
210
callaccount(const char *name)
214
if ((mp = malook(name, NULL, accounts)) == NULL)
220
callhook(const char *name, int newmail)
226
var = ac_alloc(len = strlen(name) + 13);
227
snprintf(var, len, "folder-hook-%s", name);
228
if ((cp = value(var)) == NULL && (cp = value("folder-hook")) == NULL)
230
if ((mp = malook(cp, NULL, macros)) == NULL) {
231
fprintf(stderr, "Cannot call hook for folder \"%s\": "
232
"Macro \"%s\" does not exist.\n",
236
inhook = newmail ? 3 : 1;
243
maexec(struct macro *mp)
250
unset_allow_undefined = 1;
251
for (lp = mp->ma_contents; lp; lp = lp->l_next) {
253
while (sp < &lp->l_line[lp->l_linesize] &&
254
(blankchar(*sp&0377) || *sp == '\n' ||
257
if (sp == &lp->l_line[lp->l_linesize])
259
cp = copy = smalloc(lp->l_linesize + (lp->l_line - sp));
261
*cp++ = *sp != '\n' ? *sp : ' ';
262
while (++sp < &lp->l_line[lp->l_linesize]);
263
r = execute(copy, 0, lp->l_linesize);
266
unset_allow_undefined = 0;
271
closingangle(const char *cp)
273
while (spacechar(*cp&0377))
277
while (spacechar(*cp&0377))
282
static struct macro *
283
malook(const char *name, struct macro *data, struct macro **table)
288
mp = table[h = mahash(name)];
290
if (mp->ma_name && strcmp(mp->ma_name, name) == 0)
297
data->ma_next = table[h];
304
freelines(struct line *lp)
306
struct line *lq = NULL;
318
listaccounts(FILE *fp)
320
return list1(fp, accounts);
324
list0(FILE *fp, struct line *lp)
329
for (sp = lp->l_line; sp < &lp->l_line[lp->l_linesize]; sp++) {
330
if ((c = *sp&0377) != '\0') {
331
if ((c = *sp&0377) == '\n')
340
list1(FILE *fp, struct macro **table)
342
struct macro **mp, *mq;
346
for (mp = table; mp < &table[MAPRIME]; mp++)
347
for (mq = *mp; mq; mq = mq->ma_next)
351
fprintf(fp, "%s %s {\n",
353
"account" : "define",
355
for (lp = mq->ma_contents; lp; lp = lp->l_next)
370
if ((fp = Ftemp(&cp, "Ra", "w+", 0600, 1)) == NULL) {
376
mc = list1(fp, macros);
384
delaccount(const char *name)
386
undef1(name, accounts);