#include "makecdf.h"
#define AT_LAST_SUBCYCLE 2
/* 09/2000 HKH Made numerous category changes (ERROR <--> WARNING) in
           messages, and in their numerical category. Condensed the 
           messages sent at successful conclusion of CDF.
           Added version of SAMPEX source with "magnetospheric" instead
           of the incorrect "magnetic".
*/

/*********************************************************************/
/*               STRIP 3CHARACTER SUFFIX FROM FILENAME               */
/*********************************************************************/
void StripName (oldname,newname)
char *oldname, *newname;
{
  LONG length,i,j;
  char suffix[5] = "";
  length=(LONG)strlen(oldname);
  if (length > 4) {
    for (i=0,j=length-4;i<4;i++,j++) suffix[i]=toupper(oldname[j]);
    suffix[4]='\0';
    if ((strcmp(suffix,".CDF")==0)||(strcmp(suffix,".SKT")==0)) {
      for (i=0;i<(length-4);i++) newname[i] = oldname[i];
      newname[i]='\0'; }
    else strcpy(newname,oldname);
  }
  else strcpy(newname,oldname);
}

/*********************************************************************/
/*                           Message Output                          */
/*********************************************************************/
/* 9/28/00 HKH Changed to call CDFerror with "cdfmessage", and add   */
/*             printing of "instring".                               */
void MSG_control(mtype,instring,status)
LONG mtype;
char *instring;
CDFstatus status;
{
  LONG nofeed=FALSE;
  LONG printit=FALSE;
  char cdfmessage[CDF_ERRTEXT_LEN+1];
  char tempname[80];
  
  if (strlen(instring) == 0) return;

  if ((mtype >= 0)&&(RPARMS.debug == TRUE)) printit=TRUE;
  else if ((mtype >= 1)&&(RPARMS.progress == TRUE)) printit=TRUE;
  else if ( mtype >= 2) printit=TRUE;

  if (printit == TRUE) { /* message passes output level test */

    if (status != 0) {
      CDFerror (status,cdfmessage);
      if (cdfmessage[strlen(cdfmessage)-1] != 10) nofeed=TRUE;
    }
    if (RPARMS.sendtoterm == TRUE) {
      if (nofeed==TRUE) {
         if (status != 0) printf("%s\n",cdfmessage);
         printf("%s\n",instring);
        }
      else {
         if (status != 0) printf("%s",cdfmessage);
         printf("%s\n",instring);
      }
    }

    if ((RPARMS.sendtolog == TRUE)&&(LOGFILE.fptr == NULL)) {
      /* Construct new LOGFILE.fname from CDFname argument of makecdf command */
      StripName(RPARMS.outcdfname,LOGFILE.fname);
      strcat(LOGFILE.fname,".log");
      LOGFILE.fptr = fopen(LOGFILE.fname,"w");
      if (LOGFILE.fptr == NULL) {
          RPARMS.sendtolog = FALSE;
          printf("ERROR: Unable to open log file for output. \n");
          printf("       makeCDF execution continuing... \n");
      }
      else {
          LOGFILE.nrecs = 0;
          if (LOGFILE.appendlog == 0) {
             fprintf(LOGFILE.fptr,"%s",IDENT.version);
              LOGFILE.nrecs++;
          }
      }
    }

    if ((RPARMS.sendtolog == TRUE)&&(LOGFILE.fptr != NULL)) {
      if (nofeed==TRUE) {
        if (status != 0) fprintf(LOGFILE.fptr,"%s\n",cdfmessage);
        fprintf(LOGFILE.fptr,"%s\n",instring);
      }
      else {
        if (status != 0) fprintf(LOGFILE.fptr,"%s",cdfmessage);
        fprintf(LOGFILE.fptr,"%s\n",instring);
      }
      LOGFILE.nrecs++;
      if (LOGFILE.nrecs > LOGFILE.maxrecs) {
        RPARMS.sendtolog = FALSE;
       /* fclose(LOGFILE.fptr); Now closed in main, at end of run. */
        fprintf(LOGFILE.fptr,"%d %s\n",
                LOGFILE.maxrecs," rcrds max for this CDF's log.");
        LOGFILE.big = 1; /* Flag that we hit max lines. */
  } } }
}


/**********************************************************************/
/*                  VALIDATE INPUT STRING AS ON OR OFF                */
/**********************************************************************/
LONG Validate_BOOLEAN(instring)
char *instring;
{
  LONG i;
  LONG ival = -1;
  for (i=0;i<(LONG)strlen(instring);i++) instring[i]=toupper(instring[i]);
  if (strcmp(instring,"ON")==0) ival=1;
  else if (strcmp(instring,"TRUE")==0) ival=1;
  else if (strcmp(instring,"YES")==0) ival=1;
  else if (strcmp(instring,"T")==0) ival=1;
  else if (strcmp(instring,"Y")==0) ival=1;
  else if (strcmp(instring,"1")==0) ival=1;
  else if (strcmp(instring,"OFF")==0) ival=0;
  else if (strcmp(instring,"FALSE")==0) ival=0;
  else if (strcmp(instring,"NO")==0) ival=0;
  else if (strcmp(instring,"F")==0) ival=0;
  else if (strcmp(instring,"N")==0) ival=0;
  else if (strcmp(instring,"0")==0) ival=0;
  return(ival);
}
/**********************************************************************/
/*                  VALIDATE EOL FLAG */
/**********************************************************************/
LONG Validate_EOL(instring)
char *instring;
{
  LONG i;
  LONG ival = -1;
  for (i=0;i<(LONG)strlen(instring);i++) instring[i]=toupper(instring[i]);
  if (strcmp(instring,"ON")==0) ival=1;
  else if (strcmp(instring,"TRUE")==0) ival=1;
  else if (strcmp(instring,"YES")==0) ival=1;
  else if (strcmp(instring,"T")==0) ival=1;
  else if (strcmp(instring,"Y")==0) ival=1;
  else if (strcmp(instring,"1")==0) ival=1;
  else if (strcmp(instring,"OFF")==0) ival=0;
  else if (strcmp(instring,"FALSE")==0) ival=0;
  else if (strcmp(instring,"NO")==0) ival=0;
  else if (strcmp(instring,"F")==0) ival=0;
  else if (strcmp(instring,"N")==0) ival=0;
  else if (strcmp(instring,"0")==0) ival=0;
  /*
   Same as Validate boolean except add a test for the
   S type, which be used when the end-of-line which be at
   the last subcycle
   */
  else if (strcmp(instring,"S")==0) ival=AT_LAST_SUBCYCLE;
  return(ival);
}

/**********************************************************************/
/* VALIDATE INPUT STRING AS POSITIVE INTEGER COULD BE MULTIPLE DIMENSIONS */
/**********************************************************************/
LONG Validate_SIZE(char *str, LONG *ndims, LONG *dim_sizes)
{
  LONG i;
  LONG isize=0;
  LONG ierr = -1;
  char *savestart;
  char *savetmp;
  char *savestr;
  char tmp[20];
  LONG index=0;
  int cnt;
  static char emes1[] = "ERROR: Validate_SIZE scan error in Size field in .ffd file, ";
  static char emes2a[] = "ERROR: non-numeric character (";
  static char emes2b[] = ") detected in Size field in .ffd file, ";
  char mess[256];

  savetmp = tmp;  
  savestart = tmp; 
  savestr = str;

  for (i=0; i<3; i++) dim_sizes[i]=0;
 
  /*
    Parse each character, until end-of-line or null-terminator found.  
    comma is the expected delimeter and only non-numeric character to
    be allowed
    */
  while (1) {
    if (*str == ',' || *str == '\n' || *str == '\0') {
      /* End-of line or field separator, null terminate that value */
      *savetmp = '\0';
      /* 
        Make sure there is a value here 
	*/
      if (strlen(savestart) > 0) {
	cnt=sscanf(savestart,"%d",&dim_sizes[index]);
	if (cnt == 0) {
	  /*  Something wrong with the field if cnt is 0 */
	  sprintf(mess,"%s\"%s\"",emes1,savestr);
	  MSG_control(2,mess,0);
	  *ndims = 0;
	  return ierr;
	}
        /*  This dimension complete, set the tmp buffer back to the beginning  */
	savetmp = savestart;
	index++;
      } 
      /*  If this was the end-of-line you're done or currently makecdf handles
          3 dimensions you're done if more */
      if ( *str != ',' || index > 2) break;
    } 
    else if (*str != ' ') {
      /*  If value is a digit, store it */
      if(isdigit(*str)) 
	*savetmp++ = *str;
      else {
	/* Non-numeric other that a comma, something wrong */
	sprintf(mess,"%s%c%s\"%s\"",emes2a,*str,emes2b,savestr);
	MSG_control(2,mess,0);
	*ndims = 0;
	return ierr;
      }

	
    }
    
    str++;
  }
  /*
    index is a offset, set to proper dimensions, remember 3 is the max currently for makecdf */
  if (index > 2) 
    *ndims = 3;
  else
    *ndims = index;
  /* Calculate the total size of this variable in elements */
  isize = 1;
  if (*ndims < 1 ) 
    *ndims = 0;
  else 
    for (i=0; i<*ndims; i++) isize *= dim_sizes[i];
      
  /* Makecdf expects the total size to be returned */
  return isize;
}
/**********************************************************************/
/*             VALIDATE INPUT STRING AS POSITIVE INTEGER or zero      */
/**********************************************************************/
LONG Validate_POSINT(instring)
char *instring;
{
  LONG i,ival;
  LONG ierr = -1;
  if (sscanf(instring,"%ld",&ival) == 0) return(ierr);
  else if (ival < 0) return(ierr);
  return(ival);
}

/**********************************************************************/
/*             VALIDATE THAT FILLVAL MATCHES CDF TYPE                 */
/**********************************************************************/
double Validate_FILLVAL(instring, cdfvartype)
char *instring;
LONG cdfvartype;
{
  double dval;
  LONG ierr = -1;
  if (sscanf(instring,"%lf",&dval) == 0) return(ierr);
  return(dval);
}

/**********************************************************************/
/*             VALIDATE INPUT VARIABLE FORMAT STRING                  */
/**********************************************************************/
LONG Validate_FORMAT(instring, outstring, length, cdfvartype)
char *instring;
char *outstring;
LONG *length;
LONG *cdfvartype;
{
  char ctype;
  char cwidth[10] = "";
  LONG i,icount,iwidth,ival;
  LONG ierr = -1;

  ctype = *instring++;
  icount = sscanf(instring,"%ld",&iwidth);
  if (icount == 1) sprintf(cwidth,"%d",iwidth);
  if      ((ctype=='i')||(ctype=='I')) {
    ctype='d'; *cdfvartype=CDF_INT4;   }
  else if ((ctype=='r')||(ctype=='R')) {
    ctype='f'; *cdfvartype=CDF_REAL4;  }
  else if ((ctype=='f')||(ctype=='F')) {
    ctype='f'; *cdfvartype=CDF_REAL4;  }
  else if ((ctype=='c')||(ctype=='C')) {
    ctype='c'; *cdfvartype=CDF_CHAR;   }
  else if ((ctype=='s')||(ctype=='S')) {
    ctype='s'; *cdfvartype=CDF_CHAR;   }
  else if (ctype =='0')                {
    ctype='0'; *cdfvartype=CDF_CHAR;   }

  /* check for double precision floating point */
  if ((*cdfvartype == CDF_REAL4)&&(iwidth == 8)) *cdfvartype=CDF_REAL8;

  /* determine parsing format */
  if (INFILE.format == 0) { /* freeform */
    *outstring++ = ' ';
    *outstring++ = '%';
    if (ctype=='c') {
      for (i=0;i<strlen(cwidth);i++) *outstring++ = cwidth[i];
      *length = iwidth;
    }
    else { 
      if (ctype=='s') *length = 40;
      else if (ctype=='0') *length = 0;
      else *length = 20;
    }
    *outstring++ = ctype;
  } 
  else { /* formatted */
    *outstring++ = '%';  
    for (i=0;i<strlen(cwidth);i++) *outstring++ = cwidth[i];
    *outstring++ = ctype;
    *length = iwidth;
  }
  *outstring++ = '\0';
  ival = 1;
  return(ival);
}

/**********************************************************************/
/*             SEPARATE VARIABLE NAME(S) FROM ELEMENT NUMBER          */
/**********************************************************************/
LONG Separate_Varnames(instring,vname1,vname2,velem1,velem2)
char *instring;
char *vname1;
char *vname2;
LONG *velem1;
LONG *velem2;
{
  char *cptr;
  LONG ierr =  0;
  LONG elem1 = -1;
  LONG elem2 = -1;

  *vname2 = '\0';                                 /* initialize          */
  cptr = memchr(instring,',',strlen(instring));   /* search for comma    */
  if (cptr != NULL) {                             /* comma found         */
    *cptr = '\0'; cptr++;                         /* terminate instring  */
    ierr=sscanf(cptr,"%ld",&elem2);               /* extract element #   */
    if (ierr != 1) {                              /* error reading elem# */
      strcpy(LOGFILE.message,"ERROR: Reading element2# for the variable:");
      strcat(LOGFILE.message,instring);   MSG_control(2,LOGFILE.message,0);
      ierr = 1; }                                 /* set error flag      */
    else { ierr=0; elem2 = elem2 - 1; }           /* base 0 not base1    */
  }
  cptr = memchr(instring,'(',strlen(instring));   /* search for L paren  */
  if (cptr != NULL) {                             /* L parenthesis found */
    *cptr = '\0'; cptr++;                         /* terminate instring  */
    ierr=sscanf(cptr,"%ld",&elem1);               /* extract element #   */
    if (ierr != 1) {                              /* error reading elem# */
      strcpy(LOGFILE.message,"ERROR: Reading element1# for the variable:");
      strcat(LOGFILE.message,instring);   MSG_control(2,LOGFILE.message,0);
      ierr = 1; }                                 /* set error flag      */
    else { ierr=0; elem1 = elem1 - 1; }           /* base 0 not base1    */
  }
  cptr = memchr(instring,'=',strlen(instring));   /* search for equals   */
  if (cptr != NULL) {                             /* varname equivalence */
    *cptr = '\0';                                 /* terminate instring  */
    cptr++; strcpy(vname2,cptr);                  /* copy CDF varname    */
  }
  strcpy(vname1,instring);                        /* copy input varname  */
  *velem1 = elem1;                                /* pass elem1# out     */
  *velem2 = elem2;                                /* pass elem2# out     */
  return(ierr);
}

