home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / EMBL Search / Sources / cd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-04  |  15.3 KB  |  527 lines  |  [TEXT/KAHL]

  1. /*
  2. *********************************************************************
  3. *    
  4. *    cd.c
  5. *    Initialization of CD-ROM
  6. *
  7. *    Rainer Fuchs
  8. *    EMBL Data Library
  9. *    Postfach 10.2209
  10. *    D-6900 Heidelberg, FRG
  11. *    E-mail: fuchs@embl-heidelberg.de
  12. *
  13. *    Copyright © 1992 EMBL Data Library
  14. *        
  15. **********************************************************************
  16. *
  17. */
  18.  
  19. #include <Packages.h>
  20. #include <string.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23.  
  24. #include "EMBL-Search.h"
  25. #include "EMBL-Search.rsrc.h"
  26.  
  27. /*
  28. ******************************* Prototypes ***************************
  29. */
  30.  
  31. #include "cd.h"
  32. #include "pstr.h"
  33. #include "util.h"
  34. #include "window.h"
  35.  
  36. static short GetWDFromPath(StringPtr dirName, short vRefNum, StringPtr volName);
  37. static short GetWDFromSpec(DirSpec *dirSpec);
  38. static Boolean ProcessDBFiles(short dbcode);
  39. static Boolean CheckHeader(StringPtr fName, short fd, short dbcode, long rec_size, u_long *nrec, u_short *recsize);
  40.  
  41. /*
  42. ******************************** Global variables *****************
  43. */
  44.  
  45. extern VolInfo        gCurrentCD;
  46. extern DBInfo        gDBInfo[DB_NUM];
  47. extern IndexFiles    gFileList;
  48. extern Str255        gVolLabel;
  49. extern char            gError[256];
  50. extern Prefs        gPrefs;
  51.  
  52. /**************************************
  53. *    Startup check for an attached EMBL CD-ROM.
  54. *    We compare the volume name to the value stored in a STR# resource
  55. *    (variable gVolLabel).
  56. */
  57.  
  58. void InitCD()
  59. {
  60.     register short    i;
  61.     HParamBlockRec    myPB;
  62.     Str255            volName;
  63.     Boolean            foundCD=FALSE;
  64.     OSErr                err;
  65.     DialogPtr        myDialog;
  66.     
  67.     *gCurrentCD.volName=EOS;            /* clear volume name. A valid volume name
  68.                                                     indicates that we´ve found a CD-ROM        */
  69.     
  70.     /* now check every attached device */
  71.     myPB.volumeParam.ioNamePtr=volName;
  72.     for(i=1,err=noErr;err == noErr;++i) {
  73.         myPB.volumeParam.ioVolIndex=i;
  74.         err=PBHGetVInfo(&myPB,FALSE);                    /* get volume information        */
  75.         if(err == noErr) {                                /* error or no more volumes    */
  76.             /* Check volume name */
  77.             if(!pstrncmp(volName,gVolLabel,*gVolLabel)) {
  78.                 /* it looks like an EMBL CD-ROM, now try to initialize it */
  79.                 StartWaitCursor();
  80.                 CenterDA('DLOG',INITWAIT_DLG,50);
  81.                 ShowWindow(myDialog=GetNewDialog(INITWAIT_DLG,NULL,(WindowPtr)-1));
  82.                 DrawDialog(myDialog);
  83.                 foundCD=InitDB(myPB.volumeParam.ioVRefNum,volName);
  84.                 DisposDialog(myDialog);
  85.                 InitCursor();
  86.                 if( foundCD == TRUE )
  87.                     break;
  88.             }
  89.         }
  90.     }
  91.     
  92.     /* In case no EMBL CD-ROM is attached or something went wrong, we exit */
  93.     
  94.     if(! foundCD)
  95.         FatalErrorMsg(ERR_NOCD);
  96. }
  97.  
  98.  
  99. /**************************************
  100. *    Check files on CD for correctness
  101. *    Return value:    TRUE, if successful
  102. *                        FALSE, if an error occurred
  103. */
  104.  
  105. Boolean InitDB(short vRefNum,StringPtr volName)
  106. {
  107.     Str255 name;
  108.  
  109.     /* create working directory for EMBL sequence directory */
  110.     pstrcpy(name,gDBInfo[DB_EMBL].SeqDName);
  111.     if(!(gDBInfo[DB_EMBL].SeqWDRefNum  = GetWDFromPath(name,vRefNum,volName)))
  112.         return(FALSE);
  113.         
  114.     /* create working directory for Swissprot sequence directory */
  115.     pstrcpy(name,gDBInfo[DB_SWISS].SeqDName);
  116.     if(!(gDBInfo[DB_SWISS].SeqWDRefNum = GetWDFromPath(name,vRefNum,volName)))
  117.         return(FALSE);
  118.         
  119.     /* Try to create working directory for EMBL index directory according to specs
  120.         stored in Prefs file */
  121.     if(*gPrefs.inxDirSpec[DB_EMBL].volName != EOS) {
  122.         if(!(gDBInfo[DB_EMBL].InxWDRefNum  = GetWDFromSpec(&gPrefs.inxDirSpec[DB_EMBL]))) {
  123.             sprintf(gError,LoadErrorStr(ERR_PNF,FALSE),"EMBL");
  124.             ErrorMsg(0);
  125.             *gPrefs.inxDirSpec[DB_EMBL].volName = EOS;    /* reset name on error */
  126.         }
  127.     }
  128.     
  129.     /* create working directory for EMBL index directory */
  130.     if(*gPrefs.inxDirSpec[DB_EMBL].volName == EOS) {
  131.         pstrcpy(name,volName);
  132.         pstrcat(name,"\p:");
  133.         pstrcat(name,gDBInfo[DB_EMBL].InxDName);
  134.         if(!(gDBInfo[DB_EMBL].InxWDRefNum  = GetWDFromPath(name,vRefNum,volName)))
  135.             return(FALSE);
  136.     }
  137.     
  138.     /* Try to create working directory for Swissprot index directory according to specs
  139.         stored in Prefs file */
  140.     if(*gPrefs.inxDirSpec[DB_SWISS].volName != EOS) {
  141.         if(!(gDBInfo[DB_SWISS].InxWDRefNum  = GetWDFromSpec(&gPrefs.inxDirSpec[DB_SWISS]))) {
  142.             sprintf(gError,LoadErrorStr(ERR_PNF,FALSE),"SWISS");
  143.             ErrorMsg(0);
  144.             *gPrefs.inxDirSpec[DB_SWISS].volName = EOS;    /* reset name on error */
  145.         }
  146.     }
  147.     
  148.     /* create working directory for Swissprot index directory */
  149.     if(*gPrefs.inxDirSpec[DB_SWISS].volName == EOS) {
  150.         pstrcpy(name,volName);
  151.         pstrcat(name,"\p:");
  152.         pstrcat(name,gDBInfo[DB_SWISS].InxDName);
  153.         if(!(gDBInfo[DB_SWISS].InxWDRefNum = GetWDFromPath(name,vRefNum,volName)))
  154.             return(FALSE);
  155.     }
  156.  
  157.     /* now check individual files */
  158.     if( !ProcessDBFiles(DB_EMBL) || !ProcessDBFiles(DB_SWISS) )
  159.         return(FALSE);
  160.  
  161.     /* Fill gCurrentCd and thus make current CD valid */
  162.     pstrcpy(gCurrentCD.volName,volName);
  163.     gCurrentCD.vRefNum=vRefNum;
  164.     return(TRUE);
  165. }
  166.  
  167.  
  168. /**************************************
  169. *    Create a working directory from a full path specification
  170. *    Returns working directory refnum, or 0 if an error occurred
  171. */
  172.  
  173. static short GetWDFromPath(StringPtr dirName,short vRefNum,StringPtr volName)
  174. {
  175.     CInfoPBRec    myPB;
  176.     OSErr            err;
  177.     short            wdRefNum;
  178.  
  179.     /* Get DirID */
  180.     myPB.dirInfo.ioNamePtr=dirName;
  181.     myPB.dirInfo.ioVRefNum=vRefNum;
  182.     myPB.dirInfo.ioFDirIndex=0;
  183.     myPB.dirInfo.ioDrDirID=0;
  184.     if((err = PBGetCatInfo(&myPB,FALSE)) != noErr) {
  185.         sprintf(gError,LoadErrorStr(ERR_NOCDDIR,FALSE),
  186.                     PtoCstr(dirName), PtoCstr(volName));
  187.         CtoPstr((char *)volName);
  188.         return(ErrorMsg(0));
  189.     }
  190.     
  191.     /* Create a working directory */
  192.     if( (err=OpenWD(vRefNum,myPB.dirInfo.ioDrDirID,kApplSignature,&wdRefNum))
  193.             != noErr) {
  194.         sprintf(gError,LoadErrorStr(ERR_CREATEWD,FALSE),err );
  195.         return(ErrorMsg(0));
  196.     }
  197.     
  198.     return(wdRefNum);
  199. }
  200.  
  201. /**************************************
  202. *    Create a working directory from a DirSpec
  203. *    Returns working directory refnum, or 0 if an error occurred
  204. */
  205.  
  206. static short GetWDFromSpec(DirSpec *dirSpec)
  207. {
  208.     OSErr            err;
  209.     short            wdRefNum;
  210.     short            vRefNum;
  211.     
  212.     if(!GetVRefNumFromName(dirSpec->volName,&vRefNum))
  213.         return(0);
  214.             
  215.     /* Create a working directory */
  216.     if( (err=OpenWD(vRefNum,dirSpec->dirID,kApplSignature,&wdRefNum)) != noErr) {
  217.         sprintf(gError,LoadErrorStr(ERR_CREATEWD,FALSE),err );
  218.         return((short)ErrorMsg(0));
  219.     }
  220.     
  221.     return(wdRefNum);
  222. }
  223.  
  224. /**************************************
  225. *    Analyse index files on CD-ROM
  226. *    Return value:    TRUE, if successful
  227. *                        FALSE, if an error occurred
  228. */
  229.  
  230. static Boolean ProcessDBFiles(short dbcode)
  231. {
  232.     Str255            fName;
  233.     short                fd;
  234.     short                i;
  235.     Header            hdr;
  236.     DivisionRec        divRec;
  237.     long                size;
  238.     unsigned long    secs;
  239.     DateTimeRec        date;
  240.     Boolean            ret;
  241.     SignedByte        oldHState;
  242.     u_long            temp;
  243.     u_short            recsize;
  244.     short                rel;
  245.     
  246.     /* Process division information file */
  247.     pstrcpy(fName,gFileList.divFName);
  248.     if( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd, TRUE) != noErr )
  249.         return(FALSE);
  250.     
  251.     /* check header */
  252.     size=sizeof(Header);
  253.     if ( ReadMacFile(fd,&size,&hdr,fName, TRUE) ) {
  254.         FSClose(fd);
  255.         return(FALSE);
  256.     }
  257.  
  258.     /* store db name and release number */
  259.     strncpy(gDBInfo[dbcode].DBName,hdr.db_name,DBNAMELEN);
  260.     gDBInfo[dbcode].DBName[DBNAMELEN]=EOS;
  261.     rtrim(gDBInfo[dbcode].DBName);
  262.  
  263.     strncpy(gDBInfo[dbcode].DBRelNum,hdr.db_relnum,DBRELNUMLEN);
  264.     gDBInfo[dbcode].DBRelNum[DBRELNUMLEN]=EOS;
  265.     rtrim(gDBInfo[dbcode].DBRelNum);
  266.     
  267.     /* check for compatibility of software with CD-ROM
  268.     if(dbcode == DB_EMBL) {
  269.         rel=atoi( gDBInfo[dbcode].DBRelNum );
  270.         if (rel < 29) {
  271.             sprintf(gError,LoadErrorStr(ERR_TOOOLD,FALSE));
  272.             return(ErrorMsg(0));
  273.         }
  274.     }
  275.     
  276.     /* get release date and convert it to a string */
  277.     date.year=1900+hdr.db_reldate.year;
  278.     date.month=hdr.db_reldate.month;
  279.     date.day=hdr.db_reldate.day;
  280.     date.hour=date.minute=date.second=0;
  281.     Date2Secs(&date,&secs);
  282.     IUDateString(secs,shortDate,(StringPtr)gDBInfo[dbcode].DBRelDate);
  283.     PtoCstr((StringPtr)gDBInfo[dbcode].DBRelDate);
  284.     
  285.     /* check record size */
  286.     if(ConvertShort(&hdr.record_size) != sizeof(DivisionRec)){
  287.         FSClose(fd);
  288.         sprintf(gError,LoadErrorStr(ERR_INVRECSIZE,FALSE),PtoCstr(fName));
  289.         CtoPstr((char *)fName);
  290.         return(ErrorMsg(0));
  291.     }
  292.     
  293.     /* allocate memory for division information */ 
  294.     gDBInfo[dbcode].ndiv = (short)ConvertLong(&hdr.nrecords);
  295.     size= (sizeof(Str255) * (gDBInfo[dbcode].ndiv+1));
  296.     if( !(gDBInfo[dbcode].gDivNames = 
  297.         (char **)NewHandleClear((DIVNAMELEN+1) * (gDBInfo[dbcode].ndiv+1))) ) {
  298.         FSClose(fd);
  299.         return(ErrorMsg(ERR_MEMORY));
  300.     }
  301.     
  302.     /* read sequence file names and division codes*/
  303.     oldHState = LockHandleHigh(gDBInfo[dbcode].gDivNames);
  304.     for(i=1;i<=gDBInfo[dbcode].ndiv;++i) {
  305.         size=sizeof(DivisionRec);
  306.         if( ReadMacFile(fd,&size,&divRec,fName,TRUE) ) {
  307.             FSClose(fd);
  308.             DisposHandle((Handle)gDBInfo[dbcode].gDivNames);
  309.             gDBInfo[dbcode].gDivNames = NULL;
  310.             return(FALSE);
  311.         }
  312.         if(ConvertShort(&divRec.div_code) != (u_short)i) {
  313.             FSClose(fd);
  314.             DisposHandle((Handle)gDBInfo[dbcode].gDivNames);
  315.             gDBInfo[dbcode].gDivNames = NULL;
  316.             sprintf(gError,LoadErrorStr(ERR_DIVCODEORDER,FALSE),PtoCstr(fName));
  317.             CtoPstr((char *)fName);
  318.             return(ErrorMsg(0));
  319.         }
  320.         else {
  321.             strncpy( *gDBInfo[dbcode].gDivNames + i*(DIVNAMELEN+1),divRec.filename,
  322.                         DIVNAMELEN);
  323.             (*gDBInfo[dbcode].gDivNames + i*(DIVNAMELEN+1))[DIVNAMELEN]=EOS;
  324.             rtrim(*gDBInfo[dbcode].gDivNames + i*(DIVNAMELEN+1));
  325.             strcat(*gDBInfo[dbcode].gDivNames + i*(DIVNAMELEN+1),";1");
  326.             CtoPstr(*gDBInfo[dbcode].gDivNames + i*(DIVNAMELEN+1));
  327.         }
  328.     }
  329.     HSetState((Handle)gDBInfo[dbcode].gDivNames,oldHState);
  330.     FSClose(fd);
  331.     
  332.     /* Check short description file */
  333.     pstrcpy(fName,gFileList.briefIdxFName);
  334.     if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum, &fd, TRUE) == noErr))) {
  335.         ret = CheckHeader(fName,fd,dbcode,sizeof(DescRec),&temp,&recsize);
  336.         FSClose(fd);
  337.     }
  338.     if(ret == FALSE) return(FALSE);
  339.  
  340.     /* Check entry name index */
  341.     pstrcpy(fName,gFileList.enameIdxFName);
  342.     if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,TRUE) == noErr))) {
  343.         ret = CheckHeader(fName,fd,dbcode,sizeof(EnameRec),
  344.                                 &gDBInfo[dbcode].ename_nrec, &recsize);
  345.         FSClose(fd);
  346.     }
  347.     if(ret == FALSE) return(FALSE);
  348.     
  349.     /* Compare nrec of entryname and shortdir indexes */
  350.     if (gDBInfo[dbcode].ename_nrec != temp)
  351.         return(ErrorMsg(ERR_WRONGNREC));
  352.     
  353.     /* Check accession number hit file */
  354.     pstrcpy(fName,gFileList.acnumHitFName);
  355.     if ((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,TRUE) == noErr))) {
  356.         ret = CheckHeader(fName,fd,dbcode,sizeof(u_long),&gDBInfo[dbcode].achit_nrec,
  357.                                 &recsize);
  358.         FSClose(fd);
  359.     }
  360.     if(ret == FALSE) return(FALSE);
  361.  
  362.     /* Check accession number target list */
  363.     pstrcpy(fName,gFileList.acnumTrgFName);
  364.     if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,TRUE) == noErr))) {
  365.         ret = CheckHeader(fName,fd,dbcode,0L,&gDBInfo[dbcode].actrg_nrec,&recsize);
  366.         FSClose(fd);
  367.     }
  368.     if(ret)
  369.         gDBInfo[dbcode].actrg_recsize=recsize;
  370.     else
  371.         return(FALSE);
  372.         
  373.     /* Check keyword hit file */
  374.     pstrcpy(fName,gFileList.keywHitFName);
  375.     if ((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,FALSE) == noErr))) {
  376.         ret = CheckHeader(fName,fd,dbcode,sizeof(u_long),
  377.                                 &gDBInfo[dbcode].kwhit_nrec, &recsize);
  378.         FSClose(fd);
  379.     }
  380.     if(ret == FALSE) 
  381.         gDBInfo[dbcode].kwtrg_recsize=0;
  382.     else {
  383.         /* Check keyword target list */
  384.         pstrcpy(fName,gFileList.keywTrgFName);
  385.         if((ret=(OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,FALSE) == noErr))) {
  386.             ret = CheckHeader(fName,fd,dbcode,0L,&gDBInfo[dbcode].kwtrg_nrec,&recsize);
  387.             FSClose(fd);
  388.         }
  389.         if(ret == FALSE)
  390.             gDBInfo[dbcode].kwtrg_recsize=0;
  391.         else
  392.             gDBInfo[dbcode].kwtrg_recsize=recsize;
  393.     }
  394.  
  395.     /* Check free text hit file */
  396.     pstrcpy(fName,gFileList.textHitFName);
  397.     if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,FALSE) == noErr))) {
  398.         ret = CheckHeader(fName,fd,dbcode,sizeof(u_long),
  399.                                 &gDBInfo[dbcode].texthit_nrec, &recsize);
  400.         FSClose(fd);
  401.     }
  402.     if(ret == FALSE)    /* no error, we simply disable free text queries
  403.                                     (might be a pre-Rel.29 CD-ROM */
  404.         gDBInfo[dbcode].texttrg_recsize=0;
  405.     else {
  406.         /* Check free text target list */
  407.         pstrcpy(fName,gFileList.textTrgFName);
  408.         if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd, FALSE) == noErr))) {
  409.             ret = CheckHeader(fName,fd,dbcode,0L,&gDBInfo[dbcode].texttrg_nrec,
  410.                                     &recsize);
  411.             FSClose(fd);
  412.         } 
  413.         if(ret == FALSE)    /* no error, we simply disable free text queries
  414.                                     (might be a pre-Rel.29 CD-ROM */
  415.             gDBInfo[dbcode].texttrg_recsize=0;
  416.         else
  417.             gDBInfo[dbcode].texttrg_recsize=recsize;
  418.     }
  419.     
  420.     /* Check author hit file */
  421.     pstrcpy(fName,gFileList.authorHitFName);
  422.     if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,FALSE) == noErr))) {
  423.         ret = CheckHeader(fName,fd,dbcode,sizeof(u_long),
  424.                                 &gDBInfo[dbcode].authorhit_nrec, &recsize);
  425.         FSClose(fd);
  426.     }
  427.     if(ret == FALSE)    /* no error, we simply disable author queries
  428.                                     (might be a pre-Rel.30 CD-ROM */
  429.         gDBInfo[dbcode].authortrg_recsize=0;
  430.     else {
  431.         /* Check author target list */
  432.         pstrcpy(fName,gFileList.authorTrgFName);
  433.         if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd, FALSE) == noErr))) {
  434.             ret = CheckHeader(fName,fd,dbcode,0L,&gDBInfo[dbcode].authortrg_nrec,
  435.                                     &recsize);
  436.             FSClose(fd);
  437.         } 
  438.         if(ret == FALSE)    /* no error, we simply disable author queries
  439.                                     (might be a pre-Rel.30 CD-ROM */
  440.             gDBInfo[dbcode].authortrg_recsize=0;
  441.         else
  442.             gDBInfo[dbcode].authortrg_recsize=recsize;
  443.     }
  444.     
  445.     /* Check taxonomy hit file */
  446.     pstrcpy(fName,gFileList.taxonHitFName);
  447.     if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd,FALSE) == noErr))) {
  448.         ret = CheckHeader(fName,fd,dbcode,sizeof(u_long),
  449.                                 &gDBInfo[dbcode].taxonhit_nrec, &recsize);
  450.         FSClose(fd);
  451.     }
  452.     if(ret == FALSE)    /* no error, we simply disable taxonomy queries
  453.                                     (might be a pre-Rel.30 CD-ROM */
  454.         gDBInfo[dbcode].taxontrg_recsize=0;
  455.     else {
  456.         /* Check taxonomy target list */
  457.         pstrcpy(fName,gFileList.taxonTrgFName);
  458.         if((ret=( OpenMacFileReadOnly(fName,gDBInfo[dbcode].InxWDRefNum,&fd, FALSE) == noErr))) {
  459.             ret = CheckHeader(fName,fd,dbcode,0L,&gDBInfo[dbcode].taxontrg_nrec,
  460.                                     &recsize);
  461.             FSClose(fd);
  462.         } 
  463.         if(ret == FALSE)    /* no error, we simply disable taxonomy queries
  464.                                     (might be a pre-Rel.30 CD-ROM */
  465.             gDBInfo[dbcode].taxontrg_recsize=0;
  466.         else
  467.             gDBInfo[dbcode].taxontrg_recsize=recsize;
  468.     }
  469.  
  470.     return(TRUE);
  471. }
  472.  
  473.  
  474. /**************************************
  475. *    Check index file header
  476. *    Return value:    TRUE, if successful
  477. *                        FALSE, if an error occurred
  478. *    Side-effect:    *nrec contains number of records, *recsize the size of a record
  479. */
  480.  
  481. static Boolean CheckHeader(StringPtr fName, short fd, short dbcode,
  482.                                     long rec_size, u_long *nrec, u_short *recsize)
  483. {
  484.     long        size;
  485.     Header    hdr;
  486.     char        dbname[DBNAMELEN+1];
  487.     char        dbrelnum[DBRELNUMLEN+1];
  488.     
  489.     *nrec=0L;
  490.     
  491.     /* rewind file */
  492.     if(SetFPos(fd,fsFromStart,0L) != noErr)
  493.         return(FALSE);
  494.     
  495.     /* read header */
  496.     size=sizeof(Header);
  497.     if ( ReadMacFile(fd,&size,&hdr,fName,TRUE) )
  498.         return(FALSE);
  499.  
  500.     /* check record size; for generic record structures we pass rec_size of 0 and
  501.         do not check */
  502.     if(rec_size != 0L) {
  503.         if(ConvertShort(&hdr.record_size) != rec_size){
  504.             sprintf(gError,LoadErrorStr(ERR_INVRECSIZE,FALSE),fName);
  505.             return(ErrorMsg(0));
  506.         }
  507.     }
  508.  
  509.     /* check dbcode name and version (we don't check the date) */
  510.     strncpy(dbname,hdr.db_name,DBNAMELEN);
  511.     dbname[DBNAMELEN]=EOS;
  512.     rtrim(dbname);
  513.     
  514.     strncpy(dbrelnum,hdr.db_relnum,DBRELNUMLEN);
  515.     dbrelnum[DBRELNUMLEN]=EOS;
  516.     rtrim(dbrelnum);
  517.     
  518.     if(strcmp(dbname,gDBInfo[dbcode].DBName) ||
  519.         strcmp(dbrelnum,gDBInfo[dbcode].DBRelNum)) {
  520.         sprintf(gError,LoadErrorStr(ERR_HEADINC,FALSE),fName);
  521.         return(ErrorMsg(0));
  522.     }    
  523.  
  524.     *nrec=ConvertLong(&hdr.nrecords);
  525.     *recsize = ConvertShort(&hdr.record_size);
  526.     return(TRUE);
  527. }