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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide 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 sysadm 1.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