/**********************************************************************/
/*               PREVIEW SELECTED RUNTIME PARAMETERS                  */
/**********************************************************************/
LONG Preview_RPARMS(file_ptr)
FILE *file_ptr;
{
  char buffer[81];
  char operand[81];
  char sval[20];
  LONG i,done,found,count,ival;
  LONG ierr=0;

  /* Locate runtime parameters portion of ffd file */
  found = FALSE; done = FALSE; /* initialize loop flags   */
  do {
    if (fgets(buffer,80,file_ptr) != NULL) {
      if (memcmp(buffer,";",1) != 0) {
        count = sscanf(buffer,"%s",operand);
        if (count == 1) {
          for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
          if (strcmp(operand,"RUNTIME_PARAMETERS") == 0) found = TRUE;
    } } }
    else done=TRUE;
  } while ((found==FALSE)&&(done==FALSE));
  if (found==FALSE) {
    return(ierr); }
  else done=FALSE;

  /* Read the run time parameters from the ffd file */
  do {
  if (fgets(buffer,80,file_ptr) != NULL) {
    if (memcmp(buffer,";",1) != 0) {
      count = sscanf(buffer,"%s",operand);
      if (count==1) {

        for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
        if (strcmp(operand,"PROGRESS_OUTPUT")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.progress=ival;
          }
        }
        else if (strcmp(operand,"DEBUG_OUTPUT")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.debug=ival;
          }
        }
        else if (strcmp(operand,"LOG_TO_SCREEN")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.sendtoterm=ival;
          }
        }
        else if (strcmp(operand,"LOG_TO_FILE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.sendtolog=ival;
          }
        }
  } } }
  else done=TRUE;
  } while (done == FALSE);
  return (ierr);
}
/**********************************************************************/
/*                     IMPORT THE RUNTIME PARAMETERS                  */
/**********************************************************************/
LONG Import_RPARMS(file_ptr)
FILE *file_ptr;
{
  char buffer[81];
  char operand[81];
  char sval[20];
  LONG i,done,found,count,ival;
  LONG ierr=0;

  MSG_control(1,"Reading runtime parameters.",0);

  /* Locate runtime parameters portion of ffd file */
  found = FALSE; done = FALSE; /* initialize loop flags   */
  do {
    if (fgets(buffer,80,file_ptr) != NULL) {
      MSG_control(0,buffer,0);
      if (memcmp(buffer,";",1) != 0) {
        count = sscanf(buffer,"%s",operand);
        if (count == 1) {
          for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
          if (strcmp(operand,"RUNTIME_PARAMETERS") == 0) found = TRUE;
    } } }
    else done=TRUE;
  } while ((found==FALSE)&&(done==FALSE));
  if (found==FALSE) {
    MSG_control(1,"WARNING: RUNTIME_PARAMETERS not found...Using defaults.",0);
    return(ierr); }
  else done=FALSE;

  /* Read the run time parameters from the ffd file */
  do {
  if (fgets(buffer,80,file_ptr) != NULL) {
    MSG_control(0,buffer,0);
    if (memcmp(buffer,";",1) != 0) {
      count = sscanf(buffer,"%s",operand);
      if (count==1) {

        for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
        if (strcmp(operand,"PROGRESS_OUTPUT")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.progress=ival;
            else MSG_control(2,"ERROR: Unknown value for progress_output",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"DEBUG_OUTPUT")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.debug=ival;
            else MSG_control(2,"ERROR: Unknown value for debug_output.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"LOG_TO_SCREEN")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.sendtoterm=ival;
            else MSG_control(2,"ERROR: Unknown value for log_to_term.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"LOG_TO_FILE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.sendtolog=ival;
            else MSG_control(2,"ERROR: Unknown value for log_to_file.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"LOGFILE_MAXRECS")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_POSINT(sval);
            if (ival != -1) LOGFILE.maxrecs=ival;
            else MSG_control(2,"ERROR: logfile_maxrecs must be +Integer.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"AUTONAMING_CASE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.autocase=ival;
            else MSG_control(2,"ERROR: Unknown value for autonaming case.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0); 
        }
        else if (strcmp(operand,"AUTONAMING_STYLE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            ival=Validate_BOOLEAN(sval);
            if (ival != -1) RPARMS.autostyle=ival;
            else MSG_control(2,"ERROR: Unknown value for autonaming style.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"END_RUNTIME_PARAMETERS")==0) done=TRUE;
        else MSG_control(2,"ERROR: Unknown runtime parameter encountered.",0);
  } } }
  else done=TRUE;
  } while (done == FALSE);
  return (ierr);
}

/**********************************************************************/
/*                  IMPORT THE INPUT FILE DESCRIPTION                 */
/**********************************************************************/
LONG Import_INFILE(file_ptr)
FILE *file_ptr;
{
  char buffer[81];
  char operand[81];
  char sval[20];
  LONG i,done,found,count,ival;
  LONG ierr=0;

  MSG_control(1,"Reading infile description...",0);

  /* Locate input file description portion of ffd file */
  found = FALSE; done = FALSE; /* initialize loop flags   */
  do {
    if (fgets(buffer,80,file_ptr) != NULL) {
      MSG_control(0,buffer,0);
      if (memcmp(buffer,";",1) != 0) {
        count = sscanf(buffer,"%s",operand);
        if (count==1) {
          for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
          if (strcmp(operand,"INFILE_DESCRIPTION") == 0) found = TRUE;
    } } }
    else done=TRUE;
  } while ((found==FALSE)&&(done==FALSE));
  if (found==FALSE) {
    MSG_control(1,"WARNING: INFILE_DESCRIPTION  not found...Using defaults.",0);
    return(ierr); }
  else done=FALSE;

  /* Read the input file description from the ffd file */
  do {
  if (fgets(buffer,80,file_ptr) != NULL) {
    MSG_control(0,buffer,0);
    if (memcmp(buffer,";",1) != 0) {
      count = sscanf(buffer,"%s",operand);
      if (count==1) {
        for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
        if (strcmp(operand,"FORMAT")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            for (i=0;i<strlen(sval);i++) sval[i]=toupper(sval[i]);
            if (strcmp(sval,"FREEFORM")==0) INFILE.format=0;
            else if (strcmp(sval,"FORMATTED")==0) INFILE.format=1;
            else {
             MSG_control(2,"ERROR: Unknown format value. Default: FREEFORM",0);
             INFILE.format=0;
            }
          }
          else {
           MSG_control(1,"WARNING: Missing value for format. Use FREEFORM",0);
           INFILE.format=0;
          }
        }
        else if (strcmp(operand,"DATA_TYPE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            for (i=0;i<strlen(sval);i++) sval[i]=toupper(sval[i]);
            if (strcmp(sval,"TEXT")==0) INFILE.dtype=0;
            else if (strcmp(sval,"BINARY")==0) {
              if (INFILE.format==0) 
                MSG_control(2,"ERROR: Freeform datasets MUST be TEXT",0);
            else INFILE.dtype=1; }
            else {
              MSG_control(2,"ERROR: Unknown value for data_type. Default: TEXT",0);
              INFILE.dtype=0;  /* sets default */
            }
          }
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"TEXT_TYPE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            for (i=0;i<strlen(sval);i++) sval[i]=toupper(sval[i]);
            if (strcmp(sval,"ASCII")==0) INFILE.ttype=0;
            else if (strcmp(sval,"EBCDIC")==0) INFILE.ttype=1;
            else {
              MSG_control(2,"ERROR: Unknown value for text_type. Default: ASCII",0);
              INFILE.ttype=0;
            }
          }
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"BINARY_TYPE")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
          for (i=0;i<strlen(sval);i++) sval[i]=toupper(sval[i]);
          if (strcmp(sval,"VAX")==0) INFILE.btype=VAX_ENCODING;
          else if (strcmp(sval,"ALPHAVMSD")==0) INFILE.btype=ALPHAVMSd_ENCODING;
          else if (strcmp(sval,"ALPHAVMSG")==0) INFILE.btype=ALPHAVMSg_ENCODING;
          else if (strcmp(sval,"SUN")==0) INFILE.btype=SUN_ENCODING;
          else if (strcmp(sval,"SGI")==0) INFILE.btype=SGi_ENCODING;
          else if (strcmp(sval,"DECSTATION")==0) 
                                INFILE.btype=DECSTATION_ENCODING;
          else if (strcmp(sval,"ALPHAOSF1")==0) INFILE.btype=ALPHAOSF1_ENCODING;
          else if (strcmp(sval,"IBMRS")==0) INFILE.btype=IBMRS_ENCODING;
          else if (strcmp(sval,"IBMPC")==0) INFILE.btype=IBMPC_ENCODING;
          else if (strcmp(sval,"HP")==0) INFILE.btype=HP_ENCODING;
          else if (strcmp(sval,"NEXT")==0) INFILE.btype=NeXT_ENCODING;
          else if (strcmp(sval,"MAC")==0) INFILE.btype=MAC_ENCODING;
          else MSG_control(2,"ERROR: Unknown value for binary_type.",0);}
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"DELIMITER")==0) {
          count=sscanf(buffer,"%s %s",operand,sval);
          if (count==2) {
            if (strcmp(sval,"blank")==0) INFILE.delimiter=' ';
            else if (strcmp(sval,"BLANK")==0) INFILE.delimiter=' ';
            else INFILE.delimiter=sval[0]; }
          else MSG_control(1,"WARNING: Missing value for operand.",0);
        }
        else if (strcmp(operand,"END_INFILE_DESCRIPTION")==0) done=TRUE;
        else MSG_control(2,"ERROR: Unknown infile parameter encountered.",0);
  } } }
  else done=TRUE;
  } while (done == FALSE);
  return (ierr);
}

/**********************************************************************/
/*                     IMPORT THE EPOCH PARAMETERS                    */
/**********************************************************************/
LONG Import_EpALG(file_ptr)
FILE *file_ptr;
{
  char buffer[81];
  char operand[81];
  char sval[9][20];
  LONG i,done,found,count,ival;
  LONG ierr=0;

  MSG_control(1,"Reading Epoch description...",0);

  /* Locate epoch parameters portion of ffd file */
  found = FALSE; done = FALSE; /* initialize loop flags   */
  do {
    if (fgets(buffer,80,file_ptr) != NULL) {
      MSG_control(0,buffer,0);
      if (memcmp(buffer,";",1) != 0) {
        count = sscanf(buffer,"%s",operand);
        if (count==1) {
          for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
          if (strcmp(operand,"EPOCH_DESCRIPTION") == 0) found = TRUE;
    } } }
    else done=TRUE;
  } while ((found==FALSE)&&(done==FALSE));
  if (found==FALSE) {
    MSG_control(2,"ERROR: EPOCH_DESCRIPTION not found...NO defaults.",0);
    ierr = -1; return(ierr); }
  else done=FALSE;

  /* Read the epoch description parameters from the ffd file */
  do {
  if (fgets(buffer,80,file_ptr) != NULL) {
    MSG_control(0,buffer,0);
    if (memcmp(buffer,";",1) != 0) {
      count = sscanf(buffer,"%s",operand);
      if (count==1) {
        for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
        if (strcmp(operand,"ALGORITHM")==0) {
          count=sscanf(buffer,"%s %s",operand,sval[0]);
          if (count==2) {
            ival=Validate_POSINT(sval[0]);
            if (ival != -1) EpALG.algorithm=ival;
            else {
              MSG_control(2,"ERROR: Unknown value for Epoch algorithm.",0);
              done=TRUE; ierr = -1;
          } }
          else MSG_control(2,"ERROR: Missing value for Epoch algorithm.",0);
        }
        else if (strcmp(operand,"OPERANDS")==0) {
          count=sscanf(buffer,"%s %s %s %s %s %s %s %s %s %s %s",operand,
                       sval[0],sval[1],sval[2],sval[3],sval[4],
                       sval[5],sval[6],sval[7],sval[8],sval[9]);
          if (count==11) {
            for (i=0;i<10;i++) {
              ival=Validate_POSINT(sval[i]);
              if (ival != -1) EpALG.operand[i]=ival;
              else {
                MSG_control(2,"ERROR: Invalid value found in Epoch operands",0);
                done=TRUE; ierr = -1;
          } } }
          else MSG_control(2,"ERROR: Incorrect number of Epoch operands.",0);
        }
        else if (strcmp(operand,"END_EPOCH_DESCRIPTION")==0) done=TRUE;
        else MSG_control(2,"ERROR: Unknown EPOCH parameter encountered.",0);
  } } }
  else done=TRUE;
  } while (done == FALSE);

  /* Because variable numbers in the ffd file use base 1 but C is */
  /* base 0, subtract one from any operand which represends a var# */
  switch (EpALG.algorithm) {
  case 0 : for(i=0;i<10;i++) EpALG.operand[i]=EpALG.operand[i]-1; break;
  case 1 : EpALG.operand[0] = EpALG.operand[0] - 1; break;
  case 2 : EpALG.operand[0] = EpALG.operand[0] - 1; break;
  case 3 : EpALG.operand[0] = EpALG.operand[0] - 1; break;
  case 4 : EpALG.operand[0] = EpALG.operand[0] - 1; break;
  case 5 : EpALG.operand[7] = EpALG.operand[7] - 1; break;
  case 6 : for(i=0;i<8;i++) EpALG.operand[i]=EpALG.operand[i]-1; break;
  case 7 : EpALG.operand[7] = EpALG.operand[7]-1;
  case 8 : for(i=0;i<10;i++) EpALG.operand[i]=EpALG.operand[i]-1; break;
  case 9 : for(i=0;i<10;i++) EpALG.operand[i]=EpALG.operand[i]-1; break;
  }
  return (ierr);
}

/**********************************************************************/
/*                     IMPORT THE VARIABLES                           */
/**********************************************************************/
LONG Import_Variables(file_ptr)
FILE *file_ptr;
{
  char buffer[133];
  char operand[81];
  char sval[16][20];
  char instring[80];
  char vname1[40];
  char vname2[40];
  char cform[10];
  double dfill;
  LONG i,done,found,count,ielem1,ielem2,ival,ilength,icdftype;
  LONG isize,ieperr,imaj,icon,ieol,ihead,ifill,ibsub,iesub,inrep,idelta;
  LONG iavx,iasx,iafx,iafil;
  LONG ierr=0;
  LONG ndims,dim_sizes[3];

  MSG_control(1,"Reading Variable descriptions...",0);

  /* Locate epoch parameters portion of ffd file */
  found = FALSE; done = FALSE; /* initialize loop flags   */
  do {
    if (fgets(buffer,132,file_ptr) != NULL) {
      MSG_control(0,buffer,0);
      if (memcmp(buffer,";",1) != 0) {
        count = sscanf(buffer,"%s",operand);
        if (count==1) {
          for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
          if (strcmp(operand,"VARIABLE_DESCRIPTIONS") == 0) found = TRUE;
    } } }
    else done=TRUE;
  } while ((found==FALSE)&&(done==FALSE));
  if (found==FALSE) {
    MSG_control(2,"ERROR: VARIABLE_DESCRIPTIONS not found...NO defaults.",0);
    ierr = -1; return(ierr); }
  else done=FALSE;

  /* Read the epoch description parameters from the ffd file */
  do {
  if (fgets(buffer,132,file_ptr) != NULL) {
    MSG_control(0,buffer,0);
    if (memcmp(buffer,";",1) != 0) {
      count = sscanf(buffer,"%s",operand);
      if (count==1) {
       for (i=0;i<strlen(operand);i++) operand[i]=toupper(operand[i]);
       if (strcmp(operand,"END_VARIABLE_DESCRIPTIONS")==0) done=TRUE;
       else {
       count=sscanf(buffer,"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
                    instring,sval[0],sval[1],sval[2],sval[3],sval[4],sval[5],
                    sval[6],sval[7],sval[8],sval[9],sval[10],sval[11],sval[12],
                    sval[13],sval[14],sval[15]);
          if (count==17) {
	    /* This routine was added to handle the multiple dimension possibility in the size field */
	    isize = Validate_SIZE(sval[0], &ndims, dim_sizes); if (isize==0) isize=1;
	    if (isize == -1) return(isize);
	    /* This doesn't handle multiple dimensions in the size field
            isize =Validate_POSINT(sval[0]); if (isize==0)  isize=1; */
            ival  =Validate_FORMAT(sval[1],cform,&ilength,&icdftype);
            ihead =Validate_BOOLEAN(sval[2]);
	    /*            ieol  =Validate_BOOLEAN(sval[3]); */
            ieol  =Validate_EOL(sval[3]);
            ibsub =Validate_POSINT(sval[4]);
            iesub =Validate_POSINT(sval[5]);
            inrep =Validate_POSINT(sval[6]);
            idelta=Validate_POSINT(sval[7]);
            ieperr=Validate_POSINT(sval[8]);
            if (ieperr == 0)  ieperr = 1;     /* correct to default of 1 */
            if (ieperr == -1) ieperr = isize; /* illegal same as flat */
            imaj  =Validate_POSINT(sval[9]);
            icon  =Validate_BOOLEAN(sval[10]);
            iavx  =Validate_BOOLEAN(sval[11]);
            iasx  =Validate_BOOLEAN(sval[12]);
            iafx  =Validate_BOOLEAN(sval[13]);
            iafil =Validate_BOOLEAN(sval[14]);
            dfill =Validate_FILLVAL(sval[15],icdftype);
            ierr  =Separate_Varnames(instring,vname1,vname2,&ielem1,&ielem2);
            if (ierr != 0) done=TRUE;
            /* allocate another VLIST element */
            VLISTne++;
            VLIST=  realloc(VLIST,(sizeof(VLISTz)*VLISTne));
/* make vname and cdfvname fixed length and try again
            VLIST[VLISTne-1].vname = (char*)malloc(sizeof(strlen(vname1)+1));
            VLIST[VLISTne-1].cdfvname = (char*)malloc(sizeof(strlen(vname2)+1));
*/
            strcpy(VLIST[VLISTne-1].vname,vname1);
            strcpy(VLIST[VLISTne-1].cdfvname,vname2);
            strcpy(VLIST[VLISTne-1].format,cform);
            if (isize <= 1) {
                   VLIST[VLISTne-1].ndims=0;
                   VLIST[VLISTne-1].nelems=1;
            }
            /* New method using Validate_SIZE to handle multiple dimensions in the size field */
            else { VLIST[VLISTne-1].ndims=ndims;
	           for (i=0; i<ndims; i++) 
		     VLIST[VLISTne-1].dims[i]= dim_sizes[i];
                   VLIST[VLISTne-1].nelems = isize;
            }
	    /* Old
            else { VLIST[VLISTne-1].ndims=1;
                   VLIST[VLISTne-1].dims[0]= isize;
                   VLIST[VLISTne-1].nelems = isize;
            }*/
            VLIST[VLISTne-1].Elem[0]    = ielem1;
            VLIST[VLISTne-1].Elem[1]    = ielem2;
            VLIST[VLISTne-1].length     = ilength;
            VLIST[VLISTne-1].cdfvartype = icdftype;
            VLIST[VLISTne-1].eperr      = ieperr;
            VLIST[VLISTne-1].majority   = imaj;
            VLIST[VLISTne-1].constant   = icon;
            VLIST[VLISTne-1].header     = ihead;
            VLIST[VLISTne-1].eol        = ieol;
            VLIST[VLISTne-1].bsubr      = ibsub;
            VLIST[VLISTne-1].esubr      = iesub;
            VLIST[VLISTne-1].autovalids = iavx;
            VLIST[VLISTne-1].autoscales = iasx;
            VLIST[VLISTne-1].autoformat = iafx;
            VLIST[VLISTne-1].autofill   = iafil;
            VLIST[VLISTne-1].fillval    = dfill;
            /* add new subrecord if needed */
            if ((LONG)ibsub >= SRECSne+1) {
              MSG_control(0,"Adding new subrecord",0);
              SRECSne++;
              SRECS= realloc(SRECS,( sizeof(SRECSz)*SRECSne));
              SRECS[SRECSne-1].nreps  = inrep;
              SRECS[SRECSne-1].delta  = (double)idelta;
              SRECS[SRECSne-1].countr = 0;
  } } } } } }
  else done=TRUE;
  } while (done == FALSE);
  /* >>>>>Commented out this line now handles GME data <<<<< */
  /*VLIST[VLISTne-1].eol=1;  last variable always has EOL flag */
  return (ierr);
}

/**********************************************************************/
/*                      PREVIEW THE DESCRIPTION FILE                   */
/**********************************************************************/
LONG Preview_FFD()
{
  FILE *file_ptr;
  LONG ierr=0;

  /* open file which contains the description of input data file */
  file_ptr = fopen(RPARMS.ffdfname,"r");
  if (file_ptr == NULL) {
     fclose(file_ptr); ierr=1; return(ierr);
  }
  ierr = Preview_RPARMS(file_ptr);
  fclose(file_ptr);
  return (ierr);
}
/**********************************************************************/
/*                      IMPORT THE DESCRIPTION FILE                   */
/**********************************************************************/
LONG Import_FFD()
{
  FILE *file_ptr;
  LONG ierr=0;

  /* open file which contains the description of input data file */
  file_ptr = fopen(RPARMS.ffdfname,"r");
  if (file_ptr == NULL) {
    MSG_control(2,"ERROR: Unable to open input description file",0);
    MSG_control(2,"       Translation Aborted.",0);
    ierr=1; return(ierr);
  }

  ierr = Import_RPARMS(file_ptr);
  if (ierr == 0) {
    ierr = Import_INFILE(file_ptr);
    if (ierr == 0) {
      ierr = Import_EpALG(file_ptr);
      if (ierr == 0) {
        ierr = Import_Variables(file_ptr);
  } } }

  MSG_control(1,"Translation file input completed.",0); MSG_control(1," ",0);
  fclose(file_ptr);
  return (ierr);
}

/**********************************************************************/
/*                  DETERMINE SUBRECORD BOUNDARIES                    */
/**********************************************************************/
LONG SREC_Bounds(subrecno, firstvar, lastvar)
LONG subrecno;
LONG *firstvar;
LONG *lastvar;
{
  LONG i,j;
  LONG ierr=0;

  j= subrecno + 1;
  for (i=0;i<VLISTne;i++) if (VLIST[i].bsubr == j) *firstvar = i;
  for (i=0;i<VLISTne;i++) if (VLIST[i].esubr == j) *lastvar  = i;

/*
  if (subrecno == 0) {
    *firstvar = 0;
    *lastvar = VLISTne-1; }
  else {
    for (i=0;i<VLISTne;i++) if (VLIST[i].bsubr == subrecno) *firstvar = i;
    for (i=0;i<VLISTne;i++) if (VLIST[i].esubr == subrecno) *lastvar  = i;
  }
*/

  return(ierr);
}

/**********************************************************************/
/*             BUILD THE ORDERED LIST OF VARIABLES TO READ            */
/**********************************************************************/
LONG Build_OLIST()
{
  LONG g,h,i,j,k,l,m,n,iflag,rflag,pflag,past_headers,done,addeol;
  LONG ierr=0;
  LONG *ecount, *rcount;

  MSG_control(1,"Contructing the Ordered List for data stream input...",0);
  past_headers = FALSE;
  for (i=0;i<SRECSne;i++) {
    for (j=0;j<SRECS[i].nreps;j++) {
      iflag=SREC_Bounds(i,&n,&m); /* find first and last var in subrec i */
      ecount = (long*)calloc((size_t)m+1,sizeof(LONG));
      rcount = (long*)calloc((size_t)m+1,sizeof(LONG));
      for (h=n;h<=m;h++) {
        ecount[h]=VLIST[h].nelems;
        rcount[h]=ecount[h];
      }

      done = FALSE;
      while (done == FALSE) {
        done = TRUE;
        for (k=n;k<=m;k++) { /* process each variable in subrecord */
          for (l=0;l<VLIST[k].eperr;l++) { /* process each element */
            rflag = TRUE;                  /* initialize read flag */
            if (VLIST[k].header == FALSE) past_headers = TRUE;
            if ((VLIST[k].header == TRUE)&&(past_headers == TRUE)) rflag=FALSE;
            if (ecount[k] > 0) {           /* elements still to be processed */
              pflag = TRUE;                /* process the element */
              ecount[k] = ecount[k]-1;     /* adjust the element counter */
            }
            else {                         /* element count reached */
              pflag = FALSE;               /* no new element to process */
              if (VLIST[k].eol != FALSE) rflag=FALSE; /* no element to read */
            }
            if (VLIST[k].length == 0) rflag=FALSE;   /* no element to read */

            /* add new element to the ordered list */
            OLISTne++;
            OLIST= realloc(OLIST,(sizeof(OLISTz)*OLISTne));
            OLIST[OLISTne-1].vnum  = k;
            OLIST[OLISTne-1].velem = rcount[k]-ecount[k]-1;
            OLIST[OLISTne-1].rflag = rflag;
            OLIST[OLISTne-1].pflag = pflag;
          }
          /* determine if eol should be added to olist */
          addeol = FALSE;
          if (VLIST[k].eol == TRUE) addeol = TRUE; /* check rflag? */
	  if (VLIST[k].eol == AT_LAST_SUBCYCLE) {
/*
   There should be eol but only at the last subcycle
*/           
	    if (j == SRECS[i].nreps-1) addeol = TRUE;

	  } else if ((k == (VLISTne-1))&&(ecount[k] == 0)) 
	       addeol = TRUE;

	  if (addeol == TRUE) {  /* add eol read to olist */
            OLISTne++;
            OLIST =  realloc(OLIST,(sizeof(OLISTz)*OLISTne));
            OLIST[OLISTne-1].vnum  = -1;
            OLIST[OLISTne-1].velem = 0;
            OLIST[OLISTne-1].rflag = TRUE;
            OLIST[OLISTne-1].pflag = FALSE;
          }
          if (ecount[k] > 0) done = FALSE;
        }
      }
      free(ecount); free(rcount);
    }
  }
  /* ordered list construction is complete.*/
  if (RPARMS.progress == TRUE) {
    MSG_control(1,"Ordered List construction completed.",0);
  }
  if (RPARMS.debug == TRUE) {
    MSG_control(0,"------ ORDERED LIST -----",0);
    MSG_control(0,"   v#    e# r p ",0);
    g=OLISTne-1;
    if (g > 200) { 
      MSG_control(0,"WARNING: Only showing first 200 OLIST elements",0);
      g = 200;
    }
    for (i=0;i<=g;i++) {
      sprintf(LOGFILE.message,"%5d %5d %d %d \n",
              OLIST[i].vnum,OLIST[i].velem,OLIST[i].rflag,OLIST[i].pflag);
      MSG_control(0,LOGFILE.message,0);
    }
  }
  return(ierr);
}

/**********************************************************************/
/*      DETERMINE IF INPUT CDF IS IN FORM OF CDF OR SKELETON TABLE    */
/**********************************************************************/
LONG inCDFform (filename)
char *filename;
{
  char suffix[5] = "";
  LONG length,i,j;
  LONG iform = 0;

  length=(LONG)strlen(filename);
  if (length >= 4) {
    for (i=0,j=length-4;i<4;i++,j++) suffix[i]=toupper(filename[j]);
    suffix[4]='\0';
    if (strcmp(suffix,".CDF")==0) iform=1;
    else if (strcmp(suffix,".SKT")==0) iform=2;
  }
  if (iform==0) {
    MSG_control(2,"ERROR: Cannot determine if the input CDF is in the form",0);
    MSG_control(2,"       of a CDF or a skeleton table because of a missing",0);
    MSG_control(2,"       or unrecognized file extension.  Recognized file ",0);
    MSG_control(2,"       extensions are .cdf and .skt.",0);
  }
  return(iform);
}

/**********************************************************************/
/*      GENERATE CDF SKELETON TO BE POPULATED WITH INPUT DATA         */
/**********************************************************************/
LONG Generate_CDFskeleton()
{
   LONG iform,eNum,numrecs,allswell;
   LONG ierr=0;
   char tempname[80];
   char command[120];
   struct stat fs;
   CDFid id;
   CDFstatus status;

   iform = inCDFform(RPARMS.incdfname);
   if (iform == 2) { /* input cdf description is a skeleton table */
       StripName(RPARMS.incdfname,tempname);
       StripName(RPARMS.outcdfname,RPARMS.outcdfname);

#if defined (vms)
       if (fopen("auto.cdf","r") != NULL) {
	 strcpy(command,"DELETE auto.cdf;*");
	 allswell = system(command);
       }
       strcpy(command," skeletoncdf /DELETE");
       strcat(command,"/CDF=");
#else
#if defined (unix)
       if (fopen("auto.cdf","r") != NULL) {
	 strcpy(command,"rm auto.cdf");
	 allswell = system(command);
       }
       strcpy(command,"$CDF_BIN/skeletoncdf ");
       strcat(command,"-cdf ");
#endif
#endif
       strcat(command,RPARMS.outcdfname); strcat(command," ");
       strcat(command,tempname); strcat(command,"");
       MSG_control(1,"Creating empty CDF from skeleton table...",0);
       MSG_control(1,command,0);
       allswell=system(command);
       if (allswell != SYS_OK) {
	   MSG_control(2,"ERROR: During creation of cdf from skeleton table",0);
	   ierr=1;
       } 
   }
   else if (iform == 1) { /* input cdf description is a CDF */
     /* Determine the number of records in the CDF */
     MSG_control(1,"Opening input CDF to determine empty or full...",0);
     allswell=FALSE;
     StripName(RPARMS.incdfname,tempname);
     StripName(RPARMS.outcdfname,RPARMS.outcdfname);
     status = CDFlib(OPEN_,CDF_,tempname,&id,NULL_);
     if (status < CDF_WARN) MSG_control(2,"CDFERROR:",status); /* "=" removed 9/00 */
     else {
       MSG_control(0,"Getting the variable number of Epoch...",0);
       status = CDFlib(SELECT_, CDF_, id,
                       GET_,zVAR_NUMBER_,"Epoch",&eNum,NULL_);
       if (status != CDF_OK) MSG_control(2,"CDFERROR:",status);
       else {
         MSG_control(0,"Getting the number of records for Epoch...",0);
         status = CDFlib(SELECT_, CDF_, id,
                                  zVAR_, eNum,
                         GET_, zVARs_MAXREC_, &numrecs, NULL_);
         if (status != CDF_OK) MSG_control(2,"CDFERROR:",status);
         else { 
           MSG_control(0,"Closing the input CDF...",0);
           status = CDFlib(CLOSE_, CDF_, NULL_);
           if (status != CDF_OK) MSG_control(2,"CDFERROR:",status);
           else allswell=TRUE;
     } } }

     if (allswell==TRUE) {
       if (numrecs == -1) { /* cdf is empty */
#if defined (vms)
         strcpy(command,"copy ");
#else
#if defined (unix)
         strcpy(command,"cp ");
#endif
#endif
	 /* was         strcat(command,tempname) ;*/
	 /* Need to use the cdfname with extension to make copy */
         strcat(command,RPARMS.incdfname);
	 strcat(command," ");
         strcat(command,RPARMS.outcdfname); 
	 strcat (command,".cdf") ; /*HAL added need extension so later rename will work */
	 strcat(command,"");
         MSG_control(1,"Creating copy of empty cdf...",0);
         MSG_control(0,command,0);
         allswell=system(command);
         if (allswell != SYS_OK) {
           MSG_control(2,"ERROR: During creation of copy of empty cdf.",0);
           ierr=1;
       } }
       else { /* cdf is not empty */
#if defined (vms)
         strcpy(command,"skeletontable ");
#else 
#if defined (unix)
	 strcpy(command,"$CDF_BIN/skeletontable ");
#endif
#endif
         strcat(command,tempname); strcat(command," ");
         MSG_control(1,"Creating skeleton table from non-empty CDF...",0);
         MSG_control(1,command,0);
         allswell=system(command);
         if (allswell != SYS_OK) {
           MSG_control(2,"ERROR: During creation of skeleton table.",0);
           ierr=1; }
         else {
#if defined (vms)
           strcpy(command,"skeletoncdf /CDF=");
	   printf("***Only in VMS****\n");
#else 
#if defined (unix)
           strcpy(command, "$CDF_BIN/skeletoncdf  -cdf ");
#endif
#endif
           strcat(command,RPARMS.outcdfname); strcat(command," ");
           strcat(command,tempname);  strcat(command,"");
           MSG_control(1,"Creating cdf from skeleton table",0);
           MSG_control(0,command,0);
           allswell=system(command);
           if (allswell != SYS_OK) {
             MSG_control(2,"ERROR: During creation of cdf.",0);
             ierr=1;
     } } } }
     else ierr=1;
   }
   else {
     MSG_control(2,RPARMS.incdfname,0);
     MSG_control(2,"ERROR: Missing or unknown file extension.",0);
     MSG_control(2,"       Cannot determine form of input cdf description.",0);
     ierr=1;
   }
   return(ierr);
}

/**********************************************************************/
/*            Determine CDF var#'s for input variables                */
/**********************************************************************/
LONG Match_Variables()
{
  CDFstatus status;
  char vname[40];
  LONG i,itype,isize;
  LONG ierr=0;

  MSG_control(1,"Matching input variables to output CDF vars...",0);
  status = CDFlib(OPEN_,CDF_,RPARMS.outcdfname,&OUTCDF.outCDFid,
                  SELECT_, CDF_zMODE_, zMODEon2, NULL_);
  if (status < CDF_WARN) {   /* "=" removed 9/00 */
    MSG_control(2,"CDFERROR:",status);
    ierr=1; return(ierr);
  }

  for (i=0;i<VLISTne;i++) {
    strcpy(vname,VLIST[i].vname);
    if (strlen(VLIST[i].cdfvname) != 0) strcpy(vname,VLIST[i].cdfvname);
    status = CDFlib(GET_,zVAR_NUMBER_,vname,&VLIST[i].cdfvarnum,NULL_);
    if (status != CDF_OK) {
      VLIST[i].cdfvarnum  = -1;
      strcpy(LOGFILE.message,"WARNING: the input variable '");
      strcat(LOGFILE.message,VLIST[i].vname);
      strcat(LOGFILE.message,"' does not exist in output CDF.");
      MSG_control(0,LOGFILE.message,0); }
    else { /* variable is found, get varnum and vartype */
      status = CDFlib(SELECT_,zVAR_,VLIST[i].cdfvarnum,
                      GET_,zVAR_DATATYPE_,&VLIST[i].cdfvartype,NULL_);
      if (status != CDF_OK) MSG_control(2,"CDFERROR:",status);
      else {
        /* determine type & byte-size of the data space to be allocated */
        itype = VLIST[i].cdfvartype;
        if ((itype==CDF_INT1)||(itype==CDF_UINT1)||(itype==CDF_BYTE)) isize=1;
        else if ((itype==CDF_CHAR) ||(itype==CDF_UCHAR))  isize=1;
        else if ((itype==CDF_INT2) ||(itype==CDF_UINT2))  isize=2;
        else if ((itype==CDF_INT4) ||(itype==CDF_UINT4))  isize=4;
        else if ((itype==CDF_REAL4)||(itype==CDF_FLOAT))  isize=4;
        else if ((itype==CDF_REAL8)||(itype==CDF_DOUBLE)) isize=8;
        else if (itype==CDF_EPOCH) isize=8;
        else { 
          MSG_control(2,"ERROR: Unknown CDF datatype encountered during ",0);
          MSG_control(2,"       Buffer and space allocation ... ",0);
          ierr=1; return(ierr);
        }
        /* allocate another CLIST element */
        CLISTne++;
        CLIST=realloc(CLIST,(sizeof(CLISTz)*CLISTne));
        CLIST[CLISTne-1].flagone = 0L;             /* initialize flag   */
        CLIST[CLISTne-1].ccount  = 0L;             /* initialize countr */
        CLIST[CLISTne-1].vmin = calloc(1L,isize);  /* space for min     */
        CLIST[CLISTne-1].vmax = calloc(1L,isize);  /* space for max     */
        VLIST[i].clistnum = CLISTne-1;             /* link to VLIST     */
      }
    }
  }

  status = CDFlib(GET_,zVAR_NUMBER_,"Epoch",&EpALG.Epvarnum,NULL_);
  if (status != CDF_OK) {
    MSG_control(2,"ERROR: CDF does not contain variable named:Epoch",status);
    ierr=1;
  }

  status = CDFlib(CLOSE_,CDF_);
  return(ierr);
}

/**********************************************************************/
/*               Insert 'l' into format because var is DOUBLE         */
/**********************************************************************/
LONG Fix_Format(format, newform)
char *format;
char *newform;
{
  LONG ierr=0;
  while (*format != 'f') *newform++ = *format++;
  *newform++ = 'l';
  while (*format != '\0') *newform++ = *format++;
  *newform = '\0';
  return (ierr);
}

/**********************************************************************/
/*               Allocate Buffer Space for Variables                  */
/**********************************************************************/
LONG Allocate_Buffers()
{
  LONG i,j,ecount,itype,isize,Last_True_Var;
  char newform[15]="";
  LONG ierr=0;

  for (i=0;i<VLISTne;i++) {
    /* allocate character buffer space */
    VLIST[i].buffer = (char *) malloc(VLIST[i].length+1);
    if (VLIST[i].buffer == NULL) {
      strcpy(LOGFILE.message,"ERROR: Unable to allocate data space for '");
      strcat(LOGFILE.message,VLIST[i].vname);
      strcat(LOGFILE.message,"' variable.  Unable to continue.");
      MSG_control(2,LOGFILE.message,0);
      ierr=1; return(ierr);
    }

    /* allocate data buffer space */
    ecount=VLIST[i].nelems;
    itype = VLIST[i].cdfvartype;
    if ((itype==CDF_INT1)||(itype==CDF_UINT1)||(itype==CDF_BYTE)) isize=1;
    else if ((itype==CDF_CHAR) ||(itype==CDF_UCHAR))  isize=1;
    else if ((itype==CDF_INT2) ||(itype==CDF_UINT2))  isize=2;
    else if ((itype==CDF_INT4) ||(itype==CDF_UINT4))  isize=4;
    else if ((itype==CDF_REAL4)||(itype==CDF_FLOAT))  isize=4;
    else if ((itype==CDF_REAL8)||(itype==CDF_DOUBLE)) isize=8;
    else if (itype==CDF_EPOCH) isize=8;
    else { 
      MSG_control(2,"ERROR: Unknown CDF datatype encountered during ",0);
      MSG_control(2,"       Buffer and space allocation ... ",0);
      ierr=1; return(ierr);
    }
    /* allocate the data space */
    if (VLIST[i].length != 0) { /* normal allocation */
      VLIST[i].dataptr = calloc((ecount+1), isize);
      Last_True_Var = i;
    }
    else { /* special case: input variable is in > 1 cdf variable */
      VLIST[i].dataptr = VLIST[Last_True_Var].dataptr;
    }
    /* test allocation results */
    if (VLIST[i].dataptr == NULL) {
      strcpy(LOGFILE.message,"ERROR: Unable to allocate data space for '");
      strcat(LOGFILE.message,VLIST[i].vname);
      strcat(LOGFILE.message,"' variable.  Unable to continue.");
      MSG_control(2,LOGFILE.message,0);
      ierr=1; return(ierr);
    }
    if (isize == 8) {
      ierr=Fix_Format(VLIST[i].format,newform);
      strcpy(VLIST[i].format,newform);
    }
  }
  return(ierr);
}

/**********************************************************************/
/*        Determine Size of Largest Input record in bytes             */
/**********************************************************************/
LONG Determine_Bufsize()
{
  LONG ibufsize=0;
  LONG imaxsize=0;
  LONG i,ilength,ipad;

  /* Determine the size of the input buffer by summing the lengths of */
  /* all elements of the OLIST, which are bounded by EOL markers.     */
  for (i=0;i<OLISTne-1;i++) {
    if (OLIST[i].vnum == -1) { /* EOL marker found */
/*hkh mod 7/00  if (ibufsize > imaxsize) {imaxsize = ibufsize; ibufsize = 0;}*/
      if (ibufsize > imaxsize) {imaxsize = ibufsize;}
      ibufsize = 0;
    }
    else {
      if (OLIST[i].rflag == TRUE) { /* only count bytes for readable data */
        ilength = VLIST[(OLIST[i].vnum)].length;
        ipad=0; if (INFILE.format == 0) ipad=1; /* pad if freeform */
        ibufsize= ibufsize + ilength + ipad;
      }
    }
  }
  if (INFILE.dtype == 0) ibufsize=ibufsize+2; /* bump up for text EOL */
  if (ibufsize > imaxsize) imaxsize = ibufsize;
  return(imaxsize);
}

/**********************************************************************/
/*        Read the next record from the input data file               */
/**********************************************************************/
/*
Return 0 = EOF found w/ no data in records
Return 1 = Data record, EOF is possible
*/
int Read_Infile()
     
{
  size_t nbytes;
  if (INFILE.dtype == 0) { /* input data file is text */
    INFILE.bptr = INFILE.buffer;
    INFILE.buffer[0] = '\0';
    INFILE.recnum = INFILE.recnum + 1;
    fgets(INFILE.buffer,INFILE.buflen,INFILE.fptr);
    sprintf(LOGFILE.message,
       "rec:%d length:%d max:%d eof:%d ASCII\n",
       INFILE.recnum,strlen(INFILE.buffer),INFILE.buflen,feof(INFILE.fptr));
    MSG_control(0,LOGFILE.message,0); 
    MSG_control(0,INFILE.buffer,0); 
    if (feof(INFILE.fptr) && strlen(INFILE.buffer) == 0)return 0;
  }
  else {
    INFILE.buflen = Determine_Bufsize();
    INFILE.bptr = INFILE.buffer;
    INFILE.recnum = INFILE.recnum + 1;
    nbytes=fread(INFILE.buffer,INFILE.buflen,1,INFILE.fptr); 
    sprintf(LOGFILE.message,
       "rec:%d length:%d max:%d eof:%d BINARY\n",INFILE.recnum,nbytes,
       INFILE.buflen,feof(INFILE.fptr));
    MSG_control(0,LOGFILE.message,0); 
    if (feof(INFILE.fptr))return 0;
  }
return 1;
}


/**********************************************************************/
/*        Open the input file and allocate input buffer space         */
/**********************************************************************/
LONG Open_Infile(ifile)
LONG ifile;
{
  LONG ierr=0;
  LONG ilength=0;
  LONG i;
  int status;

  INFILE.buflen = Determine_Bufsize();
  INFILE.buffer = (char*)malloc(INFILE.buflen);
  INFILE.bptr   = INFILE.buffer;
  if (INFILE.buffer == NULL) {
    MSG_control(2,"ERROR: Unable to allocate input buffer for reading file!",0);
    MSG_control(2,"       Unable to proceed with translation...",0);
    ierr=1; return(ierr);
  }

  /* construct name of next input data file from FLIST */
  strcpy(RPARMS.infname,FLIST[ifile].Pathname);
  strcat(RPARMS.infname,FLIST[ifile].Filename);

  /* output a progress message */
  strcpy(LOGFILE.message,"\nOpening Input File: "); 
  strcat(LOGFILE.message,RPARMS.infname);
  MSG_control(2,LOGFILE.message,0); /* HKH 8/31/00 to make it always appear. */

  /* open the file */
  if (INFILE.dtype == 0) INFILE.fptr = fopen(RPARMS.infname,"r");
  else INFILE.fptr = fopen(RPARMS.infname,"rb");
  if (INFILE.fptr == NULL) {
    MSG_control(2,"ERROR: Unable to open input data file.",0);
    MSG_control(2,"       Unable to proceed with translation...",0);
    ierr=1; return(ierr);
  }
  else INFILE.recnum = 0;

  MSG_control(1,"Reading the input file...",0);
  status =  Read_Infile();
  if ( (LONG)*INFILE.buffer == 10) {
    MSG_control(1,"WARNING: Line Feed encountered at beginning of first",0);
    MSG_control(1,"         record of input file...Reading next record...",0);
    status = Read_Infile();
  }

  return(ierr);
}

/**********************************************************************/
/*     Freeform Scan the given variable from the input buffer         */
/**********************************************************************/
LONG Parser1(vnum,velem)
LONG vnum;
LONG velem;
{
  int  icnt,ccnt,dcnt,icountr;
  INT16 *sptr;
  UINT16 *sptru;
  INT32 *lptr;
  UINT32 *lptru;
  float *fptr;
  double *dptr;
  char *cptr,*bptr,tst[21];
  char form[20],sval[20];
  LONG idone=0;
  LONG icount=0;

  /* Count the number of delimiting characters at current point of inbuffer */
  strncpy(tst,INFILE.bptr,20);
  for (bptr=INFILE.bptr,dcnt=0;*bptr==INFILE.delimiter;dcnt++,bptr++);
  INFILE.bptr = bptr; /* point to first character past delimiters */

  /* set the format argument for the sscanf function */
  strcpy(form,VLIST[vnum].format); strcat(form,"%n");
  /* execute the sscanf function based on data type and update buffer ptr */
  switch (VLIST[vnum].cdfvartype) {
    case CDF_REAL4 : fptr=(float *)VLIST[vnum].dataptr;
                     fptr=fptr+velem;
                     icnt=sscanf(INFILE.bptr,form,fptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_FLOAT : fptr=(float *)VLIST[vnum].dataptr;
                     fptr=fptr+velem;
                     icnt=sscanf(INFILE.bptr,form,fptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_REAL8 : dptr=(double *)VLIST[vnum].dataptr;
                     dptr=dptr+velem;
                     icnt=sscanf(INFILE.bptr,form,dptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_DOUBLE: dptr=(double *)VLIST[vnum].dataptr;
                     dptr=dptr+velem;
                     icnt=sscanf(INFILE.bptr,form,dptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_EPOCH : dptr=(double *)VLIST[vnum].dataptr;
                     dptr=dptr+velem;
                     icnt=sscanf(INFILE.bptr,form,dptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_INT4  : lptr=(INT32 *)VLIST[vnum].dataptr;
                     lptr=lptr+velem;
                     icnt=sscanf(INFILE.bptr,form,lptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_UINT4 : lptru=(UINT32 *)VLIST[vnum].dataptr;
                     lptru=lptru+velem;
                     icnt=sscanf(INFILE.bptr,form,lptru,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_INT2  : sptr=(INT16 *)VLIST[vnum].dataptr;
                     sptr=sptr+velem;
		     strcpy(form,"%hd%n");
                     icnt=sscanf(INFILE.bptr,form,sptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_UINT2 : sptru=(UINT16 *)VLIST[vnum].dataptr;
                     sptru=sptru+velem;
		     strcpy(form,"%hd%n");
                     icnt=sscanf(INFILE.bptr,form,sptru,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
    case CDF_CHAR  : if (VLIST[vnum].eol == FALSE) {
                       icnt=sscanf(INFILE.bptr,form,VLIST[vnum].buffer,&ccnt);
                       INFILE.bptr=INFILE.bptr+ccnt; }
                     else { /* cannot just read using sscanf */
                       while (*INFILE.bptr == INFILE.delimiter) INFILE.bptr++;
                       cptr=(char *)VLIST[vnum].buffer;
                       while (idone == 0) {
                         *cptr++ = *INFILE.bptr++;
                         icount++; if (icount == VLIST[vnum].length) idone=1;
                         if (*INFILE.bptr == '\n') idone=1;
                       }
                       strcat(VLIST[vnum].buffer,"\n"); icnt=1; /* success */
		       ccnt = icount;  /* 7/25/00 added this line because no length was returned */
                     }
                     break;
    case CDF_UCHAR : if (VLIST[vnum].eol == FALSE) {
                       icnt=sscanf(INFILE.bptr,form,VLIST[vnum].buffer,&ccnt);
                       INFILE.bptr=INFILE.bptr+ccnt; }
                     else { /* cannot just read using sscanf */
                       while (*INFILE.bptr == INFILE.delimiter) INFILE.bptr++;
                       cptr=(char *)VLIST[vnum].buffer;
                       while (idone == 0) {
                         *cptr++ = *INFILE.bptr++;
                         icount++; if (icount == VLIST[vnum].length) idone=1;
                         if (*INFILE.bptr == '\n') idone=1;
                       }
                       strcat(VLIST[vnum].buffer,"\n"); icnt=1; /* succcess */
		       ccnt = icount;  /* 7/25/00 added this line because no length was returned */
                     }
                     break;
    default        : cptr=(char *)VLIST[vnum].dataptr;
                     cptr=cptr+velem;
                     icnt=sscanf(INFILE.bptr,form,cptr,&ccnt);
                     INFILE.bptr=INFILE.bptr+ccnt;
                     break;
  }
  if (icnt != 1) { icountr=0;
    sprintf(LOGFILE.message,"WARNING: Input record (%d) does not match expected format, skipping",INFILE.recnum);
    MSG_control(1,LOGFILE.message,0);
    strcpy(LOGFILE.message,"Parser1: Variable: "); 
    strcat(LOGFILE.message,VLIST[vnum].vname);
    strcat(LOGFILE.message,"  Element#");
    sprintf(sval,"%ld",(velem+1)); strcat(LOGFILE.message,sval);
    MSG_control(1,LOGFILE.message,0);


  }
  else {
    icountr = (LONG)ccnt;
    if (VLIST[vnum].ccount < icountr) VLIST[vnum].ccount=icountr;
  }
return(icountr);
}

/**********************************************************************/
/*   Fixedform ASCII Scan the given variable from the input buffer    */
/**********************************************************************/
LONG Parser2(vnum,velem)
LONG vnum;
LONG velem;
{
  int   icnt,ccnt;
  INT16 *sptr;
  UINT16 *sptru;
  INT32 *lptr;
  UINT32 *lptru;
  float *fptr;
  double *dptr;
  char *cptr;
  char form[20];
  char sval[20];
  char slen[10];
  LONG icountr=0;

  /* construct format statement for move from infile buffer to var buffer */
  icnt=sprintf(slen,"%ld",VLIST[vnum].length);
  strcpy(form,"%"); strcat(form,slen); strcat(form,"c%n");

  /* move n-characters from input buffer into the variables buffer */
  icnt=sscanf(INFILE.bptr,form,VLIST[vnum].buffer,&ccnt);
  INFILE.bptr=INFILE.bptr+ccnt;

  /* set the format argument for the sscanf function */
  strcpy(form,VLIST[vnum].format);

  /* convert character data in the variable buffer */
  switch (VLIST[vnum].cdfvartype) {
    case CDF_REAL4 : fptr=(float *)VLIST[vnum].dataptr;
                     fptr=fptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,fptr);
                     break;
    case CDF_FLOAT : fptr=(float *)VLIST[vnum].dataptr;
                     fptr=fptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,fptr);
                     break;
    case CDF_REAL8 : dptr=(double *)VLIST[vnum].dataptr;
                     dptr=dptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,dptr);
                     break;
    case CDF_DOUBLE: dptr=(double *)VLIST[vnum].dataptr;
                     dptr=dptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,dptr);
                     break;
    case CDF_EPOCH : dptr=(double *)VLIST[vnum].dataptr;
                     dptr=dptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,dptr);
                     break;
    case CDF_INT4  : lptr=(INT32 *)VLIST[vnum].dataptr;
                     lptr=lptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,lptr);
                     break;
    case CDF_UINT4 : lptru=(UINT32 *)VLIST[vnum].dataptr;
                     lptru=lptru+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,lptru);
                     break;
    case CDF_INT2  : sptr=(INT16 *)VLIST[vnum].dataptr;
                     sptr=sptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,sptr);
                     break;
    case CDF_UINT2 : sptru=(UINT16 *)VLIST[vnum].dataptr;
                     sptru=sptru+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,sptru);
                     break;
    case CDF_CHAR  : break; /* already moved */
    case CDF_UCHAR : break; /* already moved */
    default        : cptr=(char *)VLIST[vnum].dataptr;
                     cptr=cptr+velem;
                     icnt=sscanf(VLIST[vnum].buffer,form,cptr);
                     break;
  }
  if (icnt != 1) { icountr=0;
    sprintf(LOGFILE.message,"WARNING: Input record (%d) does not match expected format, skipping",INFILE.recnum);
    MSG_control(1,LOGFILE.message,0);
    strcpy(LOGFILE.message,"Parser2: Variable: "); 
    strcat(LOGFILE.message,VLIST[vnum].vname);
    strcat(LOGFILE.message,"  Element#");
    sprintf(sval,"%ld",(velem+1)); strcat(LOGFILE.message,sval);
    MSG_control(1,LOGFILE.message,0);


  }
  else if (VLIST[vnum].ccount < (LONG)ccnt) VLIST[vnum].ccount = (LONG) ccnt;
  return(icountr);
}

/**********************************************************************/
/*   Fixedform BINARY Scan the given variable from the input buffer   */
/**********************************************************************/
LONG Parser3(vnum,velem)
LONG vnum;
LONG velem;
{
  CDFstatus status;
  LONG dpointer,offset;
  LONG One=1;
  LONG icnt=0;

  /* determine address for output of data conversion */
  dpointer = (LONG)VLIST[vnum].dataptr;
  offset   = VLIST[vnum].length * velem;
  dpointer = dpointer + offset;

  /* convert binary value in buffer to host format */
  status = ConvertBuffer(INFILE.btype,HOST_ENCODING,NEGtoPOSfp0on,
                         VLIST[vnum].cdfvartype,One,
                         (void *)INFILE.bptr,(void *)dpointer);
  if (status != CDF_OK) {
    MSG_control(2,"ERROR:During binary data conversion to HOST=",status);
  } else icnt = VLIST[vnum].length;

  /* advance buffer pointer */
  INFILE.bptr = INFILE.bptr + VLIST[vnum].length;

  return(icnt);
}

/************************************************************************/
/*   Compare data values to existing min and max for the given variable */
/************************************************************************/
LONG AutoMinMax(vnum)
LONG vnum;
{
  INT16 *sptr,*sptr2,*sptr3;
  UINT16 *sptru,*sptr2u,*sptr3u;
  INT32 *lptr,*lptr2,*lptr3;
  UINT32 *lptru,*lptr2u,*lptr3u;
  float *fptr,*fptr2,*fptr3;
  double *dptr,*dptr2,*dptr3;
  char *cptr;
  LONG velem,celem;
  LONG status=0;
  LONG ierr=0;

  /* Keep track of data min and max values */
  switch (VLIST[vnum].cdfvartype) {
    case CDF_REAL4 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       fptr=(float *)VLIST[vnum].dataptr;
                       fptr=fptr+velem; celem=VLIST[vnum].clistnum;
                       fptr2=(float *)CLIST[celem].vmin;
                       fptr3=(float *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*fptr < *fptr2)) {
                         *fptr2 = *fptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*fptr > *fptr3)) {
                         *fptr3 = *fptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_FLOAT : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       fptr=(float *)VLIST[vnum].dataptr;
                       fptr=fptr+velem; celem=VLIST[vnum].clistnum;
                       fptr2=(float *)CLIST[celem].vmin;
                       fptr3=(float *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*fptr < *fptr2)) {
                         *fptr2 = *fptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*fptr > *fptr3)) {
                         *fptr3 = *fptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_REAL8 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       dptr=(double *)VLIST[vnum].dataptr;
                       dptr=dptr+velem; celem=VLIST[vnum].clistnum;
                       dptr2=(double *)CLIST[celem].vmin;
                       dptr3=(double *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*dptr < *dptr2)) {
                         *dptr2 = *dptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*dptr > *dptr3)) {
                         *dptr3 = *dptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_DOUBLE: for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       dptr=(double *)VLIST[vnum].dataptr;
                       dptr=dptr+velem; celem=VLIST[vnum].clistnum;
                       dptr2=(double *)CLIST[celem].vmin;
                       dptr3=(double *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*dptr < *dptr2)) {
                         *dptr2 = *dptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*dptr > *dptr3)) {
                         *dptr3 = *dptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_EPOCH : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       dptr=(double *)VLIST[vnum].dataptr;
                       dptr=dptr+velem; celem=VLIST[vnum].clistnum;
                       dptr2=(double *)CLIST[celem].vmin;
                       dptr3=(double *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*dptr < *dptr2)) {
                         *dptr2 = *dptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*dptr > *dptr3)) {
                         *dptr3 = *dptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_INT4  : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       lptr=(INT32 *)VLIST[vnum].dataptr;
                       lptr=lptr+velem; celem=VLIST[vnum].clistnum;
                       lptr2=(INT32 *)CLIST[celem].vmin;
                       lptr3=(INT32 *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*lptr < *lptr2)) {
                         *lptr2 = *lptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*lptr > *lptr3)) {
                         *lptr3 = *lptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_UINT4 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       lptru=(UINT32 *)VLIST[vnum].dataptr;
                       lptru=lptru+velem; celem=VLIST[vnum].clistnum;
                       lptr2u=(UINT32 *)CLIST[celem].vmin;
                       lptr3u=(UINT32 *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*lptru < *lptr2u)) {
                         *lptr2u = *lptru; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*lptru > *lptr3u)) {
                         *lptr3u = *lptru; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_INT2  : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       sptr=(INT16 *)VLIST[vnum].dataptr;
                       sptr=sptr+velem; celem=VLIST[vnum].clistnum;
                       sptr2=(INT16 *)CLIST[celem].vmin;
                       sptr3=(INT16 *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*sptr < *sptr2)) {
                         *sptr2 = *sptr; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*sptr > *sptr3)) {
                         *sptr3 = *sptr; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_UINT2 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       sptru=(UINT16 *)VLIST[vnum].dataptr;
                       sptru=sptru+velem; celem=VLIST[vnum].clistnum;
                       sptr2u=(UINT16 *)CLIST[celem].vmin;
                       sptr3u=(UINT16 *)CLIST[celem].vmax;
                       if ((CLIST[celem].flagone == 0)||(*sptru < *sptr2u)) {
                         *sptr2u = *sptru; CLIST[celem].flagone=1L;
                       }
                       if ((CLIST[celem].flagone == 0)||(*sptru > *sptr3u)) {
                         *sptr3u = *sptru; CLIST[celem].flagone=1L;
                       }
                     }
                     break;
    case CDF_CHAR  : MSG_control(1,"WARNING: char minmax checking TBD",status);
                     break;
    case CDF_UCHAR : MSG_control(1,"WARNING: char minmax checking TBD",status);
                     break;
    default        : MSG_control(2,"ERROR: Unknown minmax vartype",status);
  }

  /* Keep track of the #characters in the LONGest valid string from INFILE */
  celem = VLIST[vnum].clistnum;
  if (VLIST[vnum].ccount > CLIST[celem].ccount) {
    CLIST[celem].ccount=VLIST[vnum].ccount;
  }
  VLIST[vnum].ccount = 0; /* reset */

  return(ierr);
}

