Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libmseed for openSUSE:Factory 
checked in at 2025-07-30 11:43:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libmseed (Old)
 and      /work/SRC/openSUSE:Factory/.libmseed.new.13279 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libmseed"

Wed Jul 30 11:43:53 2025 rev:3 rq:1296200 version:3.1.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/libmseed/libmseed.changes        2025-04-26 
22:25:41.987221554 +0200
+++ /work/SRC/openSUSE:Factory/.libmseed.new.13279/libmseed.changes     
2025-07-30 11:45:07.690103556 +0200
@@ -1,0 +2,21 @@
+Mon Jul 28 18:29:35 UTC 2025 - Andreas Stieger <andreas.stie...@gmx.de>
+
+- update to 3.1.6:
+  Use cases creating miniSEED v2 records with microsecond
+  resolution and non-integer sampling rates are strongly encouraged
+  to update to this release to retain full microsecond accuracy in
+  created data.
+  * Properly propagate sub-fractional microseconds to v2 blockette
+    1001 when packing more than one record.
+  * Round sub-fractional and sub-microsecond times for v2 record
+    fields to retain accuracy.
+  * Ensure microsecond offsets in v2 record fields are -50 to +49,
+    which matches previous major library version behavior and SEED
+    recommendation.
+  * Add msr3_repack_mseed2() to repack v2 records efficiently
+    without decoding data samples.
+  * Add -s (start time) and -R (sample rate) options to
+    example/lm_pack.c.
+  * Fix some pedantic compiler warnings in msio.c.
+
+-------------------------------------------------------------------

Old:
----
  libmseed-3.1.5.tar.gz

New:
----
  libmseed-3.1.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libmseed.spec ++++++
--- /var/tmp/diff_new_pack.q4KQyZ/_old  2025-07-30 11:45:08.818150298 +0200
+++ /var/tmp/diff_new_pack.q4KQyZ/_new  2025-07-30 11:45:08.822150464 +0200
@@ -18,7 +18,7 @@
 
 %define sover 3
 Name:           libmseed
-Version:        3.1.5
+Version:        3.1.6
 Release:        0
 Summary:        MiniSEED data format library
 License:        Apache-2.0

++++++ libmseed-3.1.5.tar.gz -> libmseed-3.1.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/.gitignore 
new/libmseed-3.1.6/.gitignore
--- old/libmseed-3.1.5/.gitignore       2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/.gitignore       2025-07-27 02:05:46.000000000 +0200
@@ -1,4 +1,5 @@
 # C build objects
+*.a
 *.so
 *.lo
 *.o
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/ChangeLog new/libmseed-3.1.6/ChangeLog
--- old/libmseed-3.1.5/ChangeLog        2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/ChangeLog        2025-07-27 02:05:46.000000000 +0200
@@ -1,3 +1,14 @@
+2025.207: 3.1.6
+       - Properly propagate sub-fractional microseconds to v2 blockette 1001
+       when packing more than one record.
+       - Round sub-fractional and sub-microsecond times for v2 record fields
+       to retain accuracy.
+       - Ensure microsecond offsets in v2 record fields are -50 to +49, which
+       matches previous major library version behavior and SEED recommendation.
+       - Add msr3_repack_mseed2() to repack v2 records efficiently.
+       - Add -s and -R options to example/lm_pack.c.
+       - Fix some pedantic compiler warnings in msio.c.
+
 2025.114: 3.1.5
        - Add new functions to libmseed.map and libmseed.def for public use.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/example/lm_pack.c 
new/libmseed-3.1.6/example/lm_pack.c
--- old/libmseed-3.1.5/example/lm_pack.c        2025-04-24 14:08:48.000000000 
+0200
+++ new/libmseed-3.1.6/example/lm_pack.c        2025-07-27 02:05:46.000000000 
+0200
@@ -29,11 +29,13 @@
 #define VERSION "[libmseed " LIBMSEED_VERSION " example]"
 #define PACKAGE "lm_pack"
 
-static flag verbose  = 0;
-static int reclen    = -1;
-static int encoding  = 10;
-static int msformat  = 3;
-static char *outfile = NULL;
+static flag verbose       = 0;
+static int reclen         = -1;
+static double samprate    = 1.0;
+static int encoding       = 10;
+static int msformat       = 3;
+static nstime_t starttime = NSTUNSET;
+static char *outfile      = NULL;
 
 static int parameter_proc (int argcount, char **argvec);
 static void usage (void);
@@ -171,6 +173,8 @@
   if (parameter_proc (argc, argv) < 0)
     return -1;
 
