home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1993 #2
/
Image.iso
/
clipper
/
nettos11.zip
/
MSGSERV
/
BMODE.PRG
next >
Wrap
Text File
|
1993-02-23
|
11KB
|
368 lines
/*
* File......: BMODE.PRG
* Author....: Glenn Scott
* CIS ID....: 71620,1521
* Date......: $Date$
* Revision..: $Revision$
* Log file..: $Logfile$
*
* This is an original work by Glenn Scott and is placed in the
* public domain.
*
* Modification history:
* ---------------------
*
* $Log$
*
*/
#include "ftint86.ch"
#include "netto.ch"
#define GET_BMODE 4
/* $DOC$
* $FUNCNAME$
* FN_SETBMOD()
* $CATEGORY$
* Message
* $ONELINER$
* Set broadcast mode
* $SYNTAX$
*
* fn_setBMod( <nTargetMode> ) -> nMode
*
* $ARGUMENTS$
*
* <nTargetMode> is one of:
*
* 0 Servers store user and server messages sent to this station.
* Shell retrieves & displays message.
*
* 1 Shell displays server messages; discards user messages
*
* 2 Server stores server messages; discards user messages;
* shell won't display the message (app must poll for it)
*
* 3 Server stores server and user messages but shell doesn't
* display; app must poll for messages
*
* $RETURNS$
*
* The resulting message mode after attempting to set to the
* target mode. (See "Arguments")
*
* $DESCRIPTION$
*
* $EXAMPLES$
*
* $INCLUDE$
*
* $SEEALSO$
* FN_GETBMOD()
* $END$
*/
function fn_setbmod( nMode )
local aRegs[ INT86_MAX_REGS ]
default nMode to 0
aRegs[AX] := makehi( 222 ) // DEh
aRegs[DX] := nMode
_fnSetErr( iif( ft_int86( INT21, aRegs ), ESUCCESS, EINT86 ) )
return lowbyte( aRegs[ AX ] )
/* $DOC$
* $FUNCNAME$
* FN_GETBMOD()
* $CATEGORY$
* Message
* $ONELINER$
* Get broadcast mode
* $SYNTAX$
*
* fn_getBMod() -> nMode
*
* $ARGUMENTS$
*
* None
*
* $RETURNS$
*
* <nMode>, one of:
*
* 0 Servers store user and server messages sent to this station
* Shell retrieves & displays message.
*
* 1 Shell displays server messages; discards user messages
*
* 2 Server stores server messages; discards user messages;
* shell won't display the message (app must poll for it)
*
* 3 Server stores server and user messages but shell doesn't
* display; app must poll for messages
*
* $DESCRIPTION$
*
* $EXAMPLES$
*
* $INCLUDE$
*
* $SEEALSO$
* FN_SETBMOD()
* $END$
*/
function fn_getbmod()
return fn_setbmod( GET_BMODE )
/* $DOC$
* $FUNCNAME$
* OVERVIEW
* $CATEGORY$
* Message
* $ONELINER$
* Message services overview
* $SYNTAX$
*
* $ARGUMENTS$
*
* $RETURNS$
*
* $DESCRIPTION$
*
* This is a really simple API, mostly because some of the calls
* aren't implemented in NETTO because they're old and Novell
* doesn't support them anymore. For further information on
* the complete API, consult a reference like Novell's documentation
* or Charles Rose's _Programmer's Guide to NetWare_ (McGraw-Hill).
*
* However, the ones that remain are useful, and have to do
* with Broadcast Messages.
*
* Broadcast messages are those annoying one-liners that show up
* on the bottom of a NetWare user's screen. They're usually
* 55 bytes or less and require the user to hit Control-Enter to
* clear.
*
* In Windows, the NWPOPUP.EXE utility intercepts those broadcast
* messages and displays them in a window.
*
* There are two sorts of broadcast messages: those that come from
* the server and those that come from other users. The manner
* in which the user receives these different types of messages
* is determined by the shell's _broadcast mode_. Netto allows
* you complete control over getting and setting the broadcast mode.
* See FN_GETBMOD() and FN_SETBMOD().
*
* When you want to send a message to another user, you
* can use the Send Broadcast Message API, FN_SBM().
*
* When you want to send a message to the file server's console,
* you can use the Broadcast to Console API, FN_BTOC().
*
* For your convenience, we have defined two commands in netto.CH
* that emulate the CASTON, CASTOFF, and CASTOFF ALL commands found
* in NetWare 2.x and 3.x. These commands simply set the
* appropriate broadcast modes.
*
* Emulating NetWare's SEND command
* --------------------------------
*
* You'll note that none of these APIs allow you to send to a
* specific USER or GROUP, just a logged in connection ID.
* While we work on a fancy set of #commands for this, you can
* do it yourself.
*
* The basic trick is to build up a list of connection numbers.
* You get these with the FN_OBJCNUM() function. If you want
* to send to user BILLY, you can first find out all the
* connections where BILLY is logged in as follows:
*
* aList := fn_objcnum( "BILLY" )
*
* If !empty( aList ), you can deliver aList directly to FN_SBM().
*
* Finding the connected members of a group is just as simple.
* If you want to send to everyone in the "SALES" group, you call:
*
* #include "netto.ch"
* aList := fn_objcnum( "SALES", OT_USER_GROUP )
*
* Once you've buit up an array of connection IDs, you can then
* call FN_SBM() with the message text and this array. That's
* pretty much all there is to it.
*
* You can simplify even further with something like:
*
* function fn_sndUser( cUser, cMsg )
* return fn_sbm( fn_objcnum( cUser ), cMsg )
*
* How do you send to someone on another file server?
* --------------------------------------------------
*
* A variation on the same theme, but a little trickier (which is
* why we hope to implement these in a cleaner #command format
* someday). First, to send to another server, you of course have
* to be attached to that server.
*
* Second, you must get the current preferred connection ID and
* save it. Then, you must set the preferred connection ID, via
* the fn_spfcid() function, to the ID of the server you're sending
* to. Next, you send the broadcast message. Last, you restore
* the old preferred connection ID.
*
* Let's see that in action:
*
* function fn_sndUser( cUser, cMsg, cServer )
* local aRes, nOldID, nNewID
* if !( cServer == nil )
* nOldID := fn_pfConid()
* nNewID := ascan( fn_fsname(), upper( cServer ) )
* if nNewID # 0
* fn_spfcid( nNewID )
* endif
* endif
* aRes := fn_sbm( fn_objcnum( cUser ), cMsg )
* if !( cServer == nil )
* fn_spfcid( nOldID )
* endif
* return aRes
*
* We've added the ability to optionally specify a server. We've
* also added a lot more code. But look it over.
*
* Using the FN_PFEVAL() function, we can simplify the whole
* routine down to this:
*
* function fn_sndUser( cUser, cMsg, cServer )
* return fn_pfEval( cServer, ;
* { || fn_sbm( fn_objcnum( cUser ), cMsg ) }
*
* [ BETA WARNING! ALL CODE NOT TESTED YET, PLEASE DO SO. ]
*
* You can see that it'll take extra work to parse complex
* server/username, server/groupname pairs on a single command
* line. If you solve the problem before we do, please submit
* it, but try to use the same grammar as the NetWare SEND
* command: consult the manual!
*
* Advanced Stuff
* --------------
*
* Depending on how you set the broadcast mode, you can exercise
* control over how and when the messages are displayed. If you
* set the broadcast mode to 2 or 3, then the server will queue up
* to one message for your workstation but your shell will not display
* it. You can use the Get Broadcast Message API, FN_GBM() to
* retrieve this message and display it yourself. Of course, you'll
* have to poll fairly regularly for this message because only one
* will be stored. Also, each file server the user is attached to
* could be holding a message so you'll have to poll around quite
* a bit by saving the connection ID, setting the preferred ID,
* issuing the fn_gbm() call, etc, etc.
*
* Advanced programmers may be interested to know that in shell
* versions after 3.01, the shell will issue an interrupt 2Fh
* when a message arrives. If register AX contains 7A85H, then
* CX has the connection ID of the server holding the message
* for you. Set CX to 0 indicating that you've handled the message,
* and chain to the next process hooking interrupt 2FH. To get the
* message, save the current server's ID, set the preferred
* connection ID to the one indicated by CX, and call the
* Get Broadcast Message API. If you come up with a clean way
* of allowing a Clipper programmer to asynchronously handle these
* events with a call to a Clipper function, please contact us!
*
* $EXAMPLES$
*
* $INCLUDE$
*
* $SEEALSO$
* FN_PFEVAL() FN_SBM() FN_OBJCNUM() FN_SPFCID() FN_PFCONID()
* $END$
*/
/* $DOC$
* $FUNCNAME$
* CASTON
* $CATEGORY$
* Message
* $ONELINER$
* Enable receipt of broadcast messages
* $SYNTAX$
*
* CASTON
*
* $ARGUMENTS$
*
* $RETURNS$
*
* $DESCRIPTION$
*
* Use this call to simulate NetWare's CASTON. You must #include
* netto.CH in order to use it.
*
* $EXAMPLES$
*
* // don't want to be interrupted
* castoff all
* longProcess()
* caston
*
* $INCLUDE$
* netto.CH
* $SEEALSO$
* CASTOFF
* $END$
*/
/* $DOC$
* $FUNCNAME$
* CASTOFF
* $CATEGORY$
* Message
* $ONELINER$
* Disable receipt of broadcast messages
* $SYNTAX$
*
* CASTOFF [ALL]
*
* $ARGUMENTS$
*
* $RETURNS$
*
* $DESCRIPTION$
*
* Use this call to simulate NetWare's CASTOFF. You must #include
* netto.CH in order to use it.
*
* CASTOFF by itself will disable receipt of messages from other
* workstations. CASTOFF ALL disables both workstation messages
* and messages from the file server console.
*
* $EXAMPLES$
*
* // don't want to be interrupted
* castoff all
* longProcess()
* caston
*
* $INCLUDE$
* netto.CH
* $SEEALSO$
* CASTON
* $END$
*/