/************************************************************************/
/*   Replace all fill values identified by user with ISTP standard fill */
/************************************************************************/
LONG AutoFiller(vnum)
LONG vnum;
{
  INT16 *sptr;
  UINT16 *sptru;
  INT32 *lptr;
  UINT32 *lptru;
  float *fptr;
  double *dptr;
  char *cptr;
  LONG velem;
  LONG status=0;
  LONG iflag=0;

  switch (VLIST[vnum].cdfvartype) {
    case CDF_REAL4 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       fptr=(float *)VLIST[vnum].dataptr;
                       fptr=fptr+velem;
                       if (*fptr==(float)VLIST[vnum].fillval) {
                         *fptr = -1.0e31; iflag=1L;
                       }
                     }
                     break;
    case CDF_FLOAT : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       fptr=(float *)VLIST[vnum].dataptr;
                       fptr=fptr+velem;
                       if (*fptr==(float)VLIST[vnum].fillval) {
                         *fptr = -1.0e31; iflag=1L;
                       }
                     }
                     break;
    case CDF_REAL8 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       dptr=(double *)VLIST[vnum].dataptr;
                       dptr=dptr+velem;
                       if (*dptr==VLIST[vnum].fillval) {
                         *dptr = -1.0e31; iflag=1L;
                       }
                     }
                     break;
    case CDF_DOUBLE: for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       dptr=(double *)VLIST[vnum].dataptr;
                       dptr=dptr+velem;
                       if (*dptr==VLIST[vnum].fillval) {
                         *dptr = -1.0e31; iflag=1L;
                       }
                     }
                     break;
    case CDF_EPOCH : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       dptr=(double *)VLIST[vnum].dataptr;
                       dptr=dptr+velem;
                       if (*dptr==VLIST[vnum].fillval) {
                         *dptr = -1.0e31; iflag=1L;
                       }
                     }
                     break;
    case CDF_INT4  : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       lptr=(INT32 *)VLIST[vnum].dataptr;
                       lptr=lptr+velem;
                       if (*lptr==(INT32)VLIST[vnum].fillval) {
                         *lptr = -2147483648; iflag=1L;
                       }
                     }
                     break;
    case CDF_UINT4 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       lptru=(UINT32 *)VLIST[vnum].dataptr;
                       lptru=lptru+velem;
                       if (*lptru==(UINT32)VLIST[vnum].fillval) {
                         *lptru = -2147483648; iflag=1L;
                       }
                     }
                     break;
    case CDF_INT2  : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       sptr=(INT16 *)VLIST[vnum].dataptr;
                       sptr=sptr+velem;
                       if (*sptr==(INT16)VLIST[vnum].fillval) {
                         *sptr = -32768; iflag=1L;
                       }
                     }
                     break;
    case CDF_UINT2 : for (velem=0;velem < VLIST[vnum].nelems;velem++) {
                       sptru=(UINT16 *)VLIST[vnum].dataptr;
                       sptru=sptru+velem;
                       if (*sptr==(UINT16)VLIST[vnum].fillval) {
                         *sptr = -32768; iflag=1L;
                       }
                     }
                     break;
    case CDF_CHAR  : MSG_control(1,"WARNING: char fillval checking TBD",status);
                     break;
    case CDF_UCHAR : MSG_control(1,"WARNING: char fillval checking TBD",status);
                     break;
    default        : MSG_control(2,"ERROR: Unknown fillval vartype",status);
  }

  /* If any data is filler, then reset the character counter, so that */
  /* the max field size is not set by any fill data, only non-fill.   */
  if (iflag == 1L) VLIST[vnum].ccount = 0L;
  return(iflag);
}

