/*===========================================================================
  Copyright (C) 1995-2010 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
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.LANGUAGE      C
.IDENT		MIDAS Monitor module prepz2.c
.KEYWORDS
  MIDAS monitor, process control
.COMMENTS
  holds hostinfo, ospsysinfo, pipe_mess
.VERSION

 100907		last modif	
-----------------------------------------------------------------------------*/

#include <fileexts.h>
#include <monitdef.h>
#include <midback.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <math.h>

/*
#include <sys/utsname.h>
*/

#define MAX_CBUF  4000





/* hostinfo: return useful system info */

int hostinfo(prf,sizes,node,mach,opsys)

int  prf;	/* IN: print flag (1 = yes) */
int *sizes;	/* OUT: 7 elements to get size of
			short int, int, long int,
			float, double,
			pointer, off_t, size_t */

char *node;	/* OUT: name of computer */
char *mach;	/* OUT: machine architecture */
char *opsys;	/* OUT: host system */

{
short int sm;
int  m, fid, svp, sst;
long int lm;
unsigned long int ulm;

float f;

double d;

size_t t;
off_t offset;

void *vp;

char   *workdir, filename[132], cbuf[144], myunit[4];

/*
struct utsname *sysbuf;
*/





*sizes = sizeof(sm);
*(sizes+1) = sizeof(m);
*(sizes+2) = sizeof(lm);
*(sizes+3) = sizeof(ulm);
*(sizes+4) = sizeof(f);
*(sizes+5) = sizeof(d);
*(sizes+6) = svp = sizeof(vp);
*(sizes+7) = sst = sizeof(t);
*(sizes+8) = sizeof(offset);

if (svp == 4)
   {
   KCWORDS[OFF_SYS+30] = '3';
   KCWORDS[OFF_SYS+31] = '2';
   }
else
   {
   KCWORDS[OFF_SYS+30] = '6';
   KCWORDS[OFF_SYS+31] = '4';
   }
m = OFF_AUX + 18;				/* point to AUX_MODE(19) */
KIWORDS[m++] = sst * 8;				/* 32 or 64 */

t = (size_t) pow((double)2,(double)(31));	/* store in AUX_MODE(20) */
KIWORDS[m] = (int) (t - 1); 			/* max signed int */

if (prf == 1)
   { 
   printf("size of short int = %d, int = %d (bytes)\n",*sizes,*(sizes+1));
   printf("size of long int = %d, unsigned long int = %d (bytes)\n",
          *(sizes+2),*(sizes+3));
   printf("size of float = %d, double = %d (bytes)\n",*(sizes+4),*(sizes+5));
   printf("size of pointer = %d, size_t = %d, off_t = %d (bytes)\n",
          svp,*(sizes+7),*(sizes+8));
   }


/* get machine hardware name + host system 
   using the uname() system call leads to segfault on Fedora 6 
   and also strange behaviour on Suse 11.1 ... 
   so we do it via: $ uname -mo > file                     */

#if !defined(__APPLE__)
(void) strcpy(cbuf,"uname -nmo > ");
#else					/* 'uname -o' not on Mac ... */
(void) strcpy(cbuf,"uname -nma > ");
#endif
 
if (!(workdir = getenv("MID_WORK")))
   {
   if (!(workdir = getenv("HOME"))) return (-1);

   (void) strcpy(filename,workdir);
   (void) strcat(filename,"/midwork");
   }
else
   (void) strcpy(filename,workdir);

myunit[0] = FRONT.DAZUNIT[0];
myunit[1] = FRONT.DAZUNIT[1];
myunit[2] = '\0';
(void) strcat(filename,"/Midas_info");
(void) strcat(filename,myunit);		/* filename: $MID_WORK/Midas_infoXY */

(void) strcat(cbuf,filename);
(void) system((const char *)cbuf); 			/* execute the $uname command */

fid = osaopen(filename,READ);
if (fid < 0) return (-1);

m = osaread(fid,cbuf,40);
osaclose(fid);
if (m < 0) return (-1);			/* could not read the file... */

m = CGN_INDEXC(cbuf,' ');	/* we should have the string: */
if (m < 0) return (-1);		/* "node mach opsys"          */   

cbuf[m] = '\0';
(void) strcpy(node,cbuf);
CGN_strcpy(cbuf,cbuf+m+1);

m = CGN_INDEXC(cbuf,' ');
if (m < 0) return (-1);

cbuf[m] = '\0';
(void) strcpy(mach,cbuf);
(void) strcpy(opsys,cbuf+m+1);

if (prf == 1)
   {
   printf("name: %s\n",node);
   printf("architecture: %s\n",mach);
   printf("hostsys: %s (%c%c bit)\n",opsys,
                    KCWORDS[OFF_SYS+30],KCWORDS[OFF_SYS+31]);
   }

return 0;



/* here is the code which fails on some Linux systems...

m = uname(sysbuf);

if (m == 0)
   {
   (void) strcpy(opsys,sysbuf->sysname);
   (void) strcpy(mach,sysbuf->machine);
   if (prf == 1)
      {
      printf("sysname: %s\n",sysbuf->sysname);
      printf("machine: %s\n",sysbuf->machine);
      printf("release: %s\n",sysbuf->release);
      printf("version: %s\n",sysbuf->version);
      }
   return 0;
   }
else
   {
   *opsys = '\0';
   *mach = '\0';
   return -1;
   }
*/

}

