1 | /*===================================================================== |
---|
2 | // Copyright (C) 2000,2001 Instrumental Software Technologies, Inc. |
---|
3 | // |
---|
4 | // Redistribution and use in source and binary forms, with or without |
---|
5 | // modification, are permitted provided that the following conditions |
---|
6 | // are met: |
---|
7 | // 1. Redistributions of source code, or portions of this source code, |
---|
8 | // must retain the above copyright notice, this list of conditions |
---|
9 | // and the following disclaimer. |
---|
10 | // 2. Redistributions in binary form must reproduce the above copyright |
---|
11 | // notice, this list of conditions and the following disclaimer in |
---|
12 | // the documentation and/or other materials provided with the |
---|
13 | // distribution. |
---|
14 | // 3. All advertising materials mentioning features or use of this |
---|
15 | // software must display the following acknowledgment: |
---|
16 | // "This product includes software developed by Instrumental |
---|
17 | // Software Technologies, Inc. (http://www.isti.com)" |
---|
18 | // 4. If the software is provided with, or as part of a commercial |
---|
19 | // product, or is used in other commercial software products the |
---|
20 | // customer must be informed that "This product includes software |
---|
21 | // developed by Instrumental Software Technologies, Inc. |
---|
22 | // (http://www.isti.com)" |
---|
23 | // 5. The names "Instrumental Software Technologies, Inc." and "ISTI" |
---|
24 | // must not be used to endorse or promote products derived from |
---|
25 | // this software without prior written permission. For written |
---|
26 | // permission, please contact "info@isti.com". |
---|
27 | // 6. Products derived from this software may not be called "ISTI" |
---|
28 | // nor may "ISTI" appear in their names without prior written |
---|
29 | // permission of Instrumental Software Technologies, Inc. |
---|
30 | // 7. Redistributions of any form whatsoever must retain the following |
---|
31 | // acknowledgment: |
---|
32 | // "This product includes software developed by Instrumental |
---|
33 | // Software Technologies, Inc. (http://www.isti.com/)." |
---|
34 | // THIS SOFTWARE IS PROVIDED BY INSTRUMENTAL SOFTWARE |
---|
35 | // TECHNOLOGIES, INC. "AS IS" AND ANY EXPRESSED OR IMPLIED |
---|
36 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
---|
37 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
---|
38 | // DISCLAIMED. IN NO EVENT SHALL INSTRUMENTAL SOFTWARE TECHNOLOGIES, |
---|
39 | // INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
---|
40 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
---|
41 | // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
---|
42 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
43 | // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
---|
44 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
45 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
---|
46 | // OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
47 | //===================================================================== |
---|
48 | // A current version of the software can be found at |
---|
49 | // http://www.isti.com |
---|
50 | // Bug reports and comments should be directed to |
---|
51 | // Instrumental Software Technologies, Inc. at info@isti.com |
---|
52 | //===================================================================== |
---|
53 | // This work was funded by the IRIS Data Management Center |
---|
54 | // http://www.iris.washington.edu |
---|
55 | //===================================================================== |
---|
56 | */ |
---|
57 | /* |
---|
58 | ** THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE |
---|
59 | ** CHECKED IT OUT USING THE COMMAND CHECKOUT. |
---|
60 | ** |
---|
61 | ** $Id$ |
---|
62 | ** |
---|
63 | ** Revision history: |
---|
64 | ** $Log$ |
---|
65 | ** Revision 1.1 2010/03/10 17:14:58 paulf |
---|
66 | ** first check in of ew2mseed to EW proper |
---|
67 | ** |
---|
68 | ** Revision 1.5 2007/04/13 19:43:22 hal |
---|
69 | ** use flock instead of lockf when compiling under cygwin (which lacks lockf) |
---|
70 | ** |
---|
71 | ** Revision 1.4 2007/04/12 19:21:04 hal |
---|
72 | ** Added ew7.0+ support (-dSUPPORT_SCNL) and linux port (-D_LINUX) |
---|
73 | ** |
---|
74 | ** -Hal |
---|
75 | ** |
---|
76 | ** Revision 1.3 2002/12/19 00:35:00 ilya |
---|
77 | ** Byteswapping in shorts and doubles is fixed |
---|
78 | ** |
---|
79 | ** Revision 1.2 2002/04/02 14:42:01 ilya |
---|
80 | ** Version 02-Apr-2002: catchup algorithm |
---|
81 | ** |
---|
82 | ** Revision 1.1.1.1 2002/01/24 18:32:05 ilya |
---|
83 | ** Exporting only ew2mseed! |
---|
84 | ** |
---|
85 | ** Revision 1.1.1.1 2001/11/20 21:47:00 ilya |
---|
86 | ** First CVS commit |
---|
87 | ** |
---|
88 | * Revision 1.7 2001/03/15 16:42:52 comserv |
---|
89 | * void signal_handler() modified to accomodate SIGALRM |
---|
90 | * |
---|
91 | * Revision 1.6 2001/02/06 17:19:32 comserv |
---|
92 | * Functions logFailedSCN() resetWsTrace() are moved to ew2mseed_utils.c |
---|
93 | * Functions logFailedSCN() and checkLock() are changed, so you can actually |
---|
94 | * write data into them, and still use them for locking. int lockfd is now a global |
---|
95 | * variable |
---|
96 | * |
---|
97 | * Revision 1.5 2001/02/06 05:53:29 comserv |
---|
98 | * Added code to make sure is that the content of the lockfile is truncated to zero. |
---|
99 | * We now write SCNs which we cannot process in this file |
---|
100 | * |
---|
101 | * Revision 1.4 2001/01/18 21:58:20 comserv |
---|
102 | * checkForGaps is modified to detect snippet overlaps |
---|
103 | * |
---|
104 | * Revision 1.4 2001/01/18 21:58:20 comserv |
---|
105 | * checkForGaps is modified to detect snippet overlaps |
---|
106 | * |
---|
107 | * Revision 1.3 2001/01/17 21:56:54 comserv |
---|
108 | * prerelease version ; copyright statement |
---|
109 | * |
---|
110 | * Revision 1.2 2001/01/08 22:55:31 comserv |
---|
111 | * locking function is added |
---|
112 | * |
---|
113 | * Revision 1.1 2000/11/17 06:56:57 comserv |
---|
114 | * Initial revision |
---|
115 | * |
---|
116 | */ |
---|
117 | |
---|
118 | /* Standard includes */ |
---|
119 | #include <stdio.h> |
---|
120 | #include <string.h> |
---|
121 | #include <stdlib.h> |
---|
122 | #include <errno.h> |
---|
123 | #include <sys/types.h> |
---|
124 | #include <sys/stat.h> |
---|
125 | #include <dirent.h> |
---|
126 | #include <signal.h> |
---|
127 | #include <unistd.h> |
---|
128 | #include <fcntl.h> |
---|
129 | #include <math.h> |
---|
130 | |
---|
131 | #ifdef _CYGWIN |
---|
132 | # include <sys/file.h> |
---|
133 | #endif |
---|
134 | |
---|
135 | /* Includes from Earthworm distribution */ |
---|
136 | #include "earthworm.h" |
---|
137 | |
---|
138 | /* Local includes */ |
---|
139 | #include "ew2mseed.h" |
---|
140 | #include "swap.h" |
---|
141 | #include "qlib2.h" |
---|
142 | |
---|
143 | /* Global variable */ |
---|
144 | int lockfd = -1; |
---|
145 | |
---|
146 | /***************************************************************************/ |
---|
147 | double getReqEndTime (double startTime, double SampRate, int samples) |
---|
148 | { |
---|
149 | double endTime; |
---|
150 | endTime = startTime + (double)samples/SampRate; |
---|
151 | return endTime; |
---|
152 | } |
---|
153 | |
---|
154 | |
---|
155 | /*****************************************************************************/ |
---|
156 | /* Define how many UNCOMPRESSED bytes from WS we have to request to fill */ |
---|
157 | /* for sure a single MiniSEED record */ |
---|
158 | /* IGD 03/28/02 highWaterMark is assuming possible increase in the size of */ |
---|
159 | /* the requested snippet */ |
---|
160 | /****************************************************************************/ |
---|
161 | long int assumeSnippetSize (int logRec, short CompAlg, short RecNum, |
---|
162 | int highWaterMark) |
---|
163 | { |
---|
164 | long int bytes; |
---|
165 | |
---|
166 | /*Must be larger than the maximum */ |
---|
167 | if (CompAlg == STEIM1) |
---|
168 | bytes = 2 * logRec * RecNum * highWaterMark * sizeof(int); |
---|
169 | else if(CompAlg == STEIM2) |
---|
170 | bytes = 4 * logRec * RecNum * highWaterMark * sizeof(int); |
---|
171 | else { |
---|
172 | fprintf(stderr, "fatal error in assumeSnippetSize: %d is not supported compression algorithm\n", CompAlg); |
---|
173 | logit("pt", "fatal error in assumeSnippetSize: %d is not supported compression algorithm\n", CompAlg); |
---|
174 | return -1; |
---|
175 | } |
---|
176 | return bytes; |
---|
177 | } |
---|
178 | |
---|
179 | /***************************************************************************/ |
---|
180 | |
---|
181 | void makeSNCLoop (RINGS *rn) |
---|
182 | { |
---|
183 | int i; |
---|
184 | struct SCN_ring *scn_head; |
---|
185 | |
---|
186 | scn_head = rn->scnRing; |
---|
187 | |
---|
188 | for (i=0; i < rn->SCN_avail-1; i++) |
---|
189 | rn->scnRing = rn->scnRing->next; |
---|
190 | |
---|
191 | rn->scnRing->next = scn_head; |
---|
192 | |
---|
193 | |
---|
194 | } |
---|
195 | /***************************************************************************/ |
---|
196 | /************************************************************************/ |
---|
197 | /* checkForGaps: */ |
---|
198 | /* Reads in the sampling rate, time of the last sample of the */ |
---|
199 | /* previous snippet and the first sample of the current snippet. */ |
---|
200 | /* Checks for the data consistency */ |
---|
201 | /* returns: */ |
---|
202 | /* 0 if there is no gaps (tears) or overlaps */ |
---|
203 | /* positive double gap in seconds or negative overlap in seconds */ |
---|
204 | /* */ |
---|
205 | /************************************************************************/ |
---|
206 | double checkForGaps (double prevEndTime, double startTime, double sampRate) |
---|
207 | { |
---|
208 | double smallValue, invSampRate; |
---|
209 | |
---|
210 | invSampRate = 1./sampRate; |
---|
211 | smallValue = invSampRate/10.; |
---|
212 | |
---|
213 | /* Here is the gap |
---|
214 | ****************************/ |
---|
215 | if ((prevEndTime + invSampRate + smallValue) < startTime ) |
---|
216 | return (startTime - prevEndTime - invSampRate); /*positive */ |
---|
217 | |
---|
218 | /* Here is the overlap |
---|
219 | ***************************/ |
---|
220 | if ((prevEndTime + invSampRate - smallValue) > startTime ) |
---|
221 | return (startTime - prevEndTime - invSampRate); /* negative */ |
---|
222 | |
---|
223 | return 0; |
---|
224 | } |
---|
225 | /****************************************************************************/ |
---|
226 | long ew2mseedAddData (int *buffer, char *msg_p, long position, int bufLen, char swap, int bytesPerSample) |
---|
227 | { float *fBuf = NULL; |
---|
228 | int *iBuf = NULL; |
---|
229 | short *sBuf= NULL; |
---|
230 | int i; |
---|
231 | |
---|
232 | if (swap == 't' && bytesPerSample == 8) /*t8 SUN IEEE double precision real */ |
---|
233 | { |
---|
234 | for (i = 0; i< bufLen; i ++) |
---|
235 | { |
---|
236 | double tmp; |
---|
237 | tmp = *(sBuf + i); |
---|
238 | #if defined _INTEL |
---|
239 | ew2mseed_SwapDouble(&tmp, 't'); |
---|
240 | #endif |
---|
241 | *(buffer + i+ position) = (int)tmp; |
---|
242 | } |
---|
243 | } |
---|
244 | else if (swap == 't' && bytesPerSample == 4) /*t4 SUN IEEE single precision real */ |
---|
245 | { |
---|
246 | fBuf = (float *) msg_p; |
---|
247 | for (i = 0; i< bufLen; i ++) |
---|
248 | { |
---|
249 | *(buffer + i+ position) = (int) *(fBuf + i); |
---|
250 | #if defined _INTEL |
---|
251 | SwapInt(buffer+i+position); |
---|
252 | #endif |
---|
253 | } |
---|
254 | } |
---|
255 | else if (swap == 's' && bytesPerSample == 4) /*s4 SUN IEEE integer */ |
---|
256 | { |
---|
257 | iBuf = (int *) msg_p; |
---|
258 | for (i = 0; i< bufLen; i ++) |
---|
259 | { |
---|
260 | *(buffer + i+ position) = (int) *(iBuf + i); |
---|
261 | #if defined _INTEL |
---|
262 | SwapInt(buffer+i+position); |
---|
263 | #endif |
---|
264 | } |
---|
265 | } |
---|
266 | else if (swap == 's' && bytesPerSample == 2) /*s2 SUN IEEE short integer */ |
---|
267 | { |
---|
268 | sBuf = (short *) msg_p; |
---|
269 | for (i = 0; i< bufLen; i ++) |
---|
270 | { |
---|
271 | short tmp; |
---|
272 | tmp = *(sBuf + i); |
---|
273 | #if defined _INTEL |
---|
274 | ew2mseed_SwapShort(&tmp, 's'); |
---|
275 | #endif |
---|
276 | *(buffer + i+ position) = (int) tmp; |
---|
277 | } |
---|
278 | } |
---|
279 | else if (swap == 'f' && bytesPerSample == 8) /*f8 VAX/Intel IEEE double precision real */ |
---|
280 | { |
---|
281 | for (i = 0; i< bufLen; i ++) |
---|
282 | { |
---|
283 | double tmp; |
---|
284 | tmp = *(sBuf + i); |
---|
285 | #if defined _SPARC |
---|
286 | ew2mseed_SwapDouble(&tmp, 'f'); |
---|
287 | #endif |
---|
288 | *(buffer + i+ position) = (int) tmp; |
---|
289 | } |
---|
290 | } |
---|
291 | else if (swap == 'f' && bytesPerSample == 4) /*f4 VAX/Intel IEEE single precision real */ |
---|
292 | { |
---|
293 | fBuf = (float *) msg_p; |
---|
294 | for (i = 0; i< bufLen; i ++) |
---|
295 | { |
---|
296 | *(buffer + i+ position) = (int) *(fBuf + i); |
---|
297 | #if defined _SPARC |
---|
298 | SwapInt(buffer+i+position); |
---|
299 | #endif |
---|
300 | } |
---|
301 | } |
---|
302 | else if (swap == 'i' && bytesPerSample == 4) /*i4 VAX/Intel IEEE integer */ |
---|
303 | { |
---|
304 | iBuf = (int *) msg_p; |
---|
305 | for (i = 0; i< bufLen; i ++) |
---|
306 | { |
---|
307 | *(buffer + i+ position) = (int) *(iBuf + i); |
---|
308 | #if defined _SPARC |
---|
309 | SwapInt(buffer+i+position); |
---|
310 | #endif |
---|
311 | } |
---|
312 | } |
---|
313 | else if (swap == 'i' && bytesPerSample == 2) /*i2 VAX/Intel IEEE short integer */ |
---|
314 | { |
---|
315 | sBuf = (short *) msg_p; |
---|
316 | for (i = 0; i< bufLen; i ++) |
---|
317 | { |
---|
318 | short tmp; |
---|
319 | tmp = *(sBuf + i); |
---|
320 | #if defined _SPARC |
---|
321 | ew2mseed_SwapShort(&tmp, 'i'); |
---|
322 | #endif |
---|
323 | *(buffer + i+ position) = (int) tmp; |
---|
324 | } |
---|
325 | } |
---|
326 | else |
---|
327 | { |
---|
328 | return -1; |
---|
329 | } |
---|
330 | |
---|
331 | return (position + bufLen); |
---|
332 | } |
---|
333 | |
---|
334 | /****************************************************************************/ |
---|
335 | int getBufferShift (double reqStarttime, double actStarttime, double samprate) |
---|
336 | { |
---|
337 | int myshift; |
---|
338 | double timeDiff; |
---|
339 | double verySmall = 0.000001; |
---|
340 | |
---|
341 | if (reqStarttime < actStarttime) |
---|
342 | { |
---|
343 | if (reqStarttime + 0.5/samprate >= actStarttime ) |
---|
344 | return 0; |
---|
345 | else |
---|
346 | return -1; |
---|
347 | } |
---|
348 | |
---|
349 | timeDiff = reqStarttime - actStarttime; |
---|
350 | myshift = (int) nearbyint(timeDiff * samprate); |
---|
351 | while (1) |
---|
352 | { |
---|
353 | if ( actStarttime + myshift/samprate - reqStarttime >= (0.5/samprate)) |
---|
354 | { |
---|
355 | if (fabs(actStarttime + myshift/samprate - reqStarttime - 0.5/samprate) < verySmall ) |
---|
356 | { |
---|
357 | printf("fabs = %f\n", fabs(actStarttime + myshift/samprate - reqStarttime - 0.5/samprate)); |
---|
358 | break; |
---|
359 | } |
---|
360 | myshift--; |
---|
361 | } |
---|
362 | else if (actStarttime + myshift/samprate - reqStarttime < -0.5/samprate) |
---|
363 | { |
---|
364 | myshift++; |
---|
365 | } |
---|
366 | else |
---|
367 | break; |
---|
368 | } |
---|
369 | /* printf("%d %f %f %f\n", myshift, actStarttime + myshift/samprate - reqStarttime, samprate, timeDiff); */ |
---|
370 | return myshift; |
---|
371 | |
---|
372 | } |
---|
373 | |
---|
374 | /****************************************************************************/ |
---|
375 | |
---|
376 | int checkCompilationFlags (char *prog) |
---|
377 | { int retVal = -2; |
---|
378 | #ifdef _SPARC |
---|
379 | retVal = 1; |
---|
380 | #endif |
---|
381 | #ifdef _INTEL |
---|
382 | retVal = 1; |
---|
383 | #endif |
---|
384 | if(retVal == -2) |
---|
385 | { |
---|
386 | fprintf(stderr, "-------------------------------------------------------\n"); |
---|
387 | fprintf(stderr, "%s should be compiled with -D_SPARC or -D_INTEL flags only!\n", prog); |
---|
388 | fprintf(stderr, "Please recompile the program with this flag\n"); |
---|
389 | fprintf(stderr, "-------------------------------------------------------\n"); |
---|
390 | } |
---|
391 | |
---|
392 | return(retVal); |
---|
393 | } |
---|
394 | |
---|
395 | char *strDate( double epochTime, char *dd) |
---|
396 | { |
---|
397 | /* Warning: dd should be allocated outside ! */ |
---|
398 | |
---|
399 | |
---|
400 | /* SEC1970 is a convertion from epoch to julian seconds */ |
---|
401 | date20(epochTime + SEC1970, dd); |
---|
402 | return dd; |
---|
403 | } |
---|
404 | |
---|
405 | /**********************************************************/ |
---|
406 | |
---|
407 | double findNewFileJulTime (double jtime) |
---|
408 | { |
---|
409 | double nextDayJtime; |
---|
410 | EXT_TIME ext_time; |
---|
411 | |
---|
412 | ext_time = int_to_ext (tepoch_to_int(jtime)); |
---|
413 | ext_time.hour = 0; |
---|
414 | ext_time.minute = 0; |
---|
415 | ext_time.second = 0; |
---|
416 | ext_time.usec = 0; |
---|
417 | /* next day */ |
---|
418 | nextDayJtime = int_to_tepoch(ext_to_int(ext_time)) + 24 * 60 *60; |
---|
419 | return (nextDayJtime); |
---|
420 | } |
---|
421 | /* IGD 03/14/01 Modified for SIGALRM and |
---|
422 | *********************************/ |
---|
423 | void signal_handler (int sig) |
---|
424 | { |
---|
425 | if (sig == SIGUSR1) |
---|
426 | ew_signal_flag = EW2MSEED_MAKE_REPORT; |
---|
427 | else if (sig == SIGALRM) |
---|
428 | ew_signal_flag = EW2MSEED_ALARM; |
---|
429 | else |
---|
430 | ew_signal_flag = EW2MSEED_TERMINATE; |
---|
431 | signal(sig, signal_handler); /*Re-install handler */ |
---|
432 | } |
---|
433 | |
---|
434 | void finish_handler (RINGS *rn) |
---|
435 | { |
---|
436 | fprintf(stderr, "TERMINATION SIGNAL ARRIVED\n"); |
---|
437 | fprintf(stderr, "PROGRAM EXITS NOW\n"); |
---|
438 | logit("pt", "TERMINATION SIGNAL ARRIVED\n"); |
---|
439 | logit("pt", "PROGRAM EXITS NOW\n"); |
---|
440 | ew_signal_flag = EW2MSEED_OK; |
---|
441 | exit(0); |
---|
442 | } |
---|
443 | |
---|
444 | void ew2mseedGenReport (RINGS *p_rn) |
---|
445 | { |
---|
446 | |
---|
447 | |
---|
448 | fprintf(stderr, "STATE-OF-HEALTH REPORT REQUEST RECEIVED\n"); |
---|
449 | ew2mseed_logconfig(p_rn); |
---|
450 | |
---|
451 | fprintf(stderr, "REPORT IS WRITTEN INTO THE LOG FILE\n"); |
---|
452 | ew_signal_flag = EW2MSEED_OK; |
---|
453 | |
---|
454 | |
---|
455 | } |
---|
456 | |
---|
457 | int checkLock (char * lockfile) |
---|
458 | { |
---|
459 | int status; |
---|
460 | if (lockfile == NULL) |
---|
461 | { |
---|
462 | fprintf(stderr, "This instance of ew2mseed does not use the locking mechanism!\n"); |
---|
463 | fprintf(stderr, "Multiple copies of ew2mseed are allowed to write into a single data file\n"); |
---|
464 | fprintf(stderr, "To enable locking set LockFile parameter in the configuration file\n"); |
---|
465 | logit ("", "This instance of ew2mseed does not use the locking mechanism!\n"); |
---|
466 | logit("", "Multiple copies of ew2mseed are allowed to write into a single data file\n"); |
---|
467 | logit("", "To enable locking set LockFile parameter in the configuration file\n"); |
---|
468 | return(0); |
---|
469 | } |
---|
470 | |
---|
471 | if ((lockfd = open (lockfile, O_RDWR|O_CREAT,0644)) < 0) |
---|
472 | { |
---|
473 | fprintf (stderr, "Error in ew2mseed: Unable to open lockfile: %s\n", lockfile); |
---|
474 | logit ("pt", "Error in ew2mseed: Unable to open lockfile: %s\n", lockfile); |
---|
475 | return (-1); |
---|
476 | } |
---|
477 | #ifdef _CYGWIN |
---|
478 | if ((status=flock(lockfd, LOCK_EX|LOCK_NB)) < 0) |
---|
479 | #else |
---|
480 | if ((status=lockf (lockfd, F_TLOCK, 0)) < 0) |
---|
481 | #endif |
---|
482 | { |
---|
483 | fprintf (stderr, "Error in ew2mseed: Unable to lock lockfile: %s status=%d errno=%d\n", |
---|
484 | lockfile, status, errno); |
---|
485 | logit ("pt", "Error in ew2mseed Unable to lock daemon lockfile: %s status=%d errno=%d\n", |
---|
486 | lockfile, status, errno); |
---|
487 | return(-2); |
---|
488 | } |
---|
489 | close(lockfd); |
---|
490 | |
---|
491 | if ((lockfd = open (lockfile, O_RDWR|O_CREAT|O_TRUNC,0644)) < 0) |
---|
492 | { |
---|
493 | fprintf (stderr, "Error in ew2mseed: Unable to open lockfile: %s\n", lockfile); |
---|
494 | logit ("pt", "Error in ew2mseed: Unable to open lockfile: %s\n", lockfile); |
---|
495 | return (-1); |
---|
496 | } |
---|
497 | |
---|
498 | #ifdef _CYGWIN |
---|
499 | if ((status=flock(lockfd, LOCK_EX|LOCK_NB)) < 0) |
---|
500 | #else |
---|
501 | if ((status=lockf (lockfd, F_TLOCK, 0)) < 0) |
---|
502 | #endif |
---|
503 | { |
---|
504 | fprintf (stderr, "Error in ew2mseed: Unable to lock lockfile: %s status=%d errno=%d\n", |
---|
505 | lockfile, status, errno); |
---|
506 | logit ("pt", "Error in ew2mseed Unable to lock daemon lockfile: %s status=%d errno=%d\n", |
---|
507 | lockfile, status, errno); |
---|
508 | return(-2); |
---|
509 | } |
---|
510 | return(1); /*Success */ |
---|
511 | |
---|
512 | } |
---|
513 | /*---------------------------------------------------------*/ |
---|
514 | /* IGD 02/05/01 a function to reset TRACE_REQ * strucuture */ |
---|
515 | |
---|
516 | int resetWsTrace (TRACE_REQ* trace, double startTime, double endTime) |
---|
517 | { |
---|
518 | trace->bufLen = 0; |
---|
519 | trace->reqStarttime = startTime; |
---|
520 | trace->reqEndtime = endTime; |
---|
521 | free(trace->pBuf); |
---|
522 | trace->pBuf = (char *)NULL; |
---|
523 | trace->timeout = 0; |
---|
524 | trace->actStarttime = 0; |
---|
525 | trace->actEndtime = 0; |
---|
526 | trace->actLen = 0; |
---|
527 | trace->retFlag = 0; |
---|
528 | return 0; |
---|
529 | } |
---|
530 | |
---|
531 | /* IGD this function is added on 02/05/01 */ |
---|
532 | |
---|
533 | void logFailedSCN (struct SCN_ring *failedTrace, char *lockFN) |
---|
534 | { |
---|
535 | |
---|
536 | char line[100]; |
---|
537 | char locId[5]; |
---|
538 | char alg[7]; |
---|
539 | memset(&locId[0], '\0', 5); |
---|
540 | if (failedTrace->locId[0] == '\000') |
---|
541 | strcpy(locId, "NONE"); |
---|
542 | else |
---|
543 | strncpy(locId, failedTrace->locId, 2); |
---|
544 | if (failedTrace->CompAlg == 11) |
---|
545 | strcpy(alg, "STEIM2"); |
---|
546 | else if (failedTrace->CompAlg == 10) |
---|
547 | strcpy(alg, "STEIM1"); |
---|
548 | else |
---|
549 | strcpy(alg, "ALG???"); |
---|
550 | sprintf(line, "SCNLocSZ %s %s %s %s %d %s\n", |
---|
551 | failedTrace->traceRec.sta, failedTrace->traceRec.chan, |
---|
552 | failedTrace->traceRec.net, locId, failedTrace->logRec, alg); |
---|
553 | |
---|
554 | logit("pt", "Trace %s is removed from ew2mseed loop\n", line); |
---|
555 | |
---|
556 | if (lockfd == -1 ) |
---|
557 | fprintf(stderr, "Trace %s is removed from ew2mseed loop\n", line); |
---|
558 | else |
---|
559 | write(lockfd, line, strlen(line)); |
---|
560 | return; |
---|
561 | } |
---|
562 | |
---|
563 | |
---|
564 | /* IGD 03/29/02 Computes priority for catchup algorithm */ |
---|
565 | |
---|
566 | void updatePriorityValues(RINGS *rn) |
---|
567 | { |
---|
568 | struct SCN_ring *scn_head; |
---|
569 | int i; |
---|
570 | int j = 0; |
---|
571 | double meanSystemTime = 0; |
---|
572 | double timeFromTank = 0; |
---|
573 | int priorityFactor = 3600 * 24; /* 1 day */ |
---|
574 | int priority; |
---|
575 | int TankPriority; |
---|
576 | int previous_priority; |
---|
577 | |
---|
578 | /* Get the ring start */ |
---|
579 | scn_head = rn->scnRing; |
---|
580 | |
---|
581 | for (i = 0; i< rn->SCN_avail; i++) |
---|
582 | { |
---|
583 | /* Process uninitialized cases */ |
---|
584 | if (rn->scnRing->prevStarttime <= 0 || |
---|
585 | rn->scnRing->prevEndtime <= 0) |
---|
586 | { |
---|
587 | rn->scnRing->lastRequestTime = -1; |
---|
588 | } |
---|
589 | else /* Normal cases */ |
---|
590 | { |
---|
591 | rn->scnRing->lastRequestTime = |
---|
592 | rn->scnRing->prevEndtime; |
---|
593 | meanSystemTime += rn->scnRing->lastRequestTime; |
---|
594 | j++; |
---|
595 | } |
---|
596 | rn->scnRing = rn->scnRing->next; |
---|
597 | } |
---|
598 | |
---|
599 | meanSystemTime /= j; |
---|
600 | |
---|
601 | /* distribute priorities */ |
---|
602 | for (i = 0; i< rn->SCN_avail; i++) |
---|
603 | { |
---|
604 | /* See how far away we are from tank start */ |
---|
605 | timeFromTank = rn->scnRing->lastRequestTime - |
---|
606 | rn->scnRing->tankStarttime; |
---|
607 | if (timeFromTank < 900) /* 15 mins */ |
---|
608 | TankPriority = rn->PriorityHighWater; |
---|
609 | else if (timeFromTank < 1800) |
---|
610 | TankPriority = rn->PriorityHighWater/2; |
---|
611 | else |
---|
612 | TankPriority = 1; |
---|
613 | |
---|
614 | previous_priority = rn->scnRing->priority; |
---|
615 | |
---|
616 | priority = (meanSystemTime - rn->scnRing->lastRequestTime) / |
---|
617 | priorityFactor; |
---|
618 | if (TankPriority > priority) |
---|
619 | priority = TankPriority; |
---|
620 | |
---|
621 | if (priority < 0) |
---|
622 | rn->scnRing->priority = 1; |
---|
623 | else if (priority > rn->PriorityHighWater) |
---|
624 | rn->scnRing->priority = rn->PriorityHighWater; |
---|
625 | else |
---|
626 | rn->scnRing->priority = priority; |
---|
627 | |
---|
628 | rn->scnRing->timeInterval = rn->scnRing->timeInterval / previous_priority * rn->scnRing->priority; |
---|
629 | |
---|
630 | if (rn->verbosity > 3) |
---|
631 | { |
---|
632 | logit("pt", " SCN-%d = %7s %7s %7s %7s : priority (%1d) %10.1f secs later than mean\n", |
---|
633 | i, rn->scnRing->traceRec.sta, |
---|
634 | rn->scnRing->traceRec.chan, |
---|
635 | rn->scnRing->traceRec.net, |
---|
636 | rn->scnRing->locId, |
---|
637 | rn->scnRing->priority, |
---|
638 | meanSystemTime - rn->scnRing->lastRequestTime); |
---|
639 | |
---|
640 | logit("pt", " SCN-%d = %7s %7s %7s %7s: time interval is set to %f s\n", |
---|
641 | i, rn->scnRing->traceRec.sta, |
---|
642 | rn->scnRing->traceRec.chan, |
---|
643 | rn->scnRing->traceRec.net, |
---|
644 | rn->scnRing->locId, |
---|
645 | rn->scnRing->timeInterval); |
---|
646 | |
---|
647 | } |
---|
648 | rn->scnRing = rn->scnRing->next; |
---|
649 | |
---|
650 | |
---|
651 | } |
---|
652 | |
---|
653 | /* Set back the start of the ring */ |
---|
654 | rn->scnRing = scn_head; |
---|
655 | |
---|
656 | return; |
---|
657 | } |
---|