/************************************************************************/
/*            Determine the FORMAT of the identified variable           */
/************************************************************************/
LONG AutoFormat(vnum,form)
LONG vnum;
char *form;
{
  double dnum1,dnum2;
  double *dptr1,*dptr2;
  float fnum1,fnum2;
  float *fptr1,*fptr2;
  LONG cnum,d,s;
  LONG ierr=0;
  char slen[10]="";
  char flen[10]="";

  cnum = VLIST[vnum].clistnum;
  switch (VLIST[vnum].cdfvartype) {
    case CDF_REAL4 : fptr1 = (float *)CLIST[cnum].vmax; fnum1 = *fptr1;
                     fptr2 = (float *)CLIST[cnum].vmin; fnum2 = *fptr2;
                     dnum1 = fabs((double)fnum1); dnum2 = fabs((double)fnum2);
                     if (dnum2 > dnum1) {
                       if (fnum2 < 0.0) s=1L; else s=0L; dnum1 = dnum2;
                     } else if (fnum1 < 0.0) s=1L; else s=0L;
                     for (d=0;dnum1 >= 1.0;d++) dnum1 = dnum1 / 10.0;
                     sprintf(slen,"%ld",CLIST[cnum].ccount);
                     sprintf(flen,"%ld",CLIST[cnum].ccount - 1 - d - s);
                     strcpy(form,"F"); strcat(form,slen); 
                     strcat(form,"."); strcat(form,flen);
                     break;
    case CDF_FLOAT : fptr1 = (float *)CLIST[cnum].vmax; fnum1 = *fptr1;
                     fptr2 = (float *)CLIST[cnum].vmin; fnum2 = *fptr2;
                     dnum1 = fabs((double)fnum1); dnum2 = fabs((double)fnum2);
                     if (dnum2 > dnum1) {
                       if (fnum2 < 0.0) s=1L; else s=0L; dnum1 = dnum2;
                     } else if (fnum1 < 0.0) s=1L; else s=0L;
                     for (d=0;dnum1 >= 1.0;d++) dnum1 = dnum1 / 10.0;
                     sprintf(slen,"%ld",CLIST[cnum].ccount);
                     sprintf(flen,"%ld",CLIST[cnum].ccount - 1 - d);
                     strcpy(form,"F"); strcat(form,slen); 
                     strcat(form,"."); strcat(form,flen);
                     break;
    case CDF_REAL8 : dptr1 = (double *)CLIST[cnum].vmax; dnum1 = *dptr1;
                     dptr2 = (double *)CLIST[cnum].vmin; dnum2 = *dptr2;
                     dnum1 = fabs(dnum1); dnum2 = fabs(dnum2);
                     if (dnum2 > dnum1) {
                       if (fnum2 < 0.0) s=1L; else s=0L; dnum1 = dnum2;
                     } else if (fnum1 < 0.0) s=1L; else s=0L;
                     for (d=0;dnum1 >= 1.0;d++) dnum1 = dnum1 / 10.0;
                     sprintf(slen,"%ld",CLIST[cnum].ccount);
                     sprintf(flen,"%ld",CLIST[cnum].ccount - 1 - d);
                     strcpy(form,"F"); strcat(form,slen); 
                     strcat(form,"."); strcat(form,flen);
                     break;
    case CDF_DOUBLE: dptr1 = (double *)CLIST[cnum].vmax; dnum1 = *dptr1;
                     dptr2 = (double *)CLIST[cnum].vmin; dnum2 = *dptr2;
                     dnum1 = fabs(dnum1); dnum2 = fabs(dnum2);
                     if (dnum2 > dnum1) {
                       if (fnum2 < 0.0) s=1L; else s=0L; dnum1 = dnum2;
                     } else if (fnum1 < 0.0) s=1L; else s=0L;
                     for (d=0;dnum1 >= 1.0;d++) dnum1 = dnum1 / 10.0;
                     sprintf(slen,"%ld",CLIST[cnum].ccount);
                     sprintf(flen,"%ld",CLIST[cnum].ccount - 1 - d);
                     strcpy(form,"F"); strcat(form,slen); 
                     strcat(form,"."); strcat(form,flen);
                     break;
    case CDF_EPOCH : dptr1 = (double *)CLIST[cnum].vmax; dnum1 = *dptr1;
                     dptr2 = (double *)CLIST[cnum].vmin; dnum2 = *dptr2;
                     dnum1 = fabs(dnum1); dnum2 = fabs(dnum2);
                     if (dnum2 > dnum1) {
                       if (fnum2 < 0.0) s=1L; else s=0L; dnum1 = dnum2;
                     } else if (fnum1 < 0.0) s=1L; else s=0L;
                     for (d=0;dnum1 >= 1.0;d++) dnum1 = dnum1 / 10.0;
                     sprintf(slen,"%ld",CLIST[cnum].ccount);
                     sprintf(flen,"%ld",CLIST[cnum].ccount - 1 - d);
                     strcpy(form,"F"); strcat(form,slen); 
                     strcat(form,"."); strcat(form,flen);
                     break;
    case CDF_INT4 :  sprintf(slen,"%ld",CLIST[cnum].ccount);
                     strcpy(form,"I"); strcat(form,slen); 
                     break;
    case CDF_UINT4 : sprintf(slen,"%ld",CLIST[cnum].ccount);
                     strcpy(form,"I"); strcat(form,slen); 
                     break;
    case CDF_INT2 :  sprintf(slen,"%ld",CLIST[cnum].ccount);
                     strcpy(form,"I"); strcat(form,slen); 
                     break;
    case CDF_UINT2 : sprintf(slen,"%ld",CLIST[cnum].ccount);
                     strcpy(form,"I"); strcat(form,slen); 
                     break;
    case CDF_BYTE  : sprintf(slen,"%ld",CLIST[cnum].ccount);
                     strcpy(form,"I"); strcat(form,slen); 
                     break;
    case CDF_CHAR  : MSG_control(2,
                        "WARNING: No auto formatting of CHAR data\n",0);
                     break;
    case CDF_UCHAR : MSG_control(2,
                        "WARNING: No auto formatting of UCHAR data\n",0);
                     break;
    default        : MSG_control(2,
                        "ERROR: Unknown data type in autoformatter\n",0);
  }
  return(ierr);
}

