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
)
83 sbuf_chr(sb
, (unsigned char) *e
);
84 if (*e
== '\\' && e
[1])
90 snprintf(kwd
, sizeof(kwd
), "%s", sbuf_buf(sb
));
91 if (regcomp(&re
, kwd
, REG_EXTENDED
| REG_ICASE
))
95 if (kwd
[0] == '^' && isalpha((unsigned char) (kwd
[1])) &&
97 int len
= strchr(kwd
, ':') - kwd
;
98 memcpy(kwd_hdr
, kwd
+ 1, len
);
101 strcpy(kwd_hdr
, "subject:");
106 static int ex_match(int i
)
113 if (i
< 0 || i
>= mbox_len(mbox
))
115 mbox_get(mbox
, i
, &msg
, &msglen
);
116 hdr
= msg_get(msg
, msglen
, kwd_hdr
);
119 len
= hdrlen(hdr
, msg
+ msglen
- hdr
);
120 buf
= malloc(len
+ 1);
121 memcpy(buf
, hdr
, len
);
123 ret
= regexec(&kwd_re
, buf
, 0, NULL
, 0);
128 static int ex_search(char *pat
)
130 int dir
= *pat
== '/' ? +1 : -1;
134 while (i
>= 0 && i
< mbox_len(mbox
)) {
142 static int ex_lineno(char *num
)
145 if (!num
[0] || num
[0] == '.')
150 n
= mbox_len(mbox
) - 1;
152 n
= pos
- (num
[1] ? ex_lineno(num
+ 1) : 1);
154 n
= pos
+ (num
[1] ? ex_lineno(num
+ 1) : 1);
155 if (num
[0] == '/' && num
[1])
157 if (num
[0] == '?' && num
[1])
162 static int ex_region(char *loc
, int *beg
, int *end
)
166 *end
= mbox_len(mbox
);
169 if (!*loc
|| loc
[0] == ';') {
171 *end
= pos
== mbox_len(mbox
) ? pos
: pos
+ 1;
174 *beg
= ex_lineno(loc
);
175 while (*loc
&& *loc
!= ',' && *loc
!= ';')
178 *end
= ex_lineno(++loc
);
180 *end
= *beg
== mbox_len(mbox
) ? *beg
: *beg
+ 1;
181 if (*beg
< 0 || *beg
>= mbox_len(mbox
))
183 if (*end
< *beg
|| *end
> mbox_len(mbox
))
188 static int ec_rm(char *arg
)
190 mbox_set(mbox
, pos
, "", 0);
194 static int ec_cp(char *arg
)
200 arg
= ex_arg(arg
, box
);
201 fd
= open(box
, O_WRONLY
| O_APPEND
| O_CREAT
, S_IRUSR
| S_IWUSR
);
202 mbox_get(mbox
, pos
, &msg
, &msz
);
203 xwrite(fd
, msg
, msz
);
208 static int ec_mv(char *arg
)
215 static int ec_hd(char *arg
)
221 struct sbuf
*sb
= sbuf_make();
222 arg
= ex_arg(arg
, hdr
);
223 arg
= ex_arg(arg
, val
);
224 mbox_get(mbox
, pos
, &msg
, &msglen
);
225 sbuf_printf(sb
, "%s %s\n", hdr
, val
);
226 if (msg_set(msg
, msglen
, &mod
, &modlen
, hdr
, sbuf_buf(sb
)))
229 mbox_set(mbox
, pos
, mod
, modlen
);
234 static int ec_ft(char *arg
)
238 mbox_get(mbox
, pos
, &msg
, &msglen
);
239 if (xpipe(arg
, msg
, msglen
, &mod
, &modlen
))
241 mbox_set(mbox
, pos
, mod
, modlen
);
246 static int ec_wr(char *arg
)
249 arg
= ex_arg(arg
, box
);
251 mbox_copy(mbox
, box
);
257 static int ex_exec(char *ec
);
259 static int ec_g(char *arg
)
261 while (isspace((unsigned char) *arg
))
263 if (arg
[0] != '/' || ex_keyword(arg
))
266 while (arg
[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 char 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
!= ';')