/*

    FILE: CONVADCP.C

          This program opens an existing ADCP CODAS3 database and
          rewrites the ADCP ancillary_1, ancillary_2, configuration_1, and
          user_buffer structures according to the new ADCP.H definitions
          (5/14/90) as needed.  It also rewrites the structure definitions.

          Note:  The old ADCP structures must be declared as character
          arrays because of possible alignment problems with the old
          structure definitions.  This makes it possible to run this
          program even on a machine with the target stricter architecture.

          Very Important:  The program uses the structure definitions
          stored in the block file as an indicator of what types of
          conversions must be performed.  This can create problems if
          those structure definitions do not correctly reflect what is
          actually in the database--especially those databases which
          acquire the structure definitions via the db2todb3 conversion.

          8/31/90 - JR - modified to interpret INVALID_TYPE_REQUEST error
                         on DBGET data as "data not present" rather than
                         fatal so will continue processing database

          9/10/90 - JR - modified for efficiency: skips to next block
                         if structure definitions for current block are
                         up-to-date; does not bother to reset data dir
                         nbytes for ancillary_2 to 80 bytes--updated
                         structure definition is sufficient

                       - modified to be stricter: checks entire structure
                         definition rather than just size and one
                         critical element as basis for deciding whether to
                         convert or not; checks all variables for
                         no. of bytes in first profile of block
                         against expected no. of bytes and warns of
                         inconsistency before rewriting anything in the
                         block

*/