/**********************************************************************/
/*      Close all open files and free all allocated buffer space      */
/**********************************************************************/
LONG Cleanup_makeCDF(ifile)
LONG ifile;
{
  CDFid id;
  CDFstatus status;
  char scnt[20]="";
  LONG i;
  LONG ierr=0;

  /* free data space used for the ordered variable list */
  free(OLIST); OLISTne=0L; OLIST=NULL;

  /* close output cdf file */
  if (OUTCDF.outCDFid != 0) {
    sprintf(scnt,"%ld",(OUTCDF.CDFrec+1));
    strcpy(LOGFILE.message,"Wrote ");
    strcat(LOGFILE.message,scnt);
    strcat(LOGFILE.message," records out to ");
    strcat(LOGFILE.message,RPARMS.outcdfname);
    strcat(LOGFILE.message,".cdf.");
  /* Write the msg in main, after possible addition by Autonamer */
/* MSG_control(2,LOGFILE.message,0);  HKH 8/31/00 Chng 1 to 2: always print*/


    status=CDFlib(CLOSE_,CDF_,OUTCDF.outCDFid,NULL_);
    OUTCDF.outCDFid=0L;
  }

  /* reset first epoch value and Base time value to zero. */
  EpALG.FirstEp = 0.0; EpALG.BaseEp = 0.0;

  if (ifile == FLISTne-1) { /* total termination */

    /* close input file and free allocated buffer space */
    free(INFILE.buffer);
    if (INFILE.fptr != NULL) fclose(INFILE.fptr);

    /* free data space allocated for variables */
    for (i=0;i<VLISTne;i++) {
      if (VLIST[i].buffer  != NULL)  free(VLIST[i].buffer);
      if (VLIST[i].dataptr != NULL)  free(VLIST[i].dataptr);
      /*      if (VLIST[i].vname != NULL)    free(VLIST[i].vname); not allocated any more */
      /*if (VLIST[i].cdfvname != NULL) free(VLIST[i].cdfvname);*/
    }

    /* free data space allocated for min/max tracking */
    for (i=0;i<CLISTne;i++) {
   if (CLIST[i].vmin !=NULL) free(CLIST[i].vmin);
      if (CLIST[i].vmax !=NULL) free(CLIST[i].vmax);
    }

    /*free(VLIST);*/   VLISTne=0L;
    /*free(CLIST);*/   CLISTne=0L;
    /*free(SRECS);*/   SRECSne=0L;
  }
  return(ierr);
}

