/* @(#)prepa.c 17.1.1.1 (ESO-DMD) 01/25/02 17:37:36 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++++++++++++ PREPA +++++++++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION MIDAS front end (main module PREPA) holds intermail, main (terminal front end) module, init_here .AUTHOR K. Banse / IPG ESO - Garching .KEYWORDS MIDAS front end .ENVIRONMENT VMS and UNIX .PURPOSE synchronize fore- and background processes; get the MIDAS command string + take action accordingly .ALGORITHM loop on command input from terminal and pass commands to MIDAS monitor test for background activity and synchronize we have our "own" connected MIDAS - commands are passed via calls of `prepx' .RETURNS nothing .VERSION [1.00] 930125: pulled out from "old" prepa.c 010917 last modif ------------------------------------------------------------------------*/ #include #include /* Defines SccsId for system command "what"*/ #include /* Defines STDIN_FILENO */ #include #ifndef SIGUSR1 #define SIGUSR1 30 #endif #ifndef SIGUSR2 #define SIGUSR2 31 #endif #ifndef STDIN_FILENO #define STDIN_FILENO 0 #endif #define TW_import 0 #include #include #include #include #include #include #include static char wstr[160]; static int tcols; int is_a_tty; /* Is this a terminal, (yes=1) */ /* */ void intermail() { osscatch(SIGUSR1,intermail); /* reenable interrupt catching */ if (server.MODE == 2) return; /* already in background mode ... */ if (TERM.INTENA != 1) { busymail(); return; } if (TERM.FLAG == 1) SupplyInput("\r"); TERM.TIMEOUT = 2; /* get current process id and send alarm signal to force timeout */ osssend(FRONT.PID,SIGALRM); } /* */ main() { int pxflag, lwindow, kk, jj, iwa; int pxinfo[6]; int cur_com, termflag, more_cmnds; char firstchar, *cpntr; char rmaind[200]; /* first time activities here... */ is_a_tty = isatty(STDIN_FILENO); /* Is this is a terminal ? (yes=1) */ tcols = 80; TERM.LINES = 24; /* initial values */ cur_com = 0; more_cmnds = 0; init_here(wstr,pxinfo); /* initialize with `prepx' */ /* startup by executing systemwide LOGIN procedure */ pxflag = -3; /* -3 tells the Monitor to do that */ login_job: (void) TTSET(0); /* close terminal settings */ iwa = prepx(pxflag,wstr,pxinfo); (void) TTSET(1); /* set terminal settings */ switch(iwa) { case -1: /* back from command BYE */ moncnt = 0; (void) COM_WINDOW("WR",&cur_com); /* save comnd-buf in midtempXY.prg */ if (server.MODE != 0) inmail(9,rmaind,&iwa); /* tidy up any outstanding mail */ (void) TTSET(2); /* close terminal */ #ifndef NO_READLINE free_cmd_list(); /* free the cmd_list allocated for readline */ close_xhelp(); /* close socket with the GUI help */ #endif ospexit(0); /* and get the hell out of here... */ case 1: FRONT.COMCNT = 999; /* forces a CLEAR next time */ break; case 2: (void) COM_WINDOW("RE",&cur_com); break; case 3: (void) COM_WINDOW("EXT",&cur_com); break; case 4: moncnt = pxinfo[0]; (void) COM_WINDOW("WR",&cur_com); break; case 6: #if vms TTSET(2); /* close terminal */ TTINIT(1); /* reinitialize */ TERM.EDITMODE = pxinfo[0]; #endif break; default: /* check if system + personal login.prg was o.k. */ (void) SCKRDI("ERROR",3,2,&iwa,pxinfo,&kk,&jj); /* still = 79? */ if (pxinfo[0] != 0) { pxinfo[0] = 0; pxinfo[1] = 1; kk = 0; (void) SCKWRI("ERROR",pxinfo,3,2,&kk); SCTPUT("Warning: Your `login.prg' is incorrect...!"); SCTPUT ("Execute it again via `@@ login' to get the relevant error messages"); } goto main_loop; /* login part finished */ } pxflag = 1; /* tell prepx that we continue */ goto login_job; main_loop: /* ---------- */ termflag = 0; /* clear terminal_input_flag */ lwindow = 1; /* default to store in command window */ if (FRONT.INTERM == 1) /* last time was an interrupt */ { FRONT.INTERM = 0; /* reset mail_interrupt_flag */ ERRORS.SYS = inmail(8,rmaind,&iwa); /* it's the `file/int' mechanism */ if (ERRORS.SYS != 0) goto mail_error; } FRONT.COMCNT++; /* increment command counter */ if (FRONT.COMCNT > 999) { /* reset FRONT.COMCNT + clear command window */ (void) COM_WINDOW("CL",&iwa); FRONT.COMCNT = 1; } cpntr = FRONT.PROMPT + FRONT.PEND; /* build prompt string */ (void) sprintf(cpntr,"%3.3d%c ",FRONT.COMCNT,FRONT.ENV); if (more_cmnds > 0) /* test, if several commans in line */ { kk = break_line(&more_cmnds,rmaind); if (kk != -1) goto parsing; } if (server.MODE != 0) /* If we are in background mode */ { /* look for input from clients */ ERRORS.SYS = inmail(1,rmaind,&iwa); if (ERRORS.SYS != 0) goto mail_error; } else { iwa = MYREAD(); /* wait for input from terminal */ if (TERM.TIMEOUT == 2) /* if there was a mail interrupt */ { FRONT.INTERM = 1; /* so next time we know */ ERRORS.SYS = inmail(1,rmaind,&iwa); /* get input from clients */ if (ERRORS.SYS != 0) goto mail_error; } else if (iwa == -1) { /* a playback is finished */ (void) prepx(-4,wstr,pxinfo); /* tell Monitor */ goto main_loop; } TERM.TIMEOUT = 0; } ERRORS.OFFSET = FRONT.PEND + 5; tinfo(&kk,&jj); /* get current terminal size */ if ((tcols != kk) || (TERM.LINES != jj)) { tcols = kk; TERM.LINES = jj; pxinfo[0] = tcols; pxinfo[1] = TERM.LINES; (void) prepx(-6,wstr,pxinfo); } more_cmnds = 0; kk = break_line(&more_cmnds,rmaind); if (kk == -1) /* e.g. only RETURN key... */ { if (LINE.STR[0] == '!') { (void) MID_LOG('G',LINE.STR,LINE.LEN); /* log comment line */ FRONT.COMCNT--; /* and go for next command */ } else (void) COM_WINDOW("SH",&iwa); goto main_loop; } /* */ /* now parse terminal input */ parsing: termflag++; /* increment terminal_input_flag */ moncnt = 0 ; /* init moncnt */ /* now we do, what PARSE does on the server side */ for (kk=0; kk= '0') && (firstchar <= '9')) || (firstchar == '.') || (firstchar == ':') ) { if (termflag > 20) /* avoid infinite loops */ { ERRORS.SYS = 5; goto error_1; } else { lwindow = 0; iwa = NUMBIZ(&cur_com); if (iwa == -1) goto main_loop; else if (iwa > 0) { if (iwa == 2) lwindow = 1; /* edited comnds are stored */ kk = REDOBIZ(iwa); if (kk == 0) goto main_loop; else { ERRORS.OFFSET = 0; kk = 0; (void) break_line(&kk,wstr); if (kk != 0) { /* update `rmaind' buffer */ if (more_cmnds != 0) (void) strcat(wstr,rmaind); (void) strcpy(rmaind,wstr); more_cmnds = 1; } goto parsing; } } } } /* store command in command window */ if (lwindow != 0) { (void) COM_WINDOW("AD",&cur_com); lwindow = 0; /* make sure we only store once */ if (firstchar == '+') goto main_loop; } /* */ /* prepare char. + int buffers for `prepx' call */ pxflag = 0; /* normal call of prepx */ call_job: (void) TTSET(0); /* close terminal settings */ iwa = prepx(pxflag,wstr,pxinfo); (void) TTSET(1); /* set terminal settings */ switch(iwa) { case -1: /* back from command BYE */ moncnt = 0; (void) COM_WINDOW("WR",&cur_com); /* save comnd-buf in midtempXY.prg */ if (server.MODE != 0) inmail(9,rmaind,&iwa); /* tidy up any outstanding mail */ (void) TTSET(2); /* close terminal */ #ifndef NO_READLINE free_cmd_list(); /* free the cmd_list allocated for readline */ close_xhelp(); /* close socket with the GUI help */ #endif ospexit(0); /* and get the hell out of here... */ case 0: goto main_loop; /* "normal" return from prepx */ case 1: FRONT.COMCNT = 999; /* forces a CLEAR next time */ break; case 2: (void) COM_WINDOW("RE",&cur_com); break; case 3: (void) COM_WINDOW("EXT",&cur_com); break; case 4: moncnt = pxinfo[0]; (void) COM_WINDOW("WR",&cur_com); break; case 5: FRONT.PP = CGN_OPEN(wstr,0); /* open for reading only */ if (FRONT.PP == -1) { FRONT.PLAYBACK = 0; ERRORS.SYS = 22; PREPERR("FSY",wstr," "); } else { char str[120]; (void) sprintf(str,"--- starting playback from: %s ---",wstr); SCTPUT(str); } goto main_loop; /* now read input from playback file */ case 6: #if vms TTSET(2); /* close terminal */ TTINIT(1); /* reinitialize */ TERM.EDITMODE = pxinfo[0]; #endif break; case 7: /* playback aborted in Monitor */ osaclose(FRONT.PP); goto main_loop; /* now read input from terminal */ case 99: /* that's the end of a batch run */ LINE.LEN = CGN_COPY(LINE.STR,"BYE"); goto parsing; /* emulate a BYE */ default: (void) printf("Prepa: We should never come here...\n\r"); } pxflag = 1; /* tell prepx that we continue */ goto call_job; /* come here to display error messages */ error_1: if (ERRORS.INDEX == -1) PREPERR("MIDAS",LINE.STR," "); else PREPERR("MIDAS",LINE.STR,TOKEN[ERRORS.INDEX].STR); goto main_loop; /* look for next command */ mail_error: PREPERR("OSY",""," "); goto main_loop; /* look for next command */ } /* */ void init_here(cp,ip) char *cp; int *ip; { int fid, stat, jj; register int nr; /* get symbols DAZUNIT, MID_WORK (as was done in INPREPA before) */ OSY_GETSYMB("DAZUNIT",wstr,4); FRONT.DAZUNIT[0] = wstr[0]; FRONT.DAZUNIT[1] = wstr[1]; stat = OSY_TRNLOG("MID_WORK",wstr,160,&jj); /* Decode startup directory */ if ( (stat != 0) || (jj > 160) ) { (void) printf ("we could not translate MID_WORK or MID_WORK > 160 char.\n\r"); ospexit(1); } #if vms if (wstr[jj-1] != FSY_DISKEND) { if (wstr[jj-1] != FSY_DIREND) { wstr[jj++] = FSY_DIREND; wstr[jj] = '\0'; } } #else if (wstr[jj-1] != FSY_DIREND) { wstr[jj++] = FSY_DIREND; wstr[jj] = '\0'; } #endif (void) strcpy(FRONT.STARTUP,wstr); /* save name of startup directory */ (void) strcpy(FRONT.PROMPT,"Midas "); /* init prompt string */ FRONT.PEND = 6; /* length of prompt + 1 */ /* get PID + also store PID in file MIDASxy.PID */ FRONT.PID = oshpid(); /* get process id */ jj = CGN_COPY(wstr,FRONT.STARTUP); (void) strcpy(&wstr[jj],"MIDAS .PID"); wstr[jj+5] = FRONT.DAZUNIT[0]; wstr[jj+6] = FRONT.DAZUNIT[1]; fid = osaopen(wstr,1); if (fid > 0) { #if vms (void)sprintf(wstr,"%X",FRONT.PID); /* we need PID in hexa ... */ #else (void)sprintf(wstr,"%d",FRONT.PID); #endif osawrite(fid,wstr,(int)strlen(wstr)); osaclose(fid); } else (void) printf("Could not build PID file MIDAS%c%c.PID\n\r", FRONT.DAZUNIT[0],FRONT.DAZUNIT[1]); FRONT.PP = -1; FRONT.PLAYBACK = 0; FRONT.INTERM = 0; FRONT.ENV = '>'; server.MODE = 0; server.ECHO = 'N'; for (nr=0; nr<10; nr++) { OLDTOKEN[nr].STR[0] = '?'; OLDTOKEN[nr].STR[1] = '\0'; OLDTOKEN[nr].LEN = 1; } (void) inxcon(FRONT.DAZUNIT,FRONT.STARTUP); /* init communication stuff */ ip[0] = tcols; ip[1] = TERM.LINES; (void) prepx(-1,cp,ip); /* init on server side */ TERM.FLAG = ip[3]; TERM.EDITMODE = 0; TERM.INTENA = 0; (void) strncpy(FRONT.TITLE,cp,13); /* (P) MIDAS version patch_level */ if (FRONT.TITLE[12] != ' ') FRONT.TITLE[13] = '\0'; else FRONT.TITLE[11] = '\0'; cp += 13; (void) strncpy(FRONT.SYSTEM,cp,20); /* create command buffer with 15 entries + init title for command list */ jj = 15; (void) COM_WINDOW("INIT",&jj); osscatch(SIGUSR1,intermail); /* `intermail' for mail interrupts */ (void) TTINIT(ip[2]); /* pass the header flag */ }