#include "dbinc.h"      /* *db declaration */
#include "adcp_old.h"   /* 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_anc1(void);
int check_anc2(void);
int check_ub(void);
int convert_configuration(void);
int convert_ancillary1(void);
int convert_user_buffer(int type);
void convert_transit_fix(char *old_fix, TRANSIT_FIX_TYPE *new_fix);
#else
int check_conf();
int check_anc1();
int check_anc2();
int check_ub();
int convert_configuration();
int convert_ancillary1();
int convert_user_buffer();
void convert_transit_fix();
#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 , "" ,
   "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 , "" ,
   "heading_bias"          , "deg"  , FLOAT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[10];
} newanc1_def[] =
{
   "ANCILLARY_1"           , 10     , "" ,
   "tr_temp"               , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "snd_spd_used"          , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "best_snd_spd"          , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_heading"            , "deg"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "pgs_sample"            , "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 , "" ,
   "unassigned5"           , "none" , SHORT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[24];
} newanc2_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 , "" ,
   /**  1999/07/06 Pierre Jaccard
       It is wrong to set an array of defined length pointing to NULL.
       Replaced with the empty string, hoping it should work the same.

       NULL                    , NULL   , 0                ,  0 , NULL
   **/
   {"", "", 0, 0, ""}
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[12];
} ub1281_def[] =
{
   "USER_BUFFER"           , 12       , "" ,
   "version"               , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "max_avgs"              , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "first_bin"             , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "n_bins"                , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "avg_uv"                , "mm/s"   , SHORT_VALUE_CODE , 20 , "" ,
   "set"                   , "deg*E-1", SHORT_VALUE_CODE ,  1 , "" ,
   "drift"                 , "kts*E-2", SHORT_VALUE_CODE ,  1 , "" ,
   "position_source"       , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "dr_time"               , "s"      , SHORT_VALUE_CODE ,  1 , "" ,
   "fix"                   , "none"   , STRUCT_VALUE_CODE,  1 , "" ,
   "time"                  , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "gps_status"            , "none"   , STRUCT_VALUE_CODE,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[10];
} ub1021_def[] =
{
   "USER_BUFFER"           , 10       , "" ,
   "fix"                   , "none"   , STRUCT_VALUE_CODE,  1 , "" ,
   "time"                  , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "max_avgs"              , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "first_bin"             , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "n_bins"                , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "avg_uv"                , "mm/s"   , SHORT_VALUE_CODE , 20 , "" ,
   "set"                   , "deg*E-1", SHORT_VALUE_CODE ,  1 , "" ,
   "drift"                 , "kts*E-2", SHORT_VALUE_CODE ,  1 , "" ,
   "position_source"       , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "dr_time"               , "s"      , SHORT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[21];
} newfix_def[] =
{
   "fix"                   , 21       , "" ,
   "ref_u"                 , "mm/s"   , SHORT_VALUE_CODE ,  1 , "" ,
   "ref_v"                 , "mm/s"   , SHORT_VALUE_CODE ,  1 , "" ,
   "ref_count"             , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "sat_id"                , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "pc_time"               , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "fix_time"              , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "lon"                   , "sec*E-2", LONG_VALUE_CODE  ,  1 , "" ,
   "lat"                   , "sec*E-2", LONG_VALUE_CODE  ,  1 , "" ,
   "antenna"               , "m*E-1"  , LONG_VALUE_CODE  ,  1 , "" ,
   "dr_dist"               , "nm*E-2" , SHORT_VALUE_CODE ,  1 , "" ,
   "dr_dir"                , "deg*E-1", SHORT_VALUE_CODE ,  1 , "" ,
   "sigma_lon"             , "m"      , SHORT_VALUE_CODE ,  1 , "" ,
   "sigma_lat"             , "m"      , SHORT_VALUE_CODE ,  1 , "" ,
   "used"                  , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "q1"                    , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "q2"                    , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "q3"                    , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "elevation"             , "deg"    , BYTE_VALUE_CODE  ,  1 , "" ,
   "iterations"            , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "dop_count"             , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "spare"                 , "none"   , BYTE_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 , "" ,
   "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[10];
} oldanc1_def[] =
{
   "ANCILLARY_1"           , 10     , "" ,
   "pgs_sample"            , "none" , SHORT_VALUE_CODE ,  1 , "" ,
   "tr_temp"               , "C"    , FLOAT_VALUE_CODE ,  1 , "" ,
   "snd_spd_used"          , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "best_snd_spd"          , "m/s"  , FLOAT_VALUE_CODE ,  1 , "" ,
   "mn_heading"            , "deg"  , FLOAT_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 , "" ,
   "unassigned5"           , "none" , SHORT_VALUE_CODE ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[24];
} 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 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[12];
} ub1280_def[] =
{
   "USER_BUFFER"           , 12       , "" ,
   "version"               , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "max_avgs"              , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "first_bin"             , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "n_bins"                , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "avg_uv"                , "mm/s"   , SHORT_VALUE_CODE , 20 , "" ,
   "set"                   , "deg*E-1", SHORT_VALUE_CODE ,  1 , "" ,
   "drift"                 , "kts*E-2", SHORT_VALUE_CODE ,  1 , "" ,
   "position_source"       , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "dr_time"               , "s"      , SHORT_VALUE_CODE ,  1 , "" ,
   "time"                  , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "fix"                   , "none"   , STRUCT_VALUE_CODE,  1 , "" ,
   "gps_status"            , "none"   , STRUCT_VALUE_CODE,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[10];
} ub1020_def[] =
{
   "USER_BUFFER"           , 10       , "" ,
   "max_avgs"              , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "first_bin"             , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "n_bins"                , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "avg_uv"                , "mm/s"   , SHORT_VALUE_CODE , 20 , "" ,
   "set"                   , "deg*E-1", SHORT_VALUE_CODE ,  1 , "" ,
   "drift"                 , "kts*E-2", SHORT_VALUE_CODE ,  1 , "" ,
   "position_source"       , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "dr_time"               , "s"      , SHORT_VALUE_CODE ,  1 , "" ,
   "time"                  , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "fix"                   , "none"   , STRUCT_VALUE_CODE,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[21];
} oldfix_def[] =
{
   "fix"                   , 21       , "" ,
   "ref_u"                 , "mm/s"   , SHORT_VALUE_CODE ,  1 , "" ,
   "ref_v"                 , "mm/s"   , SHORT_VALUE_CODE ,  1 , "" ,
   "ref_count"             , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "pc_time"               , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "fix_time"              , "s"      , LONG_VALUE_CODE  ,  1 , "" ,
   "lon"                   , "sec*E-2", LONG_VALUE_CODE  ,  1 , "" ,
   "lat"                   , "sec*E-2", LONG_VALUE_CODE  ,  1 , "" ,
   "antenna"               , "m*E-1"  , LONG_VALUE_CODE  ,  1 , "" ,
   "dr_dist"               , "nm*E-2" , SHORT_VALUE_CODE ,  1 , "" ,
   "dr_dir"                , "deg*E-1", SHORT_VALUE_CODE ,  1 , "" ,
   "sigma_lon"             , "m"      , SHORT_VALUE_CODE ,  1 , "" ,
   "sigma_lat"             , "m"      , SHORT_VALUE_CODE ,  1 , "" ,
   "sat_id"                , "none"   , SHORT_VALUE_CODE ,  1 , "" ,
   "used"                  , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "q1"                    , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "q2"                    , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "q3"                    , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "elevation"             , "deg"    , BYTE_VALUE_CODE  ,  1 , "" ,
   "iterations"            , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "dop_count"             , "none"   , BYTE_VALUE_CODE  ,  1 , "" ,
   "spare"                 , "none"   , BYTE_VALUE_CODE  ,  1 , ""
};

