/***************************************************************************
 *                                                                         *
 *   GALNNCVT.C                                                            *
 *                                                                         *
 *   Copyright (c) 1996-1997 Galacticomm, Inc.    All Rights Reserved.     *
 *                                                                         *
 *   GALMSGID.DAT data file conversion utility.                            *
 *                                                                         *
 *                                           - J. Alvrus    8/20/96        *
 *                                                                         *
 *   Updated for version 3.0 -> 3.1 conversion.                            *
 *                                                                         *
 *                                           - J. Alvrus    3/3/97         *
 *                                                                         *
 ***************************************************************************/

#include "gcomm.h"
#include "excphand.h"
#include "majorbbs.h"
#include "gme.h"
#include "nntp.h"
#include "dfcapi2.h"

#define FILREV "$Revision: 4 $"

#define ICOMAXLEN 282              /* largest record in old file(s)        */
#define MIDINF(dfa) ((struct midinf *)(dfa)->data) /* cast for data file   */
#define ICOFILENAME "galmsgid.dat" /* ICO 1.0/2.0 file name                */
#define ICO1SHORTNAME "galico1"    /* ICO 1.0 file name (w/out ext)        */
#define ICO1FILENAME ICO1SHORTNAME ".dat" /* ICO 1.0 file name (w/ext)     */
#define ICO2SHORTNAME "galico2"    /* ICO 2.0 file name (w/out ext)        */
#define ICO2FILENAME ICO2SHORTNAME ".dat" /* ICO 2.0 file name (w/ext)     */

VOID *cvtICO1_ICO2(pDFCFILEINFO from,pDFCFILEINFO to);
VOID *cvtICO2_WG31(pDFCFILEINFO from,pDFCFILEINFO to);

DFCDATAFIELDS dfcGlobalIDFields[]={
     {"sysid",DFCFLD_LONG,1,NULL},
     {"msgid",DFCFLD_LONG,1,NULL},
     {""     ,DFCFLD_END ,0,NULL}
};

DFCDATAFIELDS ico1Fields[]={
     {"midcrc"      ,DFCFLD_LONG   ,1        ,NULL},
     {"globid"      ,DFCFLD_STRUCT ,1        ,dfcGlobalIDFields},
     {"forum"       ,DFCFLD_SHORT  ,1        ,NULL},
     {"msgno"       ,DFCFLD_LONG   ,1        ,NULL},
     {"thrid"       ,DFCFLD_LONG   ,1        ,NULL},
     {"timadd"      ,DFCFLD_LONG   ,1        ,NULL},
     {"midstr"      ,DFCFLD_CHAR   ,MIDSIZ   ,NULL},
     {""            ,DFCFLD_END    ,0        ,NULL}
};

DFCDATAFIELDS ico2wg30Fields[]={
     {"midcrc"      ,DFCFLD_LONG   ,1        ,NULL},
     {"forum"       ,DFCFLD_SHORT  ,1        ,NULL},
     {"msgidx"      ,DFCFLD_LONG   ,1        ,NULL},
     {"msgno"       ,DFCFLD_LONG   ,1        ,NULL},
     {"thrid"       ,DFCFLD_LONG   ,1        ,NULL},
     {"timadd"      ,DFCFLD_LONG   ,1        ,NULL},
     {"midstr"      ,DFCFLD_CHAR   ,MIDSIZ   ,NULL},
     {""            ,DFCFLD_END    ,0        ,NULL}
};

DFCDATAFIELDS wg31Fields[]={
     {"globid"      ,DFCFLD_STRUCT ,1        ,dfcGlobalIDFields},
     {"midcrc"      ,DFCFLD_LONG   ,1        ,NULL},
     {"msgidx"      ,DFCFLD_LONG   ,1        ,NULL},
     {"thrid"       ,DFCFLD_LONG   ,1        ,NULL},
     {"timadd"      ,DFCFLD_LONG   ,1        ,NULL},
     {"forum"       ,DFCFLD_SHORT  ,1        ,NULL},
     {"midstr"      ,DFCFLD_CHAR   ,MIDSIZ   ,NULL},
     {""            ,DFCFLD_END    ,0        ,NULL}
};

DFCFILE dosFiles[]={
     {ICO1SHORTNAME ,NULL          ,ico1Fields},
     {ICO2SHORTNAME ,cvtICO1_ICO2  ,ico2wg30Fields},
     {"galmsgi2"    ,NULL          ,ico2wg30Fields},
     {"galmsgi3"    ,cvtICO2_WG31  ,wg31Fields},
     {""            ,NULL          ,NULL}
};

DFCFILE wntFiles[]={
     {"galmsgi2"    ,NULL          ,ico2wg30Fields},
     {"galmsgi3"    ,cvtICO2_WG31  ,wg31Fields},
     {""            ,NULL          ,NULL}
};

DFCLIST fileList[]={               /* list of files we'll convert          */
     {DFC_DOS,dosFiles},
     {DFC_WNT,wntFiles},
     {DFC_END,NULL}
};

