X-NEWS: cerritos.edu vmsnet.sources: 350 Relay-Version: VMS News - V6.0-1 14/11/90 VAX/VMS V5.3; site cerritos.edu Path: cerritos.edu!usc!rutgers!maverick.ksu.ksu.edu!deimos.cis.ksu.edu!mccall!miclon!ibmpcug!ctssuk!VERKADE Newsgroups: vmsnet.sources Subject: DWUTILS V1.0 part 4 of 6 Message-ID: <901223133603.00000F02@MARVIN.CTSS.CO.UK> From: VERKADE@CTSS.CO.UK (Herman Verkade) Date: 23 Dec 90 13:36:03 GMT Followup-To: vmsnet.sources.d Organization: CompuThoughts Software Solutions (UK) Ltd. Keywords: DECwindows utilities Lines: 487 -+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+ X`09`09lib$signal(DWSTART_TOOMANYPROC, 0); X`09 `7D X`09`7D X X`09ChildInfo`5BChildNr`5D.Busy = 1; X`09ChildInfo`5BChildNr`5D.AstRoutine = AstRoutine; X`09ChildInfo`5BChildNr`5D.AstParam = AstParam; X X`09Status = sys$crembx(0, &Channel, 0, 0, 0, 0, 0); X`09if (!(Status & 1)) lib$signal(DWSTART_CREMBXERR, 0, Status, 0); X X`09MbxUnit = GetUnitNumber(Channel); X X`09Status = sys$qio(0, Channel, IO$_READVBLK, &ChildInfo`5BChildNr`5D.Iosb, X`09`09MailboxAST, ChildNr, &ChildInfo`5BChildNr`5D.ProcessInfo, X`09`09sizeof(ChildInfo`5BChildNr`5D.ProcessInfo), 0, 0, 0, 0); X`09if (!(Status & 1)) lib$signal(DWSTART_READERR, 1, 0, Status); X`09ChildInfo`5BChildNr`5D.Channel = Channel; X `7D else `7B X`09MbxUnit = 0; X `7D X X DscInput.dsc$w_length = strlen(Input); X DscInput.dsc$a_pointer = Input; X DscOutput.dsc$w_length = strlen(Output); X DscOutput.dsc$a_pointer = Output; X DscDisplay.dsc$w_length = strlen(DisplayName); X DscProcessName.dsc$w_length = strlen(ProcessName); X DscProcessName.dsc$a_pointer = ProcessName; X X Status = sys$creprc(&Pid, &DscImage, &DscInput, &DscOutput, &DscDisplay, V 0, X`09 0, &DscProcessName, 0, 0, MbxUnit, X`09 PRC$M_DETACH `7C PRC$M_NOPASSWORD `7C (Interactive ? PRC$M_INTER : 0) V); X if (!(Status & 1)) lib$signal(DWSTART_CREPRCERR, 0, Status); X lib$signal(DWSTART_PROC_ID, 1, Pid); X return; X`7D X Xvoid MailboxAST(ChildNr) Xint ChildNr; X`7B X unsigned int Status; X X Status = ChildInfo`5BChildNr`5D.Iosb.IoStat; X if (!(Status & 1)) `7B X`09lib$signal(DWSTART_READERR, 1, 0, Status, 0); X `7D else `7B X`09Status = ChildInfo`5BChildNr`5D.ProcessInfo.acc$l_finalsts; X`09if (!(Status & 1)) lib$signal(DWSTART_PROCEXIT, 0, Status); X `7D X X Status = sys$dassgn(ChildInfo`5BChildNr`5D.Channel); X if (!(Status & 1)) lib$signal(DWSTART_DASSGNERR, 0, Status); X X if (ChildInfo`5BChildNr`5D.AstRoutine) `7B X`09(*ChildInfo`5BChildNr`5D.AstRoutine)(ChildInfo`5BChildNr`5D.AstParam); X `7D X ChildInfo`5BChildNr`5D.Busy = 0; X return; X`7D X`0C X/* X * The newly created process will not know about the logicals of this proces Vs. X * Use ParseFileName to get a name that is far more likely to be valid in th Ve X * new process (There are off course still some situations that causes this X * to fail.....). X */ XParseFileName(Input, Output, Size) Xchar *Input, *Output; Xint Size; X`7B X unsigned int Status; X struct FAB Fab; X struct NAM Nam; X X Fab = cc$rms_fab; X Fab.fab$l_fna = Input; X Fab.fab$b_fns = strlen(Input); X Fab.fab$l_nam = &Nam; X Nam = cc$rms_nam; X Nam.nam$l_esa = Output; X Nam.nam$b_ess = Size; X X Status = sys$parse(&Fab); X if (!(Status & 1)) lib$signal(DWSTART_PARSEERR, 2, strlen(Input), Input, X`09 Status, Fab.fab$l_stv); X Output`5BNam.nam$b_esl`5D = '\0'; X return; X`7D $ CALL UNPACK DWSTART_MISC.C;36 738710885 $ create 'f' X/* X * Module:`09DWstart_Remote.c X * Author:`09Herman Verkade X * Description:`09Program to start a DECwindows application on a remote node X * X * Revision History: X * X * 6-dec-1990 002 HHV`09- Rewrite to shareable image X * 19-oct-1990 001 HHV`09- Rewrite everything into one image with CLI interf Vace X * 10-sep-1990 000 HHV `09- New Module X */ X X#include "DWstart_Share.h" X X#include ssdef X#include descrip X#include iodef X Xvoid NetworkAST(int); Xvoid DisconnectAST(int); X X#define MAX_CHILDREN 20 X Xstatic struct `7B X unsigned char Busy; X unsigned short Channel; X void (*AstRoutine)(int); X int AstParam; X struct `7B X`09unsigned short IoStat; X`09unsigned short InCount; X`09unsigned int IoSender; X `7D Iosb; X struct `7B X`09unsigned int ReturnStatus; X `7D DataBuffer; X`7D ChildInfo`5BMAX_CHILDREN`5D; `20 X X/* X * SendToRemote: Takes whatever the command is and sends it to the remote X * system for processing. The command is not parsed on the local system at a Vll. X * It is up to the remote machine to check whether the command is valid. Thi Vs X * allows you to update DWstart on some central system to include an X * application that can run there, without having to update all the X * workstations. X */ XSendToRemote(RemoteNode, CommandLine) Xchar *RemoteNode, *CommandLine; X`7B X unsigned int Status; X unsigned short Channel; X int ChildNr; X char Node`5BNODENAME_LEN + 1`5D, Transport`5BTRANSPORTNAME_LEN + 1`5D; X char Server`5BSERVERNAME_LEN + 1`5D, Screen`5BSCREENNAME_LEN + 1`5D; X char RemoteSpec`5B64`5D, DisplayInfo`5B64`5D; X $DESCRIPTOR(DscRemoteSpec, RemoteSpec); X struct `7B X`09unsigned int IoStat; X`09unsigned int IoLength; X `7D Iosb; X X/* X * Before we go to another machine, get the information about the display. X */ X GetDisplayInfo(Node, Transport, Server, Screen); X X/* X * Now start talking to the remote system. X */ X sprintf(RemoteSpec, "%s::\"0=DWSTART\"", RemoteNode); X DscRemoteSpec.dsc$w_length = strlen(RemoteSpec); X X Status = sys$assign(&DscRemoteSpec, &Channel, 0, 0); X if (!(Status & 1)) lib$signal(DWSTART_ASSIGNERR, 1, &DscRemoteSpec, Stat Vus); X X/* X * First, send the display info X */ X sprintf(DisplayInfo, "%s %s %s %s", Node, Transport, Server, Screen); X Status = sys$qiow(0, Channel, IO$_WRITEVBLK, &Iosb, 0, 0, DisplayInfo, X`09 strlen(DisplayInfo), 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_WRITEERR, 1, &DscRemoteSpec, Statu Vs); X X/* X * Next, send the command X */ X Status = sys$qiow(0, Channel, IO$_WRITEVBLK, &Iosb, 0, 0, CommandLine, X`09 strlen(CommandLine), 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_WRITEERR, 1, &DscRemoteSpec, Statu Vs); X X/* X * The return status is deliver asynchronously. The ChildInfo table holds X * information about what AST to deliver when what happens. X */ X for (ChildNr = 0; ChildInfo`5BChildNr`5D.Busy; ) `7B X`09if (++ChildNr >= MAX_CHILDREN) `7B X`09 lib$signal(DWSTART_TOOMANYLINKS, 0); X`09`7D X `7D X X ChildInfo`5BChildNr`5D.Busy = 1; X ChildInfo`5BChildNr`5D.Channel = Channel; X ChildInfo`5BChildNr`5D.AstRoutine = AstRoutine; X ChildInfo`5BChildNr`5D.AstParam = AstParam; X X Status = sys$qio(0, Channel, IO$_READVBLK, &ChildInfo`5BChildNr`5D.Iosb, X`09 NetworkAST, ChildNr, &ChildInfo`5BChildNr`5D.DataBuffer, X`09 sizeof(ChildInfo`5BChildNr`5D.DataBuffer), 0, 0, 0, 0); X if (!(Status & 1)) lib$signal(DWSTART_READERR, 1, &DscRemoteSpec, Status V); X X return(SS$_NORMAL); X`7D X Xvoid NetworkAST(ChildNr) Xint ChildNr; X`7B X unsigned int Status; X X Status = ChildInfo`5BChildNr`5D.Iosb.IoStat; X if (!(Status & 1)) `7B X`09lib$signal(DWSTART_READERR, 1, 0, Status, 0); X `7D else `7B X`09Status = ChildInfo`5BChildNr`5D.DataBuffer.ReturnStatus; X`09if (!(Status & 1)) lib$signal(DWSTART_REMOTE, 0, Status); X `7D X Status = sys$qio(0, ChildInfo`5BChildNr`5D.Channel, IO$_DEACCESS `7C IO$ VM_SYNCH, X`09 &ChildInfo`5BChildNr`5D.Iosb, DisconnectAST, ChildNr, 0, 0, 0, 0, 0, V 0); X if (!(Status & 1)) lib$signal(DWSTART_NETWDISCERR, 2, 1, 0, Status); X return; X`7D X Xvoid DisconnectAST(ChildNr) Xint ChildNr; X`7B X unsigned int Status; X X Status = ChildInfo`5BChildNr`5D.Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_NETWDISCERR, 2, 1, 0, Status); X X Status = sys$dassgn(ChildInfo`5BChildNr`5D.Channel); X if (!(Status & 1)) lib$signal(DWSTART_DASSGNERR, 0, Status); X X if (ChildInfo`5BChildNr`5D.AstRoutine) `7B X`09(*ChildInfo`5BChildNr`5D.AstRoutine)(ChildInfo`5BChildNr`5D.AstParam); X `7D X ChildInfo`5BChildNr`5D.Busy = 0; X return; X`7D $ CALL UNPACK DWSTART_REMOTE.C;24 1175817498 $ create 'f' X/* X * Module:`09DWstart_Server.c X * Author:`09Herman Verkade X * Description:`09Server process for DWSTART: Start a DECwindows application X * X * Revision History: X * X * 6-dec-1990 000 HHV`09- Created separate image for server X * X * Things to be done: X * X * - Each invocation currently creates a new WSA device. Use $DEVICE_SCAN X * to find a display already pointing to the right screen and use that. X */ X X#include "DWstart.h" X X#include ssdef X#include descrip X#include iodef X Xvoid AST(); Xunsigned int ErrorHandler(unsigned int*, unsigned int*); X Xstatic unsigned int ApplStatus = SS$_NORMAL; X Xmain() X`7B X unsigned int Status; X unsigned short Channel; X char Node`5BNODENAME_LEN + 1`5D, Transport`5B15`5D, Server`5B10`5D, Scre Ven`5B10`5D; X char RemoteSpec`5B64`5D, DisplayInfo`5B64`5D; X char Command`5B255`5D; X $DESCRIPTOR(DscSysNet, "SYS$NET"); X struct `7B X`09unsigned short IoStat; X`09unsigned short IoLength; X`09unsigned int Reserved; X `7D Iosb; X X Status = sys$assign(&DscSysNet, &Channel, 0, 0); X if (!(Status & 1)) lib$signal(Status); X X Status = sys$qiow(0, Channel, IO$_READVBLK, &Iosb, 0, 0, DisplayInfo, X`09 sizeof(DisplayInfo), 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X DisplayInfo`5BIosb.IoLength`5D = '\0'; X X/* X * The remote part will send one packet containing all the information about X * the display. If the display is on the local node, avoid overhead by using X * the LOCAL transport. X */ X X sscanf(DisplayInfo, "%s%s%s%s", Node, Transport, Server, Screen); X X if (!strcmp(Node, DWS_Get_Local_NodeName()) && X`09 !strcmp(Transport, "DECNET")) `7B X`09strcpy(Node, "0"); X`09strcpy(Transport, "LOCAL"); X `7D X `20 X CreateDisplay(Node, Transport, Server, Screen); X X/* X * The next packet will contain the command we need to execute here X */ X Status = sys$qiow(0, Channel, IO$_READVBLK, &Iosb, 0, 0, Command, X`09 sizeof(Command), 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X Command`5BIosb.IoLength`5D = '\0'; X X lib$establish(ErrorHandler); X X Status = sys$clref(51); X if (!(Status & 1)) lib$signal(Status); X ApplStatus = DWS_Start_Application(0, Command, AST, 0); X if (ApplStatus & 1) `7B X`09Status = sys$waitfr(51); X`09if (!(Status & 1)) lib$signal(Status); X `7D X X lib$establish(0); X X Status = sys$qiow(0, Channel, IO$_WRITEVBLK, &Iosb, 0, 0, &ApplStatus, X`09 sizeof(ApplStatus), 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X Status = sys$qiow(0, Channel, IO$_DEACCESS `7C IO$M_SYNCH, &Iosb, 0, 0, V 0, 0, X`09 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X Status = sys$dassgn(Channel); X if (!(Status & 1)) lib$signal(Status); X X return(SS$_NORMAL); `20 X`7D X`0C XCreateDisplay(Node, Transport, Server, Screen) Xchar *Node, *Transport, *Server, *Screen; X`7B X unsigned int Status; X unsigned short Channel; X char DisplayName`5BDISPLAYNAME_LEN + 1`5D; X $DESCRIPTOR(DscDisplay, DisplayName); X $DESCRIPTOR(DscDecwDisplay, "DECW$DISPLAY"); X $DESCRIPTOR(DscWsa0, "WSA0:"); X struct `7B X`09unsigned int IoStat; X`09unsigned int IoLength; X `7D Iosb; X X/* X * Get a new WSA device X */ X X Status = sys$assign(&DscWsa0, &Channel, 0, 0); X if (!(Status & 1)) lib$signal(Status); X X/* X * Set the Node, Transport, Server and Screen parameters X */ X Status = sys$qiow(0, Channel, IO$_SETMODE `7C 0x40, &Iosb, 0, 0, Node, X`09 strlen(Node), 1, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X Status = sys$qiow(0, Channel, IO$_SETMODE `7C 0x40, &Iosb, 0, 0, Transpo Vrt, X`09 strlen(Transport), 2, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X Status = sys$qiow(0, Channel, IO$_SETMODE `7C 0x40, &Iosb, 0, 0, Server, X`09 strlen(Server), 3, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X Status = sys$qiow(0, Channel, IO$_SETMODE `7C 0x40, &Iosb, 0, 0, Screen, X`09 strlen(Screen), 4, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X/* X * Make it a permanent display X */ X Status = sys$qiow(0, Channel, IO$_SETMODE `7C 0x80, &Iosb, 0, 0, 1, 0, 0 V, 0, X`09 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X X/* X * From V5.3 onwards we need to make the display a executive mode display X */ X#ifndef V52 X Status = sys$qiow(0, Channel, IO$_SETMODE `7C 0x40, &Iosb, 0, 0, &1, X`09 sizeof(int), 5, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(Status); X#endif X X/* X * Store the name of the display X */ X DWS_Get_DeviceName(Channel, DisplayName, sizeof(DisplayName)); X X/* X * Release the channel X */ X Status = sys$dassgn(Channel); X if (!(Status & 1)) lib$signal(Status); X X/* X * Set up DECW$DISPLAY for DECterm routines. X */ X DscDisplay.dsc$w_length = strlen(DisplayName); X Status = lib$set_logical(&DscDecwDisplay, &DscDisplay); X if (!(Status & 1)) lib$signal(Status); X `20 X return(Status); X`7D X Xunsigned int ErrorHandler(Signal, Mechanism) Xunsigned int *Signal, *Mechanism; X`7B X unsigned int Status; X int i; X static char Active; X static $DESCRIPTOR(DscFacility, "DWSTART"); X X if (!Active && Signal`5B1`5D != SS$_UNWIND) `7B X`09Active = 1; X`09for (i = 1; i < Signal`5B0`5D - 1; i += Signal`5Bi + 1`5D + 2) `7B X`09 ApplStatus = Signal`5Bi`5D; X`09`7D X`09Status = sys$putmsg(Signal, 0, &DscFacility, 0); X`09if (!(Status & 1)) lib$signal(Status); X`09Active = 0; X`09if ((Signal`5B1`5D & 7) == 4) `7B X`09 Mechanism`5B3`5D = ApplStatus; X`09 sys$unwind(0, 0); X`09 return(SS$_RESIGNAL); X`09`7D X`09return(SS$_CONTINUE); X `7D X return(SS$_RESIGNAL); X`7D X Xvoid AST() X`7B X unsigned int Status; X X Status = sys$setef(51); X if (!(Status & 1)) lib$stop(Status); X return; X`7D $ CALL UNPACK DWSTART_SERVER.C;23 1644300503 $ create 'f' X/* X * Module:`09DWstart_Share.c X * Author:`09Herman Verkade +-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-