3 /* Copyright (C) 2002 Brad Jorsch <anomie@users.sourceforge.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 # if TIME_WITH_SYS_TIME
22 # include <sys/time.h>
26 # include <sys/time.h>
41 #include "wmweather+.h"
48 /* Important variables */
49 static char *warning_filename1
=NULL
;
50 static char *warning_endptr1
=NULL
;
52 static char *filenames
[]={
53 "tornado", "flash_flood>warning", "flash_flood>watch",
54 "flash_flood>statement", "flood>warning", "flood>coastal",
55 "flood>statement", "severe_weather_stmt", "special_weather_stmt",
56 "thunderstorm", "special_marine", "urgent_weather_message", "non_precip",
57 "fire_weather", "lake_shore", NULL
59 static char **reqs
[sizeof(filenames
)/sizeof(*filenames
)-1][2];
61 unsigned long current_warnings
;
62 static unsigned long *zone_current_warnings
;
64 /* Regular Expressions */
69 static int check_warning(char *file
);
74 #define compile(var, re) \
75 var=pcre_compile(re, 0, (const char **)&e, &i, NULL); \
76 if(var==NULL) die("init_warnings PCRE error: %s at %i", e, i); \
77 pcre_fullinfo(var, NULL, PCRE_INFO_CAPTURECOUNT, &i); \
78 if(i>ovecsize) ovecsize=i;
80 void init_warnings(void){
83 struct subst_val subs
[]={
84 { 'z', STRING
, NULL
},
85 { 'f', STRING
, &bigbuf
},
89 /* Count zones, and find length of longest */
90 for(i
=0; warning_zones
[i
]!=NULL
; i
++){
91 j
=strlen(warning_zones
[i
]);
95 /* Allocate char ptrs for each filename for each zone */
96 for(j
=0; filenames
[j
]!=NULL
; j
++){
97 reqs
[j
][0]=malloc(sizeof(char *)*i
);
98 reqs
[j
][1]=malloc(sizeof(char *)*i
);
99 if(reqs
[j
][0]==NULL
|| reqs
[j
][1]==NULL
) die("init_warnings malloc");
101 zone_current_warnings
=calloc(i
, sizeof(*zone_current_warnings
));
102 if(zone_current_warnings
==NULL
) die("init_warnings malloc");
104 /* Allocate filename base */
105 e
=get_pid_filename("");
107 warning_filename1
=malloc(i
+z
+32);
108 if(warning_filename1
==NULL
)
109 die("init_warnings malloc");
111 strcpy(warning_filename1
, e
);
113 warning_endptr1
=warning_filename1
+i
;
115 /* Setup misc vars */
118 compile(expires
, "Expires:(\\d+)(\\d\\d)(\\d\\d)(\\d\\d)(\\d\\d);");
119 ovecsize
=(ovecsize
+1)*3;
121 /* Remove stale files, and allocate URIs */
122 for(z
=0; warning_zones
[z
]!=NULL
; z
++){
123 subs
[0].val
=warning_zones
+z
;
124 for(i
=0; filenames
[i
]!=NULL
; i
++){
125 sprintf(warning_endptr1
, "%s.%s.txt", warning_zones
[z
], filenames
[i
]);
126 unlink(warning_filename1
);
127 sprintf(warning_endptr1
, "%s.new-%s.txt", warning_zones
[z
], filenames
[i
]);
128 unlink(warning_filename1
);
129 strncpy(bigbuf
, filenames
[i
], BIGBUF_LEN
);
130 bigbuf
[BIGBUF_LEN
-1]='\0';
131 for(j
=0; bigbuf
[j
]; j
++){
132 if(bigbuf
[j
]=='>') bigbuf
[j
]='/';
134 if((reqs
[i
][0][z
]=subst(warning_uri
, subs
))==NULL
) die("init_warning");
136 if(warning_post
!=NULL
&& (reqs
[i
][1][z
]=subst(warning_post
, subs
))==NULL
) die("init_warning");
142 struct callback_data
{
147 static void warning_callback(char *filename
, void *v
){
149 struct callback_data
*d
=(struct callback_data
*)v
;
151 sprintf(warning_endptr1
, "%s.%s.txt", warning_zones
[d
->zone
], filenames
[d
->warning
]);
152 if(stat(filename
, &statbuf
)>=0){
153 if(S_ISREG(statbuf
.st_mode
) && statbuf
.st_size
!=0
154 && check_warning(filename
)
155 && diff(filename
, warning_filename1
)){
156 current_warnings
|=1<<d
->warning
;
157 zone_current_warnings
[d
->zone
]|=1<<d
->warning
;
158 rename(filename
, warning_filename1
);
165 void warnings_cleanup(void){
168 if(warning_filename1
==NULL
) return;
169 for(z
=0; warning_zones
[z
]!=NULL
; z
++){
170 for(i
=0; filenames
[i
]!=NULL
; i
++){
171 sprintf(warning_endptr1
, "%s.%s.txt", warning_zones
[z
], filenames
[i
]);
172 unlink(warning_filename1
);
173 sprintf(warning_endptr1
, "%s.new-%s.txt", warning_zones
[z
], filenames
[i
]);
174 unlink(warning_filename1
);
179 void update_warnings(int force
){
183 struct callback_data
*d
;
185 if(warning_filename1
==NULL
) return;
187 // if(!force && warning_time>t) return;
189 // warning_time=t+15;
191 for(z
=0; warning_zones
[z
]!=NULL
; z
++){
192 for(i
=0; filenames
[i
]!=NULL
; i
++){
193 /* expire old wanrings */
194 sprintf(warning_endptr1
, "%s.%s.txt", warning_zones
[z
], filenames
[i
]);
195 if(stat(warning_filename1
, &statbuf
)>=0){
196 if(!S_ISREG(statbuf
.st_mode
) || statbuf
.st_size
==0
197 || !check_warning(warning_filename1
)){
198 unlink(warning_filename1
);
199 current_warnings
&=~(1<<i
);
200 zone_current_warnings
[z
]&=~(1<<i
);
203 current_warnings
&=~(1<<i
);
204 zone_current_warnings
[z
]&=~(1<<i
);
207 if((d
=malloc(sizeof(*d
)))==NULL
) continue;
208 sprintf(warning_endptr1
, "%s.new-%s.txt", warning_zones
[z
], filenames
[i
]);
211 download_file(warning_filename1
, reqs
[i
][0][z
], reqs
[i
][1][z
], DOWNLOAD_NO_404
, warning_callback
, d
);
217 #define get_substr(n, c) \
218 if(pcre_get_substring(s, ovector, ovalue, n, (const char **)&c)<0){ free(s); return 0; }
220 static int check_warning(char *file
){
227 int ovector
[ovecsize
];
230 if((fp
=fopen(file
, "r"))==NULL
) return 0;
232 while((len
=getLine(&s
, fp
))>0){
233 ovalue
=pcre_exec(expires
, NULL
, s
, len
, 0, 0, ovector
, ovecsize
);
238 if(ovalue
<=0) return 0;
242 get_substr(1, c
); i
=atoi(c
)-1900; pcre_free_substring(c
);
243 if(tm
->tm_year
<i
){ free(s
); return 1; }
244 if(tm
->tm_year
>i
){ free(s
); return 0; }
245 get_substr(2, c
); i
=atoi(c
)-1; pcre_free_substring(c
);
246 if(tm
->tm_mon
<i
){ free(s
); return 1; }
247 if(tm
->tm_mon
>i
){ free(s
); return 0; }
248 get_substr(3, c
); i
=atoi(c
); pcre_free_substring(c
);
249 if(tm
->tm_mday
<i
){ free(s
); return 1; }
250 if(tm
->tm_mday
>i
){ free(s
); return 0; }
251 get_substr(4, c
); i
=atoi(c
); pcre_free_substring(c
);
252 if(tm
->tm_hour
<i
){ free(s
); return 1; }
253 if(tm
->tm_hour
>i
){ free(s
); return 0; }
254 get_substr(5, c
); i
=atoi(c
); pcre_free_substring(c
);
255 if(tm
->tm_min
<=i
){ free(s
); return 1; }
259 void output_warnings(int all
){
265 if(!all
&& current_warnings
==0) return;
267 if(pipe(pipefd
)) die("output_warnings pipe creation");
269 /* Fork to display the file */
272 warn("output_warnings fork");
275 /* CHILD: Redirects stdin/stderr/stdout and execs the viewer */
278 dup2(pipefd
[0], STDIN_FILENO
);
279 dup2(devnull
, STDOUT_FILENO
);
280 execl("/bin/sh", "/bin/sh", "-c", viewer
, NULL
);
281 die("output_warnings exec");
284 /* PARENT writes warnings to the pipe and returns */
286 for(z
=0; warning_zones
[z
]!=NULL
; z
++){
287 if(!zone_current_warnings
[z
]) continue;
288 for(i
=0; filenames
[i
]!=NULL
; i
++){
289 if(!all
&& !(zone_current_warnings
[z
]&(1<<i
))) continue;
291 sprintf(warning_endptr1
, "%s.%s.txt", warning_zones
[z
], filenames
[i
]);
292 if((fp
=fopen(warning_filename1
, "r"))==NULL
) continue;
293 snprintf(bigbuf
, BIGBUF_LEN
, "======== BEGIN %s %s ========\n", warning_zones
[z
], filenames
[i
]);
294 write(pipefd
[1], bigbuf
, strlen(bigbuf
));
296 len
=fread(bigbuf
, sizeof(char), BIGBUF_LEN
, fp
);
297 write(pipefd
[1], bigbuf
, len
);
301 if(!all
) zone_current_warnings
[z
]=0;
304 if(!all
) current_warnings
=0;