/**********************************************************************/
/*                        Open the output CDF                         */
/**********************************************************************/
LONG Open_OutCDF()
{
  CDFstatus status;
  CDFid     id;
  LONG ierr=0;

  strcpy(LOGFILE.message,"Opening the output CDF named: ");
  strcat(LOGFILE.message,RPARMS.outcdfname);
  MSG_control(1,LOGFILE.message,0);
  status = CDFlib(OPEN_,CDF_,RPARMS.outcdfname,&id,
                  SELECT_, CDF_zMODE_, zMODEon2, NULL_);
  if (status >= CDF_WARN) {
    OUTCDF.outCDFid = id;
    OUTCDF.CDFrec   = -1L; }
  else {
    MSG_control(2,"CDFERROR:",status);
    ierr = 1;
  }

  status = CDFlib(GET_,CDF_ENCODING_,&OUTCDF.encoding,NULL_);
  if (status != CDF_OK) {
    MSG_control(2,"ERROR: Unable to determine CDF encoding",status);
    ierr=1;
  }
  else { /* confirm NETWORK encoding format as ISTP guideline */
    if (OUTCDF.encoding != NETWORK_ENCODING) {
      MSG_control(1,"WARNING:Output CDF encoding is not NETWORK      ",0);
      MSG_control(1,"        ISTP guidelines require NETWORK encoding",0);
      MSG_control(1,"        Processing continuing ...",0);
  } }

  return(ierr);
}

/**********************************************************************/
/*                Write Epoch value to output CDF                     */
/**********************************************************************/
LONG WriteEpochToCDF (depoch, CDFrec)
double depoch;
LONG CDFrec;
{
  CDFstatus status;
  LONG ierr=0;
  status = CDFlib(SELECT_,zVAR_,EpALG.Epvarnum,
                  SELECT_,zVAR_RECNUMBER_,CDFrec,
                  PUT_,zVAR_DATA_,&depoch,NULL_);
  if (status != CDF_OK) {
    MSG_control(2,"ERROR: while writing epoch value to cdf.",status);
    ierr=1;
  }
  return(ierr);
}

/**********************************************************************/
/*                     Write data to output CDF                       */
/**********************************************************************/
LONG WriteToCDF (vnum, CDFrec)
LONG vnum;
LONG CDFrec;
{
  CDFstatus status;
  char vstring[20];
  LONG ierr=0;
  if (VLIST[vnum].cdfvartype != CDF_CHAR) {
    if (VLIST[vnum].Elem[0] == -1L) {
      status = CDFlib(SELECT_,zVARs_RECNUMBER_,CDFrec,
                      PUT_,zVARs_RECDATA_,1,&VLIST[vnum].cdfvarnum,
                                            VLIST[vnum].dataptr,NULL_);
    }
    else {
      if (VLIST[vnum].Elem[1] == -1L) { /* only one index */
        status = CDFlib(SELECT_,zVARs_RECNUMBER_,CDFrec,
                                zVAR_,VLIST[vnum].cdfvarnum,
                                zVAR_DIMINDICES_,&VLIST[vnum].Elem[0],
                        PUT_,   zVAR_DATA_,VLIST[vnum].dataptr,NULL_); }
      else { /* both element indices being used */
        status = CDFlib(SELECT_,zVARs_RECNUMBER_,CDFrec,
                                zVAR_,VLIST[vnum].cdfvarnum,
                                zVAR_DIMINDICES_,VLIST[vnum].Elem,
                        PUT_,   zVAR_DATA_,VLIST[vnum].dataptr,NULL_);
      }
    }
  }
  else { /* character data */
    if (VLIST[vnum].Elem[0] == -1L) {
      status = CDFlib(SELECT_,zVARs_RECNUMBER_,CDFrec,
                      PUT_,zVARs_RECDATA_,1,&VLIST[vnum].cdfvarnum,
                                             VLIST[vnum].buffer,NULL_);
    }
    else {
      status = CDFlib(SELECT_,zVARs_RECNUMBER_,CDFrec,
                              zVAR_,VLIST[vnum].cdfvarnum,
                              zVAR_DIMINDICES_,VLIST[vnum].Elem,
                      PUT_,   zVAR_DATA_,VLIST[vnum].buffer,NULL_);
    }
  }
  if (status != CDF_OK) {
    strcpy(LOGFILE.message,"ERROR: while writing variable #");
    sprintf(vstring,"%d",vnum); strcat(vstring," to the cdf");
    strcat(LOGFILE.message,vstring);
    MSG_control(2,LOGFILE.message,status);
    ierr=1;
  }
  return(ierr);
}