+  if (starttime == NSTUNSET)
+    starttime = ms_timestr2nstime ("2012-01-01T00:00:00Z");
 
   if (!(msr = msr3_init (msr)))
   {
@@ -182,8 +186,8 @@
   strcpy (msr->sid, "FDSN:XX_TEST__X_Y_Z");
   msr->reclen = reclen;
   msr->pubversion = 1;
-  msr->starttime = ms_timestr2nstime ("2012-01-01T00:00:00");
-  msr->samprate = 1.0;
+  msr->starttime = starttime;
+  msr->samprate = samprate;
   msr->encoding = encoding;
 
   if (encoding == DE_TEXT)
@@ -292,10 +296,24 @@
     {
       reclen = strtol (argvec[++optind], NULL, 10);
     }
+    else if (strcmp (argvec[optind], "-R") == 0)
+    {
+      samprate = strtod (argvec[++optind], NULL);
+    }
     else if (strcmp (argvec[optind], "-e") == 0)
     {
       encoding = strtol (argvec[++optind], NULL, 10);
     }
+    else if (strcmp (argvec[optind], "-s") == 0)
+    {
+      starttime = ms_timestr2nstime (argvec[++optind]);
+
+      if (starttime == NSTERROR)
+      {
+        ms_log (2, "Invalid start time: %s\n", argvec[optind]);
+        exit (1);
+      }
+    }
     else if (strcmp (argvec[optind], "-o") == 0)
     {
       outfile = argvec[++optind];
@@ -344,7 +362,9 @@
            " -v             Be more verbose, multiple flags can be used\n"
            " -F format      Specify miniSEED version format, default is v3\n"
            " -r bytes       Specify maximum record length in bytes, default 
4096\n"
+           " -R samprate    Specify sample rate, default is 1.0\n"
            " -e encoding    Specify encoding format\n"
+           " -s starttime   Specify the start time, default is 
2012-01-01T00:00:00Z\n"
            "\n"
            " -o outfile     Specify the output file, required\n"
            "\n"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/genutils.c 
new/libmseed-3.1.6/genutils.c
--- old/libmseed-3.1.5/genutils.c       2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/genutils.c       2025-07-27 02:05:46.000000000 +0200
@@ -1735,16 +1735,19 @@
 
 /**********************************************************************/ /**
  * @brief Runtime test for host endianess
- * @returns 0 if the host is little endian, otherwise 1.
+ * @returns 1 if the host is big endian, 0 otherwise.
  ***************************************************************************/
 inline int
 ms_bigendianhost (void)
 {
-  const uint16_t endian = 256;
-  return *(const uint8_t *)&endian;
+  union
+  {
+    uint16_t word;
+    uint8_t bytes[2];
+  } test = {0x0102};
+  return (test.bytes[0] == 0x01);
 } /* End of ms_bigendianhost() */
 
-
 /**********************************************************************/ /**
  * @brief Read leap second file specified by an environment variable
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/libmseed.h 
new/libmseed-3.1.6/libmseed.h
--- old/libmseed-3.1.5/libmseed.h       2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/libmseed.h       2025-07-27 02:05:46.000000000 +0200
@@ -28,8 +28,8 @@
 extern "C" {
 #endif
 
-#define LIBMSEED_VERSION "3.1.5"     //!< Library version
-#define LIBMSEED_RELEASE "2025.114"  //!< Library release date
+#define LIBMSEED_VERSION "3.1.6"     //!< Library version
+#define LIBMSEED_RELEASE "2025.207"  //!< Library release date
 
 /** @defgroup io-functions File and URL I/O */
 /** @defgroup miniseed-record Record Handling */
@@ -418,6 +418,8 @@
 
 extern int msr3_repack_mseed3 (const MS3Record *msr, char *record, uint32_t 
recbuflen, int8_t verbose);
 
+extern int msr3_repack_mseed2 (const MS3Record *msr, char *record, uint32_t 
recbuflen, int8_t verbose);
+
 extern int msr3_pack_header3 (const MS3Record *msr, char *record, uint32_t 
recbuflen, int8_t verbose);
 
 extern int msr3_pack_header2 (const MS3Record *msr, char *record, uint32_t 
recbuflen, int8_t verbose);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/msio.c new/libmseed-3.1.6/msio.c
--- old/libmseed-3.1.5/msio.c   2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/msio.c   2025-07-27 02:05:46.000000000 +0200
@@ -22,6 +22,7 @@
 #define _LARGEFILE_SOURCE 1
 
 #include <errno.h>
+#include <stddef.h>
 
 #include "msio.h"
 
@@ -102,11 +103,11 @@
 {
   struct header_callback_parameters *hcp = (struct header_callback_parameters 
*)userdata;
 
-  char startstr[21] = {0}; /* Maximum of 20 digit value */
-  char endstr[21]   = {0}; /* Maximum of 20 digit value */
-  int startdigits   = 0;
-  int enddigits     = 0;
-  char *dash        = NULL;
+  char startstr[21]   = {0}; /* Maximum of 20 digit value */
+  char endstr[21]     = {0}; /* Maximum of 20 digit value */
+  uint8_t startdigits = 0;
+  uint8_t enddigits   = 0;
+  char *dash          = NULL;
   char *ptr;
 
   if (!buffer || !userdata)
@@ -119,7 +120,7 @@
   if (size > 22 && strncasecmp (buffer, "Content-Range: bytes", 20) == 0)
   {
     /* Process each character, starting just afer "bytes" unit */
-    for (ptr = buffer + 20; *ptr != '\0' && (ptr - buffer) < size; ptr++)
+    for (ptr = buffer + 20; *ptr != '\0' && (ptr - buffer) < (ptrdiff_t)size; 
ptr++)
     {
       /* Skip spaces before start of range */
       if (*ptr == ' ' && startdigits == 0)
@@ -148,10 +149,10 @@
 
     /* Convert start and end values to numbers if non-zero length */
     if (hcp->startoffset && startdigits)
-      *hcp->startoffset = (int64_t) strtoull (startstr, NULL, 10);
+      *hcp->startoffset = (int64_t)strtoull (startstr, NULL, 10);
 
     if (hcp->endoffset && enddigits)
-      *hcp->endoffset = (int64_t) strtoull (endstr, NULL, 10);
+      *hcp->endoffset = (int64_t)strtoull (endstr, NULL, 10);
   }
 
   return size;
@@ -159,7 +160,6 @@
 
 #endif /* defined(LIBMSEED_URL) */
 
-
 /***************************************************************************
  * msio_fopen:
  *
@@ -181,7 +181,7 @@
  ***************************************************************************/
 int
 msio_fopen (LMIO *io, const char *path, const char *mode,
-          int64_t *startoffset, int64_t *endoffset)
+            int64_t *startoffset, int64_t *endoffset)
 {
   int knownfile = 0;
 
@@ -340,7 +340,7 @@
     if (startoffset || endoffset)
     {
       hcp.startoffset = startoffset;
-      hcp.endoffset = endoffset;
+      hcp.endoffset   = endoffset;
 
       /* Configure header callback */
       if (curl_easy_setopt (io->handle, CURLOPT_HEADERFUNCTION, 
header_callback) != CURLE_OK)
@@ -389,7 +389,7 @@
 
     if ((io->handle = fopen (path, mode)) == NULL)
     {
-      ms_log (2, "Cannot open: %s (%s)\n", path, strerror(errno));
+      ms_log (2, "Cannot open: %s (%s)\n", path, strerror (errno));
       return -1;
     }
 
@@ -405,7 +405,7 @@
   }
 
   return 0;
-}  /* End of msio_fopen() */
+} /* End of msio_fopen() */
 
 /*********************************************************************
  * msio_fclose:
@@ -452,14 +452,13 @@
 #endif
   }
 
-  io->type = LMIO_NULL;
-  io->handle = NULL;
+  io->type    = LMIO_NULL;
+  io->handle  = NULL;
   io->handle2 = NULL;
 
   return 0;
 } /* End of msio_fclose() */
 
-
 /*********************************************************************
  * msio_fread:
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/pack.c new/libmseed-3.1.6/pack.c
--- old/libmseed-3.1.5/pack.c   2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/pack.c   2025-07-27 02:05:46.000000000 +0200
@@ -41,14 +41,20 @@
                              void *handlerdata, int64_t *packedsamples,
                              uint32_t flags, int8_t verbose);
 
+static int msr3_pack_header2_offsets (const MS3Record *msr, char *record, 
uint32_t recbuflen,
+                                      uint16_t *blockette_1000_offset, 
uint16_t *blockette_1001_offset,
+                                      int8_t verbose);
+
 static int64_t msr_pack_data (void *dest, void *src, uint64_t maxsamples, 
uint64_t maxdatabytes,
                               char sampletype, int8_t encoding, int8_t 
swapflag,
                               uint32_t *byteswritten, const char *sid, int8_t 
verbose);
 
 static int ms_genfactmult (double samprate, int16_t *factor, int16_t 
*multiplier);
 
-static int64_t ms_timestr2btime (const char *timestr, uint8_t *btime, const 
char *sid, int8_t swapflag);
+static nstime_t ms_timestr2btime (const char *timestr, uint8_t *btime, int8_t 
*usec_offset,
+                                  const char *sid, int8_t swapflag);
 
+static nstime_t nstime2fsec_usec_offset (nstime_t nstime, uint16_t *fsec, 
int8_t *usec_offset);
 
 /**********************************************************************/ /**
  * @brief Pack data into miniSEED records.
@@ -410,14 +416,14 @@
 
   if (recbuflen < (MS3FSDH_LENGTH + strlen(msr->sid) + msr->extralength))
   {
-    ms_log (2, "%s: Record length (%u) is not large enough for header (%u), 
SID (%"PRIsize_t"), and extra (%d)\n",
+    ms_log (2, "%s: Record buffer length (%u) is not large enough for header 
(%u), SID (%"PRIsize_t"), and extra (%d)\n",
             msr->sid, recbuflen, MS3FSDH_LENGTH, strlen(msr->sid), 
msr->extralength);
     return -1;
   }
 
   if (msr->samplecnt > UINT32_MAX)
   {
-    ms_log (2, "%s: Too many samples in input record (%" PRId64 " for a single 
record)\n",
+    ms_log (2, "%s: Too many samples in input record (%" PRId64 ") for a 
single record)\n",
             msr->sid, msr->samplecnt);
     return -1;
   }
@@ -609,6 +615,8 @@
   int64_t packoffset;
   int64_t totalpackedsamples;
 
+  uint16_t blockette_1000_offset = 0;
+  uint16_t blockette_1001_offset = 0;
   uint32_t datalength;
   nstime_t nextstarttime;
   uint16_t year;
@@ -616,7 +624,8 @@
   uint8_t hour;
   uint8_t min;
   uint8_t sec;
-  uint32_t nsec;
+  uint16_t fsec;
+  int8_t usec_offset;
 
   if (!msr)
   {
@@ -665,16 +674,22 @@
   memset (rawrec, 0, MS2FSDH_LENGTH);
 
   /* Pack fixed header and extra headers, returned size is data offset */
-  headerlen = msr3_pack_header2 (msr, rawrec, reclen, verbose);
+  headerlen = msr3_pack_header2_offsets (msr, rawrec, reclen,
+                                         &blockette_1000_offset,
+                                         &blockette_1001_offset,
+                                         verbose);
 
-  if (headerlen < 0)
+  if (headerlen < 0 || blockette_1000_offset == 0)
+  {
+    libmseed_memory.free (rawrec);
     return -1;
+  }
 
   /* Short cut: if there are no samples, record packing is complete */
   if (msr->numsamples <= 0)
   {
     /* Set encoding to text for consistency and to reduce expectations */
-    *pMS2B1000_ENCODING (rawrec + 48) = DE_TEXT;
+    *pMS2B1000_ENCODING (rawrec + blockette_1000_offset) = DE_TEXT;
 
     /* Set empty part of record to zeros */
     memset (rawrec + headerlen, 0, reclen - headerlen);
@@ -698,6 +713,7 @@
   if (!samplesize)
   {
     ms_log (2, "%s: Unknown sample type '%c'\n", msr->sid, msr->sampletype);
+    libmseed_memory.free (rawrec);
     return -1;
   }
 
@@ -807,13 +823,15 @@
     if (totalpackedsamples >= msr->numsamples)
       break;
 
-    /* Update record start time for next record */
+    /* Update encoded record start time for next record */
     nextstarttime = ms_sampletime (msr->starttime, totalpackedsamples, 
msr->samprate);
 
-    if (ms_nstime2time (nextstarttime, &year, &day, &hour, &min, &sec, &nsec))
+    nstime_t second_nextstarttime = nstime2fsec_usec_offset (nextstarttime, 
&fsec, &usec_offset);
+
+    if (ms_nstime2time (second_nextstarttime, &year, &day, &hour, &min, &sec, 
NULL))
     {
       ms_log (2, "%s: Cannot convert next record starttime: %" PRId64 "\n",
-              msr->sid, nextstarttime);
+              msr->sid, second_nextstarttime);
       libmseed_memory.free (encoded);
       libmseed_memory.free (rawrec);
       return -1;
@@ -824,7 +842,12 @@
     *pMS2FSDH_HOUR (rawrec) = hour;
     *pMS2FSDH_MIN (rawrec)  = min;
     *pMS2FSDH_SEC (rawrec)  = sec;
-    *pMS2FSDH_FSEC (rawrec) = HO2u ((nsec / 100000), swapflag);
+    *pMS2FSDH_FSEC (rawrec) = HO2u (fsec, swapflag);
+
+    if (blockette_1001_offset)
+    {
+      *pMS2B1001_MICROSECOND (rawrec + blockette_1001_offset) = usec_offset;
+    }
   }
 
   if (verbose >= 2)
@@ -839,6 +862,124 @@
 } /* End of msr3_pack_mseed2() */
 
 /**********************************************************************/ /**
+ * @brief Repack a parsed miniSEED record into a version 2 record.
+ *
+ * Pack the parsed header into a version 2 header and copy the raw
+ * encoded data from the original record.  The original record must be
+ * available at the ::MS3Record.record pointer.
+ *
+ * The new record will be the same length as the original record and an
+ * error will be returned if the repacked record would not fit.
+ * If the new record is shorter than the original record, the extra space
+ * will be zeroed.
+ *
+ * This can be used to efficiently convert format versions or modify
+ * header values without unpacking the data samples.
+ *
+ * @param[in] msr ::MS3Record containing record to repack
+ * @param[out] record Destination buffer for repacked record
+ * @param[in] recbuflen Length of destination buffer
+ * @param[in] verbose Controls logging verbosity, 0 is no diagnostic output
+ *
+ * @returns record length on success and -1 on error.
+ *
+ * \ref MessageOnError - this function logs a message on error
+ ***************************************************************************/
+int
+msr3_repack_mseed2 (const MS3Record *msr, char *record, uint32_t recbuflen,
+                    int8_t verbose)
+{
+  int headerlen;
+  uint16_t dataoffset;
+  uint32_t origdataoffset;
+  uint32_t origdatasize;
+  uint32_t totalsize;
+  uint8_t swapflag;
+
+  if (!msr || !msr->record || !record)
+  {
+    ms_log (2, "%s(): Required input not defined: 'msr', 'msr->record', or 
'record'\n",
+            __func__);
+    return -1;
+  }
+
+  if ((int64_t)recbuflen < msr->reclen)
+  {
+    ms_log (2, "%s: Record buffer length (%u) is not large enough for 
requested record length (%d)\n",
+            msr->sid, recbuflen, msr->reclen);
+    return -1;
+  }
+
+  if (msr->samplecnt > UINT16_MAX)
+  {
+    ms_log (2, "%s: Too many samples in input record (%" PRId64 ") for a 
single v2 record)\n",
+            msr->sid, msr->samplecnt);
+    return -1;
+  }
+
+  /* Pack fixed header and blockettes */
+  headerlen = msr3_pack_header2 (msr, record, recbuflen, verbose);
+
+  if (headerlen < 0)
+  {
+    ms_log (2, "%s: Cannot pack miniSEED version 2 header\n", msr->sid);
+    return -1;
+  }
+
+  /* Determine encoded data size */
+  if (msr3_data_bounds (msr, &origdataoffset, &origdatasize))
+  {
+    ms_log (2, "%s: Cannot determine original data bounds\n", msr->sid);
+    return -1;
+  }
+
+  /* Determine offset to encoded data */
+  if (msr->encoding == DE_STEIM1 || msr->encoding == DE_STEIM2)
+  {
+    dataoffset = 64;
+    while (dataoffset < headerlen)
+      dataoffset += 64;
+
+    /* Zero memory between blockettes and data if any */
+    memset (record + headerlen, 0, dataoffset - headerlen);
+  }
+  else
+  {
+    dataoffset = headerlen;
+  }
+
+  totalsize = dataoffset + origdatasize;
+
+  if (recbuflen < totalsize)
+  {
+    ms_log (2, "%s: Repacked minimum record length (%u) is larger than 
destination record buffer (%u)\n",
+            msr->sid, totalsize, recbuflen);
+    return -1;
+  }
+
+  /* Copy encoded data into record */
+  memcpy (record + dataoffset, msr->record + origdataoffset, origdatasize);
+
+  /* Check if byte swapping is needed, miniSEED 2 is written big endian */
+  swapflag = (ms_bigendianhost ()) ? 0 : 1;
+
+  /* Update number of samples and data offset */
+  *pMS2FSDH_NUMSAMPLES (record) = HO2u ((uint16_t)msr->samplecnt, swapflag);
+  *pMS2FSDH_DATAOFFSET (record) = HO2u (dataoffset, swapflag);
+
+  /* Zero any space between encoded data and end of record */
+  int32_t content = dataoffset + origdatasize;
+  if (content < msr->reclen)
+    memset (record + content, 0, msr->reclen - content);
+
+  if (verbose >= 1)
+    ms_log (0, "%s: Repacked %" PRId64 " samples into a %u byte record\n",
+            msr->sid, msr->samplecnt, msr->reclen);
+
+  return msr->reclen;
+} /* End of msr3_repack_mseed2() */
+
+/**********************************************************************/ /**
  * @brief Pack a miniSEED version 2 header into the specified buffer.
  *
  * Default values are: record length = 4096, encoding = 11 (Steim2).
@@ -857,6 +998,34 @@
 int
 msr3_pack_header2 (const MS3Record *msr, char *record, uint32_t recbuflen, 
int8_t verbose)
 {
+  return msr3_pack_header2_offsets (msr, record, recbuflen, NULL, NULL, 
verbose);
+}
+
+/**********************************************************************/ /**
+ * @internal
+ * Pack a miniSEED version 2 header into the specified buffer and return the
+ * offsets of the 1000 and 1001 blockettes.
+ *
+ * Default values are: record length = 4096, encoding = 11 (Steim2).
+ * The defaults are triggered when \a msr.reclen and \a msr.encoding
+ * are set to -1.
+ *
+ * @param[in] msr ::MS3Record to pack
+ * @param[out] record Destination for packed header
+ * @param[in] recbuflen Length of destination buffer
+ * @param[out] blockette_1000_offset Byte offset to B1000, 0 if none
+ * @param[out] blockette_1001_offset Byte offset to B1001, 0 if none
+ * @param[in] verbose Controls logging verbosity, 0 is no diagnostic output
+ *
+ * @returns the size of the header (fixed and blockettes) on success, 
otherwise -1.
+ *
+ * \ref MessageOnError - this function logs a message on error
+ ***************************************************************************/
+static int
+msr3_pack_header2_offsets (const MS3Record *msr, char *record, uint32_t 
recbuflen,
+                           uint16_t *blockette_1000_offset, uint16_t 
*blockette_1001_offset,
+                           int8_t verbose)
+{
   int written = 0;
   int8_t swapflag;
   uint32_t reclen;
@@ -872,9 +1041,8 @@
   uint8_t hour;
   uint8_t min;
   uint8_t sec;
-  uint32_t nsec;
   uint16_t fsec;
-  int8_t msec_offset;
+  int8_t usec_offset;
 
   uint32_t reclenexp = 0;
   uint32_t reclenfind;
@@ -904,6 +1072,12 @@
     return -1;
   }
 
