Mercurial > noffle
comparison src/post.c @ 150:1c7303c71f66 noffle
[svn] * src/protocol.c: Fix bug in Prt_getLn if we should read a line
starting with '\0' - according to the leafnode mailing list,
this has been seen in the wild.
* docs/inews.1,docs/noffle.1,docs/noffle.conf.5,
packages/redhat/noffle.spec,src/configfile.h,src/configfile.c,
src/noffle.c,src/post.h,src/post.c: Removed use of getopt_long,
and added inews mode - the Noffle executable behaves
as inews is invoked as inews. This includes adding From: and
Organization: headers if necessary - add configs to override
defaults for the From: domain and specify the organization.
For all my fellow trn-heads out there, and users of any other
ageing newsreader that expects inews. Updated RPM spec to create
inews link to noffle on install.
author | bears |
---|---|
date | Thu, 26 Oct 2000 22:21:13 +0100 |
parents | 55ba957023f9 |
children | ca9769519c96 |
comparison
equal
deleted
inserted
replaced
149:bfeea2bc09b6 | 150:1c7303c71f66 |
---|---|
1 /* | 1 /* |
2 post.c | 2 post.c |
3 | 3 |
4 $Id: post.c 202 2000-08-23 09:52:25Z enz $ | 4 $Id: post.c 227 2000-10-26 21:21:13Z bears $ |
5 */ | 5 */ |
6 | 6 |
7 #if HAVE_CONFIG_H | 7 #if HAVE_CONFIG_H |
8 #include <config.h> | 8 #include <config.h> |
9 #endif | 9 #endif |
10 | 10 |
11 #include <errno.h> | |
12 #include <pwd.h> | |
11 #include <stdio.h> | 13 #include <stdio.h> |
14 #include <sys/types.h> | |
15 #include <unistd.h> | |
12 #include "post.h" | 16 #include "post.h" |
13 #include <string.h> | 17 #include <string.h> |
14 #include "common.h" | 18 #include "common.h" |
15 #include "configfile.h" | 19 #include "configfile.h" |
16 #include "content.h" | 20 #include "content.h" |
23 #include "over.h" | 27 #include "over.h" |
24 #include "protocol.h" | 28 #include "protocol.h" |
25 #include "util.h" | 29 #include "util.h" |
26 #include "portable.h" | 30 #include "portable.h" |
27 | 31 |
32 #define BEGIN_SIG "-- " | |
33 #define SIG_FILE "/.signature" | |
34 | |
28 struct OverInfo | 35 struct OverInfo |
29 { | 36 { |
30 Str subject; | 37 Str subject; |
31 Str from; | 38 Str from; |
32 Str date; | 39 Str date; |
41 DynStr *text; /* Processed article text */ | 48 DynStr *text; /* Processed article text */ |
42 ItemList *newsgroups; /* Newsgroups for dispatch */ | 49 ItemList *newsgroups; /* Newsgroups for dispatch */ |
43 ItemList *control; /* Control message? NULL if not */ | 50 ItemList *control; /* Control message? NULL if not */ |
44 Bool approved; /* Has Approved: header? */ | 51 Bool approved; /* Has Approved: header? */ |
45 Bool posted; /* Has it been put in the article database? */ | 52 Bool posted; /* Has it been put in the article database? */ |
53 int flags; /* Posting flags */ | |
46 struct OverInfo over; | 54 struct OverInfo over; |
47 }; | 55 }; |
48 | 56 |
49 static struct Article article = { NULL, NULL, NULL, FALSE, FALSE, | 57 static struct Article article = { NULL, NULL, NULL, FALSE, FALSE, 0, |
50 { "", "", "", "", "", 0, 0 } }; | 58 { "", "", "", "", "", 0, 0 } }; |
51 | 59 |
52 /* Add the article to a group. */ | 60 /* Add the article to a group. */ |
53 static Bool | 61 static Bool |
54 addToGroup( const char * grp ) | 62 addToGroup( const char * grp ) |
161 static Bool | 169 static Bool |
162 getArticleText( const char *p ) | 170 getArticleText( const char *p ) |
163 { | 171 { |
164 DynStr * s; | 172 DynStr * s; |
165 Str line, field, value; | 173 Str line, field, value; |
166 Bool replyToFound, pathFound; | 174 Bool replyToFound, pathFound, orgFound; |
167 time_t t; | 175 time_t t; |
176 int sigLines; | |
168 | 177 |
169 s = new_DynStr( 10000 ); | 178 s = new_DynStr( 10000 ); |
170 article.text = s; | 179 article.text = s; |
171 | 180 |
172 memset( &article.over, 0, sizeof( article.over ) ); | 181 memset( &article.over, 0, sizeof( article.over ) ); |
173 replyToFound = pathFound = FALSE; | 182 replyToFound = pathFound = orgFound = FALSE; |
174 | 183 |
175 /* Grab header lines first, getting overview info as we go. */ | 184 /* Grab header lines first, getting overview info as we go. */ |
176 while ( ( p = Utl_getHeaderLn( line, p ) ) != NULL | 185 while ( ( p = Utl_getHeaderLn( line, p ) ) != NULL |
177 && line[ 0 ] != '\0' | 186 && line[ 0 ] != '\0' |
178 && Prt_getField( field, value, line ) ) | 187 && Prt_getField( field, value, line ) ) |
220 else if ( strcmp ( field, "path" ) == 0 ) | 229 else if ( strcmp ( field, "path" ) == 0 ) |
221 { | 230 { |
222 pathFound = TRUE; | 231 pathFound = TRUE; |
223 DynStr_appLn( s, line ); | 232 DynStr_appLn( s, line ); |
224 } | 233 } |
234 else if ( strcmp ( field, "organization" ) == 0 ) | |
235 { | |
236 orgFound = TRUE; | |
237 DynStr_appLn( s, line ); | |
238 } | |
225 else if ( strcmp ( field, "x-sender" ) == 0 ) | 239 else if ( strcmp ( field, "x-sender" ) == 0 ) |
226 { | 240 { |
227 DynStr_app( s, "X-NOFFLE-X-Sender: " ); | 241 DynStr_app( s, "X-NOFFLE-X-Sender: " ); |
228 DynStr_appLn( s, value ); | 242 DynStr_appLn( s, value ); |
229 } | 243 } |
234 } | 248 } |
235 | 249 |
236 /* Now sort header-related issues */ | 250 /* Now sort header-related issues */ |
237 if ( article.over.from[ 0 ] == '\0' ) | 251 if ( article.over.from[ 0 ] == '\0' ) |
238 { | 252 { |
239 Log_err( "Posted message has no From field" ); | 253 if ( article.flags & POST_ADD_FROM ) |
240 return FALSE; | 254 { |
255 Log_dbg( "Adding From field to posted message." ); | |
256 DynStr_app( s, "From: " ); | |
257 if ( ! Prt_genFromHdr( article.over.from ) ) | |
258 { | |
259 Log_err( "Can't generate From field" ); | |
260 return FALSE; | |
261 } | |
262 DynStr_appLn( s, article.over.from ); | |
263 } | |
264 else | |
265 { | |
266 Log_err( "Posted message has no From field" ); | |
267 return FALSE; | |
268 } | |
241 } | 269 } |
242 if ( article.over.subject[ 0 ] == '\0' ) | 270 if ( article.over.subject[ 0 ] == '\0' ) |
243 { | 271 { |
244 Log_err( "Posted message has no Subject field" ); | 272 Log_err( "Posted message has no Subject field" ); |
245 return FALSE; | 273 return FALSE; |
293 Log_dbg( "Adding Reply-To field to posted message." ); | 321 Log_dbg( "Adding Reply-To field to posted message." ); |
294 DynStr_app( s, "Reply-To: " ); | 322 DynStr_app( s, "Reply-To: " ); |
295 DynStr_appLn( s, article.over.from ); | 323 DynStr_appLn( s, article.over.from ); |
296 } | 324 } |
297 | 325 |
326 /* Ensure Organization header if required */ | |
327 if ( ( ! orgFound ) && ( article.flags & POST_ADD_ORG ) ) | |
328 { | |
329 Str org; | |
330 | |
331 Utl_cpyStr( org, Cfg_organization() ); | |
332 if ( org[ 0 ] != '\0' ) | |
333 { | |
334 Log_dbg( "Adding Organization field to posted message." ); | |
335 DynStr_app( s, "Organization: " ); | |
336 DynStr_appLn( s, org ); | |
337 } | |
338 } | |
339 | |
298 /* OK, header ready to roll. Something to accompany it? */ | 340 /* OK, header ready to roll. Something to accompany it? */ |
299 if ( p == NULL || p[ 0 ] == '\0' ) | 341 if ( p == NULL || p[ 0 ] == '\0' ) |
300 { | 342 { |
301 Log_err( "Posted message has no body" ); | 343 Log_err( "Posted message has no body" ); |
302 return FALSE; | 344 return FALSE; |
303 } | 345 } |
304 | 346 |
305 /* Add the empty line separating header and body */ | 347 /* Add the empty line separating header and body */ |
306 DynStr_appLn( s, "" ); | 348 DynStr_appLn( s, "" ); |
307 | 349 |
308 /* Now pop on the rest of the body and count the lines & bytes */ | 350 /* Now pop on the rest of the body */ |
309 DynStr_app( s, p ); | 351 DynStr_app( s, p ); |
310 for ( p++, article.over.lines = 0; *p != '\0'; p++ ) | 352 |
353 /* Add a signature if requested to do so and if one found. */ | |
354 sigLines = 0; | |
355 if ( article.flags & POST_ADD_SIG ) | |
356 { | |
357 Str sigfile; | |
358 struct passwd *pwd; | |
359 FILE *f; | |
360 | |
361 /* Generate sig file path */ | |
362 pwd = getpwuid( getuid() ); | |
363 Utl_cpyStr( sigfile, pwd->pw_dir ); | |
364 Utl_catStr( sigfile, SIG_FILE ); | |
365 | |
366 f = fopen( sigfile, "r" ); | |
367 if ( f == NULL ) | |
368 { | |
369 /* If err is ENOENT, file doesn't exist. This is OK. */ | |
370 if ( errno != ENOENT ) | |
371 { | |
372 Log_err( "Can't access .signature file (%s), " | |
373 "article not posted.", | |
374 strerror( errno ) ); | |
375 return FALSE; | |
376 } | |
377 } | |
378 else | |
379 { | |
380 /* OK, try to add it. */ | |
381 Str sline; | |
382 | |
383 Log_dbg( "Adding .signature to posted message." ); | |
384 | |
385 DynStr_appLn( s, BEGIN_SIG ); | |
386 sigLines++; | |
387 while ( Prt_getLn( sline, f, 0 ) ) | |
388 { | |
389 DynStr_appLn( s, sline ); | |
390 sigLines++; | |
391 } | |
392 | |
393 if ( ferror( f ) ) | |
394 { | |
395 Log_err( "Error reading .signature file (%s), " | |
396 "article not posted.", | |
397 strerror( errno ) ); | |
398 fclose( f ); | |
399 return FALSE; | |
400 } | |
401 | |
402 fclose( f ); | |
403 } | |
404 } | |
405 | |
406 /* | |
407 * Count the lines & bytes. This counts the original number of | |
408 * lines in the supplied body, so add in the number of signature | |
409 * lines added, including the separator. | |
410 */ | |
411 for ( p++, article.over.lines = sigLines; *p != '\0'; p++ ) | |
311 if ( *p == '\n' ) | 412 if ( *p == '\n' ) |
312 article.over.lines++; | 413 article.over.lines++; |
313 article.over.bytes = DynStr_len( s ); | 414 article.over.bytes = DynStr_len( s ); |
314 | 415 |
315 return TRUE; | 416 return TRUE; |
426 return postExternal() && err; | 527 return postExternal() && err; |
427 } | 528 } |
428 | 529 |
429 /* Register an article for posting. */ | 530 /* Register an article for posting. */ |
430 Bool | 531 Bool |
431 Post_open( const char * text ) | 532 Post_open( const char * text, unsigned flags ) |
432 { | 533 { |
433 if ( article.text != NULL ) | 534 if ( article.text != NULL ) |
434 { | 535 { |
435 Log_err( "Busy article in Post_open." ); | 536 Log_err( "Busy article in Post_open." ); |
436 return FALSE; | 537 return FALSE; |
437 } | 538 } |
438 | 539 |
540 article.flags = flags; | |
541 | |
439 if ( ! getArticleText( text ) ) | 542 if ( ! getArticleText( text ) ) |
440 return FALSE; | 543 return FALSE; |
441 | 544 |
442 if ( Db_contains( article.over.msgId ) ) | 545 if ( Db_contains( article.over.msgId ) ) |
443 { | 546 { |
451 | 554 |
452 /* Process the posting */ | 555 /* Process the posting */ |
453 Bool | 556 Bool |
454 Post_post( void ) | 557 Post_post( void ) |
455 { | 558 { |
559 if ( article.flags & POST_DEBUG ) | |
560 { | |
561 fputs( DynStr_str( article.text ), stdout ); | |
562 return TRUE; | |
563 } | |
564 | |
456 if ( ! checkPostableNewsgroup() ) | 565 if ( ! checkPostableNewsgroup() ) |
457 return FALSE; | 566 return FALSE; |
458 | 567 |
459 return ( article.control == NULL ) | 568 return ( article.control == NULL ) |
460 ? ! postArticle() | 569 ? ! postArticle() |