/***********************************************************************
*                     GENERATE THE LFILEID VALUE                       *
***********************************************************************/
LONG Generate_LFILEID(lfileid)
char *lfileid;
/* Mod 10-00 HKH To use "Logical_file_id" from CDF if it is present. */
/*               If not present, construct it if possible.           */
{
  LONG i,scope,ne,lyear,lmon,lday,lhour,lmin,lsec,lmsec,ldoy,jd,yd;
  LONG logsrc=0;
  LONG logicid,k;
  CDFstatus status;
  time_t current_time; struct tm *ptrtime;
  double depoch;
  char source[80]=""; char sabbr[10]=""; char type[80]="";
  char desc[80]=""; char version[10]=""; char datestr[20]="";
  char logsource[80]="";
  char logicfileid[80]="";
  char logfileid[80]="";
  char logic_sn[80]=""; char logic_dt[80]=""; char logic_des[80]="";
  char logic_time[80]=""; char logic_dv[80]=""; char newname[80]="";
  char comp1[3]="";  char comp2[3]="";
  char *start;
  LONG ierr=0;

 /* If "Logical_file_id" exists in CDF, retrieve it */
  LONG log_id = 0; LONG versionflag=0;
  LONG log_sn=0; LONG log_dt=0; LONG log_des=0;
  LONG log_time=0; LONG log_dv=0;
  LONG nabbr; LONG ntype; LONG ndesc;

  start = lfileid; /* save argument (pointer) */

 status=CDFlib(SELECT_,ATTR_NAME_,"Logical_file_id", SELECT_,gENTRY_,0,
               GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
               GET_,gENTRY_DATA_,logfileid,NULL_);
 if ((status == CDF_OK)&&(scope == GLOBAL_SCOPE)) {

   logfileid[ne] = '\0'; /* insert string terminator */
   log_id = 1;
   sprintf(LOGFILE.message,"Logical_file_id from gATTr: %s\n",logfileid);
   MSG_control(0,LOGFILE.message,0);

 /* Parse the string into elements separated by "_". 
    Call these logic_sn, logic_dt, logic_des, logic_time, and logic_dv. 
    If logic_time is absent, that's OK (it can be filled from timestring 
    later). 
 */
   i=0;
   k=0;
   while ((logfileid[i]!='_')&&(i<ne)) {
      logic_sn[k]=logfileid[i];
      log_sn++;
      i++;
      k++;
   }
   logic_sn[k] = '\0';
   i++;
   nabbr = log_sn;

   k=0;
   while ((logfileid[i]!='_')&&(i<ne)) {
      logic_dt[k]=logfileid[i];
      log_dt++;
      i++;
      k++;
   }
   logic_dt[k] = '\0';
   i++;
   ntype = log_dt;

   k=0;
   while ((logfileid[i]!='_')&&(i<ne)) {
      logic_des[k]=logfileid[i];
      log_des++;
      i++;
      k++;
   }
   logic_des[k] = '\0';
   i++;
   ndesc = log_des;

   k=0;
   while ((logfileid[i]!='_')&&(i<ne)) {
      logic_time[k]=logfileid[i];
      log_time++;
      i++;
      k++;
   }
   logic_time[k] = '\0';
   i++;

   k=0;
   while ((logfileid[i]!='_')&&(i<ne)) {
      logic_dv[k]=logfileid[i];
      log_dv++;
      i++;
      k++;
   }
   logic_dv[k] = '\0';

   if (i < ne) {
      MSG_control(2,"ERROR: Unexpected form of 'Logical_file_id'.",0);
      sprintf(LOGFILE.message,"%s",logfileid);
      MSG_control(2,LOGFILE.message,0);
      ierr=1;
      return(ierr);
   }   

    status=CDFlib(SELECT_,ATTR_NAME_,"Data_version", SELECT_,gENTRY_,0,
                  GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
                  GET_,gENTRY_DATA_,version,NULL_);
    if ((status != CDF_OK)||(scope != GLOBAL_SCOPE)) {
      MSG_control(1,"WARNING: gATTR 'Data_version' not found.",status);
/*
      ierr=1;
*/
      if(log_dv == 0) {
         versionflag = 1;
      }
      else {
         versionflag = 4;
      }
    }
    else {  /* i.e., Data_version was found */
      if(log_dv == 0) {
         versionflag = 2;
      }
      else {
         versionflag = 3;
      }
    }
 }

 else {  /* i.e., logical_file_id not found */
   MSG_control(1,"WARNING: gATTR 'Logical_file_id' not found.",status);
   MSG_control(1,"Now trying to construct it.",0);
/* point AA */
 
  /* If "logical_source" exists in CDF, retrieve it */
 status=CDFlib(SELECT_,ATTR_NAME_,"Logical_source", SELECT_,gENTRY_,0,
               GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
               GET_,gENTRY_DATA_,logsource,NULL_);
 if ((status == CDF_OK)&&(scope == GLOBAL_SCOPE)) {
   logsource[ne] = '\0'; /* insert string terminator at end */
   logsrc = 1;
   sprintf(LOGFILE.message,"Logical_source from skeleton: %s\n",logsource);
   MSG_control(0,LOGFILE.message,0);
   for (i=0;i<ne;i++) *lfileid++ = logsource[i]; *lfileid++ = '_';
   *lfileid = '\0';  /* 10/31 removed ptr increment */
 }
 else {
   MSG_control(1,"NOTE: gATTR 'Logical_source'; trying to make it.",status);


/* Point A */

  /* Get gATTRs Source_name, Data_type, Descriptor, and Data_version */

  status=CDFlib(SELECT_,ATTR_NAME_,"Source_name", SELECT_,gENTRY_,0,
                GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne, 
                GET_,gENTRY_DATA_,source,NULL_);
  if ((status != CDF_OK)||(scope != GLOBAL_SCOPE)) {
    MSG_control(1,"WARNING: gATTR 'Source_name' not found.",status);
    ierr=1;
    return(ierr);
  }
  else {
    source[ne] = '\0'; /* insert string terminator */
  
    ierr=AbbrSCname(source,sabbr); /* abbreviate source name */
   if (ierr !=0 ) {
      MSG_control(1,"WARNING: Error abbreviating Source Name.",0);
      ierr=1;
      return(ierr);
   }

   else {
    nabbr = 0;
    for(i=0;i<ne;i++) {
       if (sabbr[i] != '>') nabbr++;
       else break;
    }
    sabbr[i] = '\0';
    status=CDFlib(SELECT_,ATTR_NAME_,"Data_type", SELECT_,gENTRY_,0,
                  GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
                  GET_,gENTRY_DATA_,type,NULL_);
    if ((status != CDF_OK)||(scope != GLOBAL_SCOPE)) {
      MSG_control(1,"WARNING: gATTR 'Data_type' not found.",status);
      ierr=1;
      return(ierr);
    }
    else {
      ntype = 0;
      for (i=0;i<ne;i++) {
         if (type[i] != '>') ntype++;
         else break;
      }
      type[i] = '\0'; /* insert string terminator */

      status=CDFlib(SELECT_,ATTR_NAME_,"Descriptor", SELECT_,gENTRY_,0,
                    GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
                    GET_,gENTRY_DATA_,desc,NULL_);
      if ((status != CDF_OK)||(scope != GLOBAL_SCOPE)) {
        MSG_control(1,"WARNING: gATTR 'Descriptor' not found.",status);
        ierr=1;
        return(ierr);
      }
      else {
        ndesc = 0;
        for (i=0;i<ne;i++) {
           if (desc[i] != '>') ndesc++;
           else break;
        }
        desc[i] = '\0'; /* insert string terminator */

        status=CDFlib(SELECT_,ATTR_NAME_,"Data_version", SELECT_,gENTRY_,0,
                      GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
                      GET_,gENTRY_DATA_,version,NULL_);
        if ((status != CDF_OK)||(scope != GLOBAL_SCOPE)) {
          MSG_control(1,"WARNING: gATTR 'Data_version' not found.",status);

         /* this is error only if "auto". But then show default to v01.
            If not "auto", then set some flag to show "no version used".
            Messages may accompany each of these cases.

            If we're in this branch, then logical_file_id doesn't exist.
            Consider version flag = 0 initially
                In this branch    = 1 if we didn't find gATTR Data_version
                                  = 2 if we found it.
         */
/*
          ierr=1;
          return(ierr);
*/
          versionflag = 1;
        }
        else {
          versionflag = 2;
        }
      }
    }
   }
  }

/* Point B */
   /* Here we have obtained, individually, all the components of the gATTR
      logical_source. And, if versionflag=2, we also have the gATTR
      Data_version, stored in "version".                             */

 /* Now assemble the components into logical_source (e.g., i8_k0_mag) in 
    lfileid.    */

   for (i=0;i<nabbr;i++) *lfileid++ = sabbr[i]; *lfileid++ = '_';
   for (i=0;i<ntype;i++) *lfileid++ = type[i];  *lfileid++ = '_';
   for (i=0;i<ndesc;i++) *lfileid++ = desc[i];  *lfileid++ = '_';   
 }

/* Point B2 */
/* Arriving here:
    1. logical_file_id was not found
    2. logical_source was either found or constructed
       If constructed, then:
         a. source_name, data_type, and descriptor were all found.
            (Return(ierr) was taken if these three not all found.)
         b. data_version was sought (flag shows the result)
       If not constructed (if logsrc=1), then we should look for data_version:
         a. if not found, determine either "no version" or default to v01
*/

  /* logsrc = 1 means we got logical_source from gATTR (and moved it into 
     lfileid using pointers). And we did not try to obtain gATTR Data_version.
  */

    if (logsrc==1) {
       status=CDFlib(SELECT_,ATTR_NAME_,"Data_version", SELECT_,gENTRY_,0,
                  GET_,ATTR_SCOPE_,&scope, GET_,gENTRY_NUMELEMS_,&ne,
                  GET_,gENTRY_DATA_,version,NULL_);
       if ((status != CDF_OK)||(scope != GLOBAL_SCOPE)) {
          MSG_control(1,"WARNING: gATTR 'Data_version' not found.",status);
          versionflag = 1;
       }
       else {
          versionflag = 2;
       }
    }
 }

 /* The path that didn't obtain Data_version (the non-construction path, i.e.,
    if logical_file_id was found) should have fallen on thru to here. 
 */

/* Point C */ 

/* Here we have:  logical_file_id directly from gATTR, 
                or 
                  logical_source, directly from gATTR or constructed above. */


 /* logical_file_id can be, for example, "i8_k0_mag_YYYYMMDD_vnn".
    logsrc=0 means log_id = 1 means we found logical_file_id from its gATTR.
       Then we parsed it into elements separated by "_" (not by lengths):
        log_sn is # of characters in source_name (source_name= e.g., i8)
        log_dt is similar for datatype  (k0)
        log_des similar for descriptor  (mag)
        log_time similar for time       (YYYYMMDD) (may be placeholder zeroes)
        log_dv similar for Data_version (vnn)  
            in addition, we may have later set log_dv from gATTR Data_version 
 */

/* logsrc=1 means that we found logical_source and moved it into lfileid, 
using pointers, and ending with a trailing "_".  */


          /* Determine Datestring */
          if (EpALG.FirstEp != 0) {
            depoch = EpALG.FirstEp;
            EPOCHbreakdown(depoch,&lyear,&lmon,&lday,&lhour,&lmin,&lsec,&lmsec);
            /* timing information depends on autonaming style */
            if (RPARMS.autostyle == 0) { /* use ISTP autonaming convention */
              sprintf(datestr,"%4ld%02ld%02ld",lyear,lmon,lday); }
            else { /* use the ISIS autonaming convention */
              jd = julian_date(lyear,lmon,lday); /* compute julian day  */
              yd = julian_date(lyear,1L,1L);     /* compute julian year */
              ldoy = (jd - yd) + 1L;           /* doy is base 1 not 0 */
              sprintf(datestr,"%4ld%03ld%02ld%02ld%02ld",
                      lyear,ldoy,lhour,lmin,lsec);
            }
            strcat(datestr,"");}
          else { /* get time from system */
            time(&current_time);
            ptrtime = localtime(&current_time);
            strftime(datestr,9,"%Y%m%d",ptrtime);
            strcat(datestr,"");   /* Added to terminate string */
          }

          /* All information required to make lfileid has been gathered */

          if (logsrc == 0) {   /* gATTR logical_file_id used */

             sprintf(LOGFILE.message,
                "nabbr, ntype, ndesc: %d %d %d\n",nabbr,ntype,ndesc);
             MSG_control(0,LOGFILE.message,0);
             sprintf(LOGFILE.message,"logic_sn: %s\n",logic_sn);
             MSG_control(0,LOGFILE.message,0);
             sprintf(LOGFILE.message,"logic_dt: %s\n",logic_dt);
             MSG_control(0,LOGFILE.message,0);
             sprintf(LOGFILE.message,"logic_des: %s\n",logic_des);
             MSG_control(0,LOGFILE.message,0);

            for (i=0;i<log_sn;i++) *lfileid++ = logic_sn[i];
            if (log_sn != 0) *lfileid++ = '_';
            for (i=0;i<log_dt;i++) *lfileid++ = logic_dt[i];
            if (log_dt != 0) *lfileid++ = '_';
            for (i=0;i<log_des;i++) *lfileid++ = logic_des[i];
            if (log_des != 0) *lfileid++ = '_';
            if ((log_sn+log_dt+log_des) != 0) *lfileid = '\0';
            /* Temp termination; don't increment ptr. */

    sprintf(LOGFILE.message,"logical_source_id in construction: %s\n",start);
    MSG_control(0,LOGFILE.message,0);
          }

/*        if (logsrc == 1) logical_source was already in lfileid, with
           pointers. 
    The datestring is the next part of the logical_file_id, so we need to
    now append the datestring.        */ 

    sprintf(LOGFILE.message,"Size, and datestring: %d '%s'\n",strlen(datestr),datestr);
    MSG_control(0,LOGFILE.message,0);

          for (i=0;i<strlen(datestr);i++) *lfileid++ = datestr[i];
          *lfileid = '\0';  /* Temp termination; don't increment ptr. */

/* Point D */

/* Now ready to add Data_version, if we have it. */ 

/* 
 New logic was inserted here to deal with the various cases of versionflag.
*/

       strcpy(newname,RPARMS.outcdfname);
      for (i=0,k=strlen(newname);i<k;i++) newname[i]=toupper(newname[i]);
      newname[i]='\0';

  switch (versionflag) {
  case 0 : MSG_control(2,"ERROR: Problem with 'version' logic.",0);
           ierr=1;
           return(ierr);
           break;
  case 1 : /* No Data_version, either in Logical_file_id or in gATTR */
           if (strcmp(newname,"AUTO")==0) { 
             MSG_control(2,"WARNING: Defaulting 'Data_version' to 1. Please update",0);
             MSG_control(2,"skeleton to include version and 'Logical_file_id'.",0); 
             *lfileid++ = '_'; *lfileid++ = 'V'; 
             *lfileid++ = '0';
             *lfileid++ = '1';
             *lfileid = '\0';
           }
           else {
             MSG_control(1,"WARNING: No 'Data_version' in CDF filename.",0);
             *lfileid = '\0';
             /* Okay, we have logical_file_id and not using autonaming. */
           }         
           break; 
  case 2 : /* gATTR 'Data_version' exists; no version in 'Logical_file_id' */
           MSG_control(2,"WARNING: Please update skeleton to include",0);
           MSG_control(2,"version in 'Logical_file_id' and 'Data_version'.",0);
                *lfileid++ = '_'; *lfileid++ = 'V';
                if (strlen(version) == 1) *lfileid++ = '0';
                for (i=0;i<strlen(version);i++) *lfileid++ = version[i];
                *lfileid = '\0';
           break;
  case 3 : /* Version appears both in gATTR and in Logical_file_id */
/*         **Compare the two, complain and stop if different
*/
           k = 0;
           if (strlen(version) == 1) {
              comp1[0] = '0';
              k = 1;
           }
           for (i=0;i<strlen(version);i++) comp1[k+i] = version[i];
           comp1[k+i] = '\0';
           for (i=1;i<log_dv;i++) comp2[i-1] = logic_dv[i];
           comp2[i-1] = '\0';
           if (strcmp(comp1,comp2) != 0) {
              MSG_control(2,"ERROR: Data_version attribute disagrees with",0);
              MSG_control(2,"version in Logical_file_id attribute.",0);
              ierr = 1;
              return(ierr);
           } else {
              *lfileid++ = '_';
              for (i=0;i<log_dv;i++) *lfileid++ = logic_dv[i];
              *lfileid = '\0';
              break;
           }

  case 4 : /* No Data_version gATTR, but data version is in Logical_file_id */
           *lfileid++ = '_';
           for (i=0;i<log_dv;i++) *lfileid++ = logic_dv[i];
           *lfileid = '\0';
           break;

  } 


/* Point E */

  if (ierr != 0) {
    MSG_control(1,"       UNABLE TO GENERATE COMPLETE LOGICAL FILE ID.",0);
    strcpy(lfileid,"");
  }

  lfileid = start;
  return(ierr);
}

/***********************************************************************
*                        SET THE LFILEID gATTR                         *
***********************************************************************/
LONG Set_LFILEID(lfileid)
char *lfileid;
{
  CDFstatus status;
  LONG ierr=0;

  /* Put the logical file id value into the output CDF */

  /*The logical_file_id could have come, complete or incomplete, from its
    gATTR. Or it might have been constructed, in which case it might or might
    not contain version number. The routine Generate_lfileid may present 
    comment messages, and may give a suggested logical_file_id if it was not 
    given, but we cannot actually put that into the data CDF unless the 
    attribute is present in the skeleton. We might go on and build the whole 
    output CDF, even though we displayed an ERROR message. That depends on 
    whether or not we want to add a check for error here and cause an 
    "EXIT_FAILURE" exit return.
  */

  status=CDFlib(SELECT_,ATTR_NAME_,"Logical_file_id", SELECT_,gENTRY_,0,
                PUT_,gENTRY_DATA_,CDF_CHAR,strlen(lfileid),lfileid,NULL_);
  if (status != CDF_OK) {
    MSG_control(2,"ERROR: Logical_file_id must be added to skeleton CDF.",status);
    MSG_control(2,"Verify its value; apparently it should be as follows,",0);
    MSG_control(2,"except with zeroes in place of the date-string:",0);
    MSG_control(2,lfileid,0);
    ierr=1;
  }
  return(ierr);
}

