Mercurial > noffle
comparison fetch.c @ 0:04124a4423d4 noffle
[svn] Initial revision
author | enz |
---|---|
date | Tue, 04 Jan 2000 11:35:42 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:04124a4423d4 |
---|---|
1 /* | |
2 fetch.c | |
3 | |
4 $Id: fetch.c 3 2000-01-04 11:35:42Z enz $ | |
5 */ | |
6 | |
7 #include "fetch.h" | |
8 #include <errno.h> | |
9 #include <time.h> | |
10 #include <signal.h> | |
11 #include "client.h" | |
12 #include "config.h" | |
13 #include "content.h" | |
14 #include "dynamicstring.h" | |
15 #include "fetchlist.h" | |
16 #include "request.h" | |
17 #include "group.h" | |
18 #include "log.h" | |
19 #include "outgoing.h" | |
20 #include "protocol.h" | |
21 #include "pseudo.h" | |
22 #include "util.h" | |
23 | |
24 struct Fetch | |
25 { | |
26 Bool ready; | |
27 Str serv; | |
28 } fetch = { FALSE, "" }; | |
29 | |
30 static Bool | |
31 connectToServ( const char *name ) | |
32 { | |
33 Log_inf( "Fetch from '%s'", name ); | |
34 if ( ! Client_connect( name ) ) | |
35 { | |
36 Log_err( "Could not connect to %s", name ); | |
37 return FALSE; | |
38 } | |
39 return TRUE; | |
40 } | |
41 | |
42 void | |
43 Fetch_getNewGrps( void ) | |
44 { | |
45 time_t t; | |
46 Str file; | |
47 | |
48 ASSERT( fetch.ready ); | |
49 snprintf( file, MAXCHAR, "%s/groupinfo.lastupdate", Cfg_spoolDir() ); | |
50 if ( ! Utl_getStamp( &t, file ) ) | |
51 { | |
52 Log_err( "Cannot read %s. Please run noffle --query groups", file ); | |
53 return; | |
54 } | |
55 Log_inf( "Updating groupinfo" ); | |
56 Client_getNewgrps( &t ); | |
57 Utl_stamp( file ); | |
58 } | |
59 | |
60 void | |
61 Fetch_getNewArts( const char *name, FetchMode mode ) | |
62 { | |
63 int next, first, last, oldLast; | |
64 | |
65 if ( ! Client_changeToGrp( name ) ) | |
66 { | |
67 Log_err( "Could not change to group %s", name ); | |
68 return; | |
69 } | |
70 Cont_read( name ); | |
71 Client_rmtFirstLast( &first, &last ); | |
72 next = Grp_rmtNext( name ); | |
73 oldLast = Cont_last(); | |
74 if ( next == last + 1 ) | |
75 { | |
76 Log_inf( "No new articles in %s", name ); | |
77 Cont_write(); | |
78 Grp_setFirstLast( name, Cont_first(), Cont_last() ); | |
79 return; | |
80 } | |
81 if ( first == 0 && last == 0 ) | |
82 { | |
83 Log_inf( "No articles in %s", name ); | |
84 Cont_write(); | |
85 Grp_setFirstLast( name, Cont_first(), Cont_last() ); | |
86 return; | |
87 } | |
88 if ( next > last + 1 ) | |
89 { | |
90 Log_err( "Article number inconsistent (%s rmt=%lu-%lu, next=%lu)", | |
91 name, first, last, next ); | |
92 Pseudo_cntInconsistent( name, first, last, next ); | |
93 } | |
94 else if ( next < first ) | |
95 { | |
96 Log_inf( "Missing articles (%s first=%lu next=%lu)", | |
97 name, first, next ); | |
98 Pseudo_missArts( name, first, next ); | |
99 } | |
100 else | |
101 first = next; | |
102 if ( last - first > Cfg_maxFetch() ) | |
103 { | |
104 Log_ntc( "Cutting number of overviews to %lu", Cfg_maxFetch() ); | |
105 first = last - Cfg_maxFetch() + 1; | |
106 } | |
107 Log_inf( "Getting remote overviews %lu-%lu for group %s", | |
108 first, last, name ); | |
109 Client_getOver( first, last, mode ); | |
110 Cont_write(); | |
111 Grp_setFirstLast( name, Cont_first(), Cont_last() ); | |
112 } | |
113 | |
114 void | |
115 Fetch_updateGrps( void ) | |
116 { | |
117 FetchMode mode; | |
118 int i, size; | |
119 const char* name; | |
120 | |
121 ASSERT( fetch.ready ); | |
122 Fetchlist_read(); | |
123 size = Fetchlist_size(); | |
124 for ( i = 0; i < size; ++i ) | |
125 { | |
126 Fetchlist_element( &name, &mode, i ); | |
127 if ( strcmp( Grp_serv( name ), fetch.serv ) == 0 ) | |
128 Fetch_getNewArts( name, mode ); | |
129 } | |
130 } | |
131 | |
132 void | |
133 Fetch_getReq_( void ) | |
134 { | |
135 Str msgId; | |
136 DynStr *list; | |
137 const char *p; | |
138 int count = 0; | |
139 | |
140 ASSERT( fetch.ready ); | |
141 Log_dbg( "Retrieving articles marked for download" ); | |
142 list = new_DynStr( 10000 ); | |
143 if ( Req_first( fetch.serv, msgId ) ) | |
144 do | |
145 { | |
146 DynStr_appLn( list, msgId ); | |
147 if ( ++count % 20 == 0 ) /* Send max. 20 ARTICLE cmds at once */ | |
148 { | |
149 p = DynStr_str( list ); | |
150 Client_retrieveArtList( p ); | |
151 while ( ( p = Utl_getLn( msgId, p ) ) ) | |
152 Req_remove( fetch.serv, msgId ); | |
153 DynStr_clear( list ); | |
154 } | |
155 } | |
156 while ( Req_next( msgId ) ); | |
157 p = DynStr_str( list ); | |
158 Client_retrieveArtList( p ); | |
159 while ( ( p = Utl_getLn( msgId, p ) ) ) | |
160 Req_remove( fetch.serv, msgId ); | |
161 del_DynStr( list ); | |
162 } | |
163 | |
164 void | |
165 Fetch_postArts( void ) | |
166 { | |
167 DynStr *s; | |
168 Str msgId, cmd, errStr, sender; | |
169 int ret; | |
170 const char *txt; | |
171 FILE *f; | |
172 sig_t lastHandler; | |
173 | |
174 s = new_DynStr( 10000 ); | |
175 if ( Out_first( fetch.serv, msgId, s ) ) | |
176 { | |
177 Log_inf( "Posting articles" ); | |
178 do | |
179 { | |
180 txt = DynStr_str( s ); | |
181 Out_remove( fetch.serv, msgId ); | |
182 if ( ! Client_postArt( msgId, txt, errStr ) ) | |
183 { | |
184 Utl_cpyStr( sender, Cfg_mailTo() ); | |
185 if ( strcmp( sender, "" ) == 0 | |
186 && ! Prt_searchHeader( txt, "SENDER", sender ) | |
187 && ! Prt_searchHeader( txt, "X-NOFFLE-X-SENDER", | |
188 sender ) /* see server.c */ | |
189 && ! Prt_searchHeader( txt, "FROM", sender ) ) | |
190 Log_err( "Article %s has no From/Sender/X-Sender field", | |
191 msgId ); | |
192 else | |
193 { | |
194 Log_ntc( "Return article to '%s' by mail", sender ); | |
195 snprintf( cmd, MAXCHAR, | |
196 "mail -s '[ NOFFLE: Posting failed ]' '%s'", | |
197 sender ); | |
198 lastHandler = signal( SIGPIPE, SIG_IGN ); | |
199 f = popen( cmd, "w" ); | |
200 if ( f == NULL ) | |
201 Log_err( "Invocation of '%s' failed (%s)", cmd, | |
202 strerror( errno ) ); | |
203 else | |
204 { | |
205 fprintf( f, | |
206 "\t[ NOFFLE: POSTING OF ARTICLE FAILED ]\n" | |
207 "\n" | |
208 "\t[ The posting of your article failed. ]\n" | |
209 "\t[ Reason of failure at remote server: ]\n" | |
210 "\n" | |
211 "\t[ %s ]\n" | |
212 "\n" | |
213 "\t[ Full article text has been appended. ]\n" | |
214 "\n" | |
215 "%s" | |
216 ".\n", | |
217 errStr, txt ); | |
218 ret = pclose( f ); | |
219 if ( ret != EXIT_SUCCESS ) | |
220 Log_err( "'%s' exit value %d", cmd, ret ); | |
221 signal( SIGPIPE, lastHandler ); | |
222 } | |
223 } | |
224 } | |
225 } | |
226 while ( Out_next( msgId, s ) ); | |
227 } | |
228 del_DynStr( s ); | |
229 } | |
230 | |
231 Bool | |
232 Fetch_init( const char *serv ) | |
233 { | |
234 if ( ! connectToServ( serv ) ) | |
235 return FALSE; | |
236 Utl_cpyStr( fetch.serv, serv ); | |
237 fetch.ready = TRUE; | |
238 return TRUE; | |
239 } | |
240 | |
241 void | |
242 Fetch_close() | |
243 { | |
244 Client_disconnect(); | |
245 fetch.ready = FALSE; | |
246 Log_inf( "Fetch from '%s' finished", fetch.serv ); | |
247 } |