/* @(#)consubs.c 17.1.1.1 (ESO-DMD) 01/25/02 17:37:02 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++++ module consubs +++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION Module consubs .AUTHOR K. Banse ESO - Garching .KEYWORDS connection, sockets .COMMENTS holds msetup, outmail .ENVIRONMENT UNIX .VERSION [1.00] 940426: pulled out from prepb.c 010424 last modif ------------------------------------------------------------------------*/ #include #include #include #ifndef SIGUSR1 #define SIGUSR1 30 #endif #ifndef SIGUSR2 #define SIGUSR2 31 #endif #include #include #define WRITE 1 #define READ 0 static int YesSignal; void intdum2() { YesSignal = 2; } /* */ msetup(flag,token1,token2,token3,token4) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE setup data for background activities flag = 0 DISCONNECT/BACK unit = 1 CONNECT/BACK unit ... .ALGORITHM .RETURNS = 0; all o.k. = 4; problems with socket communication = 34; BKMIDAS structure overflow = 90; invalid unit (FORGRxy.PID not found) = 100; invalid seconds -----------------------------------------------------------------*/ int flag; char *token1; /* IN: backgr. Midas unit */ char *token2; /* IN: `wait,seconds' string */ char *token3; /* IN: background char. */ char *token4; /* IN: connection method, `files' or `sockets' */ { register int nr, mr; int fid, iwc, nn, kk, jj, reto; int iwa[2], idum; float rdum; double ddum; char save[4], cbuf[20], wstr[84]; if (flag == 0) { /* clear background-Midas table */ if ((token1[0] == '?') || (token1[0] == '*')) { for (nr=0; nr 0) { /* remote host */ token1[jj] = '\0'; /* ':' -> '\0' */ nr = jj + 1; } else nr = 0; save[0] = CGN_UPPER(token1[nr++]); save[1] = CGN_UPPER(token1[nr]); if (save[2] == 'w') { save[2] = 'Y'; kk = CGN_INDEXC(token2,','); if (kk > 0) { iwc = CGN_CNVT(&token2[kk+1],1,1,&idum,&rdum,&ddum); if (iwc == 1) kk = idum; else kk = -1; /* that's an error */ if (kk < 0) { return (100); } } else kk = -1; } else { save[2] = 'N'; kk = 0; } for (nr=0; nr 0) /* remote MIDAS unit */ { if (strcmp(BKMIDAS[nr].HOST,token1) == 0) { if ( (BKMIDAS[nr].UNIT[0] == save[0]) && (BKMIDAS[nr].UNIT[1] == save[1]) && (BKMIDAS[nr].COMC == cbuf[0]) ) { iwc = nr; goto get_backpid; } } } else { if (BKMIDAS[nr].HOST[0] == '\0') { if ( (BKMIDAS[nr].UNIT[0] == save[0]) && (BKMIDAS[nr].UNIT[1] == save[1]) && (BKMIDAS[nr].COMC == cbuf[0]) ) { iwc = nr; goto get_backpid; } } } } for (nr=0; nr 0) (void)strcpy(BKMIDAS[iwc].HOST,token1); else BKMIDAS[iwc].HOST[0] = '\0'; if (BKMIDAS[iwc].METHOD != 's') /* for interrupts we need the PID */ { kk = CGN_COPY(wstr,XCONNECT.SBOX); kk -= 12; /* get rid of FORGRxy.SBOX */ (void)strcpy(&wstr[kk],"MIDAS .PID"); wstr[kk+5] = BKMIDAS[iwc].UNIT[0]; wstr[kk+6] = BKMIDAS[iwc].UNIT[1]; fid = osaopen(wstr,READ); /* open to read */ if (fid > 0) { kk = osaread(fid,wstr,40); if (kk > 0) (void)sscanf(wstr,"%d",&BKMIDAS[iwc].PID); (void)osaclose(fid); } if (BKMIDAS[iwc].PID == -1) return (90); /* could not read MIDASxy.PID */ } else { cbuf[0] = BKMIDAS[iwc].UNIT[0]; cbuf[1] = BKMIDAS[iwc].UNIT[1]; cbuf[2] = '\0'; kk = ClientInit(BKMIDAS[iwc].HOST,cbuf,&BKMIDAS[iwc].CHAN,&reto); if (kk == -1) return (4); /* no connection ... */ } } return (0); } /* */ int outmail(flag,comline,bgindx,retstat) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE send single line via file "FORGRxy.SBOX" to a `background' MIDAS and wait for receive_box .ALGORITHM .RETURNS = 0; all o.k. = 1; background is busy = 2; timed out = 3; background was busy + ignored last command sent = 4; problems with osx, `oserror' in retstat[0] = 5; problems with file/interrupts, specific error in retstat[0] = 7; socket connection was closed by command sent = 9; nothing to wait for (flag = 2) -----------------------------------------------------------------*/ int flag; /* IN: 1 = send command with/without wait 2 = only wait 3 = check, if finished */ char *comline; /* IN: command line to send */ int bgindx; /* IN: index in BKMIDAS */ int retstat[2]; /* OUT: return status (2 vals) from Background Midas */ { int tmout, fp, send_more, reto; int iwa[2], nn, kk, jj, wasbusy; float rdum; double ddum; char frname[80]; /* insert unit into relevant files */ if (BKMIDAS[bgindx].METHOD == 'f') /* files/interrupt service */ { XCONNECT.SBOX[XCONNECT.OFFS] = BKMIDAS[bgindx].UNIT[0]; XCONNECT.SBOX[XCONNECT.OFFS+1] = BKMIDAS[bgindx].UNIT[1]; XCONNECT.RBOX[XCONNECT.OFFS] = XCONNECT.SBOX[XCONNECT.OFFS]; XCONNECT.RBOX[XCONNECT.OFFS+1] = XCONNECT.SBOX[XCONNECT.OFFS+1]; XCONNECT.RBOX[XCONNECT.OFFR] = XCONNECT.MYUNIT[0]; /* return address.. */ XCONNECT.RBOX[XCONNECT.OFFR+1] = XCONNECT.MYUNIT[1]; } send_more = 0; wasbusy = 0; retstat[1] = 0; /* for flag=2, we wait on given unit until finished */ if (flag == 2) { if (BKMIDAS[bgindx].ACTIVE != 'N') { if (BKMIDAS[bgindx].METHOD == 'f') /* files/interrupt service */ { w_loop: fp = osaopen(XCONNECT.RBOX,READ); /* so, see if already done */ if (fp == -1) { OSY_SLEEP(100,1); /* wait .1 sec. */ goto w_loop; } else goto read_rbox; } else { jj = ClientWait(BKMIDAS[bgindx].CHAN,-1); /* wait forever */ if (jj == -1) return (4); goto read_socket; } } return (9); /* nothing there to wait for */ } /* for flag=3, we just check on given unit */ else if (flag == 3) { if (BKMIDAS[bgindx].METHOD == 'f') /* files/interrupt service */ { if (BKMIDAS[bgindx].ACTIVE != 'N') { fp = osaopen(XCONNECT.RBOX,READ); /* see if already done */ if (fp != -1) { kk = osaread(fp,frname,72); /* read a line */ (void)osaclose(fp); if (kk < 1) return (5); if (strncmp(frname,"BUSY",4) == 0) /* check for busy status */ return (1); } else return (1); } } else { jj = ClientWait(BKMIDAS[bgindx].CHAN,0); /* just check */ if ((BKMIDAS[bgindx].ACTIVE != 'N') && (jj == 0)) return (1); /* NODATA means it's busy */ if (jj == -1) return (4); } BKMIDAS[bgindx].ACTIVE = 'N'; return (0); } /* for flag=4, we read termination status of last command */ else if (flag == 4) { BKMIDAS[bgindx].ACTIVE = 'N'; /* always clear entry */ if (BKMIDAS[bgindx].METHOD == 'f') /* files/interrupt service */ { fp = osaopen(XCONNECT.RBOX,READ); /* open for reading */ if (fp == -1) return (5); kk = osaread(fp,frname,72); /* read a line */ (void)osaclose(fp); if (kk < 1) { *retstat = -2; return (5); } /* now pull out the status info */ kk = CGN_INDEXC(frname,'=') + 2; /* Status = `status' */ if (kk > 1) { if ((frname[kk] != '0') || (frname[kk+1] != '\0')) { nn = CGN_CNVT(&frname[kk],1,2,retstat,&rdum,&ddum); if (nn < 2) { *retstat = -3; return (5); } } else *retstat = 0; } else { *retstat = -3; return (5); /* strange Receive Box */ } } else { kk = ClientRead(BKMIDAS[bgindx].CHAN,frname,&jj,&reto); if (kk != 0) { *retstat = reto; return (4); } *retstat = jj; } return (0); } /* for flag=1, we send a command check, if we're still using same background Midas */ if (BKMIDAS[bgindx].ACTIVE != 'N') { send_more = 1; /* mark that we still have to send */ if (BKMIDAS[bgindx].METHOD == 'f') /* files/interrupt service */ { fp = osaopen(XCONNECT.RBOX,READ); /* so, see if already done */ if (fp == -1) return (1); goto read_rbox; } else { jj = ClientWait(BKMIDAS[bgindx].CHAN,0); if (jj == -1) return (4); else if (jj == 0) return (1); else goto read_socket; } } /* o.k. it's an idle guy, so make this entry active and send via `osx' or create FORGRbk.SBOX */ send_mail: BKMIDAS[bgindx].ACTIVE = 'A'; if (BKMIDAS[bgindx].METHOD == 's') { nn = BKMIDAS[bgindx].CHAN; kk = ClientWrite(nn,comline,&reto); /* send via osx + return */ if (kk != 0) { *retstat = reto; return (4); } if (BKMIDAS[bgindx].FLAG == 'N') { *retstat = 0; return (wasbusy); /* if we send without wait, that's it... */ } jj = ClientWait(BKMIDAS[bgindx].CHAN,BKMIDAS[bgindx].WAIT); if (jj != 1) return (2); /* we waited the whole time */ read_socket: BKMIDAS[bgindx].ACTIVE = 'N'; /* always clear entry */ kk = ClientRead(BKMIDAS[bgindx].CHAN,frname,&jj,&reto); if (kk == -1) { *retstat = reto; return (4); } else if (jj == 99) /* connection was closed by the command we sent */ return (7); if (send_more == 1) { send_more = 0; /* clear flag again */ goto send_mail; /* we still have to send our stuff */ } *retstat = jj; return (0); } /* ASCII file + interrupt section */ kk = osfdelete(XCONNECT.RBOX); /* try to delete own old receive box */ fp = osaopen("dummy",WRITE); /* create send_box */ if (fp == -1) { *retstat = -1; return(5); } osawrite(fp,comline,(int)strlen(comline)); (void)sprintf(frname,"%d",XCONNECT.MYPID); /* write own Pid */ osawrite(fp,frname,(int)strlen(frname)); (void)osaclose(fp); osfrename("dummy",XCONNECT.SBOX); /* move to real name */ if (BKMIDAS[bgindx].PID != -1) osssend(BKMIDAS[bgindx].PID,SIGUSR1); osscatch(SIGUSR2,intdum2); if (BKMIDAS[bgindx].FLAG == 'N') { *retstat = 0; return (wasbusy); /* if we send without wait, that's it... */ } if (BKMIDAS[bgindx].WAIT != -1) tmout = BKMIDAS[bgindx].WAIT; else tmout = 1; /* initial timeout for osswait */ /* now we wait until Backgr. Midas finishes */ wait: YesSignal = 0; osswait(SIGUSR2,tmout); /* wait max. `tmout' secs */ fp = osaopen(XCONNECT.RBOX,READ); /* open for reading */ if (fp == -1) { if ((BKMIDAS[bgindx].WAIT != -1) && (YesSignal == 0)) { (void)osscatch(SIGUSR2,intdum2); /* in case, signal comes later */ return (2); /* we waited the whole time */ } else { tmout = 5; /* new timeout for osswait */ (void)osscatch(SIGUSR2,intdum2); goto wait; } } /* read RBOX and get the return status */ read_rbox: BKMIDAS[bgindx].ACTIVE = 'N'; /* clear entry */ kk = osaread(fp,frname,72); /* read a line */ (void)osaclose(fp); if (kk < 1) { *retstat = -2; return (5); } if (strncmp(frname,"BUSY",4) == 0) /* background MIDAS was busy */ { if (send_more == 1) { wasbusy = 3; send_more = 0; /* clear flag again */ goto send_mail; /* we still have to send our stuff */ } else return (1); } if (send_more == 1) { send_more = 0; /* clear flag again */ goto send_mail; /* we still have to send our stuff */ } /* pull out status info */ kk = CGN_INDEXC(frname,'=') + 2; /* Status = `status' */ if (kk > 1) { if ((frname[kk] != '0') || (frname[kk+1] != '\0')) { nn = CGN_CNVT(&frname[kk],1,2,retstat,&rdum,&ddum); if (nn < 2) { *retstat = -3; return (5); } } else *retstat = 0; } else { *retstat = -3; return (5); /* strange Receive Box */ } return (wasbusy); }