/***********************************************************************
*          SET THE VALIDMIN/MAX, SCALEMIN/MAX, AND FORMAT VATTRS       *
***********************************************************************/
/* The variable attributes must exist in the skeleton table or skeleton CDF
   so that this program can insert the data-determined values into the 
   output data CDF. Otherwise, nothing is inserted, and a warning message 
   is issued. SCALEMIN/MAX are given the same values as VALIDMIN/MAX. 
   This inserts values into the data CDF only, not into the skeleton. */

LONG Set_AutoVattrs()
{
  char form[10];
  CDFstatus status;
  LONG vnum,cnum;
  LONG ierr=0;

  for (vnum=0;vnum<VLISTne;vnum++) { /* check each variable */
    cnum = VLIST[vnum].clistnum;
    /* Determine if validmin and validmax vattrs should be set */
    if ((VLIST[vnum].autovalids > 0)&&
        (VLIST[vnum].cdfvarnum >= 0)&&
        (CLIST[cnum].flagone > 0   )) {
      /* Put the validmin and validmax values into the vattr */
      status=CDFlib(SELECT_,ATTR_NAME_,"VALIDMIN", 
                            zENTRY_,VLIST[vnum].cdfvarnum,
                    PUT_,   zENTRY_DATA_,VLIST[vnum].cdfvartype,1,
                            CLIST[cnum].vmin,NULL_);
      if (status != CDF_OK) {
        strcpy(LOGFILE.message,
         "ERROR: Can't write VALIDMIN to CDF; attr must first exist in skeleton.");
        MSG_control(2,LOGFILE.message,status);
        ierr=1;
      }
      status=CDFlib(SELECT_,ATTR_NAME_,"VALIDMAX",
                            zENTRY_,VLIST[vnum].cdfvarnum,
                    PUT_,   zENTRY_DATA_,VLIST[vnum].cdfvartype,1,
                            CLIST[cnum].vmax,NULL_);
      if (status != CDF_OK) {
        strcpy(LOGFILE.message,
         "ERROR: Can't write VALIDMAX to CDF; attr must first exist in skeleton.");
        MSG_control(2,LOGFILE.message,status);
        ierr=1;
      }
    }
    /* Determine if scalemin and scalemax vattrs should be set */
    if ((VLIST[vnum].autoscales > 0)&&
        (VLIST[vnum].cdfvarnum >= 0)&&
        (CLIST[cnum].flagone > 0   )) {
      /* Put the scalemin and scalemax values into the vattr */
      status=CDFlib(SELECT_,ATTR_NAME_,"SCALEMIN",
                            zENTRY_,VLIST[vnum].cdfvarnum,
                    PUT_,   zENTRY_DATA_,VLIST[vnum].cdfvartype,1,
                            CLIST[cnum].vmin,NULL_);
      if (status != CDF_OK) {
        strcpy(LOGFILE.message,
         "ERROR: Can't write SCALEMIN to CDF; attr must first exist in skeleton.");
        MSG_control(2,LOGFILE.message,status);
        ierr=1;
      }
      status=CDFlib(SELECT_,ATTR_NAME_,"SCALEMAX",
                            zENTRY_,VLIST[vnum].cdfvarnum,
                    PUT_,   zENTRY_DATA_,VLIST[vnum].cdfvartype,1,
                            CLIST[cnum].vmax,NULL_);
      if (status != CDF_OK) {
        strcpy(LOGFILE.message,
         "ERROR: Can't write SCALEMAX to CDF; attr must first exist in skeleton.");
        MSG_control(2,LOGFILE.message,status);
        ierr=1;
      }
    }
    /* Determine if FORMAT vattrs should be set */
    if ((VLIST[vnum].autoformat > 0)&&
        (VLIST[vnum].cdfvarnum >= 0)&&
        (CLIST[cnum].ccount > 0   )) {
      strcpy(form,""); /* initialize the format */
      ierr = AutoFormat(vnum,form); /* determine format */
      if (ierr == 0) {
        status=CDFlib(SELECT_,ATTR_NAME_,"FORMAT",
                              zENTRY_,VLIST[vnum].cdfvarnum,
                      PUT_,   zENTRY_DATA_,CDF_CHAR,strlen(form),form,NULL_);
        if (status != CDF_OK) {
        strcpy(LOGFILE.message,
         "ERROR: Can't write FORMAT to CDF; attr must first exist in skeleton.");
        MSG_control(2,LOGFILE.message,status);
          ierr=1;
    } } }

  } /* for each variable */
  return(ierr);
}

/***********************************************************************
*                    ABBREVIATE THE SPACECRAFT NAME                    *
***********************************************************************/
LONG AbbrSCname (source, abbr)
char *source, *abbr;
{
  LONG ierr=0;
  memcpy(abbr,source,2);
  strcat(abbr,"");
  if (strcmp(source,"SAMPEX>Solar Anomalous Magnetic Particle Explorer")==0)
    strcpy(abbr,"SX>");
  if (strcmp(source,"SAMPEX>Solar Anomalous Magnetospheric Particle Explorer")==0)
    strcpy(abbr,"SX>"); /*Added to catch both name versions. This one correct.*/
  if (strcmp(source,"GEOTAIL>Geomagnetic Tail")==0)
    strcpy(abbr,"GE>");
  if (strcmp(source,"WIND>Wind Interplanetary Plasma Laboratory")==0)
    strcpy(abbr,"WI>");
  if (strcmp(source,"POLAR>Polar Plasma Laboratory")==0)
    strcpy(abbr,"PO>");
  if (strcmp(source,"SOHO>Solar Heliospheric Observatory")==0)
    strcpy(abbr,"SO>");
  if (strcmp(source,"DARN>Dual Auroral Radar Network")==0)
    strcpy(abbr,"DN>");
  if (strcmp(source,
     "SESAME>Satellite Exploration Simultaneous with Antarctic Measurements")
     ==0) strcpy(abbr,"SE>");
  if (strcmp(source,"SONDRESTROM>Sondrestrom Incoherent-Scatter Radar")==0)
    strcpy(abbr,"SN>");
  if (strcmp(source,
     "CANOPUS>Canadian Auroral Network Open Program Unified Study")==0)
    strcpy(abbr,"CN>");
  if (strcmp(source,"IMP-8>Interplanetary Monitoring Platform 8")==0)
    strcpy(abbr,"I8>");
  if (strcmp(source,"INTERBALL-AURORAL>Interball Auroral Probe")==0)
    strcpy(abbr,"IA>");
  if (strcmp(source,"INTERBALL-TAIL>Interball  auroralprobe")==0)
    strcpy(abbr,"IA>"); /* Fixes erroneous early version */
  if (strcmp(source,"INTERBALL-TAIL>Interball Tail Probe")==0)
    strcpy(abbr,"IT>");
  if (strcmp(source,"LANL1989>")==0) strcpy(abbr,"L9>");
  if (strcmp(source,"LANL1990>")==0) strcpy(abbr,"L0>");
  if (strcmp(source,"LANL1991>")==0) strcpy(abbr,"L1>");
  if (strcmp(source,"GOES6>Geostationary Operational Environment Satellite")==0)
     strcpy(abbr,"G6>");
  if (strcmp(source,"GOES7>Geostationary Operational Environment Satellite")==0)
     strcpy(abbr,"G7>");
  if (strcmp(source,"GOES8>Geostationary Operational Environment Satellite")==0)
     strcpy(abbr,"G8>");
  if (strcmp(source,"GOES9>Geostationary Operational Environment Satellite")==0)
     strcpy(abbr,"G9>");
  if (strcmp(source,
     "STELAB>Solar-Terrestrial Environment Laboratory, Nagoya U.")==0)
     strcpy(abbr,"SL>");
  if (strcmp(source,
     "ISIS-1>International Satellite for Ionosphere Studies 1")==0)
     strcpy(abbr,"I1>");
  if (strcmp(source,
     "ISIS-2>International Satellite for Ionosphere Studies 2")==0)
     strcpy(abbr,"I2>");
  if (strcmp(source,"ALOUETTE-1")==0) strcpy(abbr,"A1");
  if (strcmp(source,"ALOUETTE-2")==0) strcpy(abbr,"A2");
  return(ierr);
}

/**************************************************************************
*                RENAME THE CDF USING ISTP CONVENTIONS                    *
**************************************************************************/
LONG AutoNamer (oldname, newname)
char *oldname;
char *newname;
{
  int  i,j;
  LONG ierr=0;
  LONG icerr;
  LONG olength;
  char c;
  char *ptr=oldname;
  char direc[80+1]="";
  char filen[80+1]="";
  char otemp[80+1]="";
  char ntemp[80+1]="";
  char delim;

#if defined (vms)
       delim = ']';
#else
#if defined (unix)
       delim = '/';
#endif
#endif

  /* make the newname uppercase or lowercase depending on runtime param */
  strcpy(ntemp,newname); olength=(LONG)strlen(newname);
  if (RPARMS.autocase == 1) { /* force to lowercase */
    for (i=0;i<olength;i++) ntemp[i]=tolower(ntemp[i]); ntemp[i]='\0';
  } else if (RPARMS.autocase == 0) { /* force to uppercase */
    for (i=0;i<olength;i++) ntemp[i]=toupper(ntemp[i]); ntemp[i]='\0';
  }
  strcpy(newname,ntemp);

  strcpy(otemp,oldname);  olength=(LONG)strlen(otemp);
  /* separate the filename from directory information. Find last ]or\.   */
  for (i=0,j= -1;i<olength;i++) { c= *ptr++; if((c==delim)||(c=='\'')) j=i; }
  if (j!= -1) { /* directory mark found, separate directory and filename */
    for (i=0;i<=j;i++) direc[i]=otemp[i]; direc[i]='\0'; j++;
    for (i=0;j<olength;i++,j++) filen[i]=toupper(otemp[j]); filen[i]='\0';
    if (strcmp(filen,"AUTO")==0) { /* only rename if oldname=AUTO */
      strcat(direc,newname); strcat(direc,".cdf"); strcat(oldname,".cdf");
      strcat(direc,"\0");
      strcat(oldname,"\0");
      /* output progress message */
/*
      strcpy(LOGFILE.message,"1 Renaming CDF from ");
      strcat(LOGFILE.message,oldname); strcat(LOGFILE.message," to ");
      strcat(LOGFILE.message,direc); 
      strcat(LOGFILE.message,"\0");
      MSG_control(2,LOGFILE.message,0);
*/
    /* Append to msg generated at close of CDF. Write msg in main. */
      strcat(LOGFILE.message,"  Renaming to "); 
      strcat(LOGFILE.message,direc); 
      strcat(LOGFILE.message,"\0");

      ierr = rename(oldname,direc);
      if (ierr!=0) {
        MSG_control(2,"ERROR: During attempt to rename the output CDF",0);
      }
      if ((ierr == 0) && (LOGFILE.appendlog == 0)) {
        StripName (direc,LOGFILE.appendname);
        strcat(LOGFILE.appendname,".log");
      }
    }
  }  
  else { /* no directory mark found. convert to uppercase and compare */
    for (i=0;i<olength;i++) otemp[i]=toupper(otemp[i]); strcat(otemp,"");
    if (strcmp(otemp,"AUTO")==0) { /* only rename if oldname=AUTO */
      strcat(newname,".cdf"); strcat(oldname,".cdf");
      /* output progress message */
/*
      strcpy(LOGFILE.message,"2 Renaming CDF from ");
      strcat(LOGFILE.message,oldname); strcat(LOGFILE.message," to ");
      strcat(LOGFILE.message,newname); 
      strcat(LOGFILE.message,"\0");
      MSG_control(2,LOGFILE.message,0);
*/
    /* Append to msg generated at close of CDF. Write msg in main. */
      strcat(LOGFILE.message,"  Renaming to "); 
      strcat(LOGFILE.message,newname); 
      strcat(LOGFILE.message,"\0");
      ierr = rename(oldname,newname);
      if (ierr!=0) {
        MSG_control(2,"ERROR: During attempt to rename the output CDF",0);
      }
      if ((ierr == 0) && (LOGFILE.appendlog == 0)) {
        StripName (newname,LOGFILE.appendname);
        strcat(LOGFILE.appendname,".log");
      }
    }
  }  

/* Closing of logfile was moved to main, enabling one log for whole run. */

  return (ierr);
}

/**************************************************************************
*                RENAME THE CDF USING ISTP CONVENTIONS                    *
**************************************************************************/
LONG ShortName (Lfileid)
char *Lfileid;
{
  int i,j;
  char *ptr = Lfileid;
  char tempID[80]="";
  LONG ierr=0;
  for (i=0;i<12;i++) ptr++; /* skip spacecraft,datatype,descriptor,century */
  for (i=0;i<6;i++) tempID[i] = *ptr++; /* copy year,month,and day */
  for (j=0;j<2;j++) ptr++; /* skip underscore and 'v' */
  for (j=0;j<2;j++,i++) tempID[i] = *ptr++; /* copy verion number */
  tempID[i]='\0'; /* add terminator */
  strcpy(Lfileid,tempID);
  return(ierr);
}

/**************************************************************************
*                CHECK FOR WILDCARD USAGE IN INPUT FILE                   *
**************************************************************************/
LONG Build_FLIST()
{
  int  icnt;
  int  pcount=1;
  LONG i,j;
  char *cptr;
  char **inDirs;
  char **inFiles;
  char *inPattern[1];
  char inPath[80]="";
  char inFile[80]="";
  char newname[80]="";
  LONG ierr=0;

  ParsePath(RPARMS.infname,inPath,inFile);  /* separate file and path names */
  cptr = memchr(inFile,'*',strlen(inFile)); /* search for wildcard */

  if (cptr == NULL) { /* no wildcard character found */
    FLISTne++;
    FLIST= realloc(FLIST,(sizeof(FLISTz)*FLISTne));
    strcpy(FLIST[FLISTne-1].Pathname,inPath);
    strcpy(FLIST[FLISTne-1].Filename,inFile);
    return(ierr);
  }

  /* wildcard character must have been found - get list of filenames */
  inPattern[0] = inFile;
  icnt = DirList(inPath,pcount,inPattern,&inDirs,&inFiles);

  /* Validate DirList results */
  if (icnt <= 0) {
    MSG_control(2,"ERROR: No files matched wildcard pattern...",0);
    MSG_control(2,"ERROR: Translation Aborted.",0);
    ierr=1; return(ierr); }
  else if (icnt > 1) { /* verify auto naming option is on */
    strcpy(newname,RPARMS.outcdfname);
    for (i=0,j=strlen(newname);i<j;i++) newname[i]=toupper(newname[i]);
    newname[i]='\0';
    if (strcmp(newname,"AUTO")!=0) {
      MSG_control(2,"ERROR: Wildcard pattern requires auto-naming option.",0);
      MSG_control(2,"ERROR: Translation Aborted.",0);
      ierr=1; return(ierr);
  } }

  /* Copy DirList results into FLIST data structure */
  for (i=0;i<icnt;i++) {
    FLISTne++;
    FLIST= realloc(FLIST,(sizeof(FLISTz)*FLISTne));
    strcpy(FLIST[FLISTne-1].Pathname,inDirs[i]);
    strcpy(FLIST[FLISTne-1].Filename,inFiles[i]);
  }
  return(ierr);
}
