13 static struct mbox
*mbox
;
15 static char kwd
[EXLEN
];
16 static char kwd_hdr
[EXLEN
];
17 static regex_t kwd_re
;
19 static char *ex_loc(char *s
, char *loc
)
21 while (*s
== ':' || isspace((unsigned char) *s
))
23 while (*s
&& !isalpha((unsigned char) *s
)) {
24 if (*s
== '/' || *s
== '?') {
27 while (*s
&& *s
!= d
) {
28 if (*s
== '\\' && s
[1])
40 static char *ex_cmd(char *s
, char *cmd
)
42 while (isspace((unsigned char) *s
))
44 while (isalpha((unsigned char) *s
))
50 static char *ex_arg(char *s
, char *arg
)
52 while (isspace((unsigned char) *s
))
56 while (*s
&& *s
!= '"') {
57 if (*s
== '\\' && s
[1])
63 while (*s
&& !isspace((unsigned char) *s
)) {
64 if (*s
== '\\' && s
[1])
73 static int ex_keyword(char *pat
)
82 if (*e
== '\\' && e
[1])
84 sbuf_chr(sb
, (unsigned char) *e
);
86 if (sbuf_len(sb
) && strcmp(kwd
, sbuf_buf(sb
))) {
89 snprintf(kwd
, sizeof(kwd
), "%s", sbuf_buf(sb
));
90 if (regcomp(&kwd_re
, kwd
, REG_EXTENDED
| REG_ICASE
))
92 if (kwd
[0] == '^' && isalpha((unsigned char) (kwd
[1])) &&
94 int len
= strchr(kwd
, ':') - kwd
;
95 memcpy(kwd_hdr
, kwd
+ 1, len
);
98 strcpy(kwd_hdr
, "subject:");
105 static int ex_match(int i
)
112 if (i
< 0 || i
>= mbox_len(mbox
))
114 mbox_get(mbox
, i
, &msg
, &msglen
);
115 hdr
= msg_get(msg
, msglen
, kwd_hdr
);
118 len
= hdrlen(hdr
, msg
+ msglen
- hdr
);
119 buf
= malloc(len
+ 1);
120 memcpy(buf
, hdr
, len
);
122 ret
= regexec(&kwd_re
, buf
, 0, NULL
, 0);
127 static int ex_search(char *pat
)
129 int dir
= *pat
== '/' ? +1 : -1;
133 while (i
>= 0 && i
< mbox_len(mbox
)) {
141 static int ex_lineno(char *num
)
144 if (!num
[0] || num
[0] == '.')
149 n
= mbox_len(mbox
) - 1;
151 n
= pos
- (num
[1] ? ex_lineno(num
+ 1) : 1);
153 n
= pos
+ (num
[1] ? ex_lineno(num
+ 1) : 1);
154 if (num
[0] == '/' && num
[1])
156 if (num
[0] == '?' && num
[1])
161 static int ex_region(char *loc
, int *beg
, int *end
)
165 *end
= mbox_len(mbox
);
168 if (!*loc
|| loc
[0] == ';') {
170 *end
= pos
== mbox_len(mbox
) ? pos
: pos
+ 1;
173 *beg
= ex_lineno(loc
);
174 while (*loc
&& *loc
!= ',' && *loc
!= ';')
177 *end
= ex_lineno(++loc
) + 1;
179 *end
= *beg
== mbox_len(mbox
) ? *beg
: *beg
+ 1;
180 if (*beg
< 0 || *beg
>= mbox_len(mbox
))
182 if (*end
< *beg
|| *end
> mbox_len(mbox
))
187 static int ec_rm(char *arg
)
189 mbox_set(mbox
, pos
, "", 0);
193 static int ec_cp(char *arg
)
199 arg
= ex_arg(arg
, box
);
200 fd
= open(box
, O_WRONLY
| O_APPEND
| O_CREAT
, S_IRUSR
| S_IWUSR
);
201 mbox_get(mbox
, pos
, &msg
, &msz
);
202 xwrite(fd
, msg
, msz
);
207 static int ec_mv(char *arg
)
214 static int ec_hd(char *arg
)
220 struct sbuf
*sb
= sbuf_make();
221 arg
= ex_arg(arg
, hdr
);
222 arg
= ex_arg(arg
, val
);
223 mbox_get(mbox
, pos
, &msg
, &msglen
);
224 sbuf_printf(sb
, "%s %s\n", hdr
, val
);
225 if (msg_set(msg
, msglen
, &mod
, &modlen
, hdr
, sbuf_buf(sb
)))
228 mbox_set(mbox
, pos
, mod
, modlen
);
233 static int ec_ft(char *arg
)
237 mbox_get(mbox
, pos
, &msg
, &msglen
);
238 if (xpipe(arg
, msg
, msglen
, &mod
, &modlen
))
240 mbox_set(mbox
, pos
, mod
, modlen
);
245 static int ec_wr(char *arg
)
248 arg
= ex_arg(arg
, box
);
250 mbox_copy(mbox
, box
);
256 static int ex_exec(char *ec
);
258 static int ec_g(char *arg
)
260 while (isspace((unsigned char) *arg
))
262 if (arg
[0] != '/' || ex_keyword(arg
))
265 while (arg
[0] && arg
[0] != '/')
267 if (kwd
[0] && arg
[0] == '/') {
276 static int ex_exec(char *ec
)
279 char *arg
= ex_cmd(ec
, cmd
);
280 if (!strcmp("rm", cmd
))
282 if (!strcmp("cp", cmd
))
284 if (!strcmp("mv", cmd
))
286 if (!strcmp("hd", cmd
) || !strcmp("set", cmd
))
288 if (!strcmp("ft", cmd
) || !strcmp("filt", cmd
))
290 if (!strcmp("w", cmd
))
292 if (!strcmp("g", cmd
))
297 static int ec_stat(char *ec
)
302 int i
= atoi(ec
+ 1);
305 if (i
< 0 || i
>= mbox_len(mbox
))
308 mbox_get(mbox
, pos
, &msg
, &msglen
);
309 val
= msg_get(msg
, msglen
, "status:");
311 val
+= strlen("status:");
312 while (isspace((unsigned char) val
[0]))
315 if ((!val
&& c
== 'N') || (val
&& val
[0] == c
))
317 sprintf(newval
, "Status: %c\n", c
);
318 if (msg_set(msg
, msglen
, &mod
, &modlen
, "status:", newval
))
320 mbox_set(mbox
, pos
, mod
, modlen
);
332 printf("usage: neatmail ex mbox <cmds\n");
335 mbox
= mbox_open(argv
[0]);
337 fprintf(stderr
, "neatmail: cannot open <%s>\n", argv
[0]);
340 while (fgets(ec
, sizeof(ec
), stdin
)) {
342 if (isupper((unsigned char) ec
[0]))
346 cmd
= ex_loc(ec
, loc
);
348 if (!ex_region(cur
, &beg
, &end
)) {
349 for (i
= beg
; i
< end
; i
++) {
354 while (*cur
&& *cur
!= ';')