1 #if !defined(lint) && !defined(DOS)
2 static char rcsid
[] = "$Id: maillist.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2017 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
20 * * * * * * * * * RFC 2369 support routines * * * * * * * *
24 #include "../pith/headers.h"
25 #include "../pith/maillist.h"
26 #include "../pith/state.h"
27 #include "../pith/url.h"
33 int rfc2369_parse(char *, RFC2369_S
*);
36 * * NOTE * These have to remain in sync with the MLCMD_* macros
37 * in maillist.h. Sorry.
39 static RFC2369FIELD_S rfc2369_fields
[] = {
41 "get information about the list and instructions on how to join",
44 "remove yourself from the list (Unsubscribe)",
47 "add yourself to the list (Subscribe)",
50 "send a message to the entire list (Post)",
53 "send a message to the list owner",
54 "contact the list owner"},
56 "view archive of messages sent to the list",
62 rfc2369_hdrs(char **hdrs
)
66 for(i
= 0; i
< MLCMD_COUNT
; i
++)
67 hdrs
[i
] = rfc2369_fields
[i
].name
;
75 rfc2369_parse_fields(char *h
, RFC2369_S
*data
)
80 for(i
= 0; i
< MLCMD_COUNT
; i
++)
81 data
[i
].field
= rfc2369_fields
[i
];
83 for(nhp
= h
; h
; h
= nhp
){
84 /* coerce h to start of field */
86 if((tp
= strpbrk(ep
, "\015\012")) != NULL
){
87 if(strindex(" \t", *((ep
= tp
) + 2))){
88 *ep
++ = ' '; /* flatten continuation */
90 for(; *ep
; ep
++) /* advance past whitespace */
97 *ep
= '\0'; /* tie off header data */
98 nhp
= ep
+ 2; /* start of next header */
103 while(*ep
) /* find the end of this line */
106 nhp
= NULL
; /* no more header fields */
110 /* if length is within reason, see if we're interested */
111 if(ep
- h
< MLCMD_REASON
&& rfc2369_parse(h
, data
))
120 rfc2369_parse(char *h
, RFC2369_S
*data
)
122 int l
, ifield
, idata
= 0;
123 char *p
, *p1
, *url
, *comment
;
125 /* look for interesting name's */
126 for(ifield
= 0; ifield
< MLCMD_COUNT
; ifield
++)
127 if(!struncmp(h
, rfc2369_fields
[ifield
].name
,
128 l
= strlen(rfc2369_fields
[ifield
].name
))
129 && *(h
+= l
) == ':'){
130 /* unwrap any transport encodings */
131 if((p
= (char *) rfc1522_decode_to_utf8((unsigned char *) tmp_20k_buf
,
132 SIZEOF_20KBUF
, ++h
)) == tmp_20k_buf
)
133 strcpy(h
, p
); /* assumption #383: decoding shrinks */
135 url
= comment
= NULL
;
142 if((p
= strindex(h
, '>')) != NULL
){
143 url
= ++h
; /* remember where it starts */
144 *p
= '\0'; /* tie it off */
145 h
= p
+ 1; /* advance h */
146 for(p
= p1
= url
; (*p1
= *p
) != '\0'; p
++)
148 p1
++; /* remove whitespace ala RFC */
151 *h
= '\0'; /* tie off junk */
155 case '(' : /* Comment */
156 comment
= rfc822_skip_comment(&h
, LONGT
);
159 case 'N' : /* special case? */
161 if(ifield
== MLCMD_POST
162 && (*(h
+1) == 'O' || *(h
+1) == 'o')
163 && (!*(h
+2) || *(h
+2) == ' ')){
173 removing_trailing_white_space(h
);
175 && (url
= rfc1738_scan(h
, &l
))
176 && url
== h
&& l
== strlen(h
)){
177 removing_trailing_white_space(h
);
178 data
[ifield
].data
[idata
].value
= url
;
181 data
[ifield
].data
[idata
].error
= h
;
183 return(1); /* return junk */
194 if(url
|| (comment
&& *comment
)){
195 data
[ifield
].data
[idata
].value
= url
;
196 data
[ifield
].data
[idata
].comment
= comment
;
197 url
= comment
= NULL
;
200 if(++idata
== MLCMD_MAXDATA
)