Hello again,
[email protected] wrote:
|*** Steffen Nurpmeso <[email protected]> [Sat, 16 Jan 2016 21:51:31 +0100]:
|>.Looking into that i see that mutt for example offers
|>a my_hdr/unmy_hdr command pair. That we can have, too, and i'll
|>do it for you as soon as possible, let's say as `(un)?customhdr'.
|>However, being able to edit this in compose mode, just as mutt
|>seems to allow via edit_headers, i don't think that this will be
|>possible for v14.9, it will require v15.0 infrastructure (i'm
|>still hoping i get there). I get back to you with that.
|
|Yeah, exactly that I understand as you said. my_hdr analogue will be
|great! edit_headers analogue is not so important, in my opinion. I used
|Mutt for many years and most cases of edit_headers can be replaced by
|not so convenient, but seldom my_hdr temporary setting. In Mutt this is
|rather painful, but localopts feature in s-nail is very handy there!
So i've implemented something, it is on the [next] branch, but
please find attached a version that can be patched onto the
[master] where you are at (should also do for v14.8.6), but note
it misses the manual entry.
We now have `customhdr' / `uncustomhdr' as in
? cus X-Disclaimer "things i say"
? cus X-Something Just one example how things work
? cus
? uncus*
But since v14.9 will not have copy-on-write environments i've also
added an undocumented *customhdr* variable for you, that can be
set to a comma-separated list of headers:
$ echo bla|./s-nail -Scustomhdr='Once: yes, Again: works' -ds test
...
s-nail: >>> Subject: test
s-nail: >>> User-Agent: s-nail v14.8.6-151-g0c3eeb8-dirty
s-nail: >>> Once: yes
s-nail: >>> Again: works
Note that _no_ syntax or validity checks are performed, for none
of the above. And unfortunately commas cannot be escaped -- v15
will break backward compatibility in order to be able to do so,
also we will likely support expansions in the right hand side of
value assignments, therefore breaking even more existing
configurations: maybe S-nail will even be renamed to accomplish
this. Well.
Hope you like it, have fun and
Ciao!
--steffen
diff --git a/cmd_tab.h b/cmd_tab.h
index b738df7..c13253f 100644
--- a/cmd_tab.h
+++ b/cmd_tab.h
@@ -57,7 +57,7 @@
{ "next", &c_next, (A | NDMLIST), 0, MMNDEL
DS(N_("Goes to the next message (-list) and prints it")) },
{ "alias", &c_alias, (M | RAWLIST), 0, 1000
- DS(N_("Show all or the specified <alias>(es), or (re)define one")) },
+ DS(N_("Show all/<alias>, or (re)define <alias> to <:data:>")) },
{ "print", &c_type, (A | MSGLIST), 0, MMNDEL
DS(N_("Type each message of <message-list> on the terminal")) },
{ "type", &c_type, (A | MSGLIST), 0, MMNDEL
@@ -384,6 +384,10 @@
DS(N_("Mailing-list reply to the given message")) },
{ "errors", &c_errors, (H | I | RAWLIST), 0, 1
DS(N_("Either <show> (default) or <clear> the error message ring")) },
+ { "customhdr", &c_customhdr, (M | RAWLIST), 0, 1000
+ DS(N_("Show all/<header>, or (re)define a custom <header> to <:data:>")) },
+ { "uncustomhdr", &c_uncustomhdr, (M | RAWLIST), 1, 1000
+ DS(N_("Delete custom <:header:> (\"*\" for all)")) },
{ "features", &_c_features, (H | M | NOLIST), 0, 0
DS(N_("Show features that are compiled into the MUA")) },
{ "version", &_c_version, (H | M | NOLIST), 0, 0
diff --git a/nail.h b/nail.h
index fa4ed64..6746d4b 100644
--- a/nail.h
+++ b/nail.h
@@ -417,11 +417,13 @@
#if defined __STDC_VERSION__ && __STDC_VERSION__ + 0 >= 199901L
# define VFIELD_SIZE(X)
# define VFIELD_SIZEOF(T,F) (0)
+# define VSTRUCT_SIZEOF(T,F) sizeof(T)
#else
# define VFIELD_SIZE(X) \
((X) == 0 ? sizeof(size_t) \
: ((ssize_t)(X) < 0 ? sizeof(size_t) - ABS(X) : (size_t)(X)))
# define VFIELD_SIZEOF(T,F) SIZEOF_FIELD(T, F)
+# define VSTRUCT_SIZEOF(T,F) (sizeof(T) - SIZEOF_FIELD(T, F))
#endif
#if defined __STDC_VERSION__ && __STDC_VERSION__ + 0 >= 199901L
@@ -1354,6 +1404,12 @@ struct str {
size_t l; /* the stings's length */
};
+struct strlist{
+ struct strlist *sl_next;
+ size_t sl_len;
+ char sl_dat[VFIELD_SIZE(0)];
+};
+
struct colour_table {
/* Plus a copy of *colour-user-headers* */
struct str ct_csinfo[COLOURSPEC_RESET+1 + 1];
diff --git a/nailfuns.h b/nailfuns.h
index 50acbe8..7de0000 100644
--- a/nailfuns.h
+++ b/nailfuns.h
@@ -1477,6 +1477,13 @@ FL int c_unshortcut(void *v);
FL char const * shortcut_expand(char const *str);
+/* `(un)?customhdr'.
+ * Query a list of all currently defined custom headers (salloc()ed) */
+FL int c_customhdr(void *v);
+FL int c_uncustomhdr(void *v);
+
+FL struct strlist * n_customhdr_get(void);
+
/*
* openssl.c
*/
diff --git a/nam_a_grp.c b/nam_a_grp.c
index 5090a7a..367f7fd 100644
--- a/nam_a_grp.c
+++ b/nam_a_grp.c
@@ -44,7 +44,8 @@ enum group_type {
GT_ALIAS = 1<< 0,
GT_MLIST = 1<< 1,
GT_SHORTCUT = 1<< 2,
- GT_MASK = GT_ALIAS | GT_MLIST | GT_SHORTCUT,
+ GT_CUSTOMHDR = 1<< 3,
+ GT_MASK = GT_ALIAS | GT_MLIST | GT_SHORTCUT | GT_CUSTOMHDR,
/* Subtype bits and flags */
GT_SUBSCRIBE = 1<< 4,
@@ -123,6 +124,9 @@ static size_t _mlist_size, _mlist_hits, _mlsub_size, _mlsub_hits;
/* `shortcut' */
static struct group *_shortcut_heads[HSHSIZE]; /* TODO dynamic hash */
+/* `customhdr' */
+static struct group *_customhdr_heads[HSHSIZE]; /* TODO dynamic hash */
+
/* Same name, while taking care for *allnet*? */
static bool_t _same_name(char const *n1, char const *n2);
@@ -417,7 +421,8 @@ _group_lookup(enum group_type gt, struct group_lookup *glp, char const *id)
lgp = NULL;
gp = *(glp->gl_htable = glp->gl_slot =
((gt & GT_ALIAS ? _alias_heads :
- (gt & GT_MLIST ? _mlist_heads : _shortcut_heads)) +
+ (gt & GT_MLIST ? _mlist_heads :
+ (gt & GT_SHORTCUT ? _shortcut_heads : _customhdr_heads))) +
torek_hash(id) % HSHSIZE));
for (; gp != NULL; lgp = gp, gp = gp->g_next)
@@ -450,7 +455,8 @@ _group_go_first(enum group_type gt, struct group_lookup *glp)
NYD_ENTER;
for (glp->gl_htable = gpa = (gt & GT_ALIAS ? _alias_heads :
- (gt & GT_MLIST ? _mlist_heads : _shortcut_heads)), i = 0;
+ (gt & GT_MLIST ? _mlist_heads :
+ (gt & GT_SHORTCUT ? _shortcut_heads : _customhdr_heads))), i = 0;
i < HSHSIZE; ++gpa, ++i)
if ((gp = *gpa) != NULL) {
glp->gl_slot = gpa;
@@ -640,7 +646,8 @@ _group_print_all(enum group_type gt)
xgt = gt & GT_PRINT_MASK;
gpa = (xgt & GT_ALIAS ? _alias_heads
- : (xgt & GT_MLIST ? _mlist_heads : _shortcut_heads));
+ : (xgt & GT_MLIST ? _mlist_heads
+ : (xgt & GT_SHORTCUT ? _shortcut_heads : _customhdr_heads)));
for (h = 0, i = 1; h < HSHSIZE; ++h)
for (gp = gpa[h]; gp != NULL; gp = gp->g_next)
@@ -743,6 +750,10 @@ _group_print(struct group const *gp, FILE *fo)
char const *cp;
GP_TO_SUBCLASS(cp, gp);
fprintf(fo, "shortcut %s \"%s\"", gp->g_id, string_quote(cp));
+ } else if (gp->g_type & GT_CUSTOMHDR) {
+ char const *cp;
+ GP_TO_SUBCLASS(cp, gp);
+ fprintf(fo, "customhdr %s \"%s\"", gp->g_id, string_quote(cp));
}
putc('\n', fo);
@@ -1691,4 +1702,120 @@ shortcut_expand(char const *str)
return str;
}
+FL int
+c_customhdr(void *v){
+ struct group *gp;
+ char const **argv, *hcp;
+ int rv;
+ NYD_ENTER;
+
+ rv = 0;
+
+ if((hcp = *(argv = v)) == NULL)
+ _group_print_all(GT_CUSTOMHDR);
+ else if(*++argv == NULL){
+ if((gp = _group_find(GT_CUSTOMHDR, hcp)) != NULL)
+ _group_print(gp, stdout);
+ else{
+ n_err(_("No such custom header: \"%s\"\n"), hcp);
+ rv = 1;
+ }
+ }else{
+ /* Because one hardly ever redefines, anything is stored in one chunk */
+ size_t i, l;
+ char *cp;
+
+ if(_group_find(GT_CUSTOMHDR, hcp) != NULL)
+ _group_del(GT_CUSTOMHDR, hcp);
+
+ for(l = i = 0; argv[i] != NULL; ++i)
+ l += strlen(argv[i]) + 1;
+ gp = _group_fetch(GT_CUSTOMHDR, hcp, l +1);
+ GP_TO_SUBCLASS(cp, gp);
+ for(i = 0; argv[i] != NULL; ++i){
+ l = strlen(argv[i]);
+ memcpy(cp, argv[i], l);
+ cp[l] = ' ';
+ cp += l;
+ }
+ *cp = '\0';
+ }
+ NYD_LEAVE;
+ return rv;
+}
+
+FL int
+c_uncustomhdr(void *v){
+ int rv;
+ char **argv;
+ NYD_ENTER;
+
+ rv = 0;
+
+ argv = v;
+ do{
+ if(!_group_del(GT_CUSTOMHDR, *argv)){
+ n_err(_("No such custom header: \"%s\"\n"), *argv);
+ rv = 1;
+ }
+ }while(*++argv != NULL);
+ NYD_LEAVE;
+ return rv;
+}
+
+FL struct strlist *
+n_customhdr_get(void){ /* XXX Uses salloc()! */
+ struct group const *gp;
+ ui32_t h;
+ struct strlist *thead, **tpp;
+ NYD_ENTER;
+
+ thead = NULL;
+ tpp = &thead;
+
+ for(h = 0; h < HSHSIZE; ++h)
+ for(gp = _customhdr_heads[h]; gp != NULL; gp = gp->g_next){
+ char *dp;
+ struct strlist *np;
+ size_t hl, dl, cl;
+ char const *cp;
+
+ GP_TO_SUBCLASS(cp, gp);
+ hl = strlen(gp->g_id);
+ dl = strlen(cp);
+ cl = hl + 2 + dl;
+ *tpp = np = salloc(VSTRUCT_SIZEOF(struct strlist, sl_dat) + cl +1);
+ tpp = &np->sl_next;
+ np->sl_next = NULL;
+ np->sl_len = cl;
+ dp = np->sl_dat;
+ memcpy(dp, gp->g_id, hl);
+ dp[hl++] = ':';
+ dp[hl++] = ' ';
+ dp += hl;
+ memcpy(dp, cp, dl +1);
+ }
+
+ {
+ char const *vp = vok_vlook("customhdr"); /* TODO v15-compat,undoc,drop! */
+
+ if(vp != NULL){
+ char *buf;
+
+ for (buf = savestr(vp); (vp = n_strsep(&buf, ',', TRU1)) != NULL;) {
+ struct strlist *np;
+
+ h = (ui32_t)strlen(vp) +1;
+ *tpp = np = salloc(VSTRUCT_SIZEOF(struct strlist, sl_dat) + h);
+ tpp = &np->sl_next;
+ np->sl_next = NULL;
+ np->sl_len = h - 1;
+ memcpy(np->sl_dat, vp, h);
+ }
+ }
+ }
+ NYD_LEAVE;
+ return thead;
+}
+
/* s-it-mode */
diff --git a/sendout.c b/sendout.c
index 6abe2d9..2023f90 100644
--- a/sendout.c
+++ b/sendout.c
@@ -2105,6 +2105,19 @@ j_mft_add:
if ((w & GUA) && stealthmua == 0)
fprintf(fo, "User-Agent: %s %s\n", uagent, ok_vlook(version)), ++gotcha;
+ if(gen_message){
+ struct strlist *slp = n_customhdr_get();
+
+ for(; slp != NULL; slp = slp->sl_next){
+ if(xmime_write(slp->sl_dat, slp->sl_len, fo,
+ (!nodisp ? CONV_NONE : CONV_TOHDR),
+ (!nodisp ? TD_ISPR | TD_ICONV : TD_ICONV)) < 0 ||
+ putc('\n', fo) == EOF)
+ goto jleave;
+ ++gotcha;
+ }
+ }
+
/* We don't need MIME unless.. we need MIME?! */
if ((w & GMIME) && ((pstate & PS_HEADER_NEEDED_MIME) ||
hp->h_attach != NULL || convert != CONV_7BIT ||
------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
S-nail-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/s-nail-users