/* @(#)scsa.c 17.1.1.2 (ESO-DMD) 02/25/02 17:53:50 */ /*=========================================================================== Copyright (C) 1995 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 020215 last modif -----------------------------------------------------------------------------*/ #include #include #include #include int SCSKIN(fname) char *fname; { long int modtim; long int oshtime(); 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; void tsubr(); static struct KEY_STRUCT *keypntr; modtim = oshtime(); /* get current time in secs */ i = KEY_MAXENT; k = LOC_MAXENT; keysize = sizeof(struct KEY_STRUCT) * (i + k + 1); /* + 1 for security */ tmpntr = (char *)malloc((unsigned int) 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((unsigned int) 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,&modtim,&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 if (k_typ == 'D') { 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 ++; CGN_FILL(keypntr->IDENT,' ',17); (void) memcpy(keypntr->IDENT,name,namelen); keypntr->IDENT[15] = k_typ; keypntr->BYTELEM = (short int) bytelem; keypntr->NOELEM = noelem; keypntr->LEN = byt_len; keypntr->FRPAD = (short int) pad; keypntr->MODTIME = modtim; keypntr->KLOCK = 0; 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 == -1) goto no_data; 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 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 == -1) goto no_data; 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 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 == -1) goto no_data; 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) ) ) { CGN_FILL(KCWORDS+from,' ',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 == -1) goto no_data; 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 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'; CGN_FILL(record,' ',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) goto sect_5000; /* if we're here not from `midasgo', open logfile */ if (KEYALL.ORIGIN == -1) { KEYALL.ORIGIN = -2; tsubr(); /* get terminal dimensions */ KIWORDS[OFF_LOG] = KIWORDS[OFF_LOG+7]; /* reset log flag */ status = MID_LOG('I',&KCWORDS[OFF_SESS+10],2); /* point to DAZUNIT */ if (status != ERR_NORMAL) MID_E1(1,"MID_LOG",status,1); /* if key LOG(1) = 2, init CPU timer */ if (KIWORDS[OFF_LOG] == 2) { int itime; itime = 0; status = OSY_TIMER('I',&itime); if (status != ERR_NORMAL) MID_E1(1,"OSY_TIMER",status,1); } } 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 ... */ }