source: trunk/src/archiving/ew2mseed/ew2mseed_files.c @ 7514

Revision 7514, 44.3 KB checked in by baker, 7 weeks ago (diff)

silence warning: suggest braces around empty body in an ‘else’ statement [-Wempty-body]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*=====================================================================
2// Copyright (C) 2000-2007 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/*
59**   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE
60**   CHECKED IT OUT USING THE COMMAND CHECKOUT.
61**
62**    $Id$
63**
64**      Revision history:
65**      $Log$
66**      Revision 1.2  2010/04/28 13:48:49  ilya
67**      Update to sync with IRIS DMC version
68**
69**      Revision 1.14  2010/04/23 18:45:45  ilya
70**      Fixed a bug in error message related to failed ms_pack()
71**     
72**      Revision 1.13  2010/04/23 18:39:08  ilya
73**      Fixed logging for ms_pack failed return value
74**     
75**      Revision 1.12  2009/12/21 17:31:28  ilya
76**      Fixed a problem which widened gaps in the beginning of day files
77**     
78**      Revision 1.11  2008/12/29 17:49:02  ilya
79**      Fixes to suypport long period channels
80**     
81**      Revision 1.10  2007/09/17 16:29:48  ilya
82**      Fixing problems with 78.1 EW integration
83**     
84**      Revision 1.9  2007/04/12 19:21:04  hal
85**      Added ew7.0+ support (-dSUPPORT_SCNL) and linux port (-D_LINUX)
86**     
87**      -Hal
88**     
89**      Revision 1.8  2006/09/20 21:12:13  ilya
90**      Apperantly fixed the lepseconds bug
91**     
92**      Revision 1.7  2006/07/17 17:26:02  ilya
93**      7/17/06
94**     
95**      Revision 1.6  2005/03/23 03:24:25  ilya
96**      Fixed alighnment of data in BUD volumes
97**     
98**      Revision 1.5  2003/03/12 19:09:34  ilya
99**      Patched condition generated by buggy waverserver
100**     
101**      Revision 1.4  2002/05/13 16:54:03  ilya
102**      More changes for not writing into the wrong file
103**     
104**      Revision 1.3  2002/05/03 02:35:09  ilya
105**      BUG fix: MSEED records -> wrong files
106**     
107**      Revision 1.2  2002/02/21 21:17:19  ilya
108**      Bug fixed: use SCN->num instead of SCN->avail in init functions
109**     
110**      Revision 1.1.1.1  2002/01/24 18:32:05  ilya
111**      Exporting only ew2mseed!
112**     
113**      Revision 1.1.1.1  2001/11/20 21:47:00  ilya
114**      First CVS commit
115**     
116 * Revision 1.9  2001/02/06  05:54:24  comserv
117 *  new variable writeOut is used to monitor the status of fwrite() in createMseed()
118 *
119 * Revision 1.8  2001/01/26  05:53:12  comserv
120 * Added byteswapping of wf->pinno in createMseed
121 *
122 * Revision 1.7  2001/01/24  05:07:08  comserv
123 * Condition in createFirstMseedFile is fixed
124 *
125 * Revision 1.6  2001/01/18  23:50:30  comserv
126 * Fixed memory leak in ew2mseedUpdateFileName()
127 * Removed TEAR and OVERLAP messages from stderr
128 *
129 * Revision 1.5  2001/01/18  21:58:35  comserv
130 * Modifications to removed overlapped snippets
131 * Algorithm for  computing actEndtime is changed to account for GAPS case
132 *
133 * Revision 1.4  2001/01/17  21:52:14  comserv
134 * Prerelease version ; copyright notice
135 *
136 * Revision 1.3  2001/01/08  22:54:48  comserv
137 * Modifications to speed up
138 *
139 * Revision 1.2  2001/01/04  19:29:57  comserv
140 * Changes reflecting %03d format for jday and fixes required to write correct data into the right files
141 *
142 * Revision 1.1  2000/11/17  06:56:07  comserv
143 * Initial revision
144 *
145*/
146
147/* Standard includes */
148#include <stdio.h>
149#include <string.h>
150#include <stdlib.h>
151#include <errno.h>
152#include <sys/types.h>
153#include <sys/stat.h>
154#include <dirent.h>
155#include <math.h>
156
157/* Includes from Earthworm distribution */
158#include "earthworm.h"
159#include "trace_buf.h"
160
161#include "qlib2.h"
162
163/* Local includes */
164#include "ew2mseed.h"
165
166/* Define MiniSEED fixed header size in bytes */
167/* It could be definced also in qlib2 ms_utils.c */
168#ifndef FIXED_DATA_HDR_SIZE
169#define FIXED_DATA_HDR_SIZE 48
170#endif
171
172
173/*************************************************************************************/
174
175  int filesHandler(RINGS *rn)
176  {     
177        int retVal;
178
179       
180
181  /*  Test and create (if needed) NET/STA subdirs
182   ********************************/
183        retVal = checkNetDirs(rn);
184        if (retVal == EW_FAILURE)
185        {
186                fprintf(stderr, "ew2mseed_files fatal error: checkNetDirs failed\n");   
187                logit("pt", "ew2mseed_files fatal error: checkNetDirs failed\n");
188                exit (-3);     
189        }
190 
191/*  Test and create (if needed) MSEED files
192 * Get the last MSEED time from the existing files
193   ********************************/
194        retVal = setMseedFiles (rn);
195        if (retVal == EW_FAILURE)
196
197        {
198                fprintf(stderr, "ew2mseed_files fatal error: setMseedFiles failed\n"); 
199                logit("pt", "ew2mseed_files fatal error: setMseedFiles failed\n");
200                exit (-4);
201        }
202
203
204        return EW_SUCCESS;     
205  }
206
207/***************************************************************************************/
208
209  int setMseedFiles (RINGS *rn)
210  {     
211        int i;
212        struct SCN_ring *scn_head;
213        char *begFileName;
214
215        scn_head = rn->scnRing;
216        begFileName = (char *) calloc(1, 40);
217
218        /* IGD 02/21/02 Bug fixed : was rn->sc_avail, however the unavalable
219         * stations were not removed from SCN loop yet, that caused the last
220         * few stations to never associate theirselves with the corresponding files.
221         * Thanks, Tim and Sandy
222         */ 
223        for (i = 0 ; i < rn->SCN_num ; i++)
224        {
225                sprintf(begFileName, "%s.%s.%s.%s.",
226                        rn->scnRing->traceRec.sta, rn->scnRing->traceRec.net,
227                        (rn->scnRing->locId[0] == '-') ? "" : rn->scnRing->locId, rn->scnRing->traceRec.chan);
228                rn->scnRing->curMseedFile = getMostRecentMseedFile(rn->scnRing->dir, 
229                                                                        begFileName);
230                if (rn->scnRing->curMseedFile != NULL)
231                {
232                       
233
234                        /* Find the most recent MSEED in this file
235                        ** Get the time right after the last sample
236                        ********************************************/   
237                        rn->scnRing->timeOnFiles = getMostRecentMseedTime
238                                                (rn->scnRing->dir, rn->scnRing->curMseedFile,
239                                                rn->scnRing->traceRec.sta, rn->scnRing->traceRec.net,
240                                                rn->scnRing->traceRec.chan, &(rn->scnRing->mseedSeqNo));
241                        if (rn->scnRing->timeOnFiles < 0)
242                                exit(-7); /* cannot handle the file */
243                        if  (rn->scnRing->timeOnFiles == 0) 
244                        {
245                                rn->scnRing->timeOnFiles = rn->scnRing->tankStarttime + 120;
246
247                                /*  Set the date boundary for the file name changing
248                                 ****************************************/
249                                rn->scnRing->newFileJulTime =  findNewFileJulTime (rn->scnRing->timeOnFiles);
250                                /* rn->scnRing->newFileJulTime = 0; was a bug IGD 01/03/01 */
251                        }
252                        else
253                        {
254                                char *testFileName;
255                                testFileName = createBUDFileName(rn->scnRing->dir, 
256                                                        begFileName, rn->scnRing->timeOnFiles);
257                                /* IGD 05/10/02
258                                 * The only sitution when the strcmp() below does not work is
259                                 *  presumably when we read the time on file from a fully completed
260                                 * file and setting the next MSEED should be set to the next day
261                                 */
262                                if (strcmp(rn->scnRing->curMseedFile, testFileName) != 0)
263                                {       
264                                       
265                                        free(rn->scnRing->curMseedFile);
266                                        rn->scnRing->curMseedFile = createFirstMseedFile (rn->scnRing->dir, 
267                                                        begFileName, rn->scnRing->timeOnFiles);
268                                        rn->scnRing->mseedSeqNo = 1;
269                                        logit ("pt", "New file name is available for writing due to change of date: %s\n",
270                                                rn->scnRing->curMseedFile);
271
272                                }
273
274                                free(testFileName); 
275                               
276                                rn->scnRing->prevEndtime = rn->scnRing->timeOnFiles;
277                                /* Set the date boundary for the file name changing
278                                 **********************************************/       
279                                rn->scnRing->newFileJulTime =  findNewFileJulTime (rn->scnRing->timeOnFiles);
280
281                                logit ("pt", "setMseedFiles found the most recent file %s/%s for %s %s %s\n",
282                                        rn->scnRing->dir, rn->scnRing->curMseedFile, 
283                                        rn->scnRing->traceRec.sta, rn->scnRing->traceRec.net,
284                                        rn->scnRing->traceRec.chan);
285
286                                        logit ("pt", "%s %s %s timeFromFile set to %s\n",
287                                        rn->scnRing->traceRec.sta, rn->scnRing->traceRec.net,
288                                        rn->scnRing->traceRec.chan, strDate(rn->scnRing->timeOnFiles, d20));
289                        }
290                }                               
291                else
292                { 
293
294                        /* No valid files are found: create a new file
295                        ********************************************/
296                        /* If a user-requested cutoff time is
297                         * later than the beginning of the tank, we set the FILE NAME to
298                         * the user-defined date (from configuration)
299                         * Otherwise use tankStartime
300                         ******************************/
301                        if (rn->julStartTime > rn->scnRing->tankStarttime)   /* fix IGD 01/04/01 */
302                                rn->scnRing->curMseedFile = createFirstMseedFile (rn->scnRing->dir, 
303                                                        begFileName, rn->julStartTime);
304                        else
305                                rn->scnRing->curMseedFile = createFirstMseedFile (rn->scnRing->dir, 
306                                                        begFileName, rn->scnRing->tankStarttime);
307                        if (rn->scnRing->curMseedFile == (char *) NULL)
308                                exit (-6); /* Fatal: could not create a file */
309
310                        logit("pt", "setMseedFiles created new file %s/%s\n", 
311                                                rn->scnRing->dir, rn->scnRing->curMseedFile);
312
313                        /*we will start 2 minutes after the beginning of
314                        * the tank : otherwise the data could be removed from the tank
315                        *****************************************************/ 
316                        rn->scnRing->timeOnFiles = rn->scnRing->tankStarttime + 120;
317                }
318
319                /* A last check: if a user-requested cutoff time is
320                 * later than the timeOnFiles, we set the timeOnFile to
321                 * the user-defined time (from configuration)
322                 ******************************/
323                if (rn->julStartTime > rn->scnRing->timeOnFiles)
324                        rn->scnRing->timeOnFiles = rn->julStartTime;   
325
326                /* Here we have enough info to set the requestesed start time
327                 * for the first data snippet                                           
328                 ***********************************************************/
329
330                rn->scnRing->traceRec.reqStarttime = getReqStartTime (rn->scnRing->tankStarttime,
331                                                                rn->scnRing->timeOnFiles);
332               
333                /* We now check for the following:
334                 * Data file has exist, but the data in the tank are for the day after the file date
335                 * We need to start a new file in this case
336                 ********************************************/ 
337                if (rn->scnRing->newFileJulTime > 0 && 
338                        rn->scnRing->traceRec.reqStarttime >= rn->scnRing->newFileJulTime) /*IGD was just = before */
339                {
340                        free(rn->scnRing->curMseedFile);
341                        rn->scnRing->curMseedFile = ew2mseedUpdateFileName
342                                (&(rn->scnRing->traceRec), rn->scnRing->dir, rn->scnRing->locId);
343                        rn->scnRing->mseedSeqNo = 1;
344                        logit ("pt", "New file name is available for writing: %s\n",
345                                rn->scnRing->curMseedFile);
346
347                }
348               
349               
350
351                /* From the reqStarttime we find the gregorian second
352                 * to start the new file (date boundary)
353                 * We only change the file once a day
354                 **********************************************/
355                rn->scnRing->newFileJulTime = findNewFileJulTime (rn->scnRing->traceRec.reqStarttime);
356               
357                                                         
358                rn->scnRing = rn->scnRing->next;
359        }
360       
361        rn->scnRing = scn_head;
362        free (begFileName); 
363        return EW_SUCCESS;
364  }
365
366/****************************************************************************************/
367
368  int checkNetDirs (RINGS *rn)
369  {     
370        char *netName, *staName, *mainDir ;
371        int i;
372        struct SCN_ring *scn_head;
373
374        scn_head = rn->scnRing;
375        mainDir = rn->MseedDir;
376
377        /* IGD 02/21/02 Bug fixed : was rn->sc_avail, however the unavalable
378         * stations were not removed from SCN loop yet, that caused the last
379         * few stations to never create corresponding files. Thanks, Tim and
380         * Sandy
381         */ 
382        for (i = 0 ; i < rn->SCN_num ; i++) 
383        {       
384                netName = (char *) calloc(1, strlen(mainDir) +
385                                         strlen(rn->scnRing->traceRec.net) + 2);
386                sprintf(netName, "%s/%s", mainDir, rn->scnRing->traceRec.net);
387                if (make_dir(netName, 0777) < 0 && errno != EEXIST)
388                {
389                        logit ("pt", "ew2mseed_files: cannot create directory %s\n",
390                                netName);
391                        fprintf (stderr, "ew2mseed_files fatal error: cannot create directory %s\n",
392                                netName);
393                        free (netName);
394                        perror ("Error message \n");
395                        return EW_FAILURE;
396                }
397                if (errno != EEXIST)
398                        logit("pt", "ew2mseed_files: created directory %s\n", netName); 
399                staName  = (char *) calloc(1, strlen(netName) +
400                                         strlen(rn->scnRing->traceRec.sta) + 2);
401                sprintf(staName, "%s/%s", netName, rn->scnRing->traceRec.sta);
402                if (make_dir(staName, 0777) < 0 && errno != EEXIST)
403                {
404                        logit ("pt", "ew2mseed_files: cannot create directory %s\n",
405                                staName);
406                        fprintf (stderr, "ew2mseed_files fatal error: cannot create directory %s\n",
407                                staName);
408                        perror ("Error message is ");
409                        return EW_FAILURE;
410                }
411                if (errno != EEXIST)
412                        logit("pt", "ew2mseed_files: created directory %s\n", staName); 
413                rn->scnRing->dir = (char *)calloc(1, strlen(staName) + 1);
414                strcpy(rn->scnRing->dir, staName);
415                free(netName); free(staName);
416                rn->scnRing = rn->scnRing->next;               
417        }
418
419        rn->scnRing = scn_head;
420        return EW_SUCCESS;
421  } 
422/*************************************************************************************/
423  int make_dir (char *dirname, int mode)
424  {
425        int status;
426         while((status = mkdir (dirname, mode)) == -1 && errno == EINTR)
427                /*do nothing , just loop */  ;  /* EINTR - interrupted fucntion call */
428
429        return(status);
430  }
431
432/*************************************************************************************/
433  char *getMostRecentMseedFile (char *dirName, char *nameHead)
434  {
435        char *fileName = (char *) NULL;
436        int retVal;
437        DIR *curDir;
438        struct dirent *curDirContent;
439        struct yjd YJD;
440        struct yjd master_YJD; 
441        struct stat buf;
442
443        curDir = opendir(dirName);
444        if (curDir == NULL)
445        {
446                logit("pt", "getMostRecentMseedFile fatal error: %s %s\n", 
447                        strerror(errno), dirName);
448                exit(-5);
449        }
450        master_YJD.year = 0;
451        master_YJD.jday = 0;
452        while ((curDirContent = readdir(curDir)) != NULL)
453        {
454                char curPathName[1000]; 
455                YJD.year=0;
456                YJD.jday=0;
457                sprintf(curPathName, "%s/%s", dirName, curDirContent->d_name);
458                if (isValidMseedName (curDirContent->d_name, &YJD, nameHead) == EW_SUCCESS)
459
460                {
461                        /* 04/26/02 We want to prevent using the empty files as the valid file names
462                         * The code below inspired by the findings of incorrect MSEED dates in a few
463                         * BUD files pointed by Mary
464                         * 05/09/02 Fixed a bug in using dirent
465                         */
466                        retVal = stat (curPathName, &buf);
467                        logit("pt", "Processing pathname %s\n", curPathName);
468                        if (retVal < 0)
469                        {       
470                                logit ("pt", "getMostRecentMseedFile: cannot stat %s\n",
471                                        curPathName);
472                                exit(-6); 
473                        }
474                        if (buf.st_size < EW2MSEED_SMALLEST_MSEED)
475                        {
476                                logit ("pt", "getMostRecentMseedFile: %s does not contain MSEEDs\n",
477                                        curPathName);
478                                continue;
479                        }
480
481                        /* 04/26/02 END of new code -> updated 05/09/02 */
482                       
483                        if (YJD.year > master_YJD.year)
484                        {
485                                master_YJD.year = YJD.year;
486                                master_YJD.jday = YJD.jday;                             
487                        }                               
488                        else if (YJD.year == master_YJD.year && 
489                                YJD.jday > master_YJD.jday)
490                        {
491                                master_YJD.year = YJD.year;
492                                master_YJD.jday = YJD.jday;                             
493                        }
494                        else
495                        {}
496                }
497        }
498
499        /* close dir
500         ***********************/
501        closedir (curDir);
502       
503        /*  Construct an output filename
504         ***********************/
505        if (master_YJD.year > 0)       
506        {
507                fileName = (char *) calloc(1, strlen(nameHead) + 10);
508                sprintf(fileName, "%s%d.%03d", nameHead, master_YJD.year, master_YJD.jday);
509        }
510        return(fileName);
511  }
512
513/*******************************************************************************/
514
515  int isValidMseedName (char *fileName, struct yjd *YJD, char *nameHead) 
516  {
517        char *nameTail;
518        short year, jday;
519        /* Just in case
520         *****************/
521        YJD->year = 0;
522        YJD->jday = 0;
523
524        if (strncasecmp(fileName, nameHead, strlen(nameHead)) != 0)
525                return EW_FAILURE;
526        else
527        {       
528                nameTail = fileName + strlen(nameHead);
529                year = (short)(atoi(strtok(nameTail, ".")));
530                jday = (short)(atoi(strtok(NULL, ".")));
531       
532                /* Rudimentary check of the results
533                 *******************************/
534                if (year < 1000 || year > 3000)
535                        return EW_FAILURE;
536                if (jday < 1 || jday > 365)
537                        return EW_FAILURE;
538
539                /* If we are here we are OK
540                 *************************/
541                YJD->year = year;
542                YJD->jday = jday;                       
543        }
544
545        return EW_SUCCESS;
546  }
547/* Returns the epoch time of the next sample right after the last sample      */
548/* in the MSEED file. If the file not found or any other fatal error occurs,  */
549/* returns -1; If the file exist, but empty : returns 0                       */
550/******************************************************************************/
551  double getMostRecentMseedTime (char *dir, char *filename, char *sta, char *net, char *chan, long *seqNo)     
552  {     
553        char *pathname;
554        int retVal;
555        int i;
556        FILE * fid;
557        double startTime;
558        double nextRecordTime;
559        struct stat *buf;
560        SDR_HDR *mseed_hdr;
561        void *inBuf;
562        int smallestMseedSize = EW2MSEED_SMALLEST_MSEED; /*in bytes: first 64 bytes are always a header */
563        int bytesRead;
564        short foundFlag = FALSE;
565       
566        *seqNo = 1;
567        buf = (struct stat *) calloc(1, sizeof(struct stat));
568        pathname = (char *)calloc(1, strlen(dir) + strlen(filename) + 2);
569       
570        sprintf(pathname, "%s/%s", dir, filename);
571        retVal = stat (pathname, buf);
572        if (retVal < 0)
573        {
574                fprintf(stderr, "getMostRecentMseedTime fatal error: cannot stat %s\n", pathname);
575                perror("Error: ");
576                logit ("pt",  "getMsotRecentMseedTime fatal error: cannot stat %s\n", pathname);
577                free(pathname); free(buf);
578                return -1;
579        }
580        if (buf->st_size < FIXED_DATA_HDR_SIZE) /* file is empty or no valid MSEED records */
581        {
582                free(pathname); free(buf);
583                return (0);
584
585        }
586        /* Open the file for reading
587         **************************/
588        fid = fopen (pathname, "rb");
589        if (fid == NULL)
590        {
591                fprintf(stderr, "getMostRecentMseedTime fatal error: cannot open %s\n", pathname);
592                perror("Error: ");
593                logit ("pt",  "getMsotRecentMseedTime fatal error: cannot open %s\n", pathname);
594                free(pathname); free(buf);
595                return -1;
596        }
597        inBuf = (void *) calloc(1, FIXED_DATA_HDR_SIZE);
598        for (i = 0; i< 9; i++)
599        {
600               
601                if (fseek(fid, -(smallestMseedSize), SEEK_END) == -1)
602                {
603                        fprintf(stderr, "getMostRecentMseedTime fatal error: fseek %s failed\n", pathname);
604                        perror("Error: ");
605                        logit ("pt",  "getMsotRecentMseedTime fatal error: fseek %s failed\n", pathname);
606                        free(pathname); free(buf); free(inBuf); fclose(fid);
607                        return -1;
608                }
609                if ((bytesRead = fread(inBuf, 1, FIXED_DATA_HDR_SIZE, fid)) != FIXED_DATA_HDR_SIZE)
610                {
611                        fprintf(stderr, "getMostRecentMseedTime fatal error: fread %s failed\n", pathname);
612                        if (bytesRead == 0)
613                                perror("Error: ");
614                        logit ("pt",  "getMostRecentMseedTime fatal error: fread %s failed\n", pathname);
615                        free(pathname); free(buf); free(inBuf); fclose(fid);
616                        return -1;     
617                }
618 
619                mseed_hdr = (SDR_HDR *) inBuf;
620                if ((strncmp(mseed_hdr->station_id, sta, 2) == 0)
621                        && (strncmp(mseed_hdr->network_id, net, 2) == 0)
622                        && (strncmp(mseed_hdr->channel_id, chan, 2) == 0))
623                        {
624                                foundFlag = TRUE;
625                                break;
626                        }       
627                smallestMseedSize = smallestMseedSize * 2;
628        }
629        /* File has no valid records
630        ********************************/       
631        if (foundFlag == FALSE)
632        {
633                fclose(fid);
634                free (pathname); free(buf); free(inBuf);
635                return 0;
636        }
637       
638        if (mseed_hdr->time.year > 3000) /*IGD 07/17/12: Byte-swapping? */
639          ew2mseed_swapMiniSeedHeader( mseed_hdr );
640         
641               
642#ifdef _SPARC
643        startTime = int_to_tepoch(decode_time_sdr(mseed_hdr->time, SEED_BIG_ENDIAN));
644#endif
645#ifdef _INTEL
646        startTime = int_to_tepoch(decode_time_sdr(mseed_hdr->time, SEED_LITTLE_ENDIAN));
647#endif
648        nextRecordTime = startTime + ((double) mseed_hdr->num_samples)/mseed_hdr->sample_rate_factor;           
649        *seqNo = atol (mseed_hdr->seq_no) + 1;
650       
651        logit ("pt", "start time of old block %s\n", strDate(startTime, d20));
652        logit ("pt", "start time of next block %s\n", strDate(nextRecordTime, d20));
653
654       
655        fclose(fid);
656        free (pathname); free(buf); free(inBuf);
657
658        return (nextRecordTime);
659  }
660
661/***************************************************************************/
662  char *createFirstMseedFile (char * dir, char*begName, double jtime)
663  {     
664        char *fileName = (char *) NULL;
665        char *pathName;
666        struct Greg *gregDate;
667        short jday;
668        FILE *newFD;
669
670        double  sec1970 = SEC1970;
671
672        gregDate = (struct Greg *) calloc(1, sizeof (struct Greg));
673
674        datime (jtime + sec1970, gregDate);
675        if (gregDate->year < 1000 || gregDate->year > 3000)
676        {
677                logit("pt", "fatal error in createMseedFile: year %d is out of range\n",
678                        gregDate->year);
679                fprintf(stderr, "fatal error in createMseedFile: year %d is out of range\n",
680                        gregDate->year);
681                free (gregDate);
682                return ((char *) NULL);
683        }       
684
685        jday = getJdayFromGreg(gregDate);
686
687        if (jday < 1 || jday > 366 ) /* IGD 01/24/01 Fix 366 is valid once in 4 years*/
688        {
689                logit("pt", "fatal error in createMseedFile: julian day %d is invalid\n",
690                        jday);
691                fprintf(stderr, "fatal error in createMseedFile: julian day %d is invalid\n",
692                        jday);
693                free (gregDate);
694                return ((char *) NULL);
695        }
696        fileName = (char *) calloc (1, strlen(begName)+15);
697        sprintf(fileName, "%s%d.%03d", begName, gregDate->year, jday);
698        pathName = (char *) calloc(1, strlen (fileName) + strlen(dir) + 2);
699        sprintf(pathName, "%s/%s", dir, fileName);     
700
701        if ((newFD = fopen(pathName, "ab+")) == NULL)
702        {
703                logit("pt", "fatal error in createMseedFile: cannot open file %s\n",
704                        pathName);
705
706                fprintf(stderr, "fatal error in createMseedFile: cannot open file %s\n",
707                        pathName);
708                perror("Reason for error: ");
709                free (gregDate);
710                return ((char *) NULL);
711        }
712        fclose (newFD); 
713        free(gregDate); free(pathName);
714        return(fileName);
715  }
716
717/***************************************************************************/
718  char *createBUDFileName (char * dir, char*begName, double jtime)
719  {     
720        char *fileName = (char *) NULL;
721        char *pathName;
722        struct Greg *gregDate;
723        short jday;
724
725        double  sec1970 = SEC1970;
726
727        gregDate = (struct Greg *) calloc(1, sizeof (struct Greg));
728
729        datime (jtime + sec1970, gregDate);
730        if (gregDate->year < 1000 || gregDate->year > 3000)
731        {
732                logit("pt", "fatal error in createMseedFile: year %d is out of range\n",
733                        gregDate->year);
734                fprintf(stderr, "fatal error in createMseedFile: year %d is out of range\n",
735                        gregDate->year);
736                free (gregDate);
737                return ((char *) NULL);
738        }       
739
740        jday = getJdayFromGreg(gregDate);
741
742        if (jday < 1 || jday > 366 ) /* IGD 01/24/01 Fix 366 is valid once in 4 years*/
743        {
744                logit("pt", "fatal error in createMseedFile: julian day %d is invalid\n",
745                        jday);
746                fprintf(stderr, "fatal error in createMseedFile: julian day %d is invalid\n",
747                        jday);
748                free (gregDate);
749                return ((char *) NULL);
750        }
751        fileName = (char *) calloc (1, strlen(begName)+15);
752        sprintf(fileName, "%s%d.%03d", begName, gregDate->year, jday);
753        pathName = (char *) calloc(1, strlen (fileName) + strlen(dir) + 2);
754        sprintf(pathName, "%s/%s", dir, fileName);             
755        free(gregDate); free(pathName);
756        return(fileName);
757  }
758
759/***************************************************************/
760
761  char *ew2mseedUpdateFileName(TRACE_REQ *p_trace, char *dir, char *locId)
762  {
763        char *fileName;
764        char *begFileName;
765        begFileName = (char *) calloc(1, 40);
766        sprintf(begFileName, "%s.%s.%s.%s.",
767                p_trace->sta, p_trace->net,
768                '-' == locId[0] ? "" : locId, p_trace->chan);
769                                fileName = createFirstMseedFile (dir, 
770                                                        begFileName, p_trace->reqStarttime);
771        free(begFileName);
772
773        return(fileName);
774  }
775
776/****************************************************************************/
777 short getJdayFromGreg (struct Greg *gregDate)
778 {
779        short jday;
780        struct Greg *gregDateBegYear;
781       
782        gregDateBegYear = (struct Greg *) calloc(1, sizeof (struct Greg));
783               
784        gregDateBegYear->year = gregDate->year;
785        gregDateBegYear->month = 1;
786        gregDateBegYear->day = 1;
787        gregDateBegYear->hour = gregDate->hour ;
788        gregDateBegYear->minute = gregDate->minute ;
789        gregDateBegYear->second = gregDate->second ;
790
791        /* +1 is because if jday == Jan 1 and gregDateBegYear == Jan 1
792         * jday is 0, but it should be 1!!!
793         ********************************/
794        jday = (short)(julian(gregDate) - julian (gregDateBegYear) + 1) ;
795        free(gregDateBegYear);
796        return(jday);
797 } 
798
799/******************************************************************************/
800
801  double getReqStartTime (double tankStartTime, double timeFromLastFile)
802  {
803        if (tankStartTime >= timeFromLastFile)
804                return(tankStartTime);
805        else
806                return(timeFromLastFile);       
807   }
808
809/*****************************************************************************/
810
811  int createMseed (struct SCN_ring *scnRing,
812
813                                 short verbosity)
814        {
815        TRACE_REQ * trace = &(scnRing->traceRec);
816        double samprate = scnRing->samprate;
817        short mseed_data_type = scnRing->CompAlg;
818        int blocksize = scnRing->logRec;
819        char *locId = scnRing->locId;
820        long *mseedSeqNo = &(scnRing->mseedSeqNo);
821        long *gapCount = &(scnRing->gapsCount);         
822        double *oldStarttime = &(scnRing->prevStarttime);
823        double *oldEndtime = &(scnRing->prevEndtime); 
824        double timeAdvance = scnRing->timeInterval; 
825                                       
826        char pathname[500];
827        FILE *fid;                                                     
828        char *msg_p;                    /* Pointer into tracebuf data */
829        char *ms = NULL;                /* MiniSeed output structure */
830        char **pp_ms;                   /* Pointer to *ms */ 
831        char p_errmsg[1000];            /* Error message string */
832        char tear_errmsg[1000] = "";            /* Tear error message */
833
834
835        double prevEndTime;             /* Tracks the endtime obtained from the previous tracebuf wf */
836        double afterGapTime;            /* Time after the gap */
837        double gapInSec=0;              /* Gap in seconds */
838        double newReqStartTime;         /* Variable to compute the new trace->reqStarttime */
839        double smallValue;
840        double actStarttime;            /* Actual starting time of data we  write in the file */
841        double actEndtime;              /* Actual end time of data we write into the file */
842
843        int retVal;
844        int bytesPerSample;             /* How many bytes are in a single sample of WaveServer data */
845        int snipCount = 0;              /* Current number of snippets in the input trace->pBuf: not used */
846        int shiftInCounts;              /* How many counts between trace->actStarttime and trace->reqStarttime */
847        int numSamples = 0;             /* Number of data samples we have read from trace->pBuf so far */
848        int n_blocks = 0;               /* Number of MSEED blocks created */
849        int *buffer;                    /* Input data buffer for ms_pack_data() started at trace->actStarttime */
850        int *buffer1;                   /* The same buffer but started at trace-> reqStarttime */
851        int *bufferTmp;                 /* Buffer for reallocation*/ 
852        long position = 0;              /* Our current position in the input temp buffer */
853        int gapFlag = FALSE;            /* Indicates  we found the gap in the requested trace buffer */
854        int overlapFlag = FALSE;        /* Indicates if the overlap is found in the requested trace buffer */   
855        int writeOut;                   /* Return of write */
856        int bufferSizeInSamples;        /* A size of allocated temp data buffer new 11/26/01 */
857
858        DATA_HDR *mseed_hdr = NULL;     /*Fixed MiniSEED header from qlib2*/
859        TRACE_HEADER *wf;               /* Trace header from trace->pBuf : defined in ew trace_buf.h */         
860        SDR_HDR* curBlock;              /* MiniSEED standard header for the block we write */
861        SDR_HDR* lastBlock;             /* MiniSEED standard header */ 
862        BS *init_bs = NULL;             /* Temp structure required by ms_pack_data() */ 
863
864        /* Define smallValue as
865         ***************************/
866        smallValue = 1./(samprate * 10.);
867
868        /* Check if we have a proper trace buffer
869         * Something should be seriously wrong if it is not so and we must return
870         ******************************************************/
871        if (!trace)
872                return TRACE_REQ_EMPTY;
873
874        /* For the proper work of this function requested time interval
875         *  should be within the actual time interval. If it is not true,
876         * return
877         ********************************************************/ 
878       
879        /* Get trace headers  and  snippets
880         * If it does not exist, return with error message
881         *****************************************************/
882        msg_p = (char *)trace->pBuf;
883        if (msg_p == NULL)
884                return WS_DATA_BUF_EMPTY;
885
886        /* Here is a header for the first snippet       
887         ********************************************/
888        wf = (TRACE_HEADER *) calloc(1, sizeof(TRACE_HEADER));
889        memcpy(wf, msg_p, sizeof(TRACE_HEADER));
890               
891
892        /* Create and fill fixed MSEED hdr
893         *************************************/
894        mseed_hdr = new_data_hdr();
895
896        /* Fill the mseed_hdr structure
897         *************************************/   
898        memcpy (mseed_hdr->station_id, wf->sta, TRACE2_STA_LEN-1);
899        memcpy (mseed_hdr->channel_id, wf->chan, TRACE2_CHAN_LEN-1); 
900        memcpy (mseed_hdr->network_id, wf->net, 3);
901        if ('-' == locId[0])
902                mseed_hdr->location_id[0] = '\0';
903        else
904                memcpy (mseed_hdr->location_id, locId, 3);
905       
906        mseed_hdr->data_type = mseed_data_type;
907        mseed_hdr->blksize = blocksize;
908        if (samprate >= 1)
909                mseed_hdr->sample_rate = samprate;
910        else
911        {
912                mseed_hdr->sample_rate = 1;
913                mseed_hdr->sample_rate_mult = -(1./samprate + 0.5);
914        }
915        mseed_hdr->seq_no = *mseedSeqNo;
916       
917        /* calloc the tmp integer buffer
918         ***************************************/
919        bufferSizeInSamples = samprate * (trace->actEndtime - trace->actStarttime);
920        buffer = (int *) calloc( 20 + (int) bufferSizeInSamples, sizeof(int));
921
922        if (buffer == NULL)     /* die if cannot get enough memory */
923        {
924                logit("pt", "Fatal error: %s %s %s: cannot calloc %zu bytes\n",
925                        trace->sta, trace->net, trace->chan, bufferSizeInSamples * sizeof(int));
926                exit(-22);
927        }
928
929/* Debug
930        fprintf(stderr, "Buffer size = %d\n",
931         20 + (int) (samprate * (trace->actEndtime - trace->actStarttime)) * sizeof(int));
932*/
933
934        /* Loop over snippets and fill the integer buffer       
935         **************************************************/
936        while (1)
937        {
938                memcpy(wf, msg_p, sizeof(TRACE_HEADER));
939                ew2mseed_SwapInt (&(wf->pinno), wf->datatype[0]); /* IGD 01/26/01 Add this line */
940                ew2mseed_SwapInt (&(wf->nsamp), wf->datatype[0]);
941                ew2mseed_SwapDouble (&(wf->samprate), wf->datatype[0]);
942                ew2mseed_SwapDouble (&(wf->starttime), wf->datatype[0]);
943                ew2mseed_SwapDouble (&(wf->endtime), wf->datatype[0]);
944                msg_p = msg_p + sizeof(TRACE_HEADER); /* Pointer to data */     
945                /* How many bytes per sample?
946                ***********************************************/
947                bytesPerSample = atoi (&wf->datatype[1]);       /* moved this inside the while loop  after detecting midstream change */
948                if ( !(bytesPerSample == 2 || bytesPerSample == 4) ) {
949                        /* terminate the strings in case we have a bogus packet */
950                        wf->net[2] = '\0';
951                        wf->sta[TRACE2_STA_LEN-1] = '\0';
952                        wf->chan[TRACE2_CHAN_LEN-1] = '\0';
953                        logit("pt", "WARNING: bogus wf record being tossed: <%s %s %s>,  datatype not 2 or 4 bytes; %d\n",
954                                wf->sta, wf->net, wf->chan,
955                                bytesPerSample);
956                        break;
957                }
958                /*
959                fprintf(stderr, "nsamp = %d; starttime = %f endtime = %f samp = %f\n",
960                        wf->nsamp, wf->starttime, wf->endtime, wf->samprate);
961                */
962                /* PAF 08/13/2013 check for bad starttime and endtime, observed from a Winston Return recently by Wes Thelen */
963                if (wf->starttime <= 0.0 || wf->endtime <= 0.0 || wf->endtime > 4000000000.0 || wf->starttime > 4000000000.0) 
964                {
965                        /* terminate the strings in case we have a bogus packet */
966                        wf->net[2] = '\0';
967                        wf->sta[TRACE2_STA_LEN-1] = '\0';
968                        wf->chan[TRACE2_CHAN_LEN-1] = '\0';
969                        logit("pt", "WARNING: bogus wf record being tossed: <%s %s %s>, timing problem: wf start time=<%s> wf end time=<%s>\n",
970                                wf->sta, 
971                                wf->net,
972                                wf->chan,
973                                strDate(wf->starttime, d20), 
974                                strDate(wf->endtime, d20a));
975                        if ( wf->nsamp> 0 && wf->nsamp <= 1008 ) 
976                        {
977                                msg_p += (int) (bytesPerSample * wf->nsamp);
978                                if ((long) msg_p >= (long) trace->actLen + (long) trace->pBuf) 
979                                        break;
980                                else 
981                                        continue;
982                        } else {
983                                logit("pt", "WARNING: bogus wf record: <%s %s %s> , nsamp set to <%d>\n",
984                                        wf->sta, 
985                                        wf->net,
986                                        wf->chan,
987                                        wf->nsamp);
988                                break;
989                        }
990                }
991               
992                /* IGD 03/11/03 another time Sanity check */
993                if (wf->endtime  > (trace->actEndtime + 10))
994                {
995                        logit("pt", "WARNING: bogus wfdisk record tossed: <%s %s %s> wf end time <%s> is after trace endtime <%s>\n",
996                                wf->sta, 
997                                wf->net,
998                                wf->chan,
999                                strDate(wf->endtime, d20), 
1000                                strDate(trace->actEndtime, d20a));
1001 
1002                        msg_p += (int) (bytesPerSample * wf->nsamp);
1003                        if ((long) msg_p >= (long) trace->actLen + (long) trace->pBuf) 
1004                                break;
1005                        else 
1006                                continue;
1007                } 
1008                /* If this is not the beginning of data
1009                 *      we check the trace for the gaps and -since Jan. 18, 2000 - overlaps
1010                 ******************************************/                   
1011                if (snipCount != 0)
1012                {
1013                        if ((gapInSec = checkForGaps (prevEndTime, wf->starttime,  samprate)) > 0)     
1014                        {       
1015                                /* Congratulations, we discovered a tear!
1016                                 *****************************************/     
1017                                afterGapTime = wf->starttime;
1018
1019                                /* If shiftInCounts is < 0, trace->reqStarttime < wf->starttime, 
1020                                 *******************************************/
1021                                if ((shiftInCounts = getBufferShift ( trace->reqStarttime, wf->starttime, samprate)) < 0)
1022                                {
1023                                        /* Previous End time is also after requested time
1024                                         ********************************************/ 
1025                                        if (getBufferShift ( trace->reqStarttime, prevEndTime, samprate) < 0)
1026                                        {
1027                                                /* Snippet starttime is before trace->reqEndTime
1028                                                 *********************************************/ 
1029                                                if  (getBufferShift ( wf->starttime, trace->reqEndtime , samprate) < 0)
1030                                                {
1031                                                        /* If we are here, we probably have some data to write in MSEED record
1032                                                         * Increment the gapcount, set the gapflag and break the loop
1033                                                         ***********************************************************************/
1034                                                        gapFlag = TRUE; 
1035                                                        break;                                                                 
1036                                                }               
1037                                                else
1038                                                {
1039                                                        /* This is a case the snippet startime is after our requested end time
1040                                                         * Just set flag to correctly set the future reqTime and break
1041                                                         *********************************************************/
1042                                                        gapFlag = TRUE;
1043                                                        break;                                         
1044                                                }
1045                                        }
1046                                        else
1047                                        {
1048                                                /* This is a case when the tear occurs across the reqStartTime point
1049                                                 * PrevEndTime is before reqStartTime, while the snippet starttime is after
1050                                                 * We should reset the position pointer, set trace->actStarttime,
1051                                                 * trace->reqStarttime to wf->starttime and log the gap
1052                                                 * We should should not set the gap flag
1053                                                ********************************************************/
1054                                                        position = 0L;
1055                                                        trace->reqStarttime = afterGapTime;
1056                                                        trace->actStarttime = afterGapTime;
1057                                                        /* Do not break ! */                                                   
1058                                        }
1059                                }       
1060                                else   
1061                                {
1062                                        /* PrevEndTime and wf->startime are both before
1063                                         * the trace->reqStarttime: this is the gap we don't care about
1064                                         * Reset the position and trace->actStarttime and proceed
1065                                           ***********************************************/
1066                                        position = 0L;
1067                                        trace->actStarttime = afterGapTime;     
1068                                }
1069                        }
1070                        /* Overlap case: toss this snippet
1071                         ********************************/
1072                        if (gapInSec < 0)
1073                        {
1074                                overlapFlag = TRUE; /* to skip this snippet competely */
1075                                sprintf (tear_errmsg, "OVERLAP in %s %s %s (%f s) prevEndTime %s; curSnippetStartTime is %s\n",
1076                                                wf->sta, wf->net, wf->chan, gapInSec, 
1077                                                strDate(prevEndTime, d20), strDate(wf->starttime, d20a));
1078                        /*      fprintf (stderr, "%s", tear_errmsg ); */
1079                                logit ("pt", "%s", tear_errmsg);
1080                                sprintf (tear_errmsg, "OVERLAP in %s %s %s: Snippet <%s : %s > is discarded\n",
1081                                                wf->sta, wf->net, wf->chan, 
1082                                                strDate(wf->starttime, d20), strDate(wf->endtime , d20a));
1083                                logit ("pt", "%s", tear_errmsg);
1084                        /*      fprintf (stderr, "%s", tear_errmsg ); */
1085                        }
1086                }  /*end snipCount !=0 */
1087
1088                /* Add data to the buffer: no gaps or don't-care-gaps so far
1089                **********************************/
1090                if (overlapFlag == FALSE)
1091                {
1092                        /* IGD 11/26/01 Check for overflow of the buffer increase the buffer size conditionally */
1093                        if ((position + wf->nsamp) > bufferSizeInSamples + 20)
1094                        {
1095                                logit ("pt", "Warning: reallocating buffer from %zu bytes to %ld bytes: potential data problems\n",
1096                                        (bufferSizeInSamples + 20) * sizeof(int), trace->actLen);
1097                                if (trace->actLen > bufferSizeInSamples + 20)
1098                                {
1099                                        bufferTmp = (int *) calloc (sizeof(int), bufferSizeInSamples * 2);
1100                                        bufferSizeInSamples *= 2;
1101                                }
1102                                else
1103                                {       
1104                                        bufferTmp = (int *) calloc(1, trace->actLen); 
1105                                        bufferSizeInSamples = (int) (trace->actLen/sizeof(int));
1106                                }
1107                                if (bufferTmp == NULL)  /* die if cannot get enough memory */
1108                                {
1109                                        logit("pt", "Fatal error: %s %s %s: cannot calloc %ld bytes\n",
1110                                        trace->sta, trace->net, trace->chan, trace->actLen);
1111                                        exit(-22);
1112                                }
1113
1114                                memcpy (bufferTmp, buffer, position * sizeof(int));
1115                                free(buffer);
1116                                buffer = bufferTmp;
1117
1118                               
1119                        }
1120                        position = ew2mseedAddData (buffer, msg_p, position, wf->nsamp, wf->datatype[0], bytesPerSample );
1121/* debug
1122                        fprintf(stderr, "position %ld %d\n", position, wf->nsamp * sizeof(int));
1123*/
1124                        if (position == -1) 
1125                                return WRONG_DATA_TYPE;
1126                       
1127
1128                        prevEndTime = wf->endtime;
1129                        snipCount++;           
1130                }
1131                else /* if overlapFlag == TRUE reset it */
1132                        overlapFlag = FALSE;
1133               
1134                msg_p += (int) (bytesPerSample * wf->nsamp);
1135                if ((long) msg_p >= (long) trace->actLen + (long) trace->pBuf) 
1136                        break;
1137        } /*end of while */
1138
1139        shiftInCounts = getBufferShift (trace->reqStarttime, trace->actStarttime, samprate);
1140        if (shiftInCounts == -1) 
1141        {
1142                fprintf(stderr, "Algorithm error: shifting Count == -1\n");
1143                exit (-11);
1144        }
1145
1146        buffer1 = buffer + shiftInCounts;
1147        numSamples = position - shiftInCounts;
1148       
1149       
1150
1151        /* If our data buffer contains data
1152         *      (1) Set time in mseed_hdr
1153         *      (2) Pack data in mseed fromat
1154         *      (3) Update the current file
1155         *************************************/
1156       
1157       
1158        if (numSamples > 0)     
1159        {
1160                mseed_hdr->begtime = tepoch_to_int (trace->actStarttime + (double) shiftInCounts / samprate);
1161                mseed_hdr->hdrtime = tepoch_to_int (trace->actStarttime + (double) shiftInCounts / samprate);
1162               
1163                /*shorten number of samples to fit in a single day volume */
1164                if ((scnRing->newFileJulTime - (trace->actStarttime + (double) shiftInCounts / samprate)) * samprate < numSamples)
1165                {
1166                        int newNumSamples;
1167                        newNumSamples = (scnRing->newFileJulTime - (trace->actStarttime + (double) shiftInCounts / samprate)) * samprate + 1;
1168                        if (newNumSamples < numSamples)
1169                                numSamples = newNumSamples;
1170                        if (newNumSamples < 0)
1171                                numSamples = 0;
1172                        /* IGD 12/21/09 Disable gapFlag if we switch the date */
1173                        gapFlag = FALSE;
1174                }
1175
1176/*              ms = (char *) calloc(10, mseed_hdr->blksize); */
1177                ms = (char *)NULL;
1178                pp_ms = &ms;
1179/*              pp_ms = NULL; */
1180                retVal = ms_pack_data (mseed_hdr, init_bs, numSamples , buffer1, &n_blocks,   
1181                                pp_ms, (int) (10 * mseed_hdr->blksize),  p_errmsg);
1182       
1183                if (retVal > 0) /*IGD 17-Jul-2006 Check for ms_pack_data retVal */
1184                                /* Paulf - modified to check for positive return, all MS error codes are negative */
1185                {
1186                        sprintf(pathname, "%s/%s", scnRing->dir, scnRing->curMseedFile);
1187                        fid = fopen (pathname, "rb+");
1188                        if (fid == NULL)
1189                        {
1190                                logit("pt", "processSingleSCN: cannot open file %s\n", pathname);
1191                                return CANNOT_OPEN_FILE;
1192                        }
1193               
1194                        if (verbosity > 2) logit ("pt", "processSingleSCN: opened file %s for update\n", pathname);
1195
1196                        /* Update the MSEED file
1197                        ****************************/
1198                        fseek (fid, 0L, SEEK_END);
1199                        /* Since the last record is usually not filled completely
1200                        * we are not writing it if we created more than one MSEED record
1201                        ************************************************************/   
1202 
1203                        if (n_blocks > 1)       
1204                                writeOut = 
1205                                    fwrite ((const void *)ms, (size_t)mseed_hdr->blksize, (size_t) n_blocks - 1, fid);
1206                        else
1207                                writeOut = fwrite ((const void *)ms, (size_t)mseed_hdr->blksize, (size_t) n_blocks, fid);
1208
1209                        fclose(fid);
1210                        curBlock = (SDR_HDR *) ms;     
1211                }
1212                else /* error in ms_pack_data */
1213                {
1214                        logit("pt", "Failed to ms_pack_data() for %s %s %s %s\n", 
1215                                wf->sta, wf->net, wf->chan, strDate(trace->actStarttime + (double) shiftInCounts / samprate, d20));
1216                        n_blocks = 0;
1217                }
1218        }
1219
1220                       
1221        if (n_blocks > 1)
1222        {       
1223                *mseedSeqNo = *mseedSeqNo + n_blocks -1 ;
1224                lastBlock = (SDR_HDR* )(ms + blocksize * (n_blocks - 1));
1225#ifdef _SPARC
1226                newReqStartTime = int_to_tepoch(decode_time_sdr(lastBlock->time, SEED_BIG_ENDIAN));
1227#endif
1228#ifdef _INTEL
1229                if (curBlock->time.year > 3000)
1230                  newReqStartTime = int_to_tepoch(decode_time_sdr(lastBlock->time, SEED_BIG_ENDIAN));
1231                else
1232                  newReqStartTime = int_to_tepoch(decode_time_sdr(lastBlock->time, SEED_LITTLE_ENDIAN));
1233#endif
1234                actEndtime =    newReqStartTime - 1./samprate;
1235        }
1236        else if (n_blocks == 1)
1237        {
1238                *mseedSeqNo = *mseedSeqNo + 1;
1239
1240                /* If gapFlag is true
1241                 * we set the newReqStartTime to time right after the Gap + 1 sample
1242                 * whereas actEndtime is computed as a last sample on MSEED record
1243                 ****************************************************************/
1244#ifdef _SPARC
1245                actEndtime = int_to_tepoch(decode_time_sdr(curBlock->time, SEED_BIG_ENDIAN)) + 
1246                                (double)(curBlock->num_samples -1)/samprate;   
1247#endif
1248#ifdef _INTEL
1249                if (curBlock->time.year > 3000)
1250                  actEndtime = int_to_tepoch(decode_time_sdr(curBlock->time, SEED_BIG_ENDIAN)) + (double)(ntohs(curBlock->num_samples) -1)/samprate;
1251                else
1252                  actEndtime = int_to_tepoch(decode_time_sdr(curBlock->time, SEED_LITTLE_ENDIAN)) + (double)(curBlock->num_samples -1)/samprate;
1253#endif
1254                if (gapFlag == TRUE)   
1255                        newReqStartTime  = afterGapTime + 1./samprate;
1256                else           
1257                        newReqStartTime = actEndtime + 1./samprate; 
1258               
1259        }
1260        else /* No blocks at all ! */
1261        {
1262                logit("pt", "No MSEED blocks saved, move time pointer by 1 sample\n"); 
1263                newReqStartTime = trace->reqStarttime + 10./samprate;
1264        }
1265
1266        trace->reqStarttime = newReqStartTime;
1267        trace->reqEndtime = newReqStartTime - 1./samprate + timeAdvance; /*fix 01/09/01 */
1268
1269        if(n_blocks > 0)
1270        {
1271#ifdef _SPARC
1272                actStarttime =  int_to_tepoch(decode_time_sdr(curBlock->time, SEED_BIG_ENDIAN));
1273#endif
1274#ifdef _INTEL
1275                if (curBlock->time.year > 3000)
1276                  actStarttime = int_to_tepoch(decode_time_sdr(curBlock->time, SEED_BIG_ENDIAN));
1277                else
1278                  actStarttime = int_to_tepoch(decode_time_sdr(curBlock->time, SEED_LITTLE_ENDIAN));
1279#endif
1280
1281                /* See if we have any TEARS?
1282                *************************************/
1283                if (*oldEndtime != -1) /* If prevEndtime is defined */
1284                {
1285                        if (fabs(*oldEndtime - actStarttime) > (2./samprate))
1286                        {
1287                                /* There is a tear, protocol it
1288                                ****************************/
1289                                sprintf (tear_errmsg, "TEAR #%ld in %s %s %s (%f s from %s to %s)\n",
1290                                                *gapCount, wf->sta, wf->net, wf->chan, actStarttime - *oldEndtime, 
1291                                                strDate(*oldEndtime, d20), strDate(actStarttime, d20a));
1292/*                              fprintf (stderr, "%s", tear_errmsg ); */
1293                                logit ("pt", "%s", tear_errmsg);
1294                                *gapCount = *gapCount + 1;
1295                        } 
1296
1297                }
1298                *oldStarttime = actStarttime;
1299                *oldEndtime = actEndtime;
1300
1301                logit("pt", "<%ld> %s %s %s: %d  MSEED records: <%s -- %s>\n",
1302                                *mseedSeqNo, trace->sta, trace->net, 
1303                                trace->chan, (n_blocks == 1) ? n_blocks: n_blocks -1,
1304                                 strDate (actStarttime, d20), strDate(actEndtime, d20a));
1305        }
1306        else
1307                logit("pt", "CreateMseed <%ld> %s %s %s: No MSEED records written this time\n", *mseedSeqNo,
1308                        trace->sta, trace->net, trace->chan);   
1309        if (verbosity > 2) logit("pt", "%s %s %s: New WS req time set to: <%s -- %s>\n",
1310                        trace->sta, trace->net, trace->chan, 
1311        strDate (trace->reqStarttime, d20),
1312        strDate  (trace->reqEndtime, d20a));
1313
1314               
1315        /* Free temp structures
1316       
1317 **************************************/
1318        if (mseed_hdr != NULL)
1319                free (mseed_hdr); 
1320        if (wf != NULL)
1321                free (wf);
1322        if (buffer != NULL)
1323                free(buffer);
1324        if (ms != NULL)
1325                free (ms);
1326                       
1327        return WS_ERR_NONE;
1328  }
Note: See TracBrowser for help on using the repository browser.