+  /* Initialize blockette offsets to 0 */
+  if (blockette_1000_offset)
+    *blockette_1000_offset = 0;
+  if (blockette_1001_offset)
+    *blockette_1001_offset = 0;
+
   /* Use default record length and encoding if needed */
   reclen = (msr->reclen < 0) ? MS_PACK_DEFAULT_RECLEN : msr->reclen;
   encoding = (msr->encoding < 0) ? MS_PACK_DEFAULT_ENCODING : msr->encoding;
@@ -953,17 +1127,16 @@
   if (verbose > 2 && swapflag)
     ms_log (0, "%s: Byte swapping needed for packing of header\n", msr->sid);
 
+  /* Calculate time at fractional 100usec resolution and microsecond offset */
+  nstime_t second_nstime = nstime2fsec_usec_offset (msr->starttime, &fsec, 
&usec_offset);
+
   /* Break down start time into individual components */
-  if (ms_nstime2time (msr->starttime, &year, &day, &hour, &min, &sec, &nsec))
+  if (ms_nstime2time (second_nstime, &year, &day, &hour, &min, &sec, NULL))
   {
     ms_log (2, "%s: Cannot convert starttime: %" PRId64 "\n", msr->sid, 
msr->starttime);
     return -1;
   }
 
-  /* Calculate time at fractional 100usec resolution and microsecond offset */
-  fsec = nsec / 100000;
-  msec_offset = ((nsec / 1000) - (fsec * 100));
-
   /* Generate factor & multipler representation of sample rate */
   if (ms_genfactmult (msr3_sampratehz(msr), &factor, &multiplier))
   {
@@ -1136,10 +1309,13 @@
   *pMS2B1000_RECLEN (record + written)    = reclenexp;
   *pMS2B1000_RESERVED (record + written)  = 0;
 
+  if (blockette_1000_offset)
+    *blockette_1000_offset = written;
+
   written += 8;
 
   /* Add Blockette 1001 if microsecond offset or timing quality is present */
-  if (yyjson_ptr_get_uint (ehroot, "/FDSN/Time/Quality", &header_uint) || 
msec_offset)
+  if (yyjson_ptr_get_uint (ehroot, "/FDSN/Time/Quality", &header_uint) || 
usec_offset)
   {
     *next_blockette = HO2u ((uint16_t)written, swapflag);
     next_blockette = pMS2B1001_NEXT (record + written);
@@ -1153,10 +1329,13 @@
     else
       *pMS2B1001_TIMINGQUALITY (record + written) = 0;
 
-    *pMS2B1001_MICROSECOND (record + written) = msec_offset;
+    *pMS2B1001_MICROSECOND (record + written) = usec_offset;
     *pMS2B1001_RESERVED (record + written)    = 0;
     *pMS2B1001_FRAMECOUNT (record + written)  = 0;
 
+    if (blockette_1001_offset)
+      *blockette_1001_offset = written;
+
     written += 8;
   }
 
@@ -1208,26 +1387,19 @@
 
       if (yyjson_ptr_get_str (ehiterval, "/Time", &header_string))
       {
-        int64_t l_nsec;
-        uint16_t l_fsec;
-        int8_t l_msec_offset;
-
-        l_nsec = ms_timestr2btime (header_string,
-                                   (uint8_t *)pMS2B500_YEAR (record + written),
-                                   msr->sid, swapflag);
+        int8_t l_usec_offset;
+        nstime_t l_nstime = ms_timestr2btime (header_string,
+                                              (uint8_t *)pMS2B500_YEAR (record 
+ written),
+                                              &l_usec_offset, msr->sid, 
swapflag);
 
-        if (l_nsec == -1)
+        if (l_nstime == NSTERROR)
         {
           ms_log (2, "%s: Cannot convert B500 time: %s\n", msr->sid, 
header_string);
           yyjson_doc_free (ehdoc);
           return -1;
         }
 
-        /* Calculate time at fractional 100usec resolution and microsecond 
offset */
-        l_fsec        = (uint16_t)(l_nsec / 100000);
-        l_msec_offset = (int8_t)((l_nsec / 1000) - (l_fsec * 100));
-
-        *pMS2B500_MICROSECOND (record + written) = l_msec_offset;
+        *pMS2B500_MICROSECOND (record + written) = l_usec_offset;
       }
 
       if (yyjson_ptr_get_uint (ehiterval, "/ReceptionQuality", &header_uint) 
&& header_uint <= UINT8_MAX)
@@ -1316,7 +1488,7 @@
       if (yyjson_ptr_get_str (ehiterval, "/OnsetTime", &header_string))
       {
         if (ms_timestr2btime (header_string, (uint8_t *)pMS2B200_YEAR (record 
+ written),
-                              msr->sid, swapflag) == -1)
+                              NULL, msr->sid, swapflag) == NSTERROR)
         {
           ms_log (2, "%s: Cannot convert B%u time: %s\n", msr->sid, 
blockette_type, header_string);
           yyjson_doc_free (ehdoc);
@@ -1435,7 +1607,7 @@
         if (yyjson_ptr_get_str (ehiterval, "/BeginTime", &header_string))
         {
           if (ms_timestr2btime (header_string, (uint8_t *)pMS2B300_YEAR 
(record + written),
-                                msr->sid, swapflag) == -1)
+                                NULL, msr->sid, swapflag) == NSTERROR)
           {
             ms_log (2, "%s: Cannot convert B%u time: %s\n", msr->sid, 
blockette_type, header_string);
             yyjson_doc_free (ehdoc);
@@ -1600,7 +1772,7 @@
         *pMS2B395_NEXT (record + written) = 0;
 
         if (ms_timestr2btime (header_string, (uint8_t *)pMS2B395_YEAR (record 
+ written),
-                              msr->sid, swapflag) == -1)
+                              NULL, msr->sid, swapflag) == NSTERROR)
         {
           ms_log (2, "%s: Cannot convert B%u time: %s\n", msr->sid, 
blockette_type, header_string);
           yyjson_doc_free (ehdoc);
@@ -2090,8 +2262,8 @@
 } /* End of ms_genfactmult() */
 
 /***************************************************************************
- * Convenience function to convert a month-day time string to a SEED
- * 2.x "BTIME" structure.
+ * Convenience function to convert a time string to a SEED 2.x "BTIME"
+ * structure, and a microsecond offset.
  *
  * The 10-byte BTIME structure layout:
  *
@@ -2104,33 +2276,41 @@
  * unused uint8_t   7       Unused, included for alignment
  * fract  uint16_t  8       0.0001 seconds, i.e. 1/10ths of milliseconds 
(0—9999)
  *
- * Return nanoseconds on success and -1 on error.
+ * Return second-resolution nstime_t value on success and NSTERROR on error.
  *
  * \ref MessageOnError - this function logs a message on error
  ***************************************************************************/
