2 * ========================================================================
3 * Copyright 2013-2022 Eduardo Chappa
4 * Copyright 2006-2007 University of Washington
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * ========================================================================
16 * * * * * * * * * RFC 2369 support routines * * * * * * * *
20 #include "../pith/headers.h"
21 #include "../pith/maillist.h"
22 #include "../pith/state.h"
23 #include "../pith/url.h"
29 int rfc2369_parse(char *, RFC2369_S
*);
32 * * NOTE * These have to remain in sync with the MLCMD_* macros
33 * in maillist.h. Sorry.
35 static RFC2369FIELD_S rfc2369_fields
[] = {
37 "get information about the list and instructions on how to join",
40 "remove yourself from the list (Unsubscribe)",
43 "add yourself to the list (Subscribe)",
46 "send a message to the entire list (Post)",
49 "send a message to the list owner",
50 "contact the list owner"},
52 "view archive of messages sent to the list",
58 rfc2369_hdrs(char **hdrs
)
62 for(i
= 0; i
< MLCMD_COUNT
; i
++)
63 hdrs
[i
] = rfc2369_fields
[i
].name
;
71 rfc2369_parse_fields(char *h
, RFC2369_S
*data
)
76 for(i
= 0; i
< MLCMD_COUNT
; i
++)
77 data
[i
].field
= rfc2369_fields
[i
];
79 for(nhp
= h
; h
; h
= nhp
){
80 /* coerce h to start of field */
82 if((tp
= strpbrk(ep
, "\015\012")) != NULL
){
83 if(strindex(" \t", *((ep
= tp
) + 2))){
84 *ep
++ = ' '; /* flatten continuation */
86 for(; *ep
; ep
++) /* advance past whitespace */
93 *ep
= '\0'; /* tie off header data */
94 nhp
= ep
+ 2; /* start of next header */
99 while(*ep
) /* find the end of this line */
102 nhp
= NULL
; /* no more header fields */
106 /* if length is within reason, see if we're interested */
107 if(ep
- h
< MLCMD_REASON
&& rfc2369_parse(h
, data
))
116 rfc2369_parse(char *h
, RFC2369_S
*data
)
118 int l
, ifield
, idata
= 0;
119 char *p
, *p1
, *url
, *comment
;
121 /* look for interesting name's */
122 for(ifield
= 0; ifield
< MLCMD_COUNT
; ifield
++)
123 if(!struncmp(h
, rfc2369_fields
[ifield
].name
,
124 l
= strlen(rfc2369_fields
[ifield
].name
))
125 && *(h
+= l
) == ':'){
126 /* unwrap any transport encodings */
127 if((p
= (char *) rfc1522_decode_to_utf8((unsigned char *) tmp_20k_buf
,
128 SIZEOF_20KBUF
, ++h
)) == tmp_20k_buf
)
129 strcpy(h
, p
); /* assumption #383: decoding shrinks */
131 url
= comment
= NULL
;
138 if((p
= strindex(h
, '>')) != NULL
){
139 url
= ++h
; /* remember where it starts */
140 *p
= '\0'; /* tie it off */
141 h
= p
+ 1; /* advance h */
142 for(p
= p1
= url
; (*p1
= *p
) != '\0'; p
++)
144 p1
++; /* remove whitespace ala RFC */
147 *h
= '\0'; /* tie off junk */
151 case '(' : /* Comment */
152 comment
= rfc822_skip_comment(&h
, LONGT
);
155 case 'N' : /* special case? */
157 if(ifield
== MLCMD_POST
158 && (*(h
+1) == 'O' || *(h
+1) == 'o')
159 && (!*(h
+2) || *(h
+2) == ' ')){
169 removing_trailing_white_space(h
);
171 && (url
= rfc1738_scan(h
, &l
))
172 && url
== h
&& l
== strlen(h
)){
173 removing_trailing_white_space(h
);
174 data
[ifield
].data
[idata
].value
= url
;
177 data
[ifield
].data
[idata
].error
= h
;
179 return(1); /* return junk */
190 if(url
|| (comment
&& *comment
)){
191 data
[ifield
].data
[idata
].value
= url
;
192 data
[ifield
].data
[idata
].comment
= comment
;
193 url
= comment
= NULL
;
196 if(++idata
== MLCMD_MAXDATA
)