Mercurial > noffle
comparison src/protocol.c @ 43:2842f50feb55 noffle
[svn] * client.c, client.h, common.h, config.c, config.h, content.c, content.h,
control.c, control.h, database.c, database.h, dynamicstring.c,
dynamicstring.h, fetch.c, fetch.h, fetchlist.c, fetchlist.h, group.c,
group.h, itemlist.c, itemlist.h, lock.c, lock.h, log.c, log.h, noffle.c,
online.c, online.h, outgoing.c, outgoing.h, over.c, over.h, post.c, post.h,
protocol.c, protocol.h, pseudo.c, pseudo.h, request.c, request.h, server.c,
server.h, util.c, util.h, wildmat.c, wildmat.h: Moved files to the
subdirectory src/
* Makefile.am, acconfig.h, configure.in, docs/Makefile.am, src/Makefile.am,
Makefile.in, aclocal.m4, config.h.in, configure, install-sh, missing,
mkinstalldirs, stamp-h.in, docs/Makefile.in, src/Makefile.in: Added files.
They are used by aclocal, autoheader, autoconf and automake.
* src/config.c, src/config.h: Renamed to configfile.c and configfile.h,
because configure will generate a config.h file itself.
* src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c,
src/group.c, src/lock.c, src/noffle.c, src/online.c, src/outgoing.c,
src/over.c, src/pseudo.c, src/request.c, src/server.c, src/util.c:
Changed '#include "config.h"' to '#include "configfile.h"'.
* src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c,
src/group.c, src/lock.c, src/online.c, src/outgoing.c, src/post.c,
src/protocol.c, src/request.c, src/server.c: Files now #include <config.h>.
Added missing <stdio.h>. This removes the warnings about snprintf() not
being declared.
* Makefile: Removed. This is now generated by configure.
author | uh1763 |
---|---|
date | Fri, 05 May 2000 22:45:56 +0100 |
parents | |
children | 32ba1198c6fa |
comparison
equal
deleted
inserted
replaced
42:2467ff423c15 | 43:2842f50feb55 |
---|---|
1 /* | |
2 protocol.c | |
3 | |
4 $Id: protocol.c 49 2000-05-05 21:45:56Z uh1763 $ | |
5 */ | |
6 | |
7 #if HAVE_CONFIG_H | |
8 #include <config.h> | |
9 #endif | |
10 | |
11 #include <stdio.h> | |
12 #include <ctype.h> | |
13 #include <netdb.h> | |
14 #include <sys/types.h> | |
15 #include <sys/utsname.h> | |
16 #include "common.h" | |
17 #include "dynamicstring.h" | |
18 #include "log.h" | |
19 #include "over.h" | |
20 #include "util.h" | |
21 | |
22 Bool | |
23 Prt_getLn( Str line, FILE *f ) | |
24 { | |
25 size_t len; | |
26 | |
27 /* | |
28 We also accept lines ending with "\n" instead of "\r\n", some | |
29 clients wrongly send such lines. | |
30 */ | |
31 if ( ! fgets( line, MAXCHAR, f ) ) | |
32 { | |
33 Log_dbg( "Prt_getLine failed" ); | |
34 return FALSE; | |
35 } | |
36 len = strlen( line ); | |
37 if ( line[ len - 1 ] == '\n' ) | |
38 { | |
39 line[ len - 1 ] = '\0'; | |
40 if ( line[ len - 2 ] == '\r' ) | |
41 line[ len - 2 ] = '\0'; | |
42 } | |
43 Log_dbg( "[R] %s", line ); | |
44 return TRUE; | |
45 } | |
46 | |
47 Bool | |
48 Prt_getTxtLn( Str line, Bool *err, FILE *f ) | |
49 { | |
50 Str buf; | |
51 | |
52 if ( ! Prt_getLn( buf, f ) ) | |
53 { | |
54 Log_err( "Cannot get text line" ); | |
55 *err = TRUE; | |
56 return FALSE; | |
57 } | |
58 *err = FALSE; | |
59 if ( buf[ 0 ] == '.' ) | |
60 { | |
61 if ( buf[ 1 ] == 0 ) | |
62 return FALSE; | |
63 else | |
64 strcpy( line, buf + 1 ); | |
65 } | |
66 else | |
67 strcpy( line, buf ); | |
68 return TRUE; | |
69 } | |
70 | |
71 Bool | |
72 Prt_putTxtLn( const char* line, FILE *f ) | |
73 { | |
74 if ( line[ 0 ] == '.' ) | |
75 { | |
76 Log_dbg( "[S] .%s", line ); | |
77 return ( fprintf( f, ".%s\r\n", line ) == strlen( line ) + 3 ); | |
78 } | |
79 else | |
80 { | |
81 Log_dbg( "[S] %s", line ); | |
82 return ( fprintf( f, "%s\r\n", line ) == strlen( line ) + 2 ); | |
83 } | |
84 } | |
85 | |
86 Bool | |
87 Prt_putEndOfTxt( FILE *f ) | |
88 { | |
89 Log_dbg( "[S] ." ); | |
90 return ( fprintf( f, ".\r\n" ) == 3 ); | |
91 } | |
92 | |
93 /* | |
94 Write text buffer of lines each ending with '\n'. | |
95 Replace '\n' by "\r\n". | |
96 */ | |
97 Bool | |
98 Prt_putTxtBuf( const char *buf, FILE *f ) | |
99 { | |
100 Str line; | |
101 const char *pBuf; | |
102 char *pLn; | |
103 | |
104 pBuf = buf; | |
105 pLn = line; | |
106 while ( *pBuf != '\0' ) | |
107 { | |
108 if ( *pBuf == '\n' ) | |
109 { | |
110 *pLn = '\0'; | |
111 if ( ! Prt_putTxtLn( line, f ) ) | |
112 return FALSE; | |
113 pLn = line; | |
114 ++pBuf; | |
115 } | |
116 else if ( pLn - line >= MAXCHAR - 1 ) | |
117 { | |
118 /* Put it out raw to prevent String overflow */ | |
119 Log_err( "Writing VERY long line" ); | |
120 *pLn = '\0'; | |
121 if ( fprintf( f, "%s", line ) != strlen( line ) ) | |
122 return FALSE; | |
123 pLn = line; | |
124 } | |
125 else | |
126 *(pLn++) = *(pBuf++); | |
127 } | |
128 return TRUE; | |
129 } | |
130 | |
131 Bool | |
132 Prt_getField( Str resultField, Str resultValue, const char* line ) | |
133 { | |
134 char *dst; | |
135 const char *p; | |
136 Str lineLower, t; | |
137 | |
138 Utl_cpyStr( lineLower, line ); | |
139 Utl_toLower( lineLower ); | |
140 p = Utl_stripWhiteSpace( lineLower ); | |
141 dst = resultField; | |
142 while ( ! isspace( *p ) && *p != ':' && *p != '\0' ) | |
143 *(dst++) = *(p++); | |
144 *dst = '\0'; | |
145 while ( isspace( *p ) ) | |
146 ++p; | |
147 if ( *p == ':' ) | |
148 { | |
149 ++p; | |
150 strcpy( t, line + ( p - lineLower ) ); | |
151 p = Utl_stripWhiteSpace( t ); | |
152 strcpy( resultValue, p ); | |
153 return TRUE; | |
154 } | |
155 return FALSE; | |
156 } | |
157 | |
158 Bool | |
159 Prt_searchHeader( const char *artTxt, const char *which, Str result ) | |
160 { | |
161 const char *src, *p; | |
162 char *dst; | |
163 Str line, whichLower, field; | |
164 int len; | |
165 | |
166 Utl_cpyStr( whichLower, which ); | |
167 Utl_toLower( whichLower ); | |
168 src = artTxt; | |
169 while ( TRUE ) | |
170 { | |
171 dst = line; | |
172 len = 0; | |
173 while ( *src != '\n' && len < MAXCHAR ) | |
174 { | |
175 if ( *src == '\0' ) | |
176 return FALSE; | |
177 *(dst++) = *(src++); | |
178 ++len; | |
179 } | |
180 if ( *src == '\n' ) | |
181 ++src; | |
182 *dst = '\0'; | |
183 p = Utl_stripWhiteSpace( line ); | |
184 if ( *p == '\0' ) | |
185 break; | |
186 if ( Prt_getField( field, result, line ) | |
187 && strcmp( field, whichLower ) == 0 ) | |
188 return TRUE; | |
189 } | |
190 return FALSE; | |
191 } | |
192 | |
193 static Bool | |
194 getFQDN( Str result ) | |
195 { | |
196 struct hostent *myHostEnt; | |
197 struct utsname myName; | |
198 | |
199 if ( uname( &myName ) >= 0 | |
200 && ( myHostEnt = gethostbyname( myName.nodename ) ) ) | |
201 { | |
202 Utl_cpyStr( result, myHostEnt->h_name ); | |
203 return TRUE; | |
204 } | |
205 return FALSE; | |
206 } | |
207 | |
208 static void | |
209 getDomain( Str domain, const char *from ) | |
210 { | |
211 const char *addTopLevel, *p1, *p2, *p, *domainStart; | |
212 Str myDomain; | |
213 | |
214 if ( getFQDN( myDomain ) ) | |
215 { | |
216 p = strstr( myDomain, "." ); | |
217 if ( p != NULL ) | |
218 domainStart = p + 1; | |
219 else | |
220 domainStart = myDomain; | |
221 } | |
222 else /* Take domain of From field */ | |
223 { | |
224 myDomain[ 0 ] = '\0'; | |
225 p1 = strstr( from, "@" ); | |
226 if ( p1 != NULL ) | |
227 { | |
228 p2 = strstr( p1, ">" ); | |
229 if ( p2 != NULL ) | |
230 Utl_cpyStrN( myDomain, p1 + 1, p2 - p1 - 1 ); | |
231 } | |
232 if ( myDomain[ 0 ] == '\0' ) | |
233 Utl_cpyStr( myDomain, "unknown" ); | |
234 domainStart = myDomain; | |
235 } | |
236 /* | |
237 If domain contains no dot (and is probably invalid anyway), | |
238 we add ".local", because some servers insist on domainnames with dot | |
239 in message ID. | |
240 */ | |
241 addTopLevel = strstr( domainStart, "." ) == NULL ? ".local" : ""; | |
242 snprintf( domain, MAXCHAR, "%s%s", myDomain, addTopLevel ); | |
243 } | |
244 | |
245 /* See RFC 850, section 2.1.7 */ | |
246 Bool | |
247 Prt_isValidMsgId( const char *msgId ) | |
248 { | |
249 Str head, domain; | |
250 int len, headLen; | |
251 const char *p; | |
252 | |
253 len = strlen( msgId ); | |
254 p = strstr( msgId, "@" ); | |
255 if ( msgId[ 0 ] != '<' || msgId[ len - 1 ] != '>' || p == NULL ) | |
256 return FALSE; | |
257 strcpy( domain, p + 1 ); | |
258 domain[ strlen( domain ) - 1 ] = '\0'; | |
259 headLen = p - msgId - 1; | |
260 Utl_cpyStrN( head, msgId + 1, headLen ); | |
261 head[ headLen ] = '\0'; | |
262 /* | |
263 To do: check for special characters in head and domain (non-printable | |
264 or '@', '<', '>'). Maybe compare domain with a config option | |
265 and replace it by the config option, if not equal. | |
266 */ | |
267 if ( strstr( domain, "." ) == NULL ) | |
268 return FALSE; | |
269 return TRUE; | |
270 } | |
271 | |
272 void | |
273 Prt_genMsgId( Str msgId, const char *from, const char *suffix ) | |
274 { | |
275 Str domain, date; | |
276 time_t t; | |
277 | |
278 getDomain( domain, from ); | |
279 time( &t ); | |
280 strftime( date, MAXCHAR, "%Y%m%d%H%M%S", gmtime( &t ) ); | |
281 srand( time( NULL ) ); | |
282 snprintf( msgId, MAXCHAR, "<%s.%X.%s@%s>", date, rand(), suffix, domain ); | |
283 ASSERT( Prt_isValidMsgId( msgId ) ); | |
284 } |