-static inline int64_t
-ms_timestr2btime (const char *timestr, uint8_t *btime, const char *sid, int8_t 
swapflag)
+static inline nstime_t
+ms_timestr2btime (const char *timestr, uint8_t *btime, int8_t *usec_offset,
+                  const char *sid, int8_t swapflag)
 {
   uint16_t year;
   uint16_t day;
   uint8_t hour;
   uint8_t min;
   uint8_t sec;
-  uint32_t nsec;
+  uint16_t fsec;
+  int8_t l_usec_offset;
   nstime_t nstime;
+  nstime_t second_nstime;
 
   if (!timestr || !btime)
   {
     ms_log (2, "%s(%s): Required input not defined: 'timestr' or 'btime'\n",
             sid, __func__);
-    return -1;
+    return NSTERROR;
   }
 
   if ((nstime = ms_timestr2nstime (timestr)) == NSTERROR)
-    return -1;
+    return NSTERROR;
 
-  if (ms_nstime2time (nstime, &year, &day, &hour, &min, &sec, &nsec))
-    return -1;
+  if (ms_nstime2time (nstime, &year, &day, &hour, &min, &sec, NULL))
+    return NSTERROR;
+
+  second_nstime = nstime2fsec_usec_offset (nstime, &fsec, &l_usec_offset);
+
+  if (second_nstime == NSTERROR)
+    return NSTERROR;
 
   *((uint16_t *)(btime))     = HO2u (year, swapflag);
   *((uint16_t *)(btime + 2)) = HO2u (day, swapflag);
@@ -2138,7 +2318,73 @@
   *((uint8_t *)(btime + 5))  = min;
   *((uint8_t *)(btime + 6))  = sec;
   *((uint8_t *)(btime + 7))  = 0;
-  *((uint16_t *)(btime + 8)) = HO2u (nsec / 100000, swapflag);
+  *((uint16_t *)(btime + 8)) = HO2u (fsec, swapflag);
 
-  return nsec;
+  if (usec_offset)
+    *usec_offset = l_usec_offset;
+
+  return second_nstime;
 } /* End of timestr2btime() */