GBOOL isICO1;                      /* is the source file ICO 1.0 format?   */
DFAFILE *dfaDest=NULL;             /* destination file for ICO 1.0 cvt     */
LONG cursysid;                     /* GME system ID for current system     */

LONG gmeReg2SysID(const CHAR *regno);

INT
main(VOID)
{
     DFAFILE *dfa;
     UINT nkeys;
     GBOOL makeBackup;
     CHAR destPath[GCMAXPTH];

TRY
     initvid();
     cursiz(GVIDNOCURS);
     cursysid=gmeReg2SysID(getrno());

     /* check old file and rename to reflect format */
     isICO1=FALSE;
     makeBackup=FALSE;
     if (isfile(ICOFILENAME)) {
          makeBackup=TRUE;
          dfa=dfaOpen(ICOFILENAME,ICOMAXLEN,NULL);
          dfaStat(ICOMAXLEN);
          nkeys=dfa->data[4]+((UINT)dfa->data[5]<<8);
          switch (nkeys) {
          case 2:                  /* 2 keys -> WG 1.01          */
               copyfile(ICOFILENAME,ICO1FILENAME);
               isICO1=TRUE;
               break;
          case 3:                  /* 3 keys -> WG 2.00 / 3.00   */
               copyfile(ICOFILENAME,ICO2FILENAME);
               break;
          default:
               catastro("Unrecognized file format in %s",ICOFILENAME);
          }
          dfaClose(dfa);
     }

     /* do conversion */
     dfcRegister("NNTP Message ID Crossreference",fileList,NULL,1,DFC_FORWARD);
     if (makeBackup && dfcBackupRequired()) {
          makePath(destPath,dfcBackupDirectory(),ICOFILENAME,GCMAXPTH);
          if (rename(ICOFILENAME,destPath) != 0) {
               movefile(ICOFILENAME,destPath);
          }
     }

     /* cleanup */
     if (dfaDest != NULL) {
          dfaClose(dfaDest);
     }
     clsvid();
EXCEPT
     return(0);
}

VOID *
cvtICO1_ICO2(                      /* convert ICO 1.0 format to ICO 2.0 fmt*/
pDFCFILEINFO from,
pDFCFILEINFO to)
{
     to->DataLength=from->DataLength;
     return(from->Data);
}

VOID *
cvtICO2_WG31(                      /* convert ICO 2.0/WG 3.0 fmt to WG 3.1 */
pDFCFILEINFO from,
pDFCFILEINFO to)
{
     pDFCOFFSETS srcField,sysField,msgField;
     struct {
          USHORT forum;
          LONG msgidx;
     } ckey;

     if (isICO1) {
          srcField=dfcFindOffset(from,"forum");
          msgField=dfcFindOffset(to,"msgidx");
          dfcConvertDefault(from,to);
          cvtData(&from->Data[srcField->Offset],&ckey.forum
                 ,sizeof(USHORT),shortFDA,from->Type,CVTSERVER,CHAN_NUL);
          if (dfaDest == NULL) {
               dfaDest=dfaOpen(DFC_TEMPFILE,ICOMAXLEN,NULL);
          }
          dfaSetBlk(dfaDest);
          ckey.msgidx=LASTM;
          if (!dfaAcqLT(NULL,&ckey,FIDKEY)
           || MIDINF(dfaDest)->forum != ckey.forum) {
               MIDINF(dfaDest)->msgidx=0L;
          }
          dfaRstBlk();
          cvtData(&MIDINF(dfaDest)->msgidx,&to->Data[msgField->Offset]
                 ,sizeof(USHORT),shortFDA,CVTSERVER,to->Type,CHAN_NUL);
     }
     else {
          srcField=dfcFindOffset(from,"msgno");
          sysField=dfcFindOffset(to,"sysid");
          msgField=dfcFindOffset(to,"msgid");
          dfcConvertDefault(from,to);
          cvtData(&from->Data[srcField->Offset],&to->Data[msgField->Offset]
                 ,sizeof(LONG),longFDA,from->Type,to->Type,CHAN_NUL);
          cvtData(&cursysid,&to->Data[sysField->Offset]
                 ,sizeof(LONG),longFDA,CVTSERVER,to->Type,CHAN_NUL);
     }
     return(to->Data);
}

/* the following function stolen from GMEUTL.C */

LONG
gmeReg2SysID(                      /* get GME System-ID from reg #         */
const CHAR *regno)                 /*   system registration number         */
{
     ASSERT(regno != NULL);
     ASSERT(strlen(regno) == 8);
     ASSERT(alldgs((CHAR *)regno));
     return(((LONG)(((regno[0]-'0')*10+(regno[1]-'0'))|0x80))
          |(((LONG)(((regno[2]-'0')*10+(regno[3]-'0'))|0x80))<<8)
          |(((LONG)(((regno[4]-'0')*10+(regno[5]-'0'))|0x80))<<16)
          |(((LONG)(((regno[6]-'0')*10+(regno[7]-'0'))|0x80))<<24));
}