static struct
{
   STRUCT_DEF_HDR_TYPE  hdr;
   STRUCT_DEF_ELEM_TYPE e[23];
} really_newconf_def[] =    /* 3/91 */
{
   "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 , ""
};

#if PROTOTYPE_ALLOWED
void main(int argc, char *argv[])
#else
void main(argc, argv)
int argc;
char *argv[];
#endif
{
   FILE_NAME_TYPE dbname;
   char answer[2];
   int  iblkprf[2], blksave = -99;
   int  conv_conf, conv_anc1, conv_anc2, conv_ub;
   unsigned int n;

   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 */
      {
         blksave = iblkprf[0];
         /*--------------------------------------------------
             CHECK ASSUMPTIONS PRIOR TO UPDATING BLOCK FILE
           --------------------------------------------------*/
         printf("\n Checking block %3d: ", iblkprf[0]);
         if (!db->block_strdef_loaded)
            load_block_strdef();

         /* see what needs converting by checking the structure definitions */
         conv_conf = check_conf();
         conv_anc1 = check_anc1();
         conv_anc2 = check_anc2();
         conv_ub   = check_ub();
         if (conv_conf == 0 && conv_anc1 == 0 && conv_anc2 == 0 && conv_ub == 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 (iblkprf[0] == 0 &&
            (conv_conf == -1 || conv_anc1 == -1 || conv_anc2 == -1 || conv_ub == -1))
         {
            printf("\n\n Continue? (y/n) ==> ");
            scanf(" %1s", answer);
            if (toupper(answer[0]) == 'N') goto close;
         }
         printf("converting ");

         /* store new structure definitions if needed */
         if (conv_conf == 1)
         {
            printf("configuration...");
            n = sizeof(newconf_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) newconf_def, &n,
               "storing CONFIGURATION_1 definition")) goto close;
            if (convert_configuration()) goto close;
         }
         if (conv_anc1 == 1)
         {
            printf("ancillary_1...");
            n = sizeof(newanc1_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) newanc1_def, &n,
               "storing ANCILLARY_1 definition")) goto close;
         }
         if (conv_anc2 == 1)
         {
            printf("ancillary_2...");
            n = sizeof(newanc2_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) newanc2_def, &n,
               "storing ANCILLARY_2 definition")) goto close;
         }
         if (conv_ub == 1280)
         {
            printf("user buffer 1280...");
            n = sizeof(ub1281_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) ub1281_def, &n,
               "storing USER_BUFFER definition")) goto close;
            n = sizeof(newfix_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) newfix_def, &n,
               "storing fix definition")) goto close;
         }
         else if (conv_ub == 1020)
         {
            printf("user buffer 1020...");
            n = sizeof(ub1021_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) ub1021_def, &n,
               "storing USER_BUFFER definition")) goto close;
            n = sizeof(newfix_def);
            if (dbput_cnf(STRUCTURE_DEF, (char *) newfix_def, &n,
               "storing fix definition")) goto close;
         }
      }
      if (conv_anc1 == 1)
         if (convert_ancillary1()) goto close;
      if (conv_ub == 1280 || conv_ub == 1020)
         if (convert_user_buffer(conv_ub)) 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_anc1, check_anc2, check_ub

      These check if the CONFIGURATION_1, ANCILLARY_1, ANCILLARY_2,
      and USER_BUFFER 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 (1280, 1020 in case of check_ub)
