/*===========================================================================
  Copyright (C) 1995-2013 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, 
  MA 02139, USA.
 
  Correspondence concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++++++++++++++++++ SC interface module SCSA +++++++++++++++++++++
..LANGUAGE C
..IDENTIFICATION Module SCSA
..AUTHOR         K. Banse  ESO - Garching	870721
..KEYWORDS       standard interfaces.
..ENVIRONMENT    theoretically environment independant.
..COMMENTS       holds SCSKIN - routine to read in the MIDAS keywords

..VERSION  [1.00] 920212:  Creation
 130120		last modif
 
-----------------------------------------------------------------------------*/
 
#include <fileexts.h>
#include <osyparms.h>
#include <stdio.h>
#include <stdlib.h>

 
 
int SCSKIN(fname)
char   *fname;
 
{
int   actval, bytelem, status, i, k, from, in;
int   byt_len, tot_len, n, noelem, pad, odd;
int   prflag, slen, start, namelen, reclen;
int   ikey[40], fp, unit, keysize, datsize;
register int  nr;

float	rkey[40];
 
double	dkey[40];
 
char	name[18], record[128], type[20], k_typ;
char	devices[28], user[24];
char    *tmpntr;

static struct KEY_STRUCT  *keypntr;


 


i = KEY_MAXENT;
k = LOC_MAXENT;

keysize = (int)sizeof(struct KEY_STRUCT) * (i+k+1);	/* + 1 for security */
tmpntr = (char *)malloc((size_t) keysize);
if (tmpntr == (char *) 0)
   {
   (void) printf("could not allocate %d bytes for key_names\n",keysize);
   ospexit(0);
   }
else
   memset((void *)tmpntr,0,(size_t)keysize);		/* init all memory */

KEYALL.KEYNAMES = (struct KEY_STRUCT *) tmpntr;

KEYALL.GLOBENT = i;
KEYALL.GLOBDAT = KEYALL.GLOBENT * KEY_FACT;             /* counted in bytes */
KEYALL.GLOBNO = -1;
KEYALL.GLOBEND = -1;
KEYALL.LOCENT = i + k;
KEYALL.LOCDAT = KEYALL.LOCENT * KEY_FACT;
KEYALL.LOCNO = KEYALL.GLOBENT -1;
KEYALL.LOCEND = KEYALL.GLOBDAT - 1;

datsize = KEYALL.LOCDAT + 2;			     /* for security */
tmpntr = (char *)malloc((size_t) datsize);
if (tmpntr == (char *) 0)
   {
   (void) printf("could not allocate %d bytes for key_data\n",datsize);
   ospexit(0);
   }
else
   memset((void *)tmpntr,0,(size_t)datsize);		/* init all memory */

KEYALL.KEYWORDS = (double *) tmpntr;

prflag = -1;
keypntr = KEYALL.KEYNAMES;

KDWORDS = KEYALL.KEYWORDS;
KRWORDS = (float *) KDWORDS;
KIWORDS = (int *) KDWORDS;
KCWORDS = (char *) KDWORDS;
 

/* OFF_MODE = 0, offset of 1st keyword MODE... so OFF_MODE+6 = 6  */

KEYALL.KEYNAMES[0].OFFSET = 0;
KIWORDS[6] = 0;			/* prog_level has to be set for MID_FNDKEY */
KEYALL.SYSNO = 40;		/* keyw. DATTIM (#41) is the last */
 
MID_INITER();				/*  init  error business  */
 
 
/*  open passed keyword file  */
 
fp = CGN_OPEN(fname,READ);		/*  open for reading  */
if (fp < 0)
   {
   (void) printf("We couldn't open the Midas keyfile %s ...\n",fname);
   ospexit(1);
   }
 
 
/*  read first keyname, type, length     */
 
read_loop:
reclen = osaread(fp,record,132);

if (reclen < 0)				/*  EOF reached     */
   osaclose(fp);
 
else if (reclen == 0)			/* empty line */
   goto read_loop;
 
else 
   {
   if (record[reclen-1] == 13)
      {
      if (reclen == 1)
         goto read_loop;
      else
         reclen --;
      }
   if ( (record[0] == 'C') &&			/*   skip comment lines   */
        ( (record[1] == ' ') || (record[1] == '\t') || (reclen == 1) ) )
      goto read_loop;
 
   start = 0;				/*  valid keyword encountered  */
   n = KEY_NAMELEN;
   namelen = CGN_EXTRSS(record,reclen,'/',&start,name,n);
   n = 20;
   slen = CGN_EXTRSS(record,reclen,'/',&start,type,n);
   type[19] = '\0';
   slen = CGN_EXTRSS(record,reclen,'/',&start,user,n);
   user[19] = '\0';
   (void) sscanf(user,"%d",&actval);
 
   MID_TYPCHK(type,&k_typ,&bytelem);		/*  check type of keyword  */
   if (k_typ == ' ')
      {
      status = ERR_KEYBAD;
      goto sect_5000;
      }
 
   if (actval <= 0)			/*  test length of keyword values   */
      {
      status = ERR_INPINV;
      goto sect_5000;
      }
 
   noelem = actval;			/*  get noelem  */
   if ( (k_typ == 'C') && (bytelem == 0) )
      {
      bytelem = actval;
      noelem = 1;
      }
 
 
   if (KEYALL.GLOBNO >= KEYALL.GLOBENT-1)	/* check, if KEYNAME full */
      {						/* or keyname already exists */
      status = ERR_KEYOVN;
      goto sect_5000;
      }
 
   status = MID_FNDKEY(name,record,&n,&n,&unit);
   if (status != -1)				/* check, if already defined */
      {
      status = ERR_KEYBAD;
      goto sect_5000;
      }
 
 
/*  calculate length in bytes + eventual front padding bytes  */
 
   if (k_typ == 'I')
      {
      pad = II_SIZE - 1 - (KEYALL.GLOBEND % II_SIZE);
      byt_len = noelem * II_SIZE;
      }
   else if (k_typ == 'R')
      {
      pad = RR_SIZE - 1 - (KEYALL.GLOBEND % RR_SIZE);
      byt_len = noelem * RR_SIZE;
      }
   else if (k_typ == 'C')
      {
      pad = 0;
      byt_len = noelem*bytelem;
      }
   else 				/* only (k_typ == 'D') possible */
      {
      pad = DD_SIZE - 1 - (KEYALL.GLOBEND % DD_SIZE);
      byt_len = noelem * DD_SIZE;
      }
	
   if (KEYALL.GLOBNO < 0) pad = 0;		/* fix for very first time */

   tot_len = pad + byt_len;
   if (KEYALL.GLOBEND+tot_len > KEYALL.GLOBDAT)
      {
      status = ERR_KEYOVL;
      goto sect_5000;
      }
 
 
   /*  everything o.k. - do what's necessary   */
 
   KEYALL.GLOBNO ++;
   memset((void *)keypntr->IDENT,32,(size_t)17);
   (void) memcpy(keypntr->IDENT,name,(size_t)namelen);
   keypntr->IDENT[15] = k_typ;
   keypntr->BYTELEM = (short int) bytelem;
   keypntr->NOELEM = noelem;
   keypntr->LEN = byt_len;
   keypntr->FRPAD = (short int) pad;
   keypntr->UNIT = 0;			/* not used yet */
   in = KEYALL.GLOBEND + 1;			/* point to next byte */
 
 
   /*  read data into corresponding keyword  */
 
   if (k_typ == 'I')
      {
      in = (in + pad) / II_SIZE;		/* include front padding */
      from = in;
     
     i_loop:
      reclen = osaread(fp,record,132);
      if (reclen < 0)
         goto no_data;
      else if (reclen == 0)                   /* empty line */
         goto i_loop;
      if (record[reclen-1] == 13) reclen --;
 
      slen = CGN_CNVT(record,1,noelem,ikey,rkey,dkey);
      if (slen < 0) goto no_data;

      for (nr=0; nr<slen; nr++) KIWORDS[from++] = ikey[nr];
 
      noelem = noelem - slen;
      if (noelem > 0) goto i_loop;
 
      if (prflag == -1) prflag = ikey[1];		/* set it to MODE(2) */
      }
 
   else if (k_typ == 'R')
      {
      in = (in + pad) / RR_SIZE;	 	/* include front padding */
      from = in;
     
     r_loop:
      reclen = osaread(fp,record,132);
      if (reclen < 0)
         goto no_data;
      else if (reclen == 0)                   /* empty line */
         goto r_loop;
      if (record[reclen-1] == 13) reclen --;
 
      slen = CGN_CNVT(record,2,noelem,ikey,rkey,dkey);
      if (slen < 0) goto no_data;

      for (nr=0; nr<slen; nr++) KRWORDS[from++] = rkey[nr];
 
      noelem = noelem - slen;
      if (noelem > 0) goto r_loop;
      }
 
   else if (k_typ == 'C')
      {
      from = in;				/* we can start right away */
      actval = noelem * bytelem;
      odd = 0;					/* used as switch here */
 
     c_loop:
      reclen = osaread(fp,record,132);
      if (reclen < 0)
         goto no_data;
      else if (reclen == 0)                   /* empty line */
         goto c_loop;
      if (record[reclen-1] == 13) reclen --;
 
      if (odd > 0)		/* only after very first follow up is read  */
         {
         if ( (record[0] == 'C') &&
              ( (record[1] == ' ') || (reclen == 1) ) )
            {
            memset((void *)(KCWORDS+from),32,(size_t)actval);
            reclen = actval;
            goto c_check;
            }
         }
 
      (void) memcpy(KCWORDS+from,record,(size_t)reclen);
      from += reclen;
      odd ++;
 
     c_check:
      actval -= reclen;
      if (actval > 0) goto c_loop;		/* more records to read ...  */
      }
 
   else if (k_typ == 'D')
      {
      in = (in + pad) / DD_SIZE;		/* include front padding */
      from = in;
 
     d_loop:
      reclen = osaread(fp,record,132);
      if (reclen < 0)
         goto no_data;
      else if (reclen == 0)                   /* empty line */
         goto d_loop;
      if (record[reclen-1] == 13) reclen --;
 
      slen = CGN_CNVT(record,4,noelem,ikey,rkey,dkey);
      if (slen < 0) goto no_data;

      for (nr=0; nr<slen; nr++) KDWORDS[from++] = dkey[nr];
 
      noelem = noelem - slen;
      if (noelem > 0) goto d_loop;
      }
 

/* store offset already in type-units + increment pointer KEYALL->GLOBEND */
 
   keypntr->OFFSET = in;
   KEYALL.GLOBEND += tot_len;
 
   if (prflag == 1) (void) printf("keyword %8s added\n",name);

   keypntr ++;
   goto read_loop;
   }
 
 
/*  fill keyword MID$SESS with image system unit      */
 
(void) memcpy(devices,KCWORDS+OFF_SESS,25);
devices[25] = '\0';
memset((void *)record,32,(size_t)5);
OSY_GETSYMB("I_TYPE",record,6);
(void) strncpy(devices,record,5);
OSY_GETSYMB("MIDOPTION",record,6);
if ((record[0] == 'P') || (record[0] == 'p'))
   devices[14] = 'P';
else
   devices[14] = ' ';
	
 
/*  in VMS test, if we are "submitted..."  */
 
KIWORDS[OFF_MODE+2] = 0;			/* interactive mode  */

#if vms
OSY_GETSYMB("BATCH",record,4);
if (record[0] == 'Y')
   {
   (void) printf("we are in batch mode...\r\n");
   KIWORDS[OFF_MODE+2] = 1;			/* batch mode  */
   }
#endif
 
 
/*  initialize logfile  */
 
OSY_GETSYMB("DAZUNIT",record,4);			/* get MIDAS unit */
	
status = MID_LOG('S',record,2);
if (status != ERR_NORMAL)
   {
   (void) printf("We could not start up the Midas logfile...\r\n");
   ospexit(1);
   }
 
 
/*  continue filling up key MID$SESS  */
 
devices[10] = record[0];
devices[11] = record[1];
devices[12] = ' ';
devices[13] = ' ';
	
unit = 3;
status = SCKWRC("MID$SESS",1,devices,1,25,&unit);
if (status != ERR_NORMAL) goto sect_5000;
 

/* get name of MIDAS user  */
 
if (KIWORDS[OFF_MODE+2] == 1)  	
   (void) strcpy(user,"MIDAS_JOB ");			/* batch mode  */
else
   OSY_GETSYMB("USER",user,24);
 
status = SCKWRC("USER",1,user,1,20,&unit);
if (status == ERR_NORMAL) return status; 
	

sect_5000:
(void) printf("problems in writing keyword %s\n\r",name);
ospexit(1);

no_data:
(void) printf("invalid data for keyword %s\n\r",name);
ospexit(1);
return ERR_NORMAL;		/* like in SCSEPI ... */
}

