/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/news.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/bnetd/news.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: pvpgn_1-7-4-0_MIL, arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 /*
2 * Copyright (C) 2000 Alexey Belyaev (spider@omskart.ru)
3 * Copyright (C) 2004 Dizzy (dizzy@roedu.net)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 #define NEWS_INTERNAL_ACCESS
20 #include "common/setup_before.h"
21 #include <stdio.h>
22 #ifdef HAVE_STDDEF_H
23 # include <stddef.h>
24 #else
25 # ifndef NULL
26 # define NULL ((void *)0)
27 # endif
28 #endif
29 #ifdef STDC_HEADERS
30 # include <stdlib.h>
31 #else
32 # ifdef HAVE_MALLOC_H
33 # include <malloc.h>
34 # endif
35 #endif
36 #include "compat/strtoul.h"
37 #ifdef HAVE_STRING_H
38 # include <string.h>
39 #else
40 # ifdef HAVE_STRINGS_H
41 # include <strings.h>
42 # endif
43 #endif
44 #ifdef HAVE_ERRNO_H
45 # include <errno.h>
46 #endif
47 #ifdef HAVE_TIME_H
48 # include <time.h>
49 #endif
50 #ifdef HAVE_ASSERT_H
51 # include <assert.h>
52 #endif
53 #include "compat/strchr.h"
54 #include "compat/strdup.h"
55 #include "compat/strerror.h"
56 #include "common/eventlog.h"
57 #include "common/elist.h"
58 #include "common/util.h"
59 #include "common/proginfo.h"
60 #include "common/xalloc.h"
61 #include "news.h"
62 #include "common/setup_after.h"
63
64 static t_elist news_head;
65
66 static int _news_parsetime(char *buff, struct tm *date, unsigned line)
67 {
68 char *p;
69
70 date->tm_hour= 6;
71 date->tm_min = 6; // need to set non-zero values or else date is displayed wrong
72 date->tm_sec = 6;
73 date->tm_isdst=-1;
74
75 if (!(p = strchr(buff,'/'))) return -1;
76 *p = '\0';
77
78 date->tm_mon = atoi(buff) - 1;
79 if ((date->tm_mon<0) || (date->tm_mon>11)) {
80 eventlog(eventlog_level_error,__FUNCTION__,"found invalid month (%i) in news date. (format: {MM/DD/YYYY}) on line %u",date->tm_mon,line);
81 }
82
83 buff = p + 1;
84 if (!(p = strchr(buff,'/'))) return -1;
85 *p = '\0';
86
87 date->tm_mday = atoi(buff);
88 if ((date->tm_mday<1) || (date->tm_mday>31)) {
89 eventlog(eventlog_level_error,__FUNCTION__,"found invalid month day (%i) in news date. (format: {MM/DD/YYYY}) on line %u",date->tm_mday,line);
90 return -1;
91 }
92
93 buff = p + 1;
94 if (!(p = strchr(buff,'}'))) return -1;
95 *p = '\0';
96
97 date->tm_year=atoi(buff)-1900;
98 if (date->tm_year>137) //limited due to 32bit t_time
99 {
100 eventlog(eventlog_level_error,__FUNCTION__,"found invalid year (%i) (>2037) in news date. on line %u",date->tm_year+1900,line);
101 return -1;
102 }
103
104 return 0;
105 }
106
107 static void _news_insert_index(t_news_index *ni, const char *buff, unsigned len, int date_set)
108 {
109 t_elist *curr;
110 t_news_index *cni;
111
112 elist_for_each(curr,&news_head) {
113 cni = elist_entry(curr,t_news_index,list);
114 if (cni->date <= ni->date) break;
115 }
116
117 if (curr != &news_head && cni->date == ni->date) {
118 if (date_set == 1)
119 eventlog(eventlog_level_warn,__FUNCTION__,"found another news item for same date, trying to join both");
120
121 if ((lstr_get_len(&cni->body) + len +2) > 1023)
122 eventlog(eventlog_level_error,__FUNCTION__,"failed in joining news, cause news too long - skipping");
123 else {
124 lstr_set_str(&cni->body,xrealloc(lstr_get_str(&cni->body),lstr_get_len(&cni->body) + len + 1 + 1));
125 strcpy(lstr_get_str(&cni->body) + lstr_get_len(&cni->body), buff);
126 *(lstr_get_str(&cni->body) + lstr_get_len(&cni->body) + len) = '\n';
127 lstr_set_len(&cni->body,lstr_get_len(&cni->body) + len + 1);
128 }
129 xfree((void *)ni);
130 } else {
131 /* adding new index entry */
132 lstr_set_str(&ni->body,xmalloc(len + 2));
133 strcpy(lstr_get_str(&ni->body),buff);
134 strcat(lstr_get_str(&ni->body),"\n");
135 lstr_set_len(&ni->body,len + 1);
136 elist_add_tail(curr,&ni->list);
137 }
138 }
139
140 static void _news_insert_default(void)
141 {
142 const char * deftext = "No news today";
143 t_news_index *ni;
144
145 ni = (t_news_index*)xmalloc(sizeof(t_news_index));
146 ni->date = time(NULL);
147 _news_insert_index(ni, deftext, strlen(deftext), 1);
148 }
149
150 extern int news_load(const char *filename)
151 {
152 FILE * fp;
153 unsigned int line;
154 unsigned int len;
155 char buff[256];
156 struct tm date;
157 char date_set;
158 t_news_index *ni;
159
160 elist_init(&news_head);
161
162 date_set = 0;
163
164 if (!filename) {
165 eventlog(eventlog_level_error, __FUNCTION__,"got NULL fullname");
166 return -1;
167 }
168
169 if ((fp = fopen(filename,"rt"))==NULL) {
170 eventlog(eventlog_level_warn, __FUNCTION__,"can't open news file");
171 _news_insert_default();
172 return 0;
173 }
174
175 for (line=1; fgets(buff,sizeof(buff),fp); line++) {
176 len = strlen(buff);
177 while(len && (buff[len - 1] == '\n' || buff[len - 1] == '\r')) len--;
178 if (!len) continue; /* empty line */
179 buff[len] = '\0';
180
181 if (buff[0]=='{') {
182 if (_news_parsetime(buff + 1,&date, line)) {
183 eventlog(eventlog_level_error,__FUNCTION__,"error parsing news date on line %u",line);
184 return -1;
185 }
186 date_set = 1;
187 } else {
188 ni = (t_news_index*)xmalloc(sizeof(t_news_index));
189 if (date_set)
190 ni->date = mktime(&date);
191 else {
192 ni->date = time(NULL);
193 eventlog(eventlog_level_warn,__FUNCTION__,"(first) news entry seems to be missing a timestamp, please check your news file on line %u",line);
194 }
195 _news_insert_index(ni,buff,len,date_set);
196 date_set = 2;
197 }
198 }
199 fclose(fp);
200
201 if (elist_empty(&news_head)) {
202 eventlog(eventlog_level_warn,__FUNCTION__,"no news configured");
203 _news_insert_default();
204 }
205
206 return 0;
207 }
208
209 /* Free up all of the elements in the linked list */
210 extern int news_unload(void)
211 {
212 t_elist * curr, *save;
213 t_news_index * ni;
214
215 elist_for_each_safe(curr,&news_head,save)
216 {
217 ni = elist_entry(curr,t_news_index,list);
218 elist_del(&ni->list);
219 xfree((void *)lstr_get_str(&ni->body));
220 xfree((void *)ni);
221 }
222
223 elist_init(&news_head);
224
225 return 0;
226 }
227
228 extern unsigned int news_get_lastnews(void)
229 {
230 if (elist_empty(&news_head)) return 0;
231 return ((elist_entry(news_head.next,t_news_index,list))->date);
232 }
233
234 extern unsigned int news_get_firstnews(void)
235 {
236 if (elist_empty(&news_head)) return 0;
237 return ((elist_entry(news_head.prev,t_news_index,list))->date);
238 }
239
240 extern void news_traverse(t_news_cb cb, void *data)
241 {
242 t_elist *curr;
243 t_news_index *cni;
244
245 assert(cb);
246
247 elist_for_each(curr,&news_head)
248 {
249 cni = elist_entry(curr,t_news_index,list);
250 if (cb(cni->date,&cni->body,data)) break;
251 }
252 }

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1