+
+/***************************************************************************
+ * nstime2fsec_usec_offset
+ *
+ * Convert a nstime_t value to a time value in tenths of milliseconds (fsec) 
and
+ * a microsecond offset (usec_offset) from the fsec value.
+ *
+ * The nstime_t value returned is the nstime_t value at second resolution and
+ * the appropriate value to be combined with fsec and usec_offset to recover 
the
+ * time value (in microseconds).  Nanosecond resolution is lost in this case.
+ *
+ * When converting nstime_t values with sub-microsecond resolution, the result
+ * will be rounded to the nearest microsecond to retain as much accuracy as
+ * possible.
+ *
+ * The tenths of milliseconds value will be rounded to the nearest value having
+ * a microsecond offset value between -50 to +49.
+ *
+ * Returns second-resolution nstime_t value on success and NSTERROR on error.
+ ***************************************************************************/
+static nstime_t
+nstime2fsec_usec_offset (nstime_t nstime, uint16_t *fsec, int8_t *usec_offset)
+{
+  if (fsec == NULL || usec_offset == NULL)
+    return NSTERROR;
+
+  /* Round to nearest microsecond (loses nanosecond precision) */
+  nstime_t usec_time = (nstime + (nstime >= 0 ? 500 : -500)) / 1000 * 1000;
+
+  /* Convert to microseconds and tenths of milliseconds */
+  int64_t total_usec = usec_time / 1000;
+  int64_t total_fsec = usec_time / 100000;
+
+  /* Calculate microsecond offset from tenths of milliseconds */
+  *usec_offset = (int8_t)(total_usec - total_fsec * 100);
+
+  /* Adjust to keep usec_offset in range [-50, +49] */
+  if (*usec_offset > 49)
+  {
+    total_fsec += 1;
+    *usec_offset -= 100;
+  }
+  else if (*usec_offset < -50)
+  {
+    total_fsec -= 1;
+    *usec_offset += 100;
+  }
+
+  /* Extract fsec within current second (0-9999) */
+  int64_t fsec_remainder = total_fsec % 10000;
+  int64_t seconds = total_fsec / 10000;
+
+  /* Handle negative modulo properly */
+  if (fsec_remainder < 0)
+  {
+    fsec_remainder += 10000;
+    seconds -= 1;
+  }
+  *fsec = (uint16_t)fsec_remainder;
+
+  /* Return second-resolution time */
+  return seconds * NSTMODULUS;
+} /* End of nstime2fsec_usec_offset() */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/test/Makefile 
new/libmseed-3.1.6/test/Makefile
--- old/libmseed-3.1.5/test/Makefile    2025-04-24 14:08:48.000000000 +0200
+++ new/libmseed-3.1.6/test/Makefile    2025-07-27 02:05:46.000000000 +0200
@@ -8,6 +8,14 @@
 #   CC : Specify the C compiler to use
 #   CFLAGS : Specify compiler options to use
 
