
/* SPECIAL VERSION FOR WEPOCS2 -- LAST FIELD OF CONF WAS UNASSIGNED
   NOT HEADING_BIAS */


#include "dbinc.h"      /* *db declaration */
#include "adcp.h"       /* new ADCP structure type declarations */
#include "userbuff.h"   /* user buffer structure type declarations */
#include "use_db.h"     /* db*_cnf() */
#include "ioserv.h"     /* error_found() */
#include "data_id.h"    /* ADCP variable ids */

#if PROTOTYPE_ALLOWED
int check_conf(void);
int check_anc2(void);
int convert_configuration(CONFIGURATION_1_TYPE *conf);
int convert_ancillary2(double hd_misalign, double scale_factor,
                       double pit_misalign, double rol_misalign, double hd_offset);
#else
int check_conf();
int check_anc2();
int convert_configuration();
int convert_ancillary2();
#endif

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[23];
} newconf_def[] =
{
   "CONFIGURATION_1"       , 23     , "" ,
   "avg_interval"          , "s"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "compensation"          , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "num_bins"              , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "tr_depth"              , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "bin_length"            , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "pls_length"            , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "blank_length"          , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "ping_interval"         , "s"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "bot_track"             , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "pgs_ensemble"          , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "ens_threshold"         , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "ev_threshold"          , "mm/s" , SHORT_VALUE_CODE ,  1 , "" ,
   "hd_offset"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "pit_offset"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "rol_offset"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "unused1" /* hd_misal */, "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "unused2" /* pit_misal*/, "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "unused3" /* rol_misal*/, "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "freq_transmit"         , "Hz"   , FLOAT_VALUE_CODE ,  1 , "" ,
   "top_ref_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "bot_ref_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unused4" /* scale_f */ , "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "heading_bias"          , "deg"  , FLOAT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[23];
} newanc2_def[] =
{
   "ANCILLARY_2"           , 23     , "" ,
   "watrk_hd_misalign"     , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "watrk_scale_factor"    , "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "botrk_hd_misalign"     , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "botrk_scale_factor"    , "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "pit_misalign"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "rol_misalign"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "unused1"               , "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_temp"             , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_heading"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_pitch"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_roll"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_pitch"              , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_roll"               , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_temp"              , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_heading"           , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_pitch"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_roll"              , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "ocean_depth"           , "m"    , SHORT_VALUE_CODE ,  1 , "" ,
   "max_amp_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "last_good_bin"         , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unused2"               , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unused3"               , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unused4"               , "none" , SHORT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[23];
} oldconf_def[] =
{
   "CONFIGURATION_1"       , 23     , "" ,
   "avg_interval"          , "s"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "compensation"          , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "num_bins"              , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "tr_depth"              , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "bin_length"            , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "pls_length"            , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "blank_length"          , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "ping_interval"         , "s"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "bot_track"             , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "pgs_ensemble"          , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "ens_threshold"         , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "ev_threshold"          , "mm/s" , SHORT_VALUE_CODE ,  1 , "" ,
   "hd_offset"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "pit_offset"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "rol_offset"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "hd_misalign"           , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "pit_misalign"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "rol_misalign"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "freq_transmit"         , "Hz"   , FLOAT_VALUE_CODE ,  1 , "" ,
   "top_ref_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "bot_ref_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "scale_factor"          , "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "unassigned"          , "none"  , SHORT_VALUE_CODE ,  2 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[23];
} really_oldconf_def[] =
{
   "CONFIGURATION_1"       , 23     , "" ,
   "avg_interval"          , "s"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "num_bins"              , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "tr_depth"              , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "bin_length"            , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "pls_length"            , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "blank_length"          , "m"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "ping_interval"         , "s"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "bot_track"             , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "pgs_ensemble"          , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "ens_threshold"         , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "hd_offset"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "pit_offset"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "rol_offset"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "hd_misalign"           , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "pit_misalign"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "rol_misalign"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "compensation"          , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "freq_transmit"         , "Hz"   , FLOAT_VALUE_CODE ,  1 , "" ,
   "top_ref_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "bot_ref_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "ev_threshold"          , "mm/s" , SHORT_VALUE_CODE ,  1 , "" ,
   "scale_factor"          , "none" , FLOAT_VALUE_CODE ,  1 , "" ,
   "heading_bias"          , "deg"  , FLOAT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[23];
} oldanc2_def[] =
{
   "ANCILLARY_2"           , 23     , "" ,
   "avg_fwd_speed"         , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_stbd_speed"        , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_fwd_speed"         , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_stbd_speed"        , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_u_rel"             , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_v_rel"             , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_w_rel"             , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_temp"             , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_heading"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_pitch"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_roll"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_pitch"              , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_roll"               , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_temp"              , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_heading"           , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_pitch"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_roll"              , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "ocean_depth"           , "m"    , SHORT_VALUE_CODE ,  1 , "" ,
   "max_amp_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "last_good_bin"         , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned1"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned2"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned3"           , "none" , SHORT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[24];
} really_oldanc2_def[] =
{
   "ANCILLARY_2"           , 24     , "" ,
   "avg_fwd_speed"         , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_stbd_speed"        , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_fwd_speed"         , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_stbd_speed"        , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_u_rel"             , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_v_rel"             , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "avg_w_rel"             , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_temp"             , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_heading"          , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_pitch"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "last_roll"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_pitch"              , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_roll"               , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_temp"              , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_heading"           , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_pitch"             , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "std_roll"              , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "ocean_depth"           , "m"    , SHORT_VALUE_CODE ,  1 , "" ,
   "max_amp_bin"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "last_good_bin"         , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned1"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned2"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned3"           , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "unassigned4"           , "none" , SHORT_VALUE_CODE ,  1 , ""
};