*/

#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 configuration_1 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 configuration_1 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);
   if ( cmp_byte(
      (char *) conf_def, (char *) really_newconf_def, sizeof(really_newconf_def) ) == 0 )
      return(0);  /* loaded with 3/91 loadping */
   printf("\n WARNING: Unrecognized CONFIGURATION_1 definition");
   printf("\n NO configuration_1 conversion performed on this block\n");
   return(-1);
}

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

   if ( (anc1_def = find_def("ANCILLARY_1", db->block_strdef)) == NULL )
   {
      printf("\n WARNING: ANCILLARY_1 definition not in block file");
      printf("\n NO ancillary_1 conversion performed on this block\n");
      return(-1);
   }
   if ( cmp_byte(
      (char *) anc1_def, (char *) oldanc1_def, sizeof(oldanc1_def)) == 0 )
   {
      if ( dbget_cnf(ANCILLARY_1, NULL, &n, "getting ancillary_1 size") ||
         error_found( (n != sizeof(ANCILLARY_1_TYPE)),
         "size mismatch for ancillary_1" ) )
      {
         printf("\n NO ancillary_1 conversion performed on this block\n");
         return(-1);
      }
      return(1);
   }
   if ( cmp_byte(
      (char *) anc1_def, (char *) newanc1_def, sizeof(newanc1_def)) == 0 )
      return(0);
   printf("\n WARNING: Unrecognized ANCILLARY_1 definition");
   printf("\n NO ancillary_1 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 )
   {
      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 converted by convadcp */
   if (anc2_def->nelem == 23) return(0);  /* loaded with new LOADPING */
   printf("\n WARNING: Unrecognized ANCILLARY_2 definition");
   printf("\n NO ancillary_2 conversion performed on this block\n");
   return(-1);
}

#if PROTOTYPE_ALLOWED
int check_ub(void)
#else
int check_ub()
#endif
{
   STRUCT_DEF_HDR_TYPE *ub_def, *fix_def;
   unsigned int n = 0;

   if ( (ub_def = find_def("USER_BUFFER", db->block_strdef)) == NULL )
   {
      printf("\n WARNING: USER_BUFFER definition not in block file");
      printf("\n NO user buffer conversion performed on this block\n");
      return(-1);
   }
   if ( (fix_def = find_def("fix", db->block_strdef)) == NULL )
   {
      printf("\n WARNING: fix definition not in block file");
      printf("\n NO user buffer conversion performed on this block\n");
      return(-1);
   }

   if ( cmp_byte(
      (char *) ub_def, (char *) ub1280_def, sizeof(ub1280_def)) == 0 && cmp_byte(
      (char *) fix_def, (char *) oldfix_def, sizeof(oldfix_def)) == 0 )
   {
      if ( dbget_cnf(USER_BUFFER, NULL, &n, "getting user buffer size") ||
         error_found( (n != 128), "size mismatch for user buffer 1280" ) )
      {
         printf("\n NO user buffer conversion performed on this block\n");
         return(-1);
      }
      return(1280);  /* need to convert */
   }
   if ( cmp_byte(
      (char *) ub_def, (char *) ub1020_def, sizeof(ub1020_def)) == 0 && cmp_byte(
      (char *) fix_def, (char *) oldfix_def, sizeof(oldfix_def)) == 0 )
   {
      if ( dbget_cnf(USER_BUFFER, NULL, &n, "getting user buffer size") ||
         error_found( (n != 102), "size mismatch for user buffer 1020" ) )
      {
         printf("\n NO user buffer conversion performed on this block\n");
         return(-1);
      }
      return(1020);  /* need to convert */
   }
   if ( cmp_byte(
      (char *) ub_def, (char *) ub1281_def, sizeof(ub1281_def)) == 0 && cmp_byte(
      (char *) fix_def, (char *) newfix_def, sizeof(newfix_def)) == 0 )
      return(0);     /* already up-to-date */
   if ( cmp_byte(
      (char *) ub_def, (char *) ub1021_def, sizeof(ub1021_def)) == 0 && cmp_byte(
      (char *) fix_def, (char *) newfix_def, sizeof(newfix_def)) == 0 )
      return(0);     /* already up-to-date */
   printf("\n WARNING: Unrecognized USER_BUFFER_TYPE definition");
   printf("\n NO user buffer conversion performed on this block\n");
   return(-1);
}

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

   FUNCTIONS: convert_configuration, convert_ancillary1, convert_ancillary2,
              convert_user_buffer

      These get the old data from the database, perform the required byte-
      swapping, and store the converted data back into the database--
      except for convert_ancillary2 which requires truncation rather
      than byte-swapping (accomplished by reducing the nbytes field in
      the data directory entry).

   RETURN:

      0 = okay;
     -1 = database error

*/

#if PROTOTYPE_ALLOWED
int convert_configuration(void)
#else
int convert_configuration()
#endif
{
    unsigned int n = 1 + sizeof(CONFIGURATION_1_TYPE);
    char old_conf[1 + sizeof(CONFIGURATION_1_TYPE)];
    CONFIGURATION_1_TYPE new_conf;
    int ierr;

    if ((ierr = dbget_cnf(CONFIGURATION_1, old_conf, &n, "getting configuration"))
       != 0 && ierr != INVALID_TYPE_REQUEST )
       return(-1);
    if (ierr == INVALID_TYPE_REQUEST || n == 0) return(0);  /* data not present */
    if (error_found( (n != sizeof(CONFIGURATION_1_TYPE)),
       "size mismatch for CONFIGURATION_1")) return(-1);
    move_byte(old_conf   , (char *) &(new_conf.avg_interval), sizeof(FLOAT));
    move_byte(old_conf+56, (char *) &(new_conf.compensation), sizeof(SHORT));
    move_byte(old_conf+4 , (char *) &(new_conf.num_bins), sizeof(SHORT));
    move_byte(old_conf+6 , (char *) &(new_conf.tr_depth), 5 * sizeof(FLOAT));
    move_byte(old_conf+26, (char *) &(new_conf.bot_track), 3 * sizeof(SHORT));
    move_byte(old_conf+66, (char *) &(new_conf.ev_threshold), sizeof(SHORT));
    move_byte(old_conf+32, (char *) &(new_conf.hd_offset), 6 * sizeof(FLOAT));
    move_byte(old_conf+58, (char *) &(new_conf.freq_transmit), sizeof(FLOAT));
    move_byte(old_conf+62, (char *) &(new_conf.top_ref_bin), 2 * sizeof(SHORT));
    move_byte(old_conf+68, (char *) &(new_conf.scale_factor), 2 * sizeof(FLOAT));
    if (dbput_cnf(CONFIGURATION_1, (char *) &new_conf, &n,
       "storing configuration")) return(-1);
    return(0);
}

int convert_ancillary1()
{
   unsigned int n = 1 + sizeof(ANCILLARY_1_TYPE);
   char old_anc1[1 + sizeof(ANCILLARY_1_TYPE)];
   ANCILLARY_1_TYPE new_anc1;
   int ierr = 0;

   if ( (ierr = dbget_cnf(ANCILLARY_1, old_anc1, &n, "getting ancillary_1")) != 0
      && ierr != INVALID_TYPE_REQUEST) return(-1);
   if (ierr == INVALID_TYPE_REQUEST || n == 0) return(0);  /* data not present */
   if (error_found( (n != sizeof(ANCILLARY_1_TYPE)),
      "size mismatch for ANCILLARY_1")) return(-1);
   move_byte(old_anc1+2 , (char *) &(new_anc1.tr_temp), 4 * sizeof(FLOAT));
   move_byte(old_anc1   , (char *) &(new_anc1.pgs_sample), sizeof(SHORT));
   move_byte(old_anc1+18, (char *) &(new_anc1.anc6), 5 * sizeof(SHORT));
   if (dbput_cnf(ANCILLARY_1, (char *) &new_anc1, &n,
      "storing ancillary_1 data")) return(-1);
   return(0);
}

#if PROTOTYPE_ALLOWED
int convert_user_buffer(int type)
#else
int convert_user_buffer(type)
int type;
#endif
{
   char old_ub[1 + sizeof(USER_BUFFER_1281_TYPE)];
   unsigned int n, correct_n;
   int ierr = 0;
   union
   {
      USER_BUFFER_1021_TYPE ub_1021;
      USER_BUFFER_1281_TYPE ub_1281;
   } new;

   switch(type)
   {
      case 1280:
         correct_n = sizeof(USER_BUFFER_1281_TYPE);
         break;
      case 1020:
/*       correct_n = sizeof(USER_BUFFER_1021_TYPE); jr- problem with SPARC */
         correct_n = 102;
         break;
   }

   n = 1 + correct_n;
   if ( (ierr = dbget_cnf(USER_BUFFER, old_ub, &n, "getting user buffer")) != 0
      && ierr != INVALID_TYPE_REQUEST )
      return(-1);
   if (ierr == INVALID_TYPE_REQUEST || n == 0) return(0);  /* data not present */
   if (error_found( (n != correct_n), "size mismatch for USER_BUFFER"))
      return(-1);

   if (type == 1280)
   {
      move_byte(old_ub    , (char *) &(new.ub_1281.version), 28 * sizeof(SHORT));
      move_byte(old_ub+56 , (char *) &(new.ub_1281.time)   , sizeof(LONG));
      convert_transit_fix(old_ub+60, &(new.ub_1281.fix));
      move_byte(old_ub+104, (char *) &(new.ub_1281.gps_status.received),
         sizeof(GPS_STATUS_TYPE));
      new.ub_1281.version = 1281; /* to indicate conversion to new definition */
   }
   else /* 1020 */
   {
      move_byte(old_ub    , (char *) &(new.ub_1021.max_avgs), 27 * sizeof(SHORT));
      move_byte(old_ub+54 , (char *) &(new.ub_1021.time)    , sizeof(LONG));
      convert_transit_fix(old_ub+58, &(new.ub_1021.fix));
   }

   if (dbput_cnf(USER_BUFFER, (char *) &new, &correct_n,
      "storing user buffer")) return(-1);
   return(0);
}

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

   FUNCTION: convert_transit_fix

      This performs the byte-swapping on the TRANSIT_FIX_TYPE structure.

   PARAMETERS:

      old_fix = pointer to old data bytes for transit fix
      new_fix = pointer to converted transit fix structure

*/
#if PROTOTYPE_ALLOWED
void convert_transit_fix(char *old_fix, TRANSIT_FIX_TYPE *new_fix)
#else
void convert_transit_fix(old_fix, new_fix)
char *old_fix;
TRANSIT_FIX_TYPE *new_fix;
#endif
{
   move_byte(old_fix   , (char *) &(new_fix->ref_u)  , 3 * sizeof(SHORT));
   move_byte(old_fix+ 6, (char *) &(new_fix->pc_time), 5 * sizeof(LONG));
   move_byte(old_fix+26, (char *) &(new_fix->dr_dist), 4 * sizeof(SHORT));
   move_byte(old_fix+34, (char *) &(new_fix->sat_id) , sizeof(SHORT));
   move_byte(old_fix+36, (char *) &(new_fix->used)   , 8 * sizeof(BYTE));
}