/*

*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Put a formatted string to stdout and MIDAS log
-1: the message identifier is wrong
0:  no error occured
implement the pipeline commands
MESS/OUT and APPEND/OUT
Put a formatted string to stdout using MID_message
which in turn calls the message() function
developed by S. Wolf for the FORS pipeline
-------------------------------------------------------------*/


void pipe_mess(actio)
char  actio;

{
static char  *bigbuf;

int    id, mess_level;
int    indent, stat, null, unit;
int    iav;
static int  cmapped = 0, clen = 0;

float  rbuf;

double  dbuf;







if (cmapped == 0)			/* allocate once */
   {
   bigbuf = (char*) malloc( (size_t)MAX_CBUF);
   if (bigbuf == (char *) NULL)
      {
      (void) SCTPUT("could not allocate memory for MESS_CBUF..");
      return;
      }
   cmapped = 1;
   clen = 0;
   }



/* if actio = A, we do APPEND/MESS */

if (actio == 'A') 
   {
   iav = TOKEN[1].LEN;				/* process message */
   if ((TOKEN[1].STR[0] == '"') && (TOKEN[1].STR[iav-1] == '"'))
      {
      iav -= 2;
      (void) memmove(TOKEN[1].STR,&TOKEN[1].STR[1],(size_t) iav);
      TOKEN[1].STR[iav] = '\0';
      } 

   if ((clen + iav) >= MAX_CBUF)
      { 
      SCTPUT("overflow in pipeline message buffer...so we flush it first");
      iav = MID_message(1," ",bigbuf,0);
      clen = 0;
      bigbuf[clen] = '\0';
      }

   (void) memcpy(bigbuf+clen,TOKEN[1].STR,(size_t)iav);
   clen += iav;
   bigbuf[clen] = '\0';
   return;
   }



/* here for MESSAGE/OUT ... */

id = 0;
(void) CGN_CNVT(TOKEN[1].STR,1,1,&id,&rbuf,&dbuf);
if (id < 0) 
   id = -id;
else if (id == 0)
   return;

stat = SCKRDI("MESS_LEVEL",1,1,&iav,&mess_level,&unit,&null);
if ((stat == 0) && (id > mess_level))
   goto end_of_it; 		/* that means: clear message buffer */


indent = 0;
if (TOKEN[4].STR[0] != '?')
   (void) CGN_CNVT(TOKEN[4].STR,1,1,&indent,&rbuf,&dbuf);

iav = TOKEN[3].LEN;				/* process message */
if ((TOKEN[3].STR[0] != '?') && (TOKEN[3].STR[0] != '+'))
   {
   if ((TOKEN[3].STR[0] == '"') &&
       (TOKEN[3].STR[iav-1] == '"'))
      {
      iav -= 2;
      (void) memmove(TOKEN[3].STR,&TOKEN[3].STR[1],(size_t) iav);
      TOKEN[3].STR[iav] = '\0';
      }

   if ((clen + iav) >= MAX_CBUF)
     (void) SCTPUT("overflow of pipeline message buffer...");
   else
      {
      (void) memcpy(bigbuf+clen,TOKEN[3].STR,(size_t)iav);
      clen += iav;
      bigbuf[clen] = '\0';
      } 
   }


/* process + display the complete message buffer */

iav = MID_message(id,TOKEN[2].STR,bigbuf,indent);    
if (iav < 0) printf("`message' returned %d\n",iav);


end_of_it:
clen = 0;			/* clear buffer again */
bigbuf[0] = '\0';
}

