X-NEWS: cerritos.edu vmsnet.sources: 349 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 3 of 6 Message-ID: <901223133553.00000F02@MARVIN.CTSS.CO.UK> From: VERKADE@CTSS.CO.UK (Herman Verkade) Date: 23 Dec 90 13:35:53 GMT Followup-To: vmsnet.sources.d Organization: CompuThoughts Software Solutions (UK) Ltd. Keywords: DECwindows utilities Lines: 518 -+-+-+-+-+-+-+-+ START OF PART 3 -+-+-+-+-+-+-+-+ X Status = DECwTermPort(0, ResourceFile, Customization, Terminal, &RetLen) V; X if (!(Status & 1)) `7B X`09lib$signal(Status); X `7D X Terminal`5BRetLen`5D = '\0'; X return; X`7D X X#ifdef V52 Xfix_DECwTermPort_bug() X`7B X int fix`5B258`5D; X fix`5B0`5D = 0; X fix2(fix); X return; X`7D X Xfix2(fix) Xint *fix; X`7B X return; X`7D X Xstatic CheckForController() X`7B X unsigned int Status; X unsigned short Channel; X char LogName`5B64`5D, MbxName`5BMAILBOXNAME_LEN + 1`5D; X $DESCRIPTOR(DscMbxName, MbxName); X X sprintf(LogName, "DECW$DECTERM_MAILBOX_%s", DWS_Get_DisplayName()); X DscMbxName.dsc$w_length = TranslateLogical(LogName, MbxName, X`09 sizeof(MbxName), 0); X Status = sys$assign(&DscMbxName, &Channel, 0, 0); X if (!(Status & 1)) `7B X`09if (Status == SS$_IVLOGNAM `7C`7C Status == SS$_NOSUCHDEV) `7B X`09 StartDECtermController(); X`09 sleep(2); X`09`7D else `7B X`09 lib$signal(Status); X`09`7D X `7D else `7B X`09Status = sys$dassgn(Channel); X `7D X return; X`7D X#endif $ CALL UNPACK DWSTART_DECTERM.C;30 1176685176 $ create 'f' X/* X * Module:`09DWstart_Display.c X * Author:`09Herman Verkade X * Description:`09Get information about display X * X * Revision History: X * X * 7-dec-1990 000 HHV `09- New Module X */ X X#include "DWstart_Share.h" X X#include ssdef X#include descrip X X#include prcdef X#include dvidef X#include iodef X#include lnmdef X X/* X * GetDisplayInfo gets information from the WSAnn device. These calls are no Vt X * yet documented, but have been tested on VMS V5.2 to V5.4. X */ X XGetDisplayInfo(Node, Transport, Server, Screen) Xchar *Node, *Transport, *Server, *Screen; X`7B X unsigned int Status; X unsigned short Channel; X $DESCRIPTOR(DscDecwDisplay, "DECW$DISPLAY"); X struct `7B X`09unsigned int IoStat; X`09unsigned int IoLength; X `7D Iosb; X X Status = sys$assign(&DscDecwDisplay, &Channel, 0, 0); X if (!(Status & 1)) lib$signal(DWSTART_ASSIGNERR, 1, &DscDecwDisplay, X`09 Status); X X Status = sys$qiow(0, Channel, IO$_SENSEMODE `7C 0x40, &Iosb, 0, 0, Node, X`09 NODENAME_LEN, 1, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_DISPINFOERR, 0, Status); X Node`5BIosb.IoLength`5D = '\0'; X X Status = sys$qiow(0, Channel, IO$_SENSEMODE `7C 0x40, &Iosb, 0, 0, Trans Vport, X`09 TRANSPORTNAME_LEN, 2, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_DISPINFOERR, 0, Status); X Transport`5BIosb.IoLength`5D = '\0'; X X Status = sys$qiow(0, Channel, IO$_SENSEMODE `7C 0x40, &Iosb, 0, 0, Serve Vr, X`09 SERVERNAME_LEN, 3, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_DISPINFOERR, 0, Status); X Server`5BIosb.IoLength`5D = '\0'; X X Status = sys$qiow(0, Channel, IO$_SENSEMODE `7C 0x40, &Iosb, 0, 0, Scree Vn, X`09 SCREENNAME_LEN, 4, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_DISPINFOERR, 0, Status); X Screen`5BIosb.IoLength`5D = '\0'; X X Status = sys$dassgn(Channel); X if (!(Status & 1)) lib$signal(DWSTART_DASSGNERR, 1, &DscDecwDisplay, X`09 Status); X X if (!strcmp(Transport, "LOCAL") `7C`7C !strcmp(Node, "0")) `7B X`09strcpy(Transport, "DECNET"); X`09strcpy(Node, LocalNodeName); X `7D X return; X`7D X X/* X * DWS_Get_DisplayName is a simple routine that uses the above code and can X * be used by a calling program to obtain a X11 style description of the X * current display, such as `60MARVIN::0.0'. X */ Xchar *DWS_Get_DisplayName() X`7B X static char DisplayName`5B64`5D; X char Node`5BNODENAME_LEN + 1`5D, Transport`5BTRANSPORTNAME_LEN + 1`5D; X char Server`5BSERVERNAME_LEN + 1`5D, Screen`5BSCREENNAME_LEN`5D; X X LocalNodeName = DWS_Get_Local_NodeName(); X GetDisplayInfo(Node, Transport, Server, Screen); X sprintf(DisplayName, "%s::%s.%s", Node, Server, Screen); X return(DisplayName); X`7D $ CALL UNPACK DWSTART_DISPLAY.C;6 729184412 $ create 'f' X/* X * Module:`09DWstart_Main.c X * Author:`09Herman Verkade X * Description:`09Main process for DWSTART: Start a DECwindows application X * X * Revision History: X * X * 7-dec-1990 001 HHV`09- Added error handler X * 6-dec-1990 000 HHV`09- Moved code to shareable image X */ X X#include "DWstart.h" X X#include ssdef X#include descrip X#include climsgdef X Xvoid AST(); Xunsigned int ErrorHandler(unsigned int*, unsigned int*); X Xstatic unsigned int ExitStatus = SS$_NORMAL; X X/* X * The main for this program is purely a simple DCL interface to the DWstart X * routines. It gets the information from the DCL command line and passes it X * to the routine. It can be used to put DWstart behind the session manager' Vs X * Application menu or to start a one-off application from DCL. X */ Xmain() X`7B X unsigned int Status; X char NodeName`5BNODESPEC_LEN + 1`5D, *Node; X char CommandLine`5BCOMMAND_LEN + 1`5D; X unsigned short NodeNameLen, CommandLineLen; X static $DESCRIPTOR(DscNode, "NODE"); X static $DESCRIPTOR(DscCommand, "COMMAND"); X $DESCRIPTOR(DscNodeName, NodeName); X $DESCRIPTOR(DscCommandLine, CommandLine); X X lib$establish(ErrorHandler); X X Status = cli$get_value(&DscCommand, &DscCommandLine, &CommandLineLen); X if (!(Status & 1)) goto Cleanup; X CommandLine`5BCommandLineLen`5D = '\0'; X X Status = cli$get_value(&DscNode, &DscNodeName, &NodeNameLen); X if (Status & 1) `7B X`09NodeName`5BNodeNameLen`5D = '\0'; X`09Node = NodeName; X `7D else if (Status == CLI$_ABSENT) `7B X`09Node = 0; X `7D else `7B X`09goto Cleanup; X `7D X X/* X * Part of DWS_Start_Application executes asynchronusly. We need an event X * flag to wait for it X */ X Status = sys$clref(50); X if (!(Status & 1)) `7B X`09lib$signal(Status); X`09goto Cleanup; X `7D X X Status = DWS_Start_Application(Node, CommandLine, AST, 0); X if (!(Status & 1)) goto Cleanup; X X Status = sys$waitfr(50); X if (!(Status & 1)) `7B X`09lib$signal(Status); X`09goto Cleanup; X `7D X XCleanup: X exit(ExitStatus); 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 ExitStatus = Signal`5Bi`5D `7C 0x10000000; X`09`7D X`09Signal`5B0`5D -= 2; X`09Status = sys$putmsg(Signal, 0, &DscFacility, 0); X`09if (!(Status & 1)) lib$signal(Status); X`09Signal`5B0`5D += 2; X`09Active = 0; X`09if ((Signal`5B1`5D & 7) == 4) `7B X`09 Mechanism`5B3`5D = ExitStatus; 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(50); X if (!(Status & 1)) lib$stop(Status); X return; X`7D $ CALL UNPACK DWSTART_MAIN.C;52 1904176672 $ create 'f' X.facility`09dwstart,463 X`09.severity`09success XPROC_ID`09`09 X`09.severity`09informational XREMOTE`09`09 XPROCEXIT`09 X`09.severity`09error XERRTRANS`09 XCREMBXERR`09 XWRITEMBXERR`09 XCLOSEMBXERR`09 XGETDVIERR`09 XCREPRCERR`09 XPARSEERR`09 XDISPINFOERR`09 XTOOMANYLINKS`09 XTOOMANYPROC`09 XASSIGNERR`09 XREADERR`09`09 XWRITEERR`09 XNETWDISCERR`09 XDASSGNERR`09 X`09.end $ CALL UNPACK DWSTART_MESSAGE.MSG;9 858026622 $ create 'f' X/* X * Module:`09DWstart_Misc.c X * Author:`09Herman Verkade X * Description:`09Miscelaneous routine for DWstart program X * X * Revision History: X * X * 6-dec-1990 000 HHV`09- New module, extracted from various other modules X */ X X#include "DWstart_Share.h" X X#include ssdef X#include descrip X#include dvidef X#include iodef X#include lnmdef X#include prcdef X#include "accdef.h" X#include "fabdef.h" X#include "namdef.h" X Xstatic unsigned short MbxChan; X X#define MAX_CHILDREN 20 X Xnoshare 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 ACC ProcessInfo; X`7D ChildInfo`5BMAX_CHILDREN`5D; `20 X Xvoid MailboxAST(int); X`0C X/* X * DWS_Get_Local_NodeName returns a pointer to a string containing the noden Vame X * of the local machine. It is used by DWstart itself, but since I needed th Ve X * nodename in one of the calling programs, I decided to make it a global X * routine. X */ Xchar *DWS_Get_Local_NodeName() X`7B X static char NodeName`5BNODESPEC_LEN + 1`5D; X int i, Len; X X Len = TranslateLogical("SYS$NODE", NodeName, sizeof(NodeName), 1); X for (i = Len - 1; i >= 0; i--) `7B X`09if (NodeName`5Bi`5D == ':') `7B X`09 NodeName`5Bi`5D = '\0'; X`09`7D else `7B X`09 break; X`09`7D X `7D X return(NodeName); X`7D X`0C X/* X * TranslateLogical translates a logical name.... X */ Xint TranslateLogical(LogicalName, ReturnString, BufferSize, MustExist) Xchar *LogicalName, *ReturnString; Xint BufferSize, MustExist; X`7B X unsigned int Status; X static unsigned short RetLen; X static $DESCRIPTOR(DscLogicalName, ""); X static $DESCRIPTOR(DscLnmFileDev, "LNM$FILE_DEV"); X static struct `7B X`09unsigned short BufLen; X`09unsigned short ItemCode; X`09void *Buffer; X`09unsigned short *RetLen; X `7D ItemList`5B2`5D = `7B X`09`7B 0, LNM$_STRING, 0, &RetLen `7D, X`09`7B 0, 0`7D X `7D ; X X DscLogicalName.dsc$a_pointer = LogicalName; X DscLogicalName.dsc$w_length = strlen(LogicalName); X ItemList`5B0`5D.BufLen = BufferSize - 1; X ItemList`5B0`5D.Buffer = ReturnString; X `20 X Status = sys$trnlnm(0, &DscLnmFileDev, &DscLogicalName, 0, ItemList); X if (!(Status & 1)) `7B X`09if (Status != SS$_NOLOGNAM `7C`7C MustExist) `7B X`09 lib$signal(DWSTART_ERRTRANS, 1, &DscLogicalName, Status); X`09`7D else `7B X`09 RetLen = 0; X`09`7D X `7D X ReturnString`5BRetLen`5D = '\0'; X return(RetLen); X`7D X`0C X/* X * Most applications are started as a detached process with input from a X * mailbox. These three routines can be used to create, write and deassign X * to such a mailbox. X */ Xvoid CreateMailbox() X`7B X unsigned int Status; X X Status = sys$crembx(0, &MbxChan, 0, 1024, 0, 0, 0); X if (!(Status & 1)) lib$signal(DWSTART_CREMBXERR, 0, Status); X X DWS_Get_DeviceName(MbxChan, MailBox, sizeof(MailBox)); X return; X`7D X Xvoid SendCommand(Command, Wait) Xchar *Command; Xint Wait; X`7B X unsigned int Status; X struct `7B X`09unsigned short IoStat; X`09unsigned short IoLen; X`09unsigned int IoReceiver; X `7D Iosb; X `20 X Status = sys$qiow(0, MbxChan, IO$_WRITEVBLK `7C (Wait ? 0 : IO$M_NOW), X`09 &Iosb, 0, 0, Command, strlen(Command), 0, 0, 0, 0); X if (Status & 1) Status = Iosb.IoStat; X if (!(Status & 1)) lib$signal(DWSTART_WRITEMBXERR, 2, strlen(MailBox), X`09 MailBox, Status); X return; X`7D X Xvoid CloseMailbox() X`7B X unsigned int Status; X X Status = sys$dassgn(MbxChan); X if (!(Status & 1)) lib$signal(DWSTART_CLOSEMBXERR, 2, strlen(MailBox), X`09 MailBox, Status); X return; X`7D X`0C X/* X * DWS_Get_DeviceName: Returns the name of the device opened on the channel. X * It is needed in the server, so it's global. X */ Xvoid DWS_Get_DeviceName(Channel, Name, Size) Xunsigned short Channel; Xchar *Name; Xint Size; X`7B X unsigned int Status; X unsigned int Iosb`5B2`5D; X static unsigned short Len; X static struct `7B X`09unsigned short BufLen; X`09unsigned short ItemCode; X`09void *Buffer; X`09unsigned short *RetLen; X `7D ItemList`5B2`5D = `7B X`09`7B 0, DVI$_DEVNAM, 0, &Len `7D, X`09`7B 0, 0`7D X `7D ; X X ItemList`5B0`5D.BufLen = Size - 1; X ItemList`5B0`5D.Buffer = Name; X X Status = sys$getdviw(0, Channel, 0, ItemList, Iosb, 0, 0, 0); X if (Status & 1) Status = Iosb`5B0`5D; X if (!(Status & 1)) lib$signal(DWSTART_GETDVIERR, 0, Status); X Name`5BLen`5D = '\0'; X return; X`7D X`0C X/* X * GetUnitNumber: Nearly the same as above, but gives the unit number, X * i.e. give it a channel to WSA57: and it returns 57. X */ Xunsigned int GetUnitNumber(Channel) Xunsigned short Channel; X`7B X unsigned int Status; X unsigned int Iosb`5B2`5D; X unsigned int Unit; X static unsigned short Len; X struct `7B X`09unsigned short BufLen; X`09unsigned short ItemCode; X`09void *Buffer; X`09unsigned short *RetLen; X `7D ItemList`5B2`5D = `7B X`09`7B sizeof(Unit), DVI$_UNIT, &Unit, &Len `7D, X`09`7B 0, 0`7D X `7D ; X X Status = sys$getdviw(0, Channel, 0, ItemList, Iosb, 0, 0, 0); X if (Status & 1) Status = Iosb`5B0`5D; X if (!(Status & 1)) lib$signal(DWSTART_GETDVIERR, 0, Status); X return(Unit); X`7D X`0C X/* X * CreateProcess: Standard routine to create a detached process to run an X * application in. X */ Xvoid CreateProcess(Input, Output, ProcessName, Interactive, SetAST) Xchar *Input, *Output, *ProcessName; Xint Interactive, SetAST; X`7B X unsigned int Status, Pid; X int ChildNr, MbxUnit; X unsigned short Channel; X static $DESCRIPTOR(DscImage, "SYS$SYSTEM:LOGINOUT.EXE"); X static $DESCRIPTOR(DscInput, ""); X static $DESCRIPTOR(DscOutput, ""); X static $DESCRIPTOR(DscDisplay, DisplayName); X static $DESCRIPTOR(DscProcessName, ""); X X if (SetAST) `7B X`09for (ChildNr = 0; ChildInfo`5BChildNr`5D.Busy; ) `7B X`09 if (++ChildNr >= MAX_CHILDREN) `7B +-+-+-+-+-+-+-+- END OF PART 3 +-+-+-+-+-+-+-+-