+# Automatically configure URL support if libcurl is present
+# Test for curl-config command and add build options if so
+ifneq (,$(shell command -v curl-config))
+        export LM_CURL_VERSION=$(shell curl-config --version)
+        export CFLAGS:=$(CFLAGS) -DLIBMSEED_URL
+        export LDFLAGS:=$(LDFLAGS) $(shell curl-config --libs)
+endif
+
 # Required compiler parameters
 CFLAGS += -I.. -I.
 
Binary files old/libmseed-3.1.5/test/data/reference-testdata-nsec.mseed2 and 
new/libmseed-3.1.6/test/data/reference-testdata-nsec.mseed2 differ
Binary files old/libmseed-3.1.5/test/data/reference-testdata-nsec.mseed3 and 
new/libmseed-3.1.6/test/data/reference-testdata-nsec.mseed3 differ
Binary files old/libmseed-3.1.5/test/data/reference-testdata-olden.mseed2 and 
new/libmseed-3.1.6/test/data/reference-testdata-olden.mseed2 differ
Binary files old/libmseed-3.1.5/test/data/reference-testdata-olden.mseed3 and 
new/libmseed-3.1.6/test/data/reference-testdata-olden.mseed3 differ
Binary files old/libmseed-3.1.5/test/data/reference-testdata-repack.mseed2 and 
new/libmseed-3.1.6/test/data/reference-testdata-repack.mseed2 differ
Binary files old/libmseed-3.1.5/test/data/reference-testdata-repack.mseed3 and 
new/libmseed-3.1.6/test/data/reference-testdata-repack.mseed3 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/test/test-repack.c 
new/libmseed-3.1.6/test/test-repack.c
--- old/libmseed-3.1.5/test/test-repack.c       1970-01-01 01:00:00.000000000 
+0100
+++ new/libmseed-3.1.6/test/test-repack.c       2025-07-27 02:05:46.000000000 
+0200
@@ -0,0 +1,100 @@
+#include <libmseed.h>
+#include <tau/tau.h>
+
+#include "testdata.h"
+
+extern int cmpfiles (char *fileA, char *fileB);
+
+/* Write test output files.  Reference files are at "data/reference-<name>" */
+#define TESTFILE_REPACK_V3 "testdata-repack.mseed3"
+#define TESTFILE_REPACK_V2 "testdata-repack.mseed2"
+
+#define V2INPUT_RECORD "data/reference-testdata-defaults.mseed2"
+
+TEST (repack, v3)
+{
+  MS3Record *msr = NULL;
+  char buffer[8192];
+  uint32_t flags;
+  int packedlength;
+  int rv;
+
+  /* Read v2 input data */
+  flags = MSF_UNPACKDATA;
+  rv    = ms3_readmsr (&msr, V2INPUT_RECORD, flags, 0);
+
+  CHECK (rv == MS_NOERROR, "ms3_readmsr() did not return expected MS_NOERROR");
+  REQUIRE (msr != NULL, "ms3_readmsr() did not populate 'msr'");
+
+  /* Change some header fields */
+  strcpy (msr->sid, "FDSN:XX_REPAK__H_H_Z");
+  msr->starttime = ms_timestr2nstime ("2008-05-12T13:44:55.123456789Z");
+  msr->samprate = 100.0;
+  msr->pubversion = 2;
+
+  /* Repack to v3 record */
+  packedlength = msr3_repack_mseed3 (msr, buffer, sizeof (buffer), 0);
+
+  CHECK (packedlength > 0, "msr3_repack_mseed3() returned an error");
+
+  /* Write output */
+  FILE *fd = fopen (TESTFILE_REPACK_V3, "wb");
+
+  CHECK (fd != NULL, "Failed to open output file");
+
+  rv = fwrite (buffer, 1, packedlength, fd);
+
+  CHECK (rv == packedlength, "Failed to write output file");
+  CHECK (fclose (fd) == 0, "Failed to close output file");
+
+  /* Compare to reference */
+  rv = cmpfiles (TESTFILE_REPACK_V3, "data/reference-" TESTFILE_REPACK_V3);
+
+  CHECK (rv == 0, "Repacked v3 record does not match reference");
+
+  ms3_readmsr(&msr, NULL, flags, 0);
+}
+
+TEST (repack, v2)
+{
+  MS3Record *msr = NULL;
+  char buffer[8192];
+  uint32_t flags;
+  int packedlength;
+  int rv;
+
+  /* Read v2 input data */
+  flags = MSF_UNPACKDATA;
+  rv    = ms3_readmsr (&msr, V2INPUT_RECORD, flags, 0);
+
+  CHECK (rv == MS_NOERROR, "ms3_readmsr() did not return expected MS_NOERROR");
+  REQUIRE (msr != NULL, "ms3_readmsr() did not populate 'msr'");
+
+  /* Change some header fields */
+  strcpy (msr->sid, "FDSN:XX_REPAK__H_H_Z");
+  msr->starttime = ms_timestr2nstime ("2008-05-12T13:44:55.123456789Z");
+  msr->samprate = 100.0;
+  msr->pubversion = 2;
+
+  /* Repack to v2 record */
+  packedlength = msr3_repack_mseed2 (msr, buffer, sizeof (buffer), 0);
+
+  CHECK (packedlength > 0, "msr3_repack_mseed2() returned an error");
+
+  /* Write output */
+  FILE *fd = fopen (TESTFILE_REPACK_V2, "wb");
+
+  CHECK (fd != NULL, "Failed to open output file");
+
+  rv = fwrite (buffer, 1, packedlength, fd);
+
+  CHECK (rv == packedlength, "Failed to write output file");
+  CHECK (fclose (fd) == 0, "Failed to close output file");
+
+  /* Compare to reference */
+  rv = cmpfiles (TESTFILE_REPACK_V2, "data/reference-" TESTFILE_REPACK_V2);
+
+  CHECK (rv == 0, "Repacked v2 record does not match reference");
+
+  ms3_readmsr(&msr, NULL, flags, 0);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libmseed-3.1.5/test/test-write.c 
new/libmseed-3.1.6/test/test-write.c
--- old/libmseed-3.1.5/test/test-write.c        2025-04-24 14:08:48.000000000 
+0200
+++ new/libmseed-3.1.6/test/test-write.c        2025-07-27 02:05:46.000000000 
+0200
@@ -14,6 +14,8 @@
 #define TESTFILE_STEIM1_V2  "testdata-steim1.mseed2"
 #define TESTFILE_STEIM2_V2  "testdata-steim2.mseed2"
 #define TESTFILE_DEFAULTS_V2  "testdata-defaults.mseed2"
+#define TESTFILE_NSEC_V2    "testdata-nsec.mseed2"
+#define TESTFILE_OLDEN_V2   "testdata-olden.mseed2"
 
 #define TESTFILE_TEXT_V3    "testdata-text.mseed3"
 #define TESTFILE_FLOAT32_V3 "testdata-float32.mseed3"
@@ -23,6 +25,8 @@
 #define TESTFILE_STEIM1_V3  "testdata-steim1.mseed3"
 #define TESTFILE_STEIM2_V3  "testdata-steim2.mseed3"
 #define TESTFILE_DEFAULTS_V3  "testdata-defaults.mseed3"
+#define TESTFILE_NSEC_V3    "testdata-nsec.mseed3"
+#define TESTFILE_OLDEN_V3   "testdata-olden.mseed3"
 
 TEST (write, msr)
 {
@@ -134,8 +138,62 @@
   REQUIRE (rv > 0, "msr3_writemseed() return unexpected value");
   CHECK (!cmpfiles (TESTFILE_DEFAULTS_V3, "data/reference-" 
TESTFILE_DEFAULTS_V3), "Default encoding/reclen write mismatch");
 
+  /* Nanosecond time resolution with Int32 data and a timing exception and 
4096 max record length */
+  msr->starttime = ms_timestr2nstime ("2012-05-12T00:00:00.123456789Z");
+  msr->encoding = DE_INT32;
+  msr->reclen = 4096;
+  msr->numsamples  = SINE_DATA_SAMPLES;
+  msr->datasamples = sinedata;
+  msr->sampletype  = 'i';
+  msr->extra       = "{\"FDSN\":{"
+                     "\"Time\":{"
+                     "\"Exception\":[{"
+                     "\"Time\":\"2012-05-12T00:00:26.987654321Z\","
+                     "\"VCOCorrection\":50.7080078125,"
+                     "\"ReceptionQuality\":100,"
+                     "\"Count\":7654,"
+                     "\"Type\":\"Valid\","
+                     "\"ClockStatus\":\"Drift=-1973usec, Satellite SNR in 
dB=23, 0, 26, 25, 29, 28\""
+                     "}]},"
+                     "\"Clock\":{"
+                     "\"Model\":\"Acme Corporation GPS3\""
+                     "}}}";
+  msr->extralength = strlen (msr->extra);
+
+  rv = msr3_writemseed (msr, TESTFILE_NSEC_V3, 1, flags, 0);
+  REQUIRE (rv > 0, "msr3_writemseed() return unexpected value");
+  CHECK (!cmpfiles (TESTFILE_NSEC_V3, "data/reference-" TESTFILE_NSEC_V3), 
"Nanosecond timing write mismatch");
+
+  /* Old, pre-epoch times with Int32 data and a timing exception and 4096 max 
record length */
+  msr->starttime = ms_timestr2nstime ("1964-03-27T21:11:24.987654321Z");
+  msr->encoding = DE_INT32;
+  msr->reclen = 4096;
+  msr->numsamples  = SINE_DATA_SAMPLES;
+  msr->datasamples = sinedata;
+  msr->sampletype  = 'i';
+  msr->extra       = "{\"FDSN\":{"
+                     "\"Time\":{"
+                     "\"Exception\":[{"
+                     "\"Time\":\"1964-03-27T21:11:48.123456789Z\","
+                     "\"Count\":1,"
+                     "\"Type\":\"Unexpected\","
+                     "\"ClockStatus\":\"Clock tower destroyed\""
+                     "}]},"
+                     "\"Clock\":{"
+                     "\"Model\":\"Ye Olde Clock Tower Company\""
+                     "}}}";
+  msr->extralength = strlen (msr->extra);
+
+  rv = msr3_writemseed (msr, TESTFILE_OLDEN_V3, 1, flags, 0);
+  REQUIRE (rv > 0, "msr3_writemseed() return unexpected value");
+  CHECK (!cmpfiles (TESTFILE_OLDEN_V3, "data/reference-" TESTFILE_OLDEN_V3), 
"Old, pre-epoch times write mismatch");
+
+  msr->extra = NULL;
+  msr->extralength = 0;
+
   /* Set miniSEED v2 flag */
   flags |= MSF_PACKVER2;
+  msr->starttime = ms_timestr2nstime ("2012-05-12T00:00:00");
   msr->reclen = 512;
 
   /* Text encoding */
@@ -224,6 +282,58 @@
   REQUIRE (rv > 0, "msr3_writemseed() return unexpected value");
   CHECK (!cmpfiles (TESTFILE_DEFAULTS_V2, "data/reference-" 
TESTFILE_DEFAULTS_V2), "Default encoding/reclen write mismatch");
 
+  /* Nanosecond time resolution with Int32 data and a timing exception and 
4096 record length */
+  msr->starttime = ms_timestr2nstime ("2012-05-12T00:00:00.123456789Z");
+  msr->encoding = DE_INT32;
+  msr->reclen = 4096;
+  msr->numsamples  = SINE_DATA_SAMPLES;
+  msr->datasamples = sinedata;
+  msr->sampletype  = 'i';
+  msr->extra       = "{\"FDSN\":{"
+                     "\"Time\":{"
+                     "\"Exception\":[{"
+                     "\"Time\":\"2012-05-12T00:00:26.987654321Z\","
+                     "\"VCOCorrection\":50.7080078125,"
+                     "\"ReceptionQuality\":100,"
+                     "\"Count\":7654,"
+                     "\"Type\":\"Valid\","
+                     "\"ClockStatus\":\"Drift=-1973usec, Satellite SNR in 
dB=23, 0, 26, 25, 29, 28\""
+                     "}]},"
+                     "\"Clock\":{"
+                     "\"Model\":\"Acme Corporation GPS3\""
+                     "}}}";
+  msr->extralength = strlen (msr->extra);
+
+  rv = msr3_writemseed (msr, TESTFILE_NSEC_V2, 1, flags, 0);
+  REQUIRE (rv > 0, "msr3_writemseed() return unexpected value");
+  CHECK (!cmpfiles (TESTFILE_NSEC_V2, "data/reference-" TESTFILE_NSEC_V2), 
"Nanosecond timing write mismatch");
+
+  /* Old, pre-epoch times with Int32 data and a timing exception and 4096 
record length */
+  msr->starttime = ms_timestr2nstime ("1964-03-27T21:11:24.987654321Z");
+  msr->encoding = DE_INT32;
+  msr->reclen = 4096;
+  msr->numsamples  = SINE_DATA_SAMPLES;
+  msr->datasamples = sinedata;
+  msr->sampletype  = 'i';
+  msr->extra       = "{\"FDSN\":{"
+                     "\"Time\":{"
+                     "\"Exception\":[{"
+                     "\"Time\":\"1964-03-27T21:11:48.123456789Z\","
+                     "\"Count\":1,"
+                     "\"Type\":\"Unexpected\","
+                     "\"ClockStatus\":\"Clock tower destroyed\""
+                     "}]},"
+                     "\"Clock\":{"
+                     "\"Model\":\"Ye Olde Clock Tower Company\""
+                     "}}}";
+  msr->extralength = strlen (msr->extra);
+
+  rv = msr3_writemseed (msr, TESTFILE_OLDEN_V2, 1, flags, 0);
+  REQUIRE (rv > 0, "msr3_writemseed() return unexpected value");
+  CHECK (!cmpfiles (TESTFILE_OLDEN_V2, "data/reference-" TESTFILE_OLDEN_V2), 
"Old, pre-epoch times write mismatch");
+
+  msr->extra = NULL;
+  msr->extralength = 0;
   msr->datasamples = NULL;
   msr3_free (&msr);
 }

Reply via email to