#if PROTOTYPE_ALLOWED
void main(int argc, char *argv[])
#else
void main(argc, argv)
int argc;
char *argv[];
#endif
{
   FILE_NAME_TYPE dbname;
   int  iblkprf[2], blksave = -99;
   int  conv_conf, conv_anc2;
   unsigned int n;
   double save_hd_misalign, save_scale_factor,
          save_rol_misalign, save_pit_misalign;
   CONFIGURATION_1_TYPE conf1;

   if (argc < 2)
   {
      printf("\n Enter database name ==> ");
      scanf(" %79s", dbname);
   }
   else
      strncpy(dbname, argv[1], 79);

   if (dbopen_cnf(1, dbname, READ_WRITE, DIR_IN_MEMORY)) exit(-1);

   /*------------------------
       MAIN PROCESSING LOOP
     ------------------------*/
   do
   {
      n = 2 * sizeof(int);
      if (dbget_cnf(BLOCK_PROFILE_INDEX, (char *) iblkprf, &n,
         "getting block-profile index")) goto close;
      if (iblkprf[0] != blksave)  /* new block */
      {
         /*--------------------------------------------------
             CHECK ASSUMPTIONS PRIOR TO UPDATING BLOCK FILE
           --------------------------------------------------*/
         printf("\n Checking block %3d: ", iblkprf[0]);
         if (!db->block_strdef_loaded)
            load_block_strdef();

         /* see if it needs converting by checking the structure definitions */
         conv_conf = check_conf();
         conv_anc2 = check_anc2();
         if (conv_conf == 0 && conv_anc2 == 0)
         {
            printf("up-to-date");
            if (error_found( (-1 == (iblkprf[1] = get_nprofs() - 1)),
               "getting no. of profiles" )) goto close;
            if (dbsrch_cnf(BLOCK_PROFILE_SEARCH, (char *) iblkprf)) goto close;
            continue; /* dbmove to next block */
         }
         if (conv_conf == -1 || conv_anc2 == -1) goto close;
         printf("converting...");
         n = sizeof(CONFIGURATION_1_TYPE);
         if (dbget_cnf(CONFIGURATION_1, (char *) &conf1, &n,
            "getting configuration")) goto close;
         if (error_found( (n != sizeof(CONFIGURATION_1_TYPE)),
            "size mismatch for CONFIGURATION_1")) goto close;
         save_hd_misalign  = conf1.unused1;
         save_pit_misalign = conf1.unused2;
         save_rol_misalign = conf1.unused3;
         save_scale_factor = conf1.unused4;
      }
      if (convert_ancillary2(save_hd_misalign, save_scale_factor,
                             save_pit_misalign, save_rol_misalign,
                             conf1.hd_offset)) goto close;
                                            /* test/save once before */
      if (blksave != iblkprf[0])            /* clobbering below */
      {
         blksave = iblkprf[0];
         /* store new structure definitions */
         n = sizeof(newconf_def);
         if (dbput_cnf(STRUCTURE_DEF, (char *) newconf_def, &n,
            "storing CONFIGURATION_1 definition")) goto close;
         n = sizeof(newanc2_def);
         if (dbput_cnf(STRUCTURE_DEF, (char *) newanc2_def, &n,
            "storing ANCILLARY_2 definition")) goto close;
         /* reset configuration to unused values */
         if (convert_configuration(&conf1)) goto close;
      }
   } while (dbmove_cnf(1) != SEARCH_BEYOND_END);
   printf("\n Database update completed.");

close:
   printf("\n Last block-profile number = %d-%d\n", iblkprf[0], iblkprf[1]);
   dbclose_cnf();
   puts("");
}

/*-----------------------------------------------------------------------------

   FUNCTIONS:  check_conf, check_anc2

      These check if the CONFIGURATION_1, ANCILLARY_2
      structures should be converted,
      by looking for particular entries in the structure definitions
      stored in the block file.

   RETURN:

      0 = already up-to-date
     -1 = inapplicable (not present or mismatch)
      1 = proceed with conversion
*/

#if PROTOTYPE_ALLOWED
int check_conf(void)
#else
int check_conf()
#endif
{
   STRUCT_DEF_HDR_TYPE *conf_def;
   unsigned int n = 0;

   if ( (conf_def = find_def("CONFIGURATION_1", db->block_strdef)) == NULL )
   {
      printf("\n WARNING: CONFIGURATION_1 definition not in block file");
      printf("\n NO conversion performed on this block\n");
      return(-1);
   }
   if ( cmp_byte(
      (char *) conf_def, (char *) oldconf_def, sizeof(oldconf_def) ) == 0 )
   {
      if ( dbget_cnf(CONFIGURATION_1, NULL, &n, "getting configuration_1 size")
         || error_found( (n != sizeof(CONFIGURATION_1_TYPE)),
         "size mismatch for configuration_1" ) )
      {
         printf("\n NO conversion performed on this block\n");
         return(-1);
      }
      return(1);
   }
   if ( cmp_byte(
      (char *) conf_def, (char *) newconf_def, sizeof(newconf_def) ) == 0 )
      return(0);  /* up-to-date */
   if ( cmp_byte(
      (char *) conf_def, (char *) really_oldconf_def, sizeof(newconf_def) ) == 0 )
   {
      printf("\n ERROR: CONFIGURATION_1 definition is really old.");
      printf("\n Run convadcp before convadc2!\n");
      return(-1);
   }
   printf("\n WARNING: Unrecognized CONFIGURATION_1 definition");
   printf("\n NO conversion performed on this block\n");
   return(-1);
}

#if PROTOTYPE_ALLOWED
int check_anc2(void)
#else
int check_anc2()
#endif
{
   STRUCT_DEF_HDR_TYPE *anc2_def;
   unsigned int n = 0;

   if ( (anc2_def = find_def("ANCILLARY_2", db->block_strdef)) == NULL )
   {
      printf("\n WARNING: ANCILLARY_2 definition not in block file");
      printf("\n NO ancillary_2 conversion performed on this block\n");
      return(-1);
   }
   if ( cmp_byte(
      (char *) anc2_def, (char *) oldanc2_def, sizeof(oldanc2_def)) == 0  ||
      (anc2_def->nelem == 24 && cmp_byte( /* for case converted by convadcp */
      (char *) (anc2_def + 1), (char *) (oldanc2_def + 1),
      sizeof(newanc2_def) - sizeof(STRUCT_DEF_HDR_TYPE) )) )
   {
      if ( dbget_cnf(ANCILLARY_2, NULL, &n, "getting ancillary_2 size") ||
         error_found( (n != 82), "size mismatch for ancillary_2" ) )
      {
         printf("\n NO ancillary_2 conversion performed on this block\n");
         return(-1);
      }
      return(1);
   }
   if ( cmp_byte(
      (char *) anc2_def, (char *) newanc2_def, sizeof(newanc2_def)) == 0 )
      return(0);   /* already up-to-date */
   if ( cmp_byte(
      (char *) anc2_def, (char *) really_oldanc2_def, sizeof(oldanc2_def)) == 0 )
   {
      printf("\n ERROR: CONFIGURATION_1 definition is really old.");
      printf("\n Run convadcp before convadc2! \n");
      return(-1);
   }
   printf("\n WARNING: Unrecognized ANCILLARY_2 definition");
   printf("\n NO ancillary_2 conversion performed on this block\n");
   return(-1);
}

/*-----------------------------------------------------------------------------

   FUNCTIONS: convert_configuration, convert_ancillary2

      These get the old data from the database, perform the required
      updating, and store the converted data back into the database.

   RETURN:

      0 = okay;
     -1 = database error

*/

#if PROTOTYPE_ALLOWED
int convert_configuration(CONFIGURATION_1_TYPE *conf)
#else
int convert_configuration(conf)
CONFIGURATION_1_TYPE *conf;
#endif
{
    unsigned int n = sizeof(CONFIGURATION_1_TYPE);
    conf->unused1 = conf->unused2 = conf->unused3 = conf->unused4 = BADFLOAT;
    conf->heading_bias = BADFLOAT;
    if (dbput_cnf(CONFIGURATION_1, (char *) conf, &n,
       "storing configuration")) return(-1);
    return(0);
}

int convert_ancillary2(hd_misalign, scale_factor, pit_misalign, rol_misalign, hd_offset)
double hd_misalign, scale_factor, pit_misalign, rol_misalign, hd_offset;
{
   unsigned int n = sizeof(ANCILLARY_2_TYPE);
   ANCILLARY_2_TYPE anc2;

   if (dbget_cnf(ANCILLARY_2, (char *) &anc2, &n,
      "getting ancillary_2") != 0) return(-1);
   if (error_found( (n != sizeof(ANCILLARY_2_TYPE)),
      "size mismatch for ANCILLARY_2")) return(-1);
   anc2.watrk_hd_misalign = anc2.botrk_hd_misalign = hd_misalign;
   anc2.watrk_scale_factor = anc2.botrk_scale_factor = scale_factor;
   anc2.pit_misalign = pit_misalign;
   anc2.rol_misalign = rol_misalign;
   anc2.unused1 = BADFLOAT;
   anc2.last_heading -= hd_offset;
   while (anc2.last_heading > 360.0) anc2.last_heading -= 360.0;
   while (anc2.last_heading < 0.0)   anc2.last_heading += 360.0;
   if (dbput_cnf(ANCILLARY_2, (char *) &anc2, &n,
      "storing ancillary_2 data")) return(-1);
   return(0);
}

