Changeset 8145


Ignore:
Timestamp:
04/15/20 13:31:07 (3 months ago)
Author:
paulf
Message:

allowed tankplayer to fire in all at once

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/archiving/tankplayer/tankplayer.c

    r7228 r8145  
    11 
    22/* 
    3  *   THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE 
    4  *   CHECKED IT OUT USING THE COMMAND CHECKOUT. 
    5  * 
    6  *    $Id$ 
    7  * 
    8  *    Revision history: 
    9  *     $Log$ 
    10  *     Revision 1.18  2010/03/19 16:59:35  paulf 
    11  *     made tankplayer check size against MAX_TRACEBUF_SIZ for tracebuf2s 
    12  * 
    13  *     Revision 1.17  2009/03/13 20:01:44  paulf 
    14  *     added new field InterMessageDelayMillisecs for rapid fire loading of tanks 
    15  * 
    16  *     Revision 1.16  2008/09/09 20:02:47  paulf 
    17  *     upgraded tankplayer to use GetFromDir as an option to load tank files as they are created 
    18  * 
    19  *     Revision 1.15  2008/08/22 20:21:19  paulf 
    20  *     increased MAX_WF to 1000 tanks 
    21  * 
    22  *     Revision 1.14  2007/12/16 17:52:33  paulf 
    23  *     fixed SwapLong for SwapInt in tankplayer for some OS 
    24  * 
    25  *     Revision 1.13  2007/03/28 18:04:54  paulf 
    26  *     removed incl of malloc.h since it was in platform.h 
    27  * 
    28  *     Revision 1.12  2007/02/26 14:47:38  paulf 
    29  *     made sure time_t are casted to long for heartbeat sprintf() 
    30  * 
    31  *     Revision 1.11  2007/02/23 15:16:42  paulf 
    32  *     fixed long to time_t declaration 
    33  * 
    34  *     Revision 1.10  2006/07/01 03:29:06  stefan 
    35  *     SendLate command in tankplayer.d did not appear to be working. 
    36  *     The problem is that while tankplayer will play back 3 waveform types 
    37  *     (TypeADBuf, TypeTraceBuf, TypeTraceBuf2) it would only set the time 
    38  *     if the type was one of the first two. 
    39  *     set_time had code else if( msgtype == TypeTraceBuf ) 
    40  *     - John Patton 
    41  *     changed to 
    42  *     else if( msgtype == TypeTraceBuf ||  msgtype == TypeTraceBuf2) 
    43  *     - Stefan 
    44  * 
    45  *     Revision 1.9  2006/03/09 17:18:55  davek 
    46  *     removed a c++ style comment. 
    47  * 
    48  *     Revision 1.8  2006/03/09 17:07:28  davek 
    49  *     Added support for TypeTraceBuf2, which was missing from the get_time function 
    50  *     that is used to determine the time of the packet from the trace header. 
    51  *     Changed the program's behavior when Tracebuf2 packets are encountered with 
    52  *     VERSION fields that don't match those compiled into the program.  Previously 
    53  *     the program always quit at the first sign of a tracebuf with a mismatched version 
    54  *     number.  Now depending on the value of the IgnoreTBVersionNumbers config command, 
    55  *     the program attempts to parse and either play or skip the message based on 
    56  *     the value of the command.  (TRUE = play, FALSE= ignore). 
    57  *     Added a log message when tankplayer comes across a large delay between packets. 
    58  *     Modified the sleep code that executes between packets, so that it sleeps 
    59  *     in small intervals and continues to issue heartbeats even during a large gap. 
    60  *     Added additional debugging info for dealing with problems encountered in tracebuf files. 
    61  * 
    62  *     Revision 1.1.1.1  2005/06/22 19:30:36  michelle 
    63  *     new directory tree built from files in HYDRA_NEWDIR_2005-06-20 tagged hydra and earthworm projects 
    64  * 
    65  *     Revision 1.7  2004/05/21 23:56:07  dietz 
    66  *     modified to play either TYPE_TRACEBUF or TYPE_TRACEBUF2 files 
    67  * 
    68  *     Revision 1.6  2004/05/18 22:31:08  lombard 
    69  *     Modified for location code 
    70  * 
    71  *     Revision 1.5  2001/10/01 20:13:48  patton 
    72  *     Made changes due to slightly reworked logit. 
    73  *     JMP 10/1/2001 
    74  * 
    75  *     Revision 1.4  2001/08/28 05:20:34  patton 
    76  *     Made logit changes due to new logit code. 
    77  *     JMP 8/27/2001 
    78  * 
    79  *     Revision 1.3  2001/04/17 16:35:26  davidk 
    80  *     Added fixes to eliminate compiler warnings on NT. 
    81  *     (Added param to exit call, added an explicit typecast.) 
    82  * 
    83  *     Revision 1.2  2000/08/08 17:04:13  lucky 
    84  *     Lint cleanup. 
    85  * 
    86  *     Revision 1.1  2000/02/14 19:41:59  lucky 
    87  *     Initial revision 
    88  * 
    89  * 
     3 * THIS FILE IS UNDER RCS - DO NOT MODIFY UNLESS YOU HAVE CHECKED IT OUT 
     4 * USING THE COMMAND CHECKOUT. 
     5 *  
     6 * $Id$ 
     7 *  
     8 * Revision history: $Log$ Revision 1.18  2010/03/19 16:59:35  paulf made 
     9 * tankplayer check size against MAX_TRACEBUF_SIZ for tracebuf2s 
     10 *  
     11 * Revision 1.17  2009/03/13 20:01:44  paulf added new field 
     12 * InterMessageDelayMillisecs for rapid fire loading of tanks 
     13 *  
     14 * Revision 1.16  2008/09/09 20:02:47  paulf upgraded tankplayer to use 
     15 * GetFromDir as an option to load tank files as they are created 
     16 *  
     17 * Revision 1.15  2008/08/22 20:21:19  paulf increased MAX_WF to 1000 tanks 
     18 *  
     19 * Revision 1.14  2007/12/16 17:52:33  paulf fixed SwapLong for SwapInt in 
     20 * tankplayer for some OS 
     21 *  
     22 * Revision 1.13  2007/03/28 18:04:54  paulf removed incl of malloc.h since it 
     23 * was in platform.h 
     24 *  
     25 * Revision 1.12  2007/02/26 14:47:38  paulf made sure time_t are casted to long 
     26 * for heartbeat sprintf() 
     27 *  
     28 * Revision 1.11  2007/02/23 15:16:42  paulf fixed long to time_t declaration 
     29 *  
     30 * Revision 1.10  2006/07/01 03:29:06  stefan SendLate command in tankplayer.d 
     31 * did not appear to be working. The problem is that while tankplayer will 
     32 * play back 3 waveform types (TypeADBuf, TypeTraceBuf, TypeTraceBuf2) it 
     33 * would only set the time if the type was one of the first two. set_time had 
     34 * code else if( msgtype == TypeTraceBuf ) - John Patton changed to else if( 
     35 * msgtype == TypeTraceBuf ||  msgtype == TypeTraceBuf2) - Stefan 
     36 *  
     37 * Revision 1.9  2006/03/09 17:18:55  davek removed a c++ style comment. 
     38 *  
     39 * Revision 1.8  2006/03/09 17:07:28  davek Added support for TypeTraceBuf2, 
     40 * which was missing from the get_time function that is used to determine the 
     41 * time of the packet from the trace header. Changed the program's behavior 
     42 * when Tracebuf2 packets are encountered with VERSION fields that don't 
     43 * match those compiled into the program.  Previously the program always quit 
     44 * at the first sign of a tracebuf with a mismatched version number.  Now 
     45 * depending on the value of the IgnoreTBVersionNumbers config command, the 
     46 * program attempts to parse and either play or skip the message based on the 
     47 * value of the command.  (TRUE = play, FALSE= ignore). Added a log message 
     48 * when tankplayer comes across a large delay between packets. Modified the 
     49 * sleep code that executes between packets, so that it sleeps in small 
     50 * intervals and continues to issue heartbeats even during a large gap. Added 
     51 * additional debugging info for dealing with problems encountered in 
     52 * tracebuf files. 
     53 *  
     54 * Revision 1.1.1.1  2005/06/22 19:30:36  michelle new directory tree built from 
     55 * files in HYDRA_NEWDIR_2005-06-20 tagged hydra and earthworm projects 
     56 *  
     57 * Revision 1.7  2004/05/21 23:56:07  dietz modified to play either 
     58 * TYPE_TRACEBUF or TYPE_TRACEBUF2 files 
     59 *  
     60 * Revision 1.6  2004/05/18 22:31:08  lombard Modified for location code 
     61 *  
     62 * Revision 1.5  2001/10/01 20:13:48  patton Made changes due to slightly 
     63 * reworked logit. JMP 10/1/2001 
     64 *  
     65 * Revision 1.4  2001/08/28 05:20:34  patton Made logit changes due to new logit 
     66 * code. JMP 8/27/2001 
     67 *  
     68 * Revision 1.3  2001/04/17 16:35:26  davidk Added fixes to eliminate compiler 
     69 * warnings on NT. (Added param to exit call, added an explicit typecast.) 
     70 *  
     71 * Revision 1.2  2000/08/08 17:04:13  lucky Lint cleanup. 
     72 *  
     73 * Revision 1.1  2000/02/14 19:41:59  lucky Initial revision 
     74 *  
     75 *  
    9076 */ 
    9177 
    92    /********************************************************************* 
    93     *                           tankplayer.c                            * 
    94     *                                                                   * 
    95     *  Program to read a waveform file & play it into a transport ring. * 
    96     *  Reads files containing TYPE_ADBUF, TYPE_TRACEBUF, or             * 
    97     *  TYPE_TRACEBUF2 msgs.                                             * 
    98     *  Places messages into ring in pseudo-real-time, using the         * 
    99     *  timestamps in the message headers to determine the temporal      * 
    100     *  spacing of messages.                                             * 
    101     *    For TYPE_ADBUF msgs, tankplayer spaces msgs by the delta-t     * 
    102     *                    between the starttimes in the headers,         * 
    103     *    For TYPE_TRACEBUF & TYPE_TRACEBUF2, tankplayer spaces msgs by  * 
    104     *                    the delta-t between the endtimes in headers.   * 
    105     *                                                                   * 
    106     *  Command line arguments:                                          * 
    107     *     arvg[1] = tankplayer's configuration file                     * 
    108     *********************************************************************/ 
     78/********************************************************************* 
     79 *                           tankplayer.c                            * 
     80 *                                                                   * 
     81 *  Program to read a waveform file & play it into a transport ring. * 
     82 *  Reads files containing TYPE_ADBUF, TYPE_TRACEBUF, or             * 
     83 *  TYPE_TRACEBUF2 msgs.                                             * 
     84 *  Places messages into ring in pseudo-real-time, using the         * 
     85 *  timestamps in the message headers to determine the temporal      * 
     86 *  spacing of messages.                                             * 
     87 *    For TYPE_ADBUF msgs, tankplayer spaces msgs by the delta-t     * 
     88 *                    between the starttimes in the headers,         * 
     89 *    For TYPE_TRACEBUF & TYPE_TRACEBUF2, tankplayer spaces msgs by  * 
     90 *                    the delta-t between the endtimes in headers.   * 
     91 *                                                                   * 
     92 *  Command line arguments:                                          * 
     93 *     arvg[1] = tankplayer's configuration file                     * 
     94 *********************************************************************/ 
    10995/* Modified for Y2K testing: PNL, 2/17/99 */ 
    11096 
    11197/* added VERSION number 1.0.2  on Nov 5, 2014 */ 
    112 #define VERSION "1.0.3 2016.07.01" 
    113  
    114 #define NAM_LEN 256         /* length of full directory name          */ 
     98/* 1.0.4 - 2020-04-15 -> allow negative InterMessageDelay to fire in all messages to ring without delay */ 
     99#define VERSION "1.0.4 2020.04.15" 
     100 
     101#define NAM_LEN 256             /* length of full directory name          */ 
    115102 
    116103#include <stdio.h> 
     
    128115#define MAX_BUFSIZ   51740 
    129116 
    130 /* Function prototypes 
    131  *********************/ 
    132 void tankplayer_config( char * ); 
    133 void tankplayer_lookup( void ); 
    134 void tankplayer_status( unsigned char, short, char * ); 
    135 double get_time( char *, unsigned char ); 
    136 void set_time( char *, unsigned char, double ); 
    137  
    138 static SHM_INFO      Region;         /* Info structure for memory region  */ 
    139 pid_t                MyPID=0;        /* to use in heartbeat               */ 
    140  
    141 /* Things read from configuration file 
    142  *************************************/ 
    143 static long          RingKey;        /* transport ring to attach to       */ 
    144 static int           LogSwitch;      /* Log-to-disk switch                */ 
    145 static unsigned char MyModId;        /* play as this module id            */ 
    146 static long          HeartBeatInt;   /* seconds between heartbeats        */ 
    147 static unsigned char PlayType;       /* read this msgtype from wavefile   */ 
    148 static int           Pause;          /* # sec to sleep between wave files */ 
    149 static long          StartUpDelay;   /* seconds to wait before playing    */ 
    150 static int           ScreenMsg = 0;  /* =1 write info to screen, =0 don't */ 
    151 static int           Debug = 0; 
    152 static int           AdjTime = 0;    /* =1 to adjust packet time, =0 don't*/ 
    153 static double        LateTime = 0.0; /* seconds earlier than present to   */ 
    154                                      /*  put in packet timestamp.         */ 
    155 static int           bBeSuperLenient = 0; /* be lenient about putting out 
    156                                             tracebufs with incorrect 
    157                                             version numbers.              */ 
    158  
    159 static int       InterMessageDelayMillisecs = 0; /* the flag and number of ms to sleep between  
    160                                                         stuffing in tbufs, regardless of header time stamp!   
    161                                                         If this is set to 0, then all other delay settings apply 
    162                                                         */ 
    163 static char      GetFromDir[NAM_LEN]; /* directory to monitor for data     */ 
    164 static unsigned  CheckPeriod = 1;         /* secs between looking for new files*/ 
    165 static int       OpenTries = 5; 
    166 static int       OpenWait= 200;         /* milliseconds between open tries */ 
    167 static int       SaveDataFiles=1;       /* if non-zero, move to SaveSubdir,  */ 
    168                                       /*           0, remove files         */ 
    169 static char *TroubleSubdir = "trouble";   /* subdir for problem files    */ 
    170 static char *SaveSubdir = "save";         /* subdir for processed files  */ 
    171  
    172 #define MAX_WF  1000                      /* max # waveform files to play   */ 
     117/* 
     118 * Function prototypes ******************* 
     119 */ 
     120void            tankplayer_config(char *); 
     121void            tankplayer_lookup(void); 
     122void            tankplayer_status(unsigned char, short, char *); 
     123double          get_time(char *, unsigned char); 
     124void            set_time  (char *, unsigned char, double); 
     125 
     126static SHM_INFO Region;         /* Info structure for memory region  */ 
     127pid_t           MyPID = 0;      /* to use in heartbeat               */ 
     128 
     129/* 
     130 * Things read from configuration file *********************************** 
     131 */ 
     132static long     RingKey;        /* transport ring to attach to       */ 
     133static int      LogSwitch;      /* Log-to-disk switch                */ 
     134static unsigned char MyModId;   /* play as this module id            */ 
     135static long     HeartBeatInt;   /* seconds between heartbeats        */ 
     136static unsigned char PlayType;  /* read this msgtype from wavefile   */ 
     137static int      Pause;          /* # sec to sleep between wave files */ 
     138static long     StartUpDelay;   /* seconds to wait before playing    */ 
     139static int      ScreenMsg = 0;  /* =1 write info to screen, =0 don't */ 
     140static int      Debug = 0; 
     141static int      AdjTime = 0;    /* =1 to adjust packet time, =0 don't */ 
     142static double   LateTime = 0.0; /* seconds earlier than present to   */ 
     143/* put in packet timestamp.         */ 
     144static int      bBeSuperLenient = 0;    /* be lenient about putting out 
     145                                         * tracebufs with incorrect version 
     146                                         * numbers.              */ 
     147 
     148static int      InterMessageDelayMillisecs = 0; /* the flag and number of ms 
     149                                                 * to sleep between stuffing 
     150                                                 * in tbufs, regardless of 
     151                                                 * header time stamp!  If 
     152                                                 * this is set to 0, then all 
     153                                                 * other delay settings apply */ 
     154static char     GetFromDir[NAM_LEN];    /* directory to monitor for data     */ 
     155static unsigned CheckPeriod = 1;/* secs between looking for new files */ 
     156static int      OpenTries = 5; 
     157static int      OpenWait = 200; /* milliseconds between open tries */ 
     158static int      SaveDataFiles = 1;      /* if non-zero, move to SaveSubdir,  */ 
     159/* 0, remove files         */ 
     160static char    *TroubleSubdir = "trouble";      /* subdir for problem files    */ 
     161static char    *SaveSubdir = "save";    /* subdir for processed files  */ 
     162 
     163#define MAX_WF  1000            /* max # waveform files to play   */ 
    173164#define MAX_LEN 1024 
    174 static char WaveFile[MAX_WF][MAX_LEN];  /* list of waveform files to play */ 
    175 static int  nWaveFile = 0;              /* # waveform files to play       */ 
    176  
    177 /* Look up from earthworm.h 
    178  **************************/ 
    179 static unsigned char InstId;         /* local installation id             */ 
     165static char     WaveFile[MAX_WF][MAX_LEN];      /* list of waveform files to 
     166                                                 * play */ 
     167static int      nWaveFile = 0;  /* # waveform files to play       */ 
     168 
     169/* 
     170 * Look up from earthworm.h ************************ 
     171 */ 
     172static unsigned char InstId;    /* local installation id             */ 
    180173static unsigned char TypeHeartBeat; 
    181174static unsigned char TypeError; 
     
    185178 
    186179 
    187 int main( int argc, char *argv[] ) 
     180int  
     181main(int argc, char *argv[]) 
    188182{ 
    189   static char   msg[MAX_BUFSIZ];  /* waveform data buffer read from file   */ 
    190   WF_HEADER    *adhead;           /* pntr to header of TYPE_ADBUF msg      */ 
    191   TRACE2_HEADER *wfhead;          /* pntr to header of TYPE_TRACEBUF2 msg  */ 
    192   MSG_LOGO      logo;             /* logo to attach to waveform msgs       */ 
    193   FILE         *fp;               /* file of waveform data to read from    */ 
    194   double        CurrentTime;      /* current system time                   */ 
    195   double        Ptime = 0.0;      /* original time stamp on packet         */ 
    196   double        offsetTime = 0.0; /* Difference between Ptime and CurrentTime */ 
    197   double        lastdot=0.;       /* time last dot was written to screen   */ 
    198   double        wait;             /* Seconds to wait before sending pkt    */ 
    199   time_t        itime;            /* integer version of double times       */ 
    200   time_t        timeNow;          /* current system time                   */ 
    201   time_t        timeLastBeat;     /* system time of last heartbeat sent    */ 
    202   short         nchan;            /* #channels in this message             */ 
    203   short         nscan;            /* #scans in this message                */ 
    204   int           nsamp;            /* #samples in this message              */ 
    205   unsigned char module = 0;       /* source module of this waveform msg    */ 
    206   char          byte_order;       /* byte order of this trace msg          */ 
    207   int           byte_per_sample;  /* for trace msg                         */ 
    208   size_t        size = 0; 
    209   int           first;            /* flag 1st waveform message of file     */ 
    210   int           iw, i; 
    211   char          lo[2];  /* logit arg1: ""  if ScreenMsg=0; "o"  otherwise  */ 
    212   char          lot[3]; /* logit arg1: "t" if ScreenMsg=0; "ot" otherwise  */ 
    213   int           iFileOffset, iLastRead;/* tracking where we are in the     */ 
    214                                        /* current file - Debug info only   */ 
    215   int           bIsCorrectVersion=1;   /* recording match of version info  */ 
    216   int           continue_processing=1; /* switch to continue looking for more files or processing listed ones */ 
    217  
    218   char          fname[NAM_LEN];         /* filename grabbed from polling dir */ 
    219   char          fnew[NAM_LEN+25];       /* filename for moving to save dir */ 
    220  
    221   char          *current_file;          /* a pointer to the currently named tank file */ 
    222   char          *ProgName; 
    223   int           result;                 /* processing result  -1 == failure */ 
    224  
    225   adhead  = ( WF_HEADER *)&msg[0]; 
    226   wfhead =  ( TRACE2_HEADER *)&msg[0]; 
    227  
    228  
    229   /* Check arguments 
    230   *****************/ 
    231   if ( argc != 2 ) 
    232   { 
    233     fprintf( stdout, "Usage: tankplayer configfile\n" ); 
    234     fprintf( stdout, "Version: %s\n", VERSION ); 
    235     return( 0 ); 
    236   } 
    237  /* Initialize name of log-file & open it 
    238   ***************************************/ 
    239   logit_init( argv[1], 0, 512, 1 ); 
    240  
    241   GetFromDir[0]=0; 
    242  
    243   ProgName=argv[0]; 
    244  
    245  
    246   /* Read configuration file 
    247   *************************/ 
    248   tankplayer_config( argv[1] ); 
    249  
    250   logit_init( argv[1], 0, 512, LogSwitch ); 
    251   logit( "" , "tankplayer: Read command file <%s>\n", argv[1] ); 
    252   logit( "" , "tankplayer: Version %s\n", VERSION ); 
    253  
    254   if (nWaveFile> 0 && GetFromDir[0] != 0) { 
    255      logit( "e", "%s: You can only use GetFromDir OR WaveFile modes individually, not together; " 
    256                  "exiting!\n", ProgName); 
    257       return( -1 ); 
    258   } 
    259  
    260   /* Look up important info from earthworm.h tables 
    261   ************************************************/ 
    262   tankplayer_lookup(); 
    263  
    264   /* Store my own processid 
    265   ************************/ 
    266   MyPID = getpid(); 
    267  
    268   /* Set up out-going logo 
    269   ***********************/ 
    270   if( PlayType!=TypeADBuf     && 
    271       PlayType!=TypeTraceBuf  && 
    272       PlayType!=TypeTraceBuf2    ) 
    273   { 
    274     logit( "e", "tankplayer: Not programmed to process msg type <%d>", 
    275            (int) PlayType ); 
    276     logit( "e", "; exiting!\n" ); 
    277     return( 1 ); 
    278   } 
    279   logo.instid = InstId; 
    280   logo.mod    = MyModId; 
    281   logo.type   = PlayType; 
    282  
    283   /* Attach to transport ring 
    284   **************************/ 
    285   tport_attach( &Region, RingKey ); 
    286   logit( "", "tankplayer: Attached to public memory region: %ld\n", 
    287          RingKey ); 
    288  
    289   /* Force a heartbeat to be issued in first pass thru main loop 
    290   *************************************************************/ 
    291   timeLastBeat = time(&timeNow) - HeartBeatInt - 1; 
    292  
    293   /* Set up logit's first argument based on value of ScreenMsg 
    294   ***********************************************************/ 
    295   if( ScreenMsg==0 ) { strcpy( lo, "" );  strcpy( lot, "t" );  } 
    296   else               { strcpy( lo, "o" ); strcpy( lot, "ot" ); } 
    297  
    298   /* Hold off sending data for a specified bit while system staggers up 
    299   ********************************************************************/ 
    300   logit( lo, "tankplayer: startup. Waiting %ld seconds\n", StartUpDelay ); 
    301   for( i=0; i<StartUpDelay; i++ ) 
    302   { 
    303     sleep_ew( 1000 ); 
    304     if( time(&timeNow)-timeLastBeat >= HeartBeatInt ) 
    305     { 
    306       timeLastBeat = timeNow; 
    307       tankplayer_status( TypeHeartBeat, 0, "" ); 
    308     } 
    309   } 
    310   if( nWaveFile == 0 && chdir_ew( GetFromDir ) == -1 ) 
    311   { 
    312      logit( "e", "%s: GetFromDir directory <%s> not found; " 
    313                  "exiting!\n", ProgName, GetFromDir ); 
    314       return( -1 ); 
    315   } 
    316   if (GetFromDir[0]!=0 && Debug) logit("et","%s: changed to directory <%s>\n", ProgName,GetFromDir); 
    317  
    318   if (nWaveFile==0) { 
    319    /* Make sure trouble subdirectory exists 
    320     ***************************************/ 
    321    if( CreateDir( TroubleSubdir ) != EW_SUCCESS ) { 
    322       logit( "e", "%s: trouble creating trouble directory: %s/%s\n", 
    323               ProgName, GetFromDir, TroubleSubdir ); 
    324       return( -1 ); 
    325    } 
    326  
    327    /* Make sure save subdirectory exists (if it will be used) 
    328     *********************************************************/ 
    329    if( SaveDataFiles ) { 
    330       if( CreateDir( SaveSubdir ) != EW_SUCCESS ) { 
    331          logit( "e", "%s: trouble creating save directory: %s/%s\n", 
    332                 ProgName, GetFromDir, SaveSubdir ); 
    333       return( -1 ); 
    334       } 
    335    } 
    336   } 
    337  
    338   /*--------- Main Loop: over list of waveform files to play----------------*/ 
    339   iw=-1; 
    340   while (continue_processing) 
    341   { 
    342     if (nWaveFile > 0) { 
    343        /* we are processing via listed files */ 
    344        iw++; 
    345        if (iw==nWaveFile) { 
    346           /* we have reached the end! */ 
    347           break; 
    348        } 
    349        /* Open a listed waveform file 
    350         ********************/ 
    351        fp = fopen( WaveFile[iw], "rb" ); 
    352        if ( fp == NULL ) { 
    353           logit( "e", "tankplayer: Cannot open tank file <%s>\n", WaveFile[iw] ); 
    354           continue; 
    355         } 
    356         if (Debug > 0 ) { 
    357           logit("e", "tankplayer: starting tank <%s>\n", WaveFile[iw] ); 
    358         } 
    359         current_file = WaveFile[iw]; 
    360     } else { 
    361         /* open the file in the directory specified */ 
    362         while (1) { 
    363             if( tport_getflag( &Region ) == TERMINATE || tport_getflag( &Region ) == MyPID ) { 
    364               logit( lot, "tankplayer: Termination requested; exiting!\n" ); 
    365               tport_detach( &Region ); 
    366               return( 0 ); 
    367             } 
    368             if( time(&timeNow)-timeLastBeat >= HeartBeatInt ) 
    369             { 
    370               timeLastBeat = timeNow; 
    371               tankplayer_status( TypeHeartBeat, 0, "" ); 
    372             } 
    373             if( GetFileName(fname) == 1 ) {  /* No files found; wait for one to appear */ 
    374               sleep_ew( CheckPeriod*1000 ); 
    375               continue; 
    376             } else { 
    377               if(Debug)logit("et","%s: got file name <%s>\n",ProgName,fname); 
    378               break; 
    379             } 
    380         } 
    381         /* we should have a file at this point */ 
    382         current_file = fname; 
    383         /* Open the file. 
    384          * We open for updating (even though we only want to read it), 
    385          * as that will hopefully get us an exclusive open. 
    386          * We don't ever want to look at a file that's being written to. 
    387          ***************************************************************/ 
    388          fp = NULL; 
    389          for( i=0; i<OpenTries; i++ ) { 
    390             fp = fopen( fname, "rb+" ); 
    391             if( fp != NULL ) break; 
    392             sleep_ew( OpenWait ); 
    393          } 
    394          if( fp == NULL ) { /* failed to open file! */ 
    395             logit( "et","%s: Error: Could not open %s after %d*%d msec.", 
    396                    ProgName, fname, OpenTries, OpenWait); 
    397             result = -1; 
    398             goto ProcessedFile; 
    399          } 
    400          if( i>0 ) { 
    401             logit("t","Warning: %d attempts required to open file %s\n", 
    402                    i+1, fname); 
    403          } 
    404     } 
    405     iFileOffset = 0; 
    406     iLastRead   = 0; 
    407     /* See if it's time to stop 
    408     ************************/ 
    409     if( tport_getflag( &Region ) == TERMINATE || tport_getflag( &Region ) == MyPID ) { 
    410       logit( lot, "tankplayer: Termination requested; exiting!\n" ); 
    411       tport_detach( &Region ); 
    412       return( 0 ); 
    413     } 
    414  
    415     first = 1; 
    416  
    417     /* Loop over one file: get a msg from file, write it to ring 
    418     *********************************************************/ 
    419     while( tport_getflag( &Region ) != TERMINATE && tport_getflag( &Region ) != MyPID ) 
    420     { 
    421       /* Send tankplayer's heartbeat 
    422       *****************************/ 
    423       if( time(&timeNow)-timeLastBeat >= HeartBeatInt ) 
    424       { 
    425         timeLastBeat = timeNow; 
    426         tankplayer_status( TypeHeartBeat, 0, "" ); 
    427       } 
    428  
    429       /* Read ADBuf waveform message from tank 
    430       ***************************************/ 
    431       if( PlayType == TypeADBuf ) 
    432       { 
    433         /* Read the header 
    434         *****************/ 
    435         size = sizeof( WF_HEADER ); 
    436  
    437   iFileOffset += iLastRead; 
    438         if( fread( msg, sizeof(char), size, fp ) < size )  break; 
    439   iLastRead =  (int)(sizeof(char) * size); 
    440  
    441         nchan  = adhead->nchan; 
    442         nscan  = adhead->nscan; 
    443         module = adhead->mod_id; 
     183        static char     msg [MAX_BUFSIZ];       /* waveform data buffer read 
     184                                                 * from file   */ 
     185        WF_HEADER      *adhead; /* pntr to header of TYPE_ADBUF msg      */ 
     186        TRACE2_HEADER  *wfhead; /* pntr to header of TYPE_TRACEBUF2 msg  */ 
     187        MSG_LOGO        logo;   /* logo to attach to waveform msgs       */ 
     188        FILE           *fp;     /* file of waveform data to read from    */ 
     189        double          CurrentTime;    /* current system time                   */ 
     190        double          Ptime = 0.0;    /* original time stamp on packet         */ 
     191        double          offsetTime = 0.0;       /* Difference between Ptime 
     192                                                 * and CurrentTime */ 
     193        double          lastdot = 0.;   /* time last dot was written to 
     194                                         * screen   */ 
     195        double          wait;   /* Seconds to wait before sending pkt    */ 
     196        time_t          itime;  /* integer version of double times       */ 
     197        time_t          timeNow;/* current system time                   */ 
     198        time_t          timeLastBeat;   /* system time of last heartbeat sent    */ 
     199        short           nchan;  /* #channels in this message             */ 
     200        short           nscan;  /* #scans in this message                */ 
     201        int             nsamp;  /* #samples in this message              */ 
     202        unsigned char   module = 0;     /* source module of this waveform msg    */ 
     203        char            byte_order;     /* byte order of this trace msg          */ 
     204        int             byte_per_sample;        /* for trace msg                         */ 
     205        size_t          size = 0; 
     206        int             first;  /* flag 1st waveform message of file     */ 
     207        int             iw        , i; 
     208        char            lo        [2];  /* logit arg1: ""  if ScreenMsg=0; 
     209                                         * "o"  otherwise  */ 
     210        char            lot       [3];  /* logit arg1: "t" if ScreenMsg=0; 
     211                                         * "ot" otherwise  */ 
     212        int             iFileOffset, iLastRead; /* tracking where we are in 
     213                                                 * the     */ 
     214        /* current file - Debug info only   */ 
     215        int             bIsCorrectVersion = 1;  /* recording match of version 
     216                                                 * info  */ 
     217        int             continue_processing = 1;        /* switch to continue 
     218                                                         * looking for more 
     219                                                         * files or processing 
     220                                                         * listed ones */ 
     221 
     222        char            fname     [NAM_LEN];    /* filename grabbed from 
     223                                                 * polling dir */ 
     224        char            fnew      [NAM_LEN + 25];       /* filename for moving 
     225                                                         * to save dir */ 
     226 
     227        char           *current_file;   /* a pointer to the currently named 
     228                                         * tank file */ 
     229        char           *ProgName; 
     230        int             result; /* processing result  -1 == failure */ 
     231 
     232        adhead = (WF_HEADER *) & msg[0]; 
     233        wfhead = (TRACE2_HEADER *) & msg[0]; 
     234 
     235 
     236        /* 
     237         * Check arguments *************** 
     238         */ 
     239        if (argc != 2) { 
     240                fprintf(stdout, "Usage: tankplayer configfile\n"); 
     241                fprintf(stdout, "Version: %s\n", VERSION); 
     242                return (0); 
     243        } 
     244        /* 
     245         * Initialize name of log-file & open it ************************************* 
     246         */ 
     247        logit_init(argv[1], 0, 512, 1); 
     248 
     249        GetFromDir[0] = 0; 
     250 
     251        ProgName = argv[0]; 
     252 
     253 
     254        /* 
     255         * Read configuration file *********************** 
     256         */ 
     257        tankplayer_config(argv[1]); 
     258 
     259        logit_init(argv[1], 0, 512, LogSwitch); 
     260        logit("", "tankplayer: Read command file <%s>\n", argv[1]); 
     261        logit("", "tankplayer: Version %s\n", VERSION); 
     262 
     263        if (nWaveFile > 0 && GetFromDir[0] != 0) { 
     264                logit("e", "%s: You can only use GetFromDir OR WaveFile modes individually, not together; " 
     265                      "exiting!\n", ProgName); 
     266                return (-1); 
     267        } 
     268        /* 
     269         * Look up important info from earthworm.h tables ********************************************** 
     270         */ 
     271        tankplayer_lookup(); 
     272 
     273        /* 
     274         * Store my own processid ********************** 
     275         */ 
     276        MyPID = getpid(); 
     277 
     278        /* 
     279         * Set up out-going logo ********************* 
     280         */ 
     281        if (PlayType != TypeADBuf && 
     282            PlayType != TypeTraceBuf && 
     283            PlayType != TypeTraceBuf2) { 
     284                logit("e", "tankplayer: Not programmed to process msg type <%d>", 
     285                      (int)PlayType); 
     286                logit("e", "; exiting!\n"); 
     287                return (1); 
     288        } 
     289        logo.instid = InstId; 
     290        logo.mod = MyModId; 
     291        logo.type = PlayType; 
     292 
     293        /* 
     294         * Attach to transport ring ************************ 
     295         */ 
     296        tport_attach(&Region, RingKey); 
     297        logit("", "tankplayer: Attached to public memory region: %ld\n", 
     298              RingKey); 
     299 
     300        /* 
     301         * Force a heartbeat to be issued in first pass thru main loop *********************************************************** 
     302         */ 
     303        timeLastBeat = time(&timeNow) - HeartBeatInt - 1; 
     304 
     305        /* 
     306         * Set up logit's first argument based on value of ScreenMsg ********************************************************* 
     307         */ 
     308        if (ScreenMsg == 0) { 
     309                strcpy(lo, ""); 
     310                strcpy(lot, "t"); 
     311        } else { 
     312                strcpy(lo, "o"); 
     313                strcpy(lot, "ot"); 
     314        } 
     315 
     316        /* 
     317         * Hold off sending data for a specified bit while system staggers up ****************************************************************** 
     318         */ 
     319        logit(lo, "tankplayer: startup. Waiting %ld seconds\n", StartUpDelay); 
     320        for (i = 0; i < StartUpDelay; i++) { 
     321                sleep_ew(1000); 
     322                if (time(&timeNow) - timeLastBeat >= HeartBeatInt) { 
     323                        timeLastBeat = timeNow; 
     324                        tankplayer_status(TypeHeartBeat, 0, ""); 
     325                } 
     326        } 
     327        if (nWaveFile == 0 && chdir_ew(GetFromDir) == -1) { 
     328                logit("e", "%s: GetFromDir directory <%s> not found; " 
     329                      "exiting!\n", ProgName, GetFromDir); 
     330                return (-1); 
     331        } 
     332        if (GetFromDir[0] != 0 && Debug) 
     333                logit("et", "%s: changed to directory <%s>\n", ProgName, GetFromDir); 
     334 
     335        if (nWaveFile == 0) { 
     336                /* 
     337                 * Make sure trouble subdirectory exists ************************************* 
     338                 */ 
     339                if (CreateDir(TroubleSubdir) != EW_SUCCESS) { 
     340                        logit("e", "%s: trouble creating trouble directory: %s/%s\n", 
     341                              ProgName, GetFromDir, TroubleSubdir); 
     342                        return (-1); 
     343                } 
     344                /* 
     345                 * Make sure save subdirectory exists (if it will be used) ******************************************************* 
     346                 */ 
     347                if (SaveDataFiles) { 
     348                        if (CreateDir(SaveSubdir) != EW_SUCCESS) { 
     349                                logit("e", "%s: trouble creating save directory: %s/%s\n", 
     350                                      ProgName, GetFromDir, SaveSubdir); 
     351                                return (-1); 
     352                        } 
     353                } 
     354        } 
     355        /*--------- Main Loop: over list of waveform files to play----------------*/ 
     356        iw = -1; 
     357        while (continue_processing) { 
     358                if (nWaveFile > 0) { 
     359                        /* we are processing via listed files */ 
     360                        iw++; 
     361                        if (iw == nWaveFile) { 
     362                                /* we have reached the end! */ 
     363                                break; 
     364                        } 
     365                        /* 
     366                         * Open a listed waveform file ****************** 
     367                         */ 
     368                        fp = fopen(WaveFile[iw], "rb"); 
     369                        if (fp == NULL) { 
     370                                logit("e", "tankplayer: Cannot open tank file <%s>\n", WaveFile[iw]); 
     371                                continue; 
     372                        } 
     373                        if (Debug > 0) { 
     374                                logit("e", "tankplayer: starting tank <%s>\n", WaveFile[iw]); 
     375                        } 
     376                        current_file = WaveFile[iw]; 
     377                } else { 
     378                        /* open the file in the directory specified */ 
     379                        while (1) { 
     380                                if (tport_getflag(&Region) == TERMINATE || tport_getflag(&Region) == MyPID) { 
     381                                        logit(lot, "tankplayer: Termination requested; exiting!\n"); 
     382                                        tport_detach(&Region); 
     383                                        return (0); 
     384                                } 
     385                                if (time(&timeNow) - timeLastBeat >= HeartBeatInt) { 
     386                                        timeLastBeat = timeNow; 
     387                                        tankplayer_status(TypeHeartBeat, 0, ""); 
     388                                } 
     389                                if (GetFileName(fname) == 1) {  /* No files found; wait 
     390                                                                 * for one to appear */ 
     391                                        sleep_ew(CheckPeriod * 1000); 
     392                                        continue; 
     393                                } else { 
     394                                        if (Debug) 
     395                                                logit("et", "%s: got file name <%s>\n", ProgName, fname); 
     396                                        break; 
     397                                } 
     398                        } 
     399                        /* we should have a file at this point */ 
     400                        current_file = fname; 
     401                        /* 
     402                         * Open the file. We open for updating (even though 
     403                         * we only want to read it), as that will hopefully 
     404                         * get us an exclusive open. We don't ever want to 
     405                         * look at a file that's being written to. ************************************************************* 
     406                         */ 
     407                        fp = NULL; 
     408                        for (i = 0; i < OpenTries; i++) { 
     409                                fp = fopen(fname, "rb+"); 
     410                                if (fp != NULL) 
     411                                        break; 
     412                                sleep_ew(OpenWait); 
     413                        } 
     414                        if (fp == NULL) {       /* failed to open file! */ 
     415                                logit("et", "%s: Error: Could not open %s after %d*%d msec.", 
     416                                      ProgName, fname, OpenTries, OpenWait); 
     417                                result = -1; 
     418                                goto ProcessedFile; 
     419                        } 
     420                        if (i > 0) { 
     421                                logit("t", "Warning: %d attempts required to open file %s\n", 
     422                                      i + 1, fname); 
     423                        } 
     424                } 
     425                iFileOffset = 0; 
     426                iLastRead = 0; 
     427                /* 
     428                 * See if it's time to stop ********************** 
     429                 */ 
     430                if (tport_getflag(&Region) == TERMINATE || tport_getflag(&Region) == MyPID) { 
     431                        logit(lot, "tankplayer: Termination requested; exiting!\n"); 
     432                        tport_detach(&Region); 
     433                        return (0); 
     434                } 
     435                first = 1; 
     436 
     437                /* 
     438                 * Loop over one file: get a msg from file, write it to ring ******************************************************* 
     439                 */ 
     440                while (tport_getflag(&Region) != TERMINATE && tport_getflag(&Region) != MyPID) { 
     441                        /* 
     442                         * Send tankplayer's heartbeat *************************** 
     443                         */ 
     444                        if (time(&timeNow) - timeLastBeat >= HeartBeatInt) { 
     445                                timeLastBeat = timeNow; 
     446                                tankplayer_status(TypeHeartBeat, 0, ""); 
     447                        } 
     448                        /* 
     449                         * Read ADBuf waveform message from tank ************************************* 
     450                         */ 
     451                        if (PlayType == TypeADBuf) { 
     452                                /* 
     453                                 * Read the header *************** 
     454                                 */ 
     455                                size = sizeof(WF_HEADER); 
     456 
     457                                iFileOffset += iLastRead; 
     458                                if (fread(msg, sizeof(char), size, fp) < size) 
     459                                        break; 
     460                                iLastRead = (int)(sizeof(char) * size); 
     461 
     462                                nchan = adhead->nchan; 
     463                                nscan = adhead->nscan; 
     464                                module = adhead->mod_id; 
    444465#ifdef _SPARC 
    445         SwapShort( &nscan );  /* Note: By definition, TYPE_ADBUF msgs */ 
    446         SwapShort( &nchan );  /*       are always in INTEL byte order */ 
     466                                SwapShort(&nscan);      /* Note: By definition, 
     467                                                         * TYPE_ADBUF msgs */ 
     468                                SwapShort(&nchan);      /* are always in INTEL 
     469                                                         * byte order */ 
    447470#endif 
    448         adhead->mod_id = MyModId; /*relabel mod_id in msg header*/ 
    449  
    450         /* Read pin #'s and data samples from file 
    451         ***************************************/ 
    452         size = sizeof(short) * nchan * (nscan+1); 
    453         if( size + sizeof(WF_HEADER) > MAX_BUFSIZ ) { 
    454           logit( "e", 
    455                  "tankplayer: msg[%zu] adtype overflows internal buffer[%d]\n", 
    456                  size+sizeof(WF_HEADER), MAX_BUFSIZ ); 
    457           exit(-1);  /* DK 04/12/01 added param to exit() call */ 
    458         } 
    459   iFileOffset += iLastRead; 
    460         if( fread( &msg[sizeof(WF_HEADER)], sizeof(char), size, fp ) < size ) 
    461           break; 
    462   iLastRead =  (int)(sizeof(char) * size); 
    463   size += sizeof( WF_HEADER ); 
    464       } 
    465  
    466       /* Read TraceBuf waveform message from file 
    467       ******************************************/ 
    468       else if( PlayType == TypeTraceBuf2 || 
    469                PlayType == TypeTraceBuf     ) 
    470       { 
    471         /* Read the header 
    472         ***************/ 
    473         size = sizeof( TRACE2_HEADER ); 
    474  
    475   iFileOffset += iLastRead; 
    476         if( fread( msg, sizeof(char), size, fp ) < size ) 
    477     break; 
    478   iLastRead =  (int)(sizeof(char) * size); 
    479  
    480         nsamp           = wfhead->nsamp; 
    481         byte_order      = wfhead->datatype[0]; 
    482         byte_per_sample = atoi(&wfhead->datatype[1]); 
    483         module          = 0; 
     471                                adhead->mod_id = MyModId;       /* relabel mod_id in msg 
     472                                                                 * header */ 
     473 
     474                                /* 
     475                                 * Read pin #'s and data samples from file ************************************* 
     476                                 */ 
     477                                size = sizeof(short) * nchan * (nscan + 1); 
     478                                if (size + sizeof(WF_HEADER) > MAX_BUFSIZ) { 
     479                                        logit("e", 
     480                                              "tankplayer: msg[%zu] adtype overflows internal buffer[%d]\n", 
     481                                              size + sizeof(WF_HEADER), MAX_BUFSIZ); 
     482                                        exit(-1);       /* DK 04/12/01 added 
     483                                                         * param to exit() call */ 
     484                                } 
     485                                iFileOffset += iLastRead; 
     486                                if (fread(&msg[sizeof(WF_HEADER)], sizeof(char), size, fp) < size) 
     487                                        break; 
     488                                iLastRead = (int)(sizeof(char) * size); 
     489                                size += sizeof(WF_HEADER); 
     490                        } 
     491                        /* 
     492                         * Read TraceBuf waveform message from file **************************************** 
     493                         */ 
     494                        else if (PlayType == TypeTraceBuf2 || 
     495                                 PlayType == TypeTraceBuf) { 
     496                                /* 
     497                                 * Read the header ************* 
     498                                 */ 
     499                                size = sizeof(TRACE2_HEADER); 
     500 
     501                                iFileOffset += iLastRead; 
     502                                if (fread(msg, sizeof(char), size, fp) < size) 
     503                                        break; 
     504                                iLastRead = (int)(sizeof(char) * size); 
     505 
     506                                nsamp = wfhead->nsamp; 
     507                                byte_order = wfhead->datatype[0]; 
     508                                byte_per_sample = atoi(&wfhead->datatype[1]); 
     509                                module = 0; 
    484510#ifdef _SPARC 
    485         if( byte_order == 'i' || byte_order == 'f' ) SwapInt( &nsamp ); 
     511                                if (byte_order == 'i' || byte_order == 'f') 
     512                                        SwapInt(&nsamp); 
    486513#endif 
    487514#ifdef _INTEL 
    488         if( byte_order == 's' || byte_order == 't' ) SwapInt( &nsamp ); 
     515                                if (byte_order == 's' || byte_order == 't') 
     516                                        SwapInt(&nsamp); 
    489517#endif 
    490518 
    491   /* test for version; skip file if wrong type 
    492   *******************************************/ 
    493   if( PlayType == TypeTraceBuf2 ) 
    494   { 
    495     if( !TRACE2_HEADER_VERSION_IS_VALID(wfhead) ) 
    496     { 
    497       if(!bBeSuperLenient) 
    498         logit( "e", "tankplayer: Error: packet (%s,%s,%s) at file %s offset %d is not the correct TYPE_TRACEBUF2 version (%c%c).  \n" 
    499           "Parsing it as one and attempting to continue.  Will not output this packet!\n", 
    500           wfhead->sta, wfhead->chan, wfhead->net, 
    501           current_file, iFileOffset, wfhead->version[0], wfhead->version[1] ); 
    502       bIsCorrectVersion=0; 
    503     } 
    504     else 
    505     { 
    506       bIsCorrectVersion=1; 
    507     } 
    508   } 
    509  
    510         /* Read data samples from file 
    511         ***************************/ 
    512         size = byte_per_sample * nsamp; 
    513         if( size + sizeof(TRACE2_HEADER) > MAX_TRACEBUF_SIZ ) { 
    514           logit( "e", 
    515                  "tankplayer: msg[%zu] tbuf2 overflows internal buffer[%d]\n", 
    516                  size+sizeof(TRACE2_HEADER), MAX_TRACEBUF_SIZ ); 
    517           break; 
    518         } 
    519  
    520   iFileOffset += iLastRead; 
    521   if( fread( &msg[sizeof(TRACE2_HEADER)], sizeof(char), size, fp ) < size ) 
    522     break; 
    523   iLastRead =  (int)(sizeof(char) * size); 
    524  
    525  
    526         size += sizeof( TRACE2_HEADER ); 
    527       } 
    528  
    529       /* Sleep until it's time to send this message 
    530       ********************************************/ 
    531       Ptime = get_time( msg, PlayType ); 
    532       hrtime_ew( &CurrentTime ); 
    533  
    534       if( first ) { 
    535         offsetTime = CurrentTime - Ptime; 
    536         first = 0; 
    537         logit( lo, "\n" ); 
    538         logit( lo, 
    539                "tankplayer:  Reading    type:%3d  mod:%3d  from <%s>\n", 
    540                (int)PlayType, (int)module, current_file ); 
    541         logit( lo, 
    542                "             Playing as type:%3d  mod:%3d  inst:%3d\n", 
    543                (int)PlayType, (int)MyModId, (int)InstId ); 
    544         if ( AdjTime ) 
    545         { 
    546           logit( lot, "time shifted by %lf seconds from original\n", offsetTime - LateTime ); 
    547           itime = (time_t) (Ptime + offsetTime - LateTime); 
    548         } 
    549         else 
    550           itime = (time_t) Ptime; 
    551  
    552         logit( lot," 1st header time-stamp: UTC %s", asctime(gmtime(&itime)) ); 
    553       } 
    554  
    555       if (InterMessageDelayMillisecs > 0)  
    556       { 
    557             sleep_ew( (unsigned)( InterMessageDelayMillisecs ) ); 
    558       } 
    559       else 
    560       { 
    561         wait = Ptime + offsetTime - CurrentTime; 
    562         if ( wait > 0 ) 
    563         { 
    564           if( wait > 120) 
    565            logit("e", "WARNING:  waiting %d seconds for packet: <%s.%s.%s> %15.2lf\n", 
    566                  (int)wait, wfhead->sta, wfhead->chan, wfhead->net, Ptime ); 
    567           while(wait > 1.0) 
    568           { 
    569             wait -= 1; 
    570             sleep_ew( (unsigned)( 1 * 1000.0 ) ); 
    571             if( time(&timeNow)-timeLastBeat >= HeartBeatInt ) 
    572             { 
    573               timeLastBeat = timeNow; 
    574               tankplayer_status( TypeHeartBeat, 0, "" ); 
    575             } 
    576           } 
    577         } 
    578       } 
    579  
    580       if ( AdjTime ) set_time( msg, PlayType, Ptime + offsetTime - LateTime ); 
    581  
    582       /* Write waveform message to transport region 
    583       ********************************************/ 
    584       if( ScreenMsg &&  (CurrentTime - lastdot) > 1.0 ) 
    585       { 
    586         lastdot = CurrentTime; 
    587         fprintf(stdout,"."); 
    588         fflush( stdout ); 
    589       } 
    590       /* fprintf(stdout, 
    591          "tankplayer: current time-stamp:%15.2lf  dt:%5.0lf ms  dtsys:%5.0lf ms\r", 
    592          tcurr, dt, dtsys );*/ /*DEBUG*/ 
    593    if(bIsCorrectVersion || bBeSuperLenient) 
    594    { 
    595      if ( tport_putmsg( &Region, &logo, (long)size, msg ) != PUT_OK ) 
    596        logit("e", "tankplayer: tport_putmsg error.\n" ); 
    597      if (Debug > 0 ) 
    598        logit("t", "packet: <%s.%s.%s> %15.2lf\n", wfhead->sta, wfhead->chan, 
    599               wfhead->net, Ptime ); 
    600    } 
    601  
    602     } /*end-while over one file*/ 
    603  
    604     /* Clean up; get ready for next file 
    605     ***********************************/ 
    606     if(ScreenMsg) fprintf(stdout,"\n"); 
    607  
    608     result = 0; /* success up to this point */ 
    609     if ( AdjTime ) 
    610       itime = (time_t) (Ptime + offsetTime - LateTime); 
    611     else 
    612       itime = (time_t) Ptime; 
    613     logit( lot, "last header time-stamp: UTC %s", asctime(gmtime(&itime)) ); 
    614     if( feof(fp) ) 
    615       logit(lo, "tankplayer:  Reached end of <%s>\n", current_file); 
    616     else if( ferror(fp) ) { 
    617       logit(lo, "tankplayer:  Error reading from <%s>\n", current_file ); 
    618       result= -1; 
    619     } else 
    620       logit(lo, "tankplayer:  Closing <%s>\n", current_file ); 
    621     fclose( fp ); 
    622  
    623     /* Pause between playing files 
    624     *****************************/ 
    625     for( i=0; i<Pause; i++ ) 
    626     { 
    627       sleep_ew( 1000 ); 
    628       if( time(&timeNow)-timeLastBeat >= HeartBeatInt ) 
    629       { 
    630         timeLastBeat = timeNow; 
    631         tankplayer_status( TypeHeartBeat, 0, "" ); 
    632       } 
    633     } 
    634     if (iw != -1) continue;     /* jump to next file in list */ 
     519                                /* 
     520                                 * test for version; skip file if wrong type ***************************************** 
     521                                 */ 
     522                                if (PlayType == TypeTraceBuf2) { 
     523                                        if (!TRACE2_HEADER_VERSION_IS_VALID(wfhead)) { 
     524                                                if (!bBeSuperLenient) 
     525                                                        logit("e", "tankplayer: Error: packet (%s,%s,%s) at file %s offset %d is not the correct TYPE_TRACEBUF2 version (%c%c).  \n" 
     526                                                              "Parsing it as one and attempting to continue.  Will not output this packet!\n", 
     527                                                              wfhead->sta, wfhead->chan, wfhead->net, 
     528                                                              current_file, iFileOffset, wfhead->version[0], wfhead->version[1]); 
     529                                                bIsCorrectVersion = 0; 
     530                                        } else { 
     531                                                bIsCorrectVersion = 1; 
     532                                        } 
     533                                } 
     534                                /* 
     535                                 * Read data samples from file ************************* 
     536                                 */ 
     537                                size = byte_per_sample * nsamp; 
     538                                if (size + sizeof(TRACE2_HEADER) > MAX_TRACEBUF_SIZ) { 
     539                                        logit("e", 
     540                                              "tankplayer: msg[%zu] tbuf2 overflows internal buffer[%d]\n", 
     541                                              size + sizeof(TRACE2_HEADER), MAX_TRACEBUF_SIZ); 
     542                                        break; 
     543                                } 
     544                                iFileOffset += iLastRead; 
     545                                if (fread(&msg[sizeof(TRACE2_HEADER)], sizeof(char), size, fp) < size) 
     546                                        break; 
     547                                iLastRead = (int)(sizeof(char) * size); 
     548 
     549 
     550                                size += sizeof(TRACE2_HEADER); 
     551                        } 
     552                        /* 
     553                         * Sleep until it's time to send this message ****************************************** 
     554                         */ 
     555                        Ptime = get_time(msg, PlayType); 
     556                        hrtime_ew(&CurrentTime); 
     557 
     558                        if (first) { 
     559                                offsetTime = CurrentTime - Ptime; 
     560                                first = 0; 
     561                                logit(lo, "\n"); 
     562                                logit(lo, 
     563                                      "tankplayer:  Reading    type:%3d  mod:%3d  from <%s>\n", 
     564                                  (int)PlayType, (int)module, current_file); 
     565                                logit(lo, 
     566                                      "             Playing as type:%3d  mod:%3d  inst:%3d\n", 
     567                                  (int)PlayType, (int)MyModId, (int)InstId); 
     568                                if (AdjTime) { 
     569                                        logit(lot, "time shifted by %lf seconds from original\n", offsetTime - LateTime); 
     570                                        itime = (time_t) (Ptime + offsetTime - LateTime); 
     571                                } else 
     572                                        itime = (time_t) Ptime; 
     573 
     574                                logit(lot, " 1st header time-stamp: UTC %s", asctime(gmtime(&itime))); 
     575                        } 
     576                        if (InterMessageDelayMillisecs > 0) { 
     577                                sleep_ew((unsigned)(InterMessageDelayMillisecs)); 
     578                        } else if (InterMessageDelayMillisecs < 0) { 
     579                                /* do nothing, fire them in as fast as possible, this is experimental */ 
     580                                wait = 0; 
     581                        } else { 
     582                                wait = Ptime + offsetTime - CurrentTime; 
     583                                if (wait > 0) { 
     584                                        if (wait > 120) 
     585                                                logit("e", "WARNING:  waiting %d seconds for packet: <%s.%s.%s> %15.2lf\n", 
     586                                                      (int)wait, wfhead->sta, wfhead->chan, wfhead->net, Ptime); 
     587                                        while (wait > 1.0) { 
     588                                                wait -= 1; 
     589                                                sleep_ew((unsigned)(1 * 1000.0)); 
     590                                                if (time(&timeNow) - timeLastBeat >= HeartBeatInt) { 
     591                                                        timeLastBeat = timeNow; 
     592                                                        tankplayer_status(TypeHeartBeat, 0, ""); 
     593                                                } 
     594                                        } 
     595                                } 
     596                        } 
     597 
     598                        if (AdjTime) 
     599                                set_time(msg, PlayType, Ptime + offsetTime - LateTime); 
     600 
     601                        /* 
     602                         * Write waveform message to transport region ****************************************** 
     603                         */ 
     604                        if (ScreenMsg && (CurrentTime - lastdot) > 1.0) { 
     605                                lastdot = CurrentTime; 
     606                                fprintf(stdout, "."); 
     607                                fflush(stdout); 
     608                        } 
     609                        /* 
     610                         * fprintf(stdout, "tankplayer: current 
     611                         * time-stamp:%15.2lf  dt:%5.0lf ms  dtsys:%5.0lf 
     612                         * ms\r", tcurr, dt, dtsys ); 
     613                         *//* DEBUG */ 
     614                        if (bIsCorrectVersion || bBeSuperLenient) { 
     615                                if (tport_putmsg(&Region, &logo, (long)size, msg) != PUT_OK) 
     616                                        logit("e", "tankplayer: tport_putmsg error.\n"); 
     617                                if (Debug > 0) 
     618                                        logit("t", "packet: <%s.%s.%s> %15.2lf\n", wfhead->sta, wfhead->chan, 
     619                                              wfhead->net, Ptime); 
     620                        } 
     621                }               /* end-while over one file */ 
     622 
     623                /* 
     624                 * Clean up; get ready for next file ********************************* 
     625                 */ 
     626                if (ScreenMsg) 
     627                        fprintf(stdout, "\n"); 
     628 
     629                result = 0;     /* success up to this point */ 
     630                if (AdjTime) 
     631                        itime = (time_t) (Ptime + offsetTime - LateTime); 
     632                else 
     633                        itime = (time_t) Ptime; 
     634                logit(lot, "last header time-stamp: UTC %s", asctime(gmtime(&itime))); 
     635                if (feof(fp)) 
     636                        logit(lo, "tankplayer:  Reached end of <%s>\n", current_file); 
     637                else if (ferror(fp)) { 
     638                        logit(lo, "tankplayer:  Error reading from <%s>\n", current_file); 
     639                        result = -1; 
     640                } else 
     641                        logit(lo, "tankplayer:  Closing <%s>\n", current_file); 
     642                fclose(fp); 
     643 
     644                /* 
     645                 * Pause between playing files *************************** 
     646                 */ 
     647                for (i = 0; i < Pause; i++) { 
     648                        sleep_ew(1000); 
     649                        if (time(&timeNow) - timeLastBeat >= HeartBeatInt) { 
     650                                timeLastBeat = timeNow; 
     651                                tankplayer_status(TypeHeartBeat, 0, ""); 
     652                        } 
     653                } 
     654                if (iw != -1) 
     655                        continue;       /* jump to next file in list */ 
    635656 
    636657ProcessedFile: 
    637     /* now handle the GetFromDir case, and clean up the tank file lying around as directed */ 
    638         if( result >= 0 ) { 
    639         /* Keep file around */ 
    640            if( SaveDataFiles ) { 
    641               sprintf(fnew,"%s/%s",SaveSubdir,fname ); 
    642               if( rename_ew( fname, fnew ) != 0 ) { 
    643                  logit( "e", "error moving file to ./%s\n; exiting!", 
    644                         fnew ); 
    645                  break; 
    646               } else { 
    647                  logit("e","moved to ./%s\n", SaveSubdir ); 
    648               } 
    649            } 
    650         /* Delete the file */ 
    651            else { 
    652               if( remove( fname ) != 0 ) { 
    653                  logit("e","error deleting file; exiting!\n"); 
    654                  break; 
    655               } else  { 
    656                  logit("e","deleted file.\n"); 
    657               } 
    658            } 
    659         } else { 
    660            /* ...or there was trouble (result<0)! */ 
    661            logit("e","\n"); 
    662            sprintf(fnew,"%s/%s",TroubleSubdir,fname ); 
    663            if( rename_ew( fname, fnew ) != 0 ) { 
    664              logit( "e", " error moving file to ./%s ; exiting!\n", 
    665                      fnew ); 
    666              break; 
    667            } else { 
    668              logit( "e", " moved to ./%s\n", fnew ); 
    669            } 
    670         } 
    671  
    672  
    673   } /*end-while */ 
    674  
    675   tport_detach( &Region ); 
    676   logit( lot, "tankplayer: No more wavefiles to play; exiting!\n" ); 
    677   fflush ( stdout ); 
    678   return( 0 ); 
     658                /* 
     659                 * now handle the GetFromDir case, and clean up the tank file 
     660                 * lying around as directed 
     661                 */ 
     662                if (result >= 0) { 
     663                        /* Keep file around */ 
     664                        if (SaveDataFiles) { 
     665                                sprintf(fnew, "%s/%s", SaveSubdir, fname); 
     666                                if (rename_ew(fname, fnew) != 0) { 
     667                                        logit("e", "error moving file to ./%s\n; exiting!", 
     668                                              fnew); 
     669                                        break; 
     670                                } else { 
     671                                        logit("e", "moved to ./%s\n", SaveSubdir); 
     672                                } 
     673                        } 
     674                        /* Delete the file */ 
     675                        else { 
     676                                if (remove(fname) != 0) { 
     677                                        logit("e", "error deleting file; exiting!\n"); 
     678                                        break; 
     679                                } else { 
     680                                        logit("e", "deleted file.\n"); 
     681                                } 
     682                        } 
     683                } else { 
     684                        /* ...or there was trouble (result<0)! */ 
     685                        logit("e", "\n"); 
     686                        sprintf(fnew, "%s/%s", TroubleSubdir, fname); 
     687                        if (rename_ew(fname, fnew) != 0) { 
     688                                logit("e", " error moving file to ./%s ; exiting!\n", 
     689                                      fnew); 
     690                                break; 
     691                        } else { 
     692                                logit("e", " moved to ./%s\n", fnew); 
     693                        } 
     694                } 
     695 
     696 
     697        }                       /* end-while */ 
     698 
     699        tport_detach(&Region); 
     700        logit(lot, "tankplayer: No more wavefiles to play; exiting!\n"); 
     701        fflush(stdout); 
     702        return (0); 
    679703} 
    680704 
     
    683707 *                      exits if any errors are encountered            * 
    684708 ***********************************************************************/ 
    685 void tankplayer_config(char *configfile) 
     709void  
     710tankplayer_config(char *configfile) 
    686711{ 
    687   int      ncommand;   /* # of required commands you expect to process   */ 
    688   char     init[10];   /* init flags, one byte for each required command */ 
    689   int      nmiss;      /* number of required commands that were missed   */ 
    690   char    *comm; 
    691   char    *str; 
    692   int      nfiles; 
    693   int      success; 
    694   int      i; 
    695  
    696   /* Set to zero one init flag for each required command 
    697   *****************************************************/ 
    698   ncommand = 8; 
    699   for( i=0; i<ncommand; i++ )  init[i] = 0; 
    700  
    701   /* Open the main configuration file 
    702   **********************************/ 
    703   nfiles = k_open( configfile ); 
    704   if ( nfiles == 0 ) { 
    705     logit( "e", 
    706              "tankplayer: Error opening command file <%s>; exiting!\n", 
    707              configfile ); 
    708     exit( -1 ); 
    709   } 
    710  
    711   /* Process all command files 
    712   ***************************/ 
    713   while(nfiles > 0)   /* While there are command files open */ 
    714   { 
    715     while(k_rd())        /* Read next line from active file  */ 
    716     { 
    717       comm = k_str();         /* Get the first token from line */ 
    718  
    719       /* Ignore blank lines & comments 
    720       *******************************/ 
    721       if( !comm )           continue; 
    722       if( comm[0] == '#' )  continue; 
    723  
    724       /* Open a nested configuration file 
    725       **********************************/ 
    726       if( comm[0] == '@' ) { 
    727         success = nfiles+1; 
    728         nfiles  = k_open(&comm[1]); 
    729         if ( nfiles != success ) { 
    730           logit( "e", 
    731                    "tankplayer: Error opening command file <%s>; exiting!\n", 
    732                    &comm[1] ); 
    733           exit( -1 ); 
    734         } 
    735         continue; 
    736       } 
    737  
    738       /* Process anything else as a command 
    739       ************************************/ 
    740       /* Read the transport ring name 
    741       ******************************/ 
    742       /*0*/    if( k_its( "RingName" ) ) 
    743       { 
    744         if ( (str=k_str()) != NULL ) { 
    745           if ( (RingKey = GetKey(str)) == -1 ) { 
    746             logit( "e", 
    747                      "tankplayer: Invalid ring name <%s>; exiting!\n", 
    748                      str ); 
    749             exit( -1 ); 
    750           } 
    751         } 
    752         init[0] = 1; 
    753       } 
    754  
    755       /* Read the log file switch 
    756       **************************/ 
    757       /*1*/    else if( k_its( "LogFile" ) ) 
    758       { 
    759         LogSwitch = k_int(); 
    760         init[1] = 1; 
    761       } 
    762  
    763       /* Read tankplayer's module id 
    764       ******************************/ 
    765       /*2*/    else if( k_its( "MyModuleId" ) ) 
    766       { 
    767         if ( (str=k_str()) != NULL ) { 
    768           if ( GetModId( str, &MyModId ) != 0 ) { 
    769             logit( "e", 
    770                      "tankplayer: Invalid module name <%s>; exiting!\n", 
    771                      str ); 
    772             exit( -1 ); 
    773           } 
    774         } 
    775         init[2] = 1; 
    776       } 
    777  
    778       /* Read type of waveform msg to read from tankfile 
    779       *************************************************/ 
    780       /*3*/    else if( k_its("PlayMsgType") ) 
    781       { 
    782         if( (str=k_str()) != NULL ) { 
    783           if( GetType( str, &PlayType ) != 0 ) { 
    784             logit( "e", 
    785                      "tankplayer: Invalid message type <%s>", str ); 
    786             logit( "e", " in <PlayMsgType> cmd; exiting!\n" ); 
    787             exit( -1 ); 
    788           } 
    789         } 
    790         init[3] = 1; 
    791       } 
    792  
    793       /* Read heartbeat interval (seconds) 
    794       ***********************************/ 
    795       /*4*/    else if( k_its("HeartBeatInt") ) 
    796       { 
    797         HeartBeatInt = k_long(); 
    798         init[4] = 1; 
    799       } 
    800  
    801       /* Read a list of wave files to play 
    802       ***********************************/ 
    803       /*5*/    else if( k_its("WaveFile") ) 
    804       { 
    805         if( nWaveFile+1 >= MAX_WF ) { 
    806           logit( "e", 
    807                    "tankplayer: Too many <WaveFile> commands in <%s>", 
    808                    configfile ); 
    809           logit( "e", "; max=%d; exiting!\n", MAX_WF ); 
    810           exit( -1 ); 
    811         } 
    812         if( ( str=k_str() ) != NULL ) { 
    813           if( strlen(str) > (size_t)MAX_LEN-1 ) { 
    814             logit( "e", 
    815                      "tankplayer: Filename <%s> too long in <WaveFile>", 
    816                      str ); 
    817             logit( "e", " cmd; max=%d; exiting!\n", MAX_LEN-1 ); 
    818             exit( -1 ); 
    819           } 
    820           strcpy( WaveFile[nWaveFile], str ); 
    821         } 
    822         nWaveFile++; 
    823         init[5] = 1; 
    824       } else if( k_its("GetFromDir") ) { 
    825                 str = k_str(); 
    826                 if(str) strncpy( GetFromDir, str, NAM_LEN ); 
    827                 init[5] = 1;     
    828       } else if( k_its("CheckPeriod") ) { 
    829                 CheckPeriod = k_int(); 
    830       } else if( k_its("OpenTries") ) { 
    831                 OpenTries = k_int(); 
    832       } else if( k_its("OpenWait") ) { 
    833                 OpenWait = k_int(); 
    834       } else if( k_its("SaveDataFiles") ) { 
    835                 SaveDataFiles = k_int(); 
    836       } 
    837  
    838  
    839       /* Read #seconds to pause between playing wave files 
    840       ***************************************************/ 
    841       /*6*/    else if( k_its("Pause") ) 
    842       { 
    843         Pause = k_int(); 
    844         init[6] = 1; 
    845       } 
    846  
    847       /* Read #seconds to wait for system to come up before playing data 
    848       ****************************************************************/ 
    849       /*7*/    else if( k_its("StartUpDelay") ) 
    850       { 
    851         StartUpDelay = k_int(); 
    852         init[7] = 1; 
    853       } 
    854  
    855       /* Flag for writing info to screen 
    856       *********************************/ 
    857       else if( k_its("ScreenMsg") )     /*Optional command*/ 
    858       { 
    859         ScreenMsg = k_int(); 
    860       } 
    861  
    862       /* Optional packet time adjustment 
    863       **********************************/ 
    864       else if ( k_its("SendLate") ) 
    865       { 
    866         AdjTime = 1; 
    867         LateTime = k_val(); 
    868       } 
    869       else if ( k_its("InterMessageDelayMillisecs") ) 
    870       { 
    871         InterMessageDelayMillisecs = (int)k_val(); 
    872       } 
    873  
    874       /* Optional debug command */ 
    875       else if ( k_its("Debug") ) 
    876       { 
    877         Debug = k_int(); 
    878       } 
    879       else if ( k_its("IgnoreTBVersionNumbers") ) 
    880       { 
    881         bBeSuperLenient = k_int(); 
    882       } 
    883       /* Command is not recognized 
    884       ***************************/ 
    885       else 
    886       { 
    887         logit( "e", "tankplayer: <%s> unknown command in <%s>.\n", 
    888                 comm, configfile ); 
    889         continue; 
    890       } 
    891  
    892       /* See if there were any errors processing the command 
    893       *****************************************************/ 
    894       if( k_err() ) { 
    895         logit( "e", 
    896                  "tankplayer: Bad <%s> command in <%s>; exiting!\n", 
    897                  comm, configfile ); 
    898         exit( -1 ); 
    899       } 
    900     } 
    901     nfiles = k_close(); 
    902   } 
    903  
    904   /* After all files are closed, check init flags for missed commands 
    905   ******************************************************************/ 
    906   nmiss = 0; 
    907   for ( i=0; i<ncommand; i++ )  if( !init[i] ) nmiss++; 
    908   if ( nmiss ) { 
    909     logit( "e", "tankplayer: ERROR, no " ); 
    910     if ( !init[0] )  logit( "e", "<RingName> "     ); 
    911     if ( !init[1] )  logit( "e", "<LogFile> "      ); 
    912     if ( !init[2] )  logit( "e", "<MyModuleId> "   ); 
    913     if ( !init[3] )  logit( "e", "<PlayMsgType> "  ); 
    914     if ( !init[4] )  logit( "e", "<HeartBeatInt> " ); 
    915     if ( !init[5] )  logit( "e", "<WaveFile> "     ); 
    916     if ( !init[6] )  logit( "e", "<Pause> "        ); 
    917     if ( !init[7] )  logit( "e", "<StartUpDelay> " ); 
    918     logit( "e", "command(s) in <%s>; exiting!\n", configfile ); 
    919     exit( -1 ); 
    920   } 
    921  
    922   return; 
     712        int             ncommand;       /* # of required commands you expect 
     713                                         * to process   */ 
     714        char            init      [10]; /* init flags, one byte for each 
     715                                         * required command */ 
     716        int             nmiss;  /* number of required commands that were 
     717                                 * missed   */ 
     718        char           *comm; 
     719        char           *str; 
     720        int             nfiles; 
     721        int             success; 
     722        int             i; 
     723 
     724        /* 
     725         * Set to zero one init flag for each required command *************************************************** 
     726         */ 
     727        ncommand = 8; 
     728        for (i = 0; i < ncommand; i++) 
     729                init[i] = 0; 
     730 
     731        /* 
     732         * Open the main configuration file ******************************** 
     733         */ 
     734        nfiles = k_open(configfile); 
     735        if (nfiles == 0) { 
     736                logit("e", 
     737                  "tankplayer: Error opening command file <%s>; exiting!\n", 
     738                      configfile); 
     739                exit(-1); 
     740        } 
     741        /* 
     742         * Process all command files ************************* 
     743         */ 
     744        while (nfiles > 0) {    /* While there are command files open */ 
     745                while (k_rd()) {/* Read next line from active file  */ 
     746                        comm = k_str(); /* Get the first token from line */ 
     747 
     748                        /* 
     749                         * Ignore blank lines & comments ***************************** 
     750                         */ 
     751                        if (!comm) 
     752                                continue; 
     753                        if (comm[0] == '#') 
     754                                continue; 
     755 
     756                        /* 
     757                         * Open a nested configuration file ******************************** 
     758                         */ 
     759                        if (comm[0] == '@') { 
     760                                success = nfiles + 1; 
     761                                nfiles = k_open(&comm[1]); 
     762                                if (nfiles != success) { 
     763                                        logit("e", 
     764                                              "tankplayer: Error opening command file <%s>; exiting!\n", 
     765                                              &comm[1]); 
     766                                        exit(-1); 
     767                                } 
     768                                continue; 
     769                        } 
     770                        /* 
     771                         * Process anything else as a command ********************************** 
     772                         */ 
     773                        /* 
     774                         * Read the transport ring name **************************** 
     775                         */ 
     776                         /* 0 */ if (k_its("RingName")) { 
     777                                if ((str = k_str()) != NULL) { 
     778                                        if ((RingKey = GetKey(str)) == -1) { 
     779                                                logit("e", 
     780                                                      "tankplayer: Invalid ring name <%s>; exiting!\n", 
     781                                                      str); 
     782                                                exit(-1); 
     783                                        } 
     784                                } 
     785                                init[0] = 1; 
     786                        } 
     787                        /* 
     788                         * Read the log file switch ************************ 
     789                         */ 
     790                         /* 1 */  
     791                        else if (k_its("LogFile")) { 
     792                                LogSwitch = k_int(); 
     793                                init[1] = 1; 
     794                        } 
     795                        /* 
     796                         * Read tankplayer's module id **************************** 
     797                         */ 
     798                         /* 2 */  
     799                        else if (k_its("MyModuleId")) { 
     800                                if ((str = k_str()) != NULL) { 
     801                                        if (GetModId(str, &MyModId) != 0) { 
     802                                                logit("e", 
     803                                                      "tankplayer: Invalid module name <%s>; exiting!\n", 
     804                                                      str); 
     805                                                exit(-1); 
     806                                        } 
     807                                } 
     808                                init[2] = 1; 
     809                        } 
     810                        /* 
     811                         * Read type of waveform msg to read from tankfile *********************************************** 
     812                         */ 
     813                         /* 3 */  
     814                        else if (k_its("PlayMsgType")) { 
     815                                if ((str = k_str()) != NULL) { 
     816                                        if (GetType(str, &PlayType) != 0) { 
     817                                                logit("e", 
     818                                                      "tankplayer: Invalid message type <%s>", str); 
     819                                                logit("e", " in <PlayMsgType> cmd; exiting!\n"); 
     820                                                exit(-1); 
     821                                        } 
     822                                } 
     823                                init[3] = 1; 
     824                        } 
     825                        /* 
     826                         * Read heartbeat interval (seconds) ********************************* 
     827                         */ 
     828                         /* 4 */  
     829                        else if (k_its("HeartBeatInt")) { 
     830                                HeartBeatInt = k_long(); 
     831                                init[4] = 1; 
     832                        } 
     833                        /* 
     834                         * Read a list of wave files to play ********************************* 
     835                         */ 
     836                         /* 5 */  
     837                        else if (k_its("WaveFile")) { 
     838                                if (nWaveFile + 1 >= MAX_WF) { 
     839                                        logit("e", 
     840                                              "tankplayer: Too many <WaveFile> commands in <%s>", 
     841                                              configfile); 
     842                                        logit("e", "; max=%d; exiting!\n", MAX_WF); 
     843                                        exit(-1); 
     844                                } 
     845                                if ((str = k_str()) != NULL) { 
     846                                        if (strlen(str) > (size_t) MAX_LEN - 1) { 
     847                                                logit("e", 
     848                                                      "tankplayer: Filename <%s> too long in <WaveFile>", 
     849                                                      str); 
     850                                                logit("e", " cmd; max=%d; exiting!\n", MAX_LEN - 1); 
     851                                                exit(-1); 
     852                                        } 
     853                                        strcpy(WaveFile[nWaveFile], str); 
     854                                } 
     855                                nWaveFile++; 
     856                                init[5] = 1; 
     857                        } else if (k_its("GetFromDir")) { 
     858                                str = k_str(); 
     859                                if (str) 
     860                                        strncpy(GetFromDir, str, NAM_LEN); 
     861                                init[5] = 1; 
     862                        } else if (k_its("CheckPeriod")) { 
     863                                CheckPeriod = k_int(); 
     864                        } else if (k_its("OpenTries")) { 
     865                                OpenTries = k_int(); 
     866                        } else if (k_its("OpenWait")) { 
     867                                OpenWait = k_int(); 
     868                        } else if (k_its("SaveDataFiles")) { 
     869                                SaveDataFiles = k_int(); 
     870                        } 
     871                        /* 
     872                         * Read #seconds to pause between playing wave files ************************************************* 
     873                         */ 
     874                         /* 6 */  
     875                        else if (k_its("Pause")) { 
     876                                Pause = k_int(); 
     877                                init[6] = 1; 
     878                        } 
     879                        /* 
     880                         * Read #seconds to wait for system to come up before 
     881                         * playing data ************************************************************** 
     882                         */ 
     883                         /* 7 */  
     884                        else if (k_its("StartUpDelay")) { 
     885                                StartUpDelay = k_int(); 
     886                                init[7] = 1; 
     887                        } 
     888                        /* 
     889                         * Flag for writing info to screen ******************************* 
     890                         */ 
     891                        else if (k_its("ScreenMsg")) {  /* Optional command */ 
     892                                ScreenMsg = k_int(); 
     893                        } 
     894                        /* 
     895                         * Optional packet time adjustment ******************************** 
     896                         */ 
     897                        else if (k_its("SendLate")) { 
     898                                AdjTime = 1; 
     899                                LateTime = k_val(); 
     900                        } else if (k_its("InterMessageDelayMillisecs")) { 
     901                                InterMessageDelayMillisecs = (int)k_val(); 
     902                        } 
     903                        /* Optional debug command */ 
     904                        else if (k_its("Debug")) { 
     905                                Debug = k_int(); 
     906                        } else if (k_its("IgnoreTBVersionNumbers")) { 
     907                                bBeSuperLenient = k_int(); 
     908                        } 
     909                        /* 
     910                         * Command is not recognized ************************* 
     911                         */ 
     912                        else { 
     913                                logit("e", "tankplayer: <%s> unknown command in <%s>.\n", 
     914                                      comm, configfile); 
     915                                continue; 
     916                        } 
     917 
     918                        /* 
     919                         * See if there were any errors processing the 
     920                         * command *************************************************** 
     921                         */ 
     922                        if (k_err()) { 
     923                                logit("e", 
     924                                      "tankplayer: Bad <%s> command in <%s>; exiting!\n", 
     925                                      comm, configfile); 
     926                                exit(-1); 
     927                        } 
     928                } 
     929                nfiles = k_close(); 
     930        } 
     931 
     932        /* 
     933         * After all files are closed, check init flags for missed commands **************************************************************** 
     934         */ 
     935        nmiss = 0; 
     936        for (i = 0; i < ncommand; i++) 
     937                if (!init[i]) 
     938                        nmiss++; 
     939        if (nmiss) { 
     940                logit("e", "tankplayer: ERROR, no "); 
     941                if (!init[0]) 
     942                        logit("e", "<RingName> "); 
     943                if (!init[1]) 
     944                        logit("e", "<LogFile> "); 
     945                if (!init[2]) 
     946                        logit("e", "<MyModuleId> "); 
     947                if (!init[3]) 
     948                        logit("e", "<PlayMsgType> "); 
     949                if (!init[4]) 
     950                        logit("e", "<HeartBeatInt> "); 
     951                if (!init[5]) 
     952                        logit("e", "<WaveFile> "); 
     953                if (!init[6]) 
     954                        logit("e", "<Pause> "); 
     955                if (!init[7]) 
     956                        logit("e", "<StartUpDelay> "); 
     957                logit("e", "command(s) in <%s>; exiting!\n", configfile); 
     958                exit(-1); 
     959        } 
     960        return; 
    923961} 
    924962 
     
    926964 *  tankplayer_lookup( )   Look up important info from earthworm.h tables  * 
    927965 ***************************************************************************/ 
    928 void tankplayer_lookup( void ) 
     966void  
     967tankplayer_lookup(void) 
    929968{ 
    930   if ( GetLocalInst( &InstId ) != 0 ) { 
    931     fprintf( stderr, 
    932              "tankplayer: error getting local installation id; exiting!\n" ); 
    933     exit( -1 ); 
    934   } 
    935   if( GetType( "TYPE_ADBUF", &TypeADBuf ) != 0 ) { 
    936     fprintf( stderr, 
    937              "tankplayer: Invalid message type <TYPE_ADBUF>; exiting!\n" ); 
    938     exit( -1 ); 
    939   } 
    940   if( GetType( "TYPE_TRACEBUF", &TypeTraceBuf ) != 0 ) { 
    941     fprintf( stderr, 
    942              "tankplayer: Invalid message type <TYPE_TRACEBUF>; exiting!\n" ); 
    943     exit( -1 ); 
    944   } 
    945   if( GetType( "TYPE_TRACEBUF2", &TypeTraceBuf2 ) != 0 ) { 
    946     fprintf( stderr, 
    947              "tankplayer: Invalid message type <TYPE_TRACEBUF2>; exiting!\n" ); 
    948     exit( -1 ); 
    949   } 
    950   if ( GetType( "TYPE_HEARTBEAT", &TypeHeartBeat ) != 0 ) { 
    951     fprintf( stderr, 
    952              "tankplayer: Invalid message type <TYPE_HEARTBEAT>; exiting!\n" ); 
    953     exit( -1 ); 
    954   } 
    955   if ( GetType( "TYPE_ERROR", &TypeError ) != 0 ) { 
    956     fprintf( stderr, 
    957              "tankplayer: Invalid message type <TYPE_ERROR>; exiting!\n" ); 
    958     exit( -1 ); 
    959   } 
    960   return; 
     969        if (GetLocalInst(&InstId) != 0) { 
     970                fprintf(stderr, 
     971                        "tankplayer: error getting local installation id; exiting!\n"); 
     972                exit(-1); 
     973        } 
     974        if (GetType("TYPE_ADBUF", &TypeADBuf) != 0) { 
     975                fprintf(stderr, 
     976                "tankplayer: Invalid message type <TYPE_ADBUF>; exiting!\n"); 
     977                exit(-1); 
     978        } 
     979        if (GetType("TYPE_TRACEBUF", &TypeTraceBuf) != 0) { 
     980                fprintf(stderr, 
     981                        "tankplayer: Invalid message type <TYPE_TRACEBUF>; exiting!\n"); 
     982                exit(-1); 
     983        } 
     984        if (GetType("TYPE_TRACEBUF2", &TypeTraceBuf2) != 0) { 
     985                fprintf(stderr, 
     986                        "tankplayer: Invalid message type <TYPE_TRACEBUF2>; exiting!\n"); 
     987                exit(-1); 
     988        } 
     989        if (GetType("TYPE_HEARTBEAT", &TypeHeartBeat) != 0) { 
     990                fprintf(stderr, 
     991                        "tankplayer: Invalid message type <TYPE_HEARTBEAT>; exiting!\n"); 
     992                exit(-1); 
     993        } 
     994        if (GetType("TYPE_ERROR", &TypeError) != 0) { 
     995                fprintf(stderr, 
     996                "tankplayer: Invalid message type <TYPE_ERROR>; exiting!\n"); 
     997                exit(-1); 
     998        } 
     999        return; 
    9611000} 
    9621001 
     
    9651004 *                     shared memory.  Writes errors to log file & screen.    * 
    9661005 ******************************************************************************/ 
    967 void tankplayer_status( unsigned char type, short ierr, char *note ) 
     1006void  
     1007tankplayer_status(unsigned char type, short ierr, char *note) 
    9681008{ 
    969   MSG_LOGO    logo; 
    970   char        msg[256]; 
    971   long        size; 
    972   time_t        t; 
    973  
    974   /* Build the message 
    975   *******************/ 
    976   logo.instid = InstId; 
    977   logo.mod    = MyModId; 
    978   logo.type   = type; 
    979  
    980   time( &t ); 
    981  
    982   if( type == TypeHeartBeat ) 
    983   { 
    984     sprintf( msg, "%ld %ld\n", (long) t, (long) MyPID ); 
    985   } 
    986   else if( type == TypeError ) 
    987   { 
    988     sprintf( msg, "%ld %hd %s\n", (long) t, ierr, note); 
    989     logit( "et", "tankplayer: %s\n", note ); 
    990   } 
    991  
    992   size = (long)strlen( msg );   /* don't include the null byte in the message */ 
    993  
    994   /* Write the message to shared memory 
    995   ************************************/ 
    996   if( tport_putmsg( &Region, &logo, size, msg ) != PUT_OK ) 
    997   { 
    998     if( type == TypeHeartBeat ) { 
    999       logit("et","tankplayer:  Error sending heartbeat.\n" ); 
    1000     } 
    1001     else if( type == TypeError ) { 
    1002       logit("et","tankplayer:  Error sending error:%d.\n", ierr ); 
    1003     } 
    1004   } 
    1005  
    1006   return; 
     1009        MSG_LOGO        logo; 
     1010        char            msg       [256]; 
     1011        long            size; 
     1012        time_t          t; 
     1013 
     1014        /* 
     1015         * Build the message ***************** 
     1016         */ 
     1017        logo.instid = InstId; 
     1018        logo.mod = MyModId; 
     1019        logo.type = type; 
     1020 
     1021        time(&t); 
     1022 
     1023        if (type == TypeHeartBeat) { 
     1024                sprintf(msg, "%ld %ld\n", (long)t, (long)MyPID); 
     1025        } else if (type == TypeError) { 
     1026                sprintf(msg, "%ld %hd %s\n", (long)t, ierr, note); 
     1027                logit("et", "tankplayer: %s\n", note); 
     1028        } 
     1029        size = (long)strlen(msg);       /* don't include the null byte in the 
     1030                                         * message */ 
     1031 
     1032        /* 
     1033         * Write the message to shared memory ********************************** 
     1034         */ 
     1035        if (tport_putmsg(&Region, &logo, size, msg) != PUT_OK) { 
     1036                if (type == TypeHeartBeat) { 
     1037                        logit("et", "tankplayer:  Error sending heartbeat.\n"); 
     1038                } else if (type == TypeError) { 
     1039                        logit("et", "tankplayer:  Error sending error:%d.\n", ierr); 
     1040                } 
     1041        } 
     1042        return; 
    10071043} 
    10081044 
     
    10131049 *   For TYPE_TRACEBUF2 msgs, returns the endtime as a double        * 
    10141050 *********************************************************************/ 
    1015 double get_time( char *msg, unsigned char msgtype ) 
     1051double  
     1052get_time(char *msg, unsigned char msgtype) 
    10161053{ 
    1017   WF_HEADER    *adhd;    /* header for TYPE_ADBUF message     */ 
    1018   TRACE2_HEADER *wvhd;    /* header for TYPE_TRACEBUF2 message  */ 
    1019   int32_t       tssec; 
    1020   int32_t       tsmic; 
    1021   double        hdtime; 
    1022   char          byte_order; 
    1023  
    1024   if( msgtype == TypeADBuf ) 
    1025   { 
    1026     adhd = (WF_HEADER *) msg; 
    1027     tssec = adhd->tssec; 
    1028     tsmic = adhd->tsmic; 
     1054        WF_HEADER      *adhd;   /* header for TYPE_ADBUF message     */ 
     1055        TRACE2_HEADER  *wvhd;   /* header for TYPE_TRACEBUF2 message  */ 
     1056        int32_t         tssec; 
     1057        int32_t         tsmic; 
     1058        double          hdtime; 
     1059        char            byte_order; 
     1060 
     1061        if (msgtype == TypeADBuf) { 
     1062                adhd = (WF_HEADER *) msg; 
     1063                tssec = adhd->tssec; 
     1064                tsmic = adhd->tsmic; 
    10291065#ifdef _SPARC 
    1030     SwapInt32( &tssec );  /* Note: By definition, TYPE_ADBUF msgs */ 
    1031     SwapInt32( &tsmic );  /*       are always in INTEL byte order */ 
     1066                SwapInt32(&tssec);      /* Note: By definition, TYPE_ADBUF 
     1067                                         * msgs */ 
     1068                SwapInt32(&tsmic);      /* are always in INTEL byte order */ 
    10321069#endif 
    1033     return( (double)tssec + (0.000001*tsmic) ); 
    1034   } 
    1035  
    1036   else if( msgtype == TypeTraceBuf ||  msgtype == TypeTraceBuf2) 
    1037   { 
    1038     wvhd       = (TRACE2_HEADER *) msg; 
    1039     hdtime     = wvhd->endtime; 
    1040     byte_order = wvhd->datatype[0]; 
     1070                return ((double)tssec + (0.000001 * tsmic)); 
     1071        } else if (msgtype == TypeTraceBuf || msgtype == TypeTraceBuf2) { 
     1072                wvhd = (TRACE2_HEADER *) msg; 
     1073                hdtime = wvhd->endtime; 
     1074                byte_order = wvhd->datatype[0]; 
    10411075#ifdef _SPARC 
    1042     if(byte_order=='i') SwapDouble( &hdtime ); 
     1076                if (byte_order == 'i') 
     1077                        SwapDouble(&hdtime); 
    10431078#endif 
    10441079#ifdef _INTEL 
    1045     if(byte_order=='s') SwapDouble( &hdtime ); 
     1080                if (byte_order == 's') 
     1081                        SwapDouble(&hdtime); 
    10461082#endif 
    1047     return( hdtime ); 
    1048   } 
    1049  
    1050   return( 0.0 ); 
     1083                return (hdtime); 
     1084        } 
     1085        return (0.0); 
    10511086} 
    10521087 
     
    10581093 *  Byte swapping is done as necessary.                              * 
    10591094 *********************************************************************/ 
    1060 void set_time( char *msg, unsigned char msgtype, double time ) 
     1095void  
     1096set_time(char *msg, unsigned char msgtype, double time) 
    10611097{ 
    1062   WF_HEADER    *adhd;    /* header for TYPE_ADBUF message     */ 
    1063   TRACE2_HEADER *wvhd;    /* header for TYPE_TRACEBUF2 message  */ 
    1064   int32_t       tssec; 
    1065   int32_t       tsmic; 
    1066   double        starttime, endtime; 
    1067   char          byte_order; 
    1068   int           nsamp; 
    1069   double        samprate; 
    1070  
    1071   if( msgtype == TypeADBuf ) 
    1072   { 
    1073     adhd = (WF_HEADER *) msg; 
    1074     tssec = (int32_t) time; 
    1075     tsmic = (int32_t)(1000000 * ( time - (double) tssec )); 
     1098        WF_HEADER      *adhd;   /* header for TYPE_ADBUF message     */ 
     1099        TRACE2_HEADER  *wvhd;   /* header for TYPE_TRACEBUF2 message  */ 
     1100        int32_t         tssec; 
     1101        int32_t         tsmic; 
     1102        double          starttime, endtime; 
     1103        char            byte_order; 
     1104        int             nsamp; 
     1105        double          samprate; 
     1106 
     1107        if (msgtype == TypeADBuf) { 
     1108                adhd = (WF_HEADER *) msg; 
     1109                tssec = (int32_t) time; 
     1110                tsmic = (int32_t) (1000000 * (time - (double)tssec)); 
    10761111#ifdef _SPARC 
    1077     SwapInt32( &tssec );  /* Note: By definition, TYPE_ADBUF msgs */ 
    1078     SwapInt32( &tsmic );  /*       are always in INTEL byte order */ 
     1112                SwapInt32(&tssec);      /* Note: By definition, TYPE_ADBUF 
     1113                                         * msgs */ 
     1114                SwapInt32(&tsmic);      /* are always in INTEL byte order */ 
    10791115#endif 
    1080     adhd->tssec = tssec; 
    1081     adhd->tsmic = tsmic; 
    1082     return; 
    1083   } 
    1084  
    1085   else if( msgtype == TypeTraceBuf ||  msgtype == TypeTraceBuf2) 
    1086   { 
    1087     wvhd       = (TRACE2_HEADER *) msg; 
    1088     endtime     = time; 
    1089     byte_order = wvhd->datatype[0]; 
    1090     nsamp      = wvhd->nsamp; 
    1091     samprate   = wvhd->samprate; 
     1116                adhd->tssec = tssec; 
     1117                adhd->tsmic = tsmic; 
     1118                return; 
     1119        } else if (msgtype == TypeTraceBuf || msgtype == TypeTraceBuf2) { 
     1120                wvhd = (TRACE2_HEADER *) msg; 
     1121                endtime = time; 
     1122                byte_order = wvhd->datatype[0]; 
     1123                nsamp = wvhd->nsamp; 
     1124                samprate = wvhd->samprate; 
    10921125 
    10931126#ifdef _SPARC 
    1094     if(byte_order=='i' || byte_order == 'f') 
    1095     { 
    1096       SwapDouble( &endtime ); 
    1097       SwapDouble( &samprate ); 
    1098       SwapInt( &nsamp ); 
    1099     } 
     1127                if (byte_order == 'i' || byte_order == 'f') { 
     1128                        SwapDouble(&endtime); 
     1129                        SwapDouble(&samprate); 
     1130                        SwapInt(&nsamp); 
     1131                } 
    11001132#endif 
    11011133#ifdef _INTEL 
    1102     if(byte_order=='s' || byte_order == 't') 
    1103     { 
    1104       SwapDouble( &endtime ); 
    1105       SwapDouble( &samprate ); 
    1106       SwapInt( &nsamp ); 
    1107     } 
     1134                if (byte_order == 's' || byte_order == 't') { 
     1135                        SwapDouble(&endtime); 
     1136                        SwapDouble(&samprate); 
     1137                        SwapInt(&nsamp); 
     1138                } 
    11081139#endif 
    11091140 
    1110     starttime = time - (nsamp - 1) / samprate; 
     1141                starttime = time - (nsamp - 1) / samprate; 
    11111142#ifdef _SPARC 
    1112     if(byte_order=='i' || byte_order == 'f')  SwapDouble( &starttime ); 
     1143                if (byte_order == 'i' || byte_order == 'f') 
     1144                        SwapDouble(&starttime); 
    11131145#endif 
    11141146#ifdef _INTEL 
    1115     if(byte_order=='s' || byte_order == 't') SwapDouble( &starttime ); 
     1147                if (byte_order == 's' || byte_order == 't') 
     1148                        SwapDouble(&starttime); 
    11161149#endif 
    1117     wvhd->starttime = starttime; 
    1118     wvhd->endtime  = endtime; 
    1119   } 
    1120   return; 
     1150                wvhd->starttime = starttime; 
     1151                wvhd->endtime = endtime; 
     1152        } 
     1153        return; 
    11211154} 
Note: See TracChangeset for help on using the changeset viewer.