DECEMBER 1994 VOLUME 6 NUMBER 7
A NOVELL DEVELOPER SUPPORT PUBLICATION
INDEX
This Month
Welcome to the December issue of Bullets. In our lead article, Ann Davis, a UnixWare
Developer Support engineer, summarizes the basic steps of packaging applications written to the
UnixWare environment. Although her article targets the UNIX development environment, many
of the concepts and issues discussed will be useful for developers who build client applications in
any environment.
BrainShare '95
It's time to begin planning for our annual developer's conference, BrainShare '95, coming
up the week of March 20. Although the conference has become "huge" by many standards, this
year we will increase the focus of the conference sessions to give you, as a developer, a more
valuable and comprehensive conference experience.
Pervasive Computing
If you haven't already noticed, Novell has been talking a lot lately about "pervasive
computing." Pervasive computing, the technology for "connecting people with other people and
the information they need, enabling them to act on it anytime, anywhere," is critical for meeting
the needs of our changing world. Business, education, politics and society are rapidly moving
away from local and regional communication to global communication.
In our world, when technology allows us to change the way we communicate, that
technology becomes more than useful--it becomes essential to everyday human interaction. So a
cycle is begun: technology is developed; it becomes necessary; then new technology expands
upon the original one; the new technology becomes necessary; and so on. Once this phenomenon
has started, technology feeds upon itself and we cannot ignore it. We must continue forging
ahead. Thus, Novell is in for the long haul to meet our customers' and developers' needs.
Novell is responding to the needs of the quick-paced, ever-changing global marketplace by
building solid and productive relationships with partners who can fulfill customers' needs for
complete solutions with tools, applications and other services. Novell's partnership with you is
vital to fulfilling the promise of pervasive computing. The Novell Developer Support and
Services group is striving to meet your needs with information, programs and opportunities that
contribute to your success. Please let us know how we are doing. Send your comments to me via
fax (1-801-429-2990) or E-mail (jblaser@novell.com).
Jared Blaser
Director of Developer Support
UnixWare Software Packaging
So you've almost finished creating an incredible UnixWare application. All that's left is to
package your application and to make sure that your end users will be able to easily install and
remove your software. After all, what's great software if you can't install it? It's time for
UnixWare Software Packaging. UnixWare Software Packaging will help you package your
application and create installation files.
UnixWare Software Packaging is comprised of two parts: the end-user portion and the
developer portion. For end users, UnixWare Application Server and UnixWare Personal Edition
include the commands pkgadd, pkgrm and pkginfo to install, remove and determine the
installation status of applications. For the developer, the UnixWare Software Development Kit
includes packaging tools (discussed in detail below) and documentation. The documentation
includes both man pages and the online manual UNIX Software Development Tools. The
UnixWare kit also contains sample partial packages, as the pkgadd utility places a partial copy of
each package you install into /var/sadm/pkg.
The basic steps of package creation are treated in depth in Chapter 8 of UNIX Software
Development Tools. This article will briefly summarize some of the steps in the manual and
provide a few solutions that are not covered in the manual.
Creating a Package Directory
First, you must determine which files you will need to install (let's call these your
application files) and where the files will be located on your end user's system. To simplify the
packaging process, you may want to place your application files in a separate directory from your
source files on your development system. A good way to do this is to create a directory structure
for your application files similar to the directory structure that you will create for your end user.
For example, let's assume we have an application, myapp, that consists of only one file,
appfile. Let's also assume that when we install myapp onto our end user's system, we want to
create a directory, /usr/bin/myapp, and a subdirectory, /usr/bin/myapp/bin, that contains appfile.
To simplify the packaging process, we create a packaging directory (let's call it myapp_pkg) in
some location on our development system (/../myapp_pkg). Then we create a mirror of the
myapp/bin/appfile structure under /../myapp_pkg: /../myapp_pkg- /myapp/bin/appfile. This
mirrored structure will simplify the creation of the prototype file, which will be discussed later in
this article.
Making Your Package Files
Once you have decided which application files and directories to install and where they
will be located on the end user's machine, then you can begin to create your package. The first
step is to make your package files. The package files define your package and its contents. The
pkgmk command will use your package files when you build your package. In the first packaging
file, pkginfo, you specify your package name, abbreviation and so on. The following is a sample
pkginfo file for myapp:
File PKG="myapp"
NAME="My Application"
ARCH="i386"
VERSION="1"
CATEGORY="application"
CLASSES="none"
As part of your packaging files, you can also include several shell scripts to interact with
your end user and perform system modifications during package installation and removal. The
standard packaging shell scripts are the request script (which interacts with the user) and the
preinstall, postinstall, preremove and postremove scripts, which can be used to perform functions
before installation, after installation, before removal and after removal, respectively. Packaging
scripts are not required. If you do use packaging scripts, it is important to remember that the
request script is the only script in which you should solicit user input and set variables.
Furthermore, if you set variables in your request script, they will only be available to other
packaging scripts if you write them out to the response file that is called as the request script's
first argument ($1). Figure 1 illustrates a sample request script for myapp. Note: You could also
create a myapp postinstall script to print out the value of VAR1, demonstrating that postinstall
has access to VAR1's value.
In your request script, you can use the menu command to display a menu and solicit user
input. Documentation on menu is contained in the menu man page, the fmli man page and the
fmli section of the book Character User Interface Programming, available from Prentice Hall.
You can also obtain an internal menuing document by contacting UnixWare Developer Support
at 1-800-RED-WORD (1-800-733-9673). Unfortunately, menu isn't as powerful as many of us
would like, but it will be replaced by a new user interface scheme in a future release.
Figure 1: myapp sample request script
# Sample request script for the myapp package
echo "In request script"
echo "Please enter a value for variable VAR1..."
read VAR1
# Make variable VAR1 available to other packaging scripts
cat >$1 <
Creating the Prototype File
After you have created a pkginfo file and the necessary packaging scripts, you can create
your prototype file. The prototype file contains a list of all the files to be included in your
package and specifies their final locations on your end user's system. The prototype file is a
required package file. You can create your prototype file manually or simply run the pkgproto
command. If you want to create the prototype file manually, refer to the UNIX Software
Development Tools manual and the prototype man page for the prototype file format. Or you can
run the pkgproto command to create a prototype file that lists all the files, subdirectories and
subdirectory files located in a specific directory.
Using myapp as an example, assume that you have placed your packaging files in your
application root directory, /../myapp_pkg. If you run the pkgproto command in the
/../myapp_pkg directory,
pkgproto . >prototype
a prototype file will be created that includes all the packaging files, application files and
subdirectories in /../myapp_pkg. This sample prototype file is shown in Figure 2.
Figure 2: myapp sample prototype file
f none pkginfo 0644 root sys
f none request 0644 root sys
f none prototype 0644 root sys
d none myapp 0755 root sys
d none myapp/bin 0755 root sys
f none myapp/bin/appfile 0644 root sys
Now you can see why you would want to create an application root directory (which
contains your packaging files) and a mirror of the application environment that you want to
create for your end user. Use the myapp package as an example: when you run pkgproto in the
/../myapp_pkg directory, your resulting prototype file will already contain all your package files
and application files, and your application files will be listed with their approximate final
directories.
You will still have to perform some minor edits to your prototype file, but you can avoid
extra work by using the pkgproto command on a development environment similar to the sample
/../myapp_pkg directory. A development environment of this type is especially useful if your
application contains several subdirectories and files. Performing the minor edits needed on the
sample myapp prototype file creates a final prototype file. This final prototype file will install the
application subdirectories and files into a /usr/bin/myapp directory on an end user's system (as
shown in Figure 3).
Figure 3: myapp final sample prototype file
i pkginfo
i request
d none /usr/bin/myapp=myapp 0755 root sys
d none /usr/bin/myapp/bin=myapp/bin 0755 root sys
f none /usr/bin/myapp/bin/appfile=myapp/bin/appfile 0644 root sys
Making Your Package
Once your prototype file, packaging files and application files are in place, you can use the
pkgmk command to "make your package." Generally, pkgmk runs in the root directory of your
application and is told (with the -d option) where to place your package:
pkgmk -d /tmp
For the myapp application, the above command run in the /../myapp_pkg directory will
create a package in directory structure format in /tmp. The package will be /tmp/myapp, a
directory containing all the subdirectories and files for myapp.
To make packaging easier, you can quickly create a shell script that will automatically create
a new prototype file and make your package for you. This type of script is useful if you are
making frequent updates to your package and application files (including adding and removing
files), and if you are frequently repackaging your application. A sample "automatic packaging"
script for myapp, called myapp.pkg, is shown in Figure 4.
Figure 4: myapp.pkg: myapp sample automatic packaging script INSTDIR=/usr/bin
#Create the prototype file
>prototype
for file in `ls`
do
if [ -f $file ] && [ $file != "prototype" ] && [$file !=
"myapp.pkg" ]
then
echo "i $file" >>prototype
fi
done
pkgproto myapp=$INSTDIR/myapp >>prototype
#Make the package to /tmp, overwriting any existing package
pkgmk -o -d /tmp
Transferring Your Package
The final step in packaging is to transfer your package to your chosen format and
installation medium. Although pkgmk always creates a package in directory structure format,
you can use pkgtrans to transfer the package to data stream format if you wish. Packages can be
placed on devices containing file systems in either directory structure format or data stream
format, but you must use data stream format when transferring packages to stream devices such
as tapes. If you plan to place your package on the installation medium in directory structure
format, you can often use pkgmk to make a package and place it directly on the device (e.g., a
diskette), but doing this prevents you from using some of the options to pkgmk. Therefore, it's
usually better to make your package in a directory on your development system and then transfer
your package to your installation medium.
Common Packaging Problems
Of course, packaging your own application will probably involve more than creating a
pkginfo file and a short request script, so you are likely to run into a few problems. Following is
a list of some common problems, along with suggested solutions.
Problem: Regardless of which package is being made, the pkgmk command displays the
warning message "PSTAMP set to . . .".
Solution: This is a bug in pkgmk. The man page for pkginfo (man 4 pkginfo) states that if
the PSTAMP variable is not set in the pkginfo file, a default value of the system name followed
by a string containing year, month, day, hour and minute will be used. However, pkgmk is
running an incorrect command to determine the default value for PSTAMP. It therefore generates
a warning message when it cannot correctly set this variable. To work around this bug, set
PSTAMP to an appropriate value by using the -p option to pkgmk, or set PSTAMP in your
pkginfo file. Most of our internal UnixWare packages have PSTAMP set in their pkginfo files.
Problem: The -c option to pkgmk should compress application data files; however, it does
not seem to work when a package is made and placed directly on a diskette.
Solution: The compress option (-c) to pkgmk does not work when the destination for pkgmk
is a block device (see man pkgmk). Therefore, we advise you to run pkgmk in a directory on
your development system and then transfer your package to your desired format and installation
medium.
Problem: How should a package that is too large for one diskette be transferred to multiple
diskettes?
Solution: Splitting up a package to span several diskettes is actually done when making the
package, not when transferring it. To split the package, use the -l option to the pkgmk command.
Once you have determined the size (in 512- byte blocks) of the diskettes you will be using for
your package, you can add -l to your pkgmk command line. After you make your
package with the pkgmk -l command, it will be ready for transfer to multiple diskettes. When
you use pkgtrans to transfer your package, it will prompt for successive diskettes.
Conclusion
This UnixWare Software Packaging overview and problem-solving section offers some
ideas that may help you package your application. My advice is to establish your packaging
environment as early as possible in development and perhaps create an automatic packaging
script (as shown in Figure 4). If possible, reuse the existing packaging source in /var/sadm/pkg.
Finally, if you have any questions or comments about UnixWare Packaging, please contact
Developer Support at 1-800-RED-WORD (1-800-733-9673). We want to help make every
UnixWare product powerful and easy to use.
Ann Davis is an engineer in Novell's UnixWare Developer Support Group and has written
software for various versions of UNIX, Windows and DOS. She enjoys reading, travel,
computers and spending time with her family.
Santa Has a Gift for You!
NetWare 4.1 SDK Special Edition is Now Available!
The NetWare 4.1 SDK Special Edition is your key to unlocking more business profitability.
This SDK enables your company to take advantage of Novell's newest network operating
system--NetWare 4.1. Compatible software will be in great demand as NetWare 4.1 takes the
lead in the network operating system industry. Use this SDK to begin developing products today.
The NetWare 4.1 SDK Special Edition includes the following:
- A complete, full-featured two-user version of the NetWare 4.1 network operating system
- The NetWare Client SDK
- The NLM SDK
- Online documentation
The NetWare 4.1 SDK Special Edition is only $49.99 (plus shipping and handling).
Licensed owners of the Novell SDK CD Volume 2 will receive this package at no charge. Call
and start developing for NetWare 4.1 today.
To order your copy of the NetWare 4.1 SDK Special Edition, in the United States and
Canada call 1-800-RED-WORD. In all other locations call 1-801-429- 5281.
This offer is valid only through March 17, 1995. Please allow up to six weeks for delivery.
This is a one-time offer which will carry no upgrades or updates.
Insights into NetWare Client SDK 1.0e
What Is NETWARER.DRV?
NETWARER.DRV is the Windows NetWare driver enabled for English.
NETWARER.DRV should be copied to the WINDOWS\NLS\ENGLISH subdirectory, and the
NETWARE.DRV file should be copied to the \WINDOWS\SYSTEM subdirectory.
NWParseConfig() Is Supported Only on OS/2
The NWParseConfig() call documentation reflects incorrect Client Platforms. This call is
supported only on the OS/2 platform and is part of the NWCONFIG.LIB.
NWInitUnicodeTables() Returns 0xFE12
NWInitUnicodeTables() returns 0xFE12 (UNI_NO_MEMORY) when 580KB of memory
is available. This error may be caused by using the small memory model at compile time. A large
memory model should be chosen when calling the NWInitUnicodeTables() function.
Creating a Workgroup Manager
Which bindery objects or object properties must be set to establish an object as a
workgroup manager? An object intended to be a workgroup manager is unable to manage the
account of a user it created.
The object ID of the object intended to be a workgroup manager was not added as a property
value to the MANAGERS property of the supervisor OBJECT. In order for an object account to
be managed by a workgroup manager, the workgroup manager object must be added to the
MANAGERS property set of the object SUPERVISOR. Afterwards, any objects CREATED by
the workgroup manager can be managed by the workgroup manager. However, objects that
existed before the workgroup manager object was created, and that must be managed by the
workgroup manager object, require one additional step. The workgroup manager object ID must
be added to the OBJ_SUPERVISORS property set of the object to be managed before it can be
managed by the workgroup manager.
Attribute Extensions to Base Class
Attributes added as an optional attribute extension to a base class cannot be removed from
the Directory Services Schema. For example, if a new attribute such as "Pets" is defined and
added to the Directory Services Global Schema and then added as an optional attribute to the
effective class "User," the attribute "Pets" cannot be removed thereafter. The attribute itself can
be removed from the schema if it has not been added as an attribute to a base class definition.
Application Hangs With INT 24 and VLMs
A branch to an INT 24 ISR due to a sharing violation critical error of function 0Fh INT 21
causes the machine to hang if a retry is issued from the critical error handler.
While tracing program execution, it is observed that a retry attempt (01h is moved into the
AL register) from the critical error handler routine causes the DOS machine to hang. The screen
is often filled with garbage indicating that video memory has been overwritten. If NETX is
loaded on the client, this problem does not occur. The only workaround is to load NETX on the
client in place of VLMs until the problem is resolved in the VLMs.
Using Function int86x Produces GPF in Windows
Using the code shown in Figure 5 to determine if LSL.COM is loaded will produce a
General Protection Fault (GPF) upon execution of the int86x function.
This fault occurs because the int86x function loads CS (Code Segment register) with a data
segment selector. This violates one of the rules of protected mode operation.
To avoid this problem, the developer must generate a code-segment alias for the data
segment. This requires using the Windows DPMI functions to allocate a selector and descriptor.
The descriptor base address must point to the data segment so that segment registers can be acted
upon. The following sources document a means of using DMPI functions to allow int86x to
function properly from within Windows:
DOS and Windows Protected Mode, Schulman et al. Chapter 5, page 103.
Undocumented DOS, Second Edition, Williams. Chapter 3, page 113.
Figure 5: Code to determine if LSL.COM is loaded
union REGS regs;
struct SREGS segregs;
char far *installString;
regs.x.ax = 0xC000;
//code to determine if LSL.COM is loaded.
int86x(0x2F, ®s, ®s, &segregs);
FP_SEG(installString) = segregs.es;
FP_OFF(installString) = regs.x.si;
Running NetWare Aware Windows Apps in OS/2
NetWare aware Windows applications give the error message "Could not find
NETWARE.DLL" when running under OS/2 v2.1. There is no problem when the application is
run under Windows v3.1. The problem when applications are running under OS/2 v2.1 is caused
by an absent or outdated NetWare Requester for OS/2. The problem is corrected by using the
NetWare Requester for OS/2 v2.1. This requester is contained in the CLIENT.KIT area of the
NOVFILES forum. The requester consists of six files:
OS2DC1 EXE 567,801 05-02-94 10:07:38
OS2UT1 EXE 661,678 05-02-94 10:04:14
WSDRV1 EXE 589,957 05-02-94 10:06:02
WSOS21 EXE 293,701 05-02-94 10:11:46
WSOS22 EXE 885,332 05-02-94 10:10:08
READ TXT 565 04-21-94 10:09:48
NWGetServerInfo() Requires Console Privileges
NWGetServerInfo() will return 0x89C6 NO_CONSOLE_PRIVILEGES if the client does
not have console operator rights.
NWGetServerInfo() uses two different servers in the parameter list. The first server is
represented by the conn parameter, which must be a connection handle to a 4.x server with
console operator privileges. If the client does not have console privileges, error 0x89C6
(NO_CONSOLE_PRIVILEGES) will be returned. If the server is not a 4.x server, error 0x89FB
(INVALID_PARAMETER) will be returned. The second server is represented by the
serverName parameter. This server can be either a version 3.x or 4.x server.
NWGetDriveInformation() Results
NWGetDriveInformation() returns different dirHandle parameter results for NETX and
VLMs.
When NETX is running, NWGetDriveInformation() returns a nonzero dirHandle and a valid
dirPath. When the VLMs are running, NWGetDriveInformation() returns a dirHandle of zero and
a valid dirPath (the same dirPath that was returned when NETX was running).
This is in fact the way the call should work because the VLMs do not associate a directory
handle with a mapped drive. Therefore, no directory handle can be returned.
NWCAPTURE_FLAGS1.printFlags Form Feed Control
This Technical Insight clarifies the NWCAPTURE_FLAGS1.printFlags form feed control
bit definition.
Bit 3 of the NWCAPTURE_FLAGS1.printFlags structure controls whether or not a form
feed is sent to the printer after a print job is completed. If this bit is cleared, a form feed is
enabled. If the bit is set, a form feed is disabled.
Searching in DynaText
How are partial text searches accomplished in DynaText?
The wildcard character (*) should be used when searching for a partial text string in a
DynaText document.
Examples: NWScan*
NW*Directory
NW*Dir*Path
NWGetConnectionIDFromName() Server Platforms
The documentation for NWGetConnectionIDFromName() does not reflect the correct
server platforms.
NWGetConnectionIDFromName() will run in both NetWare 3.x and 4.x environments.
However, this call will only work with VLMs (not NETX). If this call is attempted when NETX
is installed, error 0x89FF will be returned.
Undocumented Function NWGetDrivePath()
NWGetDrivePath() is an obsolete function and is only included in the header files for
backward compatibility. NWGetDrivePath() is not documented. Developers are encouraged to
call NWGetDriveStatus() instead, because it returns more information.
NWStartQueueCapture() May Fail With NETX
When using NWStartQueueCapture() with NETX, it may fail with an error code of 89FF
in different situations.
A prerequisite for calling NWStartQueueCapture() is to end any capture operations active on
the LPT port to which you are trying to capture.
When capturing with the APIs to a queue, you should use NWGetCaptureStatus() to check if
the queue is already captured. If it is, use NWEndCapture() to end the current capture before
calling NWStartQueueCapture() to begin a new capture.
NetWare C Headers for OS/2 32-Bit Compilers
32-bit OS/2 compilers receive errors when compiling programs with the NetWare Client
SDK for OS/2. These errors include syntax errors, undefined variable types and unresolved
externals.
OS2HDR.EXE contains header files for the NetWare Client SDK for OS/2. These files will
help OS/2 programmers compiling with 32-bit compilers to properly format their calls for
thunking to the 16-bit NetWare C libraries. While Novell does not officially support 32-bit
compilers on the OS/2 platform at this time, these header files go a long way towards making
these compilers work with the OS/2 SDK. Please see the documentation in NWCALDEF.H for
#define statements that are necessary to make use of these headers.
NetWare 4.0 NLM Programming Samples for NLM SDK 3.0
The Novell Press book, Novell's Guide to NetWare 4.0 NLM Programming, refers to
several pieces of sample code. Where are these code samples located?
The sample code information is mentioned on page xxi of the introduction to Novell's Guide
to NetWare 4.0 NLM Programming. However, the CompuServe forum and file name are printed
incorrectly in the book.
The code samples mentioned in Novell's Guide to NetWare 4.0 NLM Programming are
available electronically via CompuServe. They are located in Library 12 of the NOVUSER
forum. The correct file name is NLM4PG.ZIP.
What's on the Developer Support BBS?
During the past couple of months, we have been working hard to add source code
examples and other information to the Developer Support BBS. Many developers have found
solutions to their problems after downloading source code and technical information from our
BBS. We continually update our bulletin board service with new information and source code
examples. Please let us know any way we can improve our BBS by forwarding your suggestions
to us via any of the methods listed under "Contacting Novell" in this issue. BBS access
information is also available under "Contacting Novell." The following is an overview of some
of the information you can find on the Developer Support BBS.
OS/2 Files
- TLIEXAMP.ZIP--This file contains source code examples of IPX and
SPX communications using the TLI interface. Although this code was written for OS/2, minimal
changes are needed for other platforms.
- OS2HDR.EXE--This file contains C header files modified for compiling 32 bit OS/2
code.
Note: C header files for the Client SDK for OS/2 have been modified for use with OS/2 32
bit compilers. Changes from the last set of files, OS2HDR.EXE, include better support for the
IBM CSET/2 and Borland C++ for OS/2. Novell does not officially support 32 bit OS/2
compilers at this time. However, Novell Developer Support wants to support their developers in
their programming efforts whenever possible.
Telephony Files
- TSERVERS.C--Source code to list the telephony servers on the network
- MAKECALL.C--Source code to make a telephone call
- TRANSFER.C--Source code to transfer a telephone call
- CONFCALL.C--Source code to conference three people on a call
- KVPHONE.EXE--Source code for a dialpad program for Windows using Borland's OWL
2.0
- TELETIPS.EXE--All the TeleTips compressed into one file
NLM Files
- XAFP1.EXE--Contains a demo program that will "TYPE" out the data fork of a
Macintosh file
- XAFP2.EXE--Contains a demo "DIR" program to list details of Macintosh directory
entries
- XAIO1.EXE--Demonstrates how to use the AIO function calls
- XDSA1.EXE--Contains an example of using a streams-like interface to NDS attributes
- XNUT1.EXE--Demonstrates how to write a basic NWSNUT application with a menu
- XNUT2.EXE--Contains a multithreaded example using the NWSNUT interface
- XREG1.EXE--Contains an example of using RegisterForEvent with a circular queue for
events
- XSAP1A.EXE--Demonstrates how to write a basic SAP client/server application
- XSNC1.EXE--Contains an example of using the Synchronized Start option for an NLM
- XTLI1.EXE--Contains an example of how to use the TLI interface with SPX/SPX2
- XTRU1.EXE--Contains an example of how to add a trustee to a file under NDS (4.x)
Directory Services Files
- READEFF.C--Displays effective rights of a Directory Service (DS) object on another DS
object
- READACL.C--Displays all ACL values for a given DS object
- DSWHO.C--Displays the currently authenticated DS object
- DSVIEW.C--Lists all the attributes of all DS objects in a specific context in the DS tree
DOS and Windows Files
- SAP.EXE--SAP sample code
- LOGIN1.EXE--Sample code that logs into a 4.x server
- ADVER.EXE--SAP sample code
- CHAT.EXE--Sample chat program
TeleTip #9
Default Queue Sizes
The documentation for the acsOpenStream() functions states that if you use zero for the
sendQSize and recvQSize parameters, a default queue size will be used. Unless you do only basic
call control functions without any device or call monitoring, you will not want to use this default
queue size. This TeleTip explains why.
When you use basic call control functions to make calls, clear calls, put calls on hold,
transfer calls and so on, the only events that will be sent to your application are solicited events.
Solicited events are the confirmation or failure events of the function your application requested.
For example, after performing a successful cstaMakeCall() function, your application will
receive a CSTA_MAKE_CALL_CONF event. As long as you receive only these solicited
events, and handle them fairly quickly, your application should be fine with the default queue
size of a two-event capacity. However, when using a monitor, either for cstaMonitorDevice,
cstaMonitorCall or cstaMonitorCallsViaDevice, you will not only receive the solicited events for
request confirmations, but you will also receive notices of actions taking place on the device or
call being monitored. A queue can quickly run out of room to store events with a default size of
two, even if your application can efficiently handle them.
What is a good queue size to use when monitoring a device or call? The answer depends on
the type of monitoring you are doing, what is taking place on the device and how quickly your
application pulls the events out of the queue. But I wouldn't drag out this entire discussion just to
leave you hanging on an abstract answer like "it depends." Actually, 15 seems to be a good queue
size for minimal monitoring. I recommend 20 if there is more significant action on the switch.
Tip: When using monitors (regardless of type), use a send and receive queue
size of 15 or 20 when opening the stream rather than the default queue size of two.
TeleTip #10
"Breaking the Polls"
I was discussing different methods of getting events with someone, when he mentioned
that he didn't like the acsGetEventPoll() function because "it was broken." This was news to me,
so I did some testing to see if I could find out what was going on. Until this time, my programs
had been simple ANSI C examples, written so they could compile and run either as NLMs for
NetWare Servers or in Borland's EasyWin for Windows. In these simple programs, my
acsGetEventPoll loops worked fine.
However, as I began programming my dialpad application (a somewhat more in-depth
Windows program) I noticed some strange problems. One problem was that I could make calls
any number of times, but I could successfully clear only the first call that was made. To find a
solution to this problem, I turned to MessageBox, my favorite debugging tool, which displays
strings so I can tell how far the program is getting.
As I put in the MessageBox code, I noticed that when I did the acsGetEventPoll() for the
first cstaClearCall(), I got an ACSPOSITIVE_ACK return code. However, each time after this,
as I called cstaClearCall() and then acsGetEventPoll(), I got an ACSERR_UBUFSMALL return
code. This error code means that the buffer size passed to the poll function was too small to hold
the event that needed to be returned.
After looking through my loop, I noticed that I had set the eventBufSize parameter to
sizeof(CSTAEvent_t) before calling acsGetEventPoll() the first time. However, I never reset this
value. After reading the documentation for acsGetEventPoll() more carefully, I noticed that it
resets the eventBufSize value to the actual size of the returned event. So if I used the same
variable the next time through the acsGetEventPoll() without first resetting it, the maximum
event size allowed for an event would be the size of the last event retrieved, which in my case
was not large enough for some of the events I later received.
To avoid this problem, the code should make a call, then go through an event poll loop until
it gets a make call confirmation event. This is illustrated in Figure 6.
Tip: Make sure that every time you call the acsGetEventPoll() function the
eventBufSize is set to the largest size of event you could expect to receive. I recommend that you
use sizeof(CSTAEvent_t) to get the size, because this is the largest size of any event that will be
returned.
Figure 6: TeleTip #10--code for making a call and entering a poll loop
rCode=cstaMakeCall(globalACSHandle,invokeID,&callerExt,&callee,NULL);
/*_______________________________________________________________
** if MakeCall was successful, it will return the invokeID (above 0)
*/
if(rCode>0)
{
/*_______________________________________________________________
** We enter a poll loop, waiting for our event to confirm the makecall
*/
while(!done)
{
/*_____________________________________________________________-
** First, very important, set the event buffer size to pass to
** getEventPoll. If we don't reset it each time, it may be too
** small to get our event, and we will never get our make call
** confirmation event
*/
eventBufferSize=sizeof(CSTAEvent_t);
/*_____________________________________________________________-
** get the event, and check its type
*/
rCode=acsGetEventPoll(globalACSHandle,&eventBuffer,&eventBufferSize,NULL,&numEvents);
if(rCode==ACSPOSITIVE_ACK)
{
if(eventBuffer.eventHeader.eventType==CSTA_MAKE_CALL_CONF)
{
/*_____________________________________________________
** If it's the right event type, the callID is stored in
** the confirmation event structure, which we will need to
** store so that the user can hangup on the call later. Then,
** we'll enable the Hangup button.
*/
callID=eventBuffer.event.cstaConfirmation.u.makeCall.newCall;
done=TRUE;
}
}
else if(rCode==ACSERR_NOMESSAGE)
{
done=FALSE;
}
else
{
/*_________________________________________________________
** we can't get the event that the call was made successfully,
** so disable the Hangup button.
*/
done=TRUE;
}
}}
Available Novell Developer Education Courses
Novell Developer Education offers several courses for developers who use Novell's
development tools.
- 930 Developing NetWare Loadable Modules (NLMs)
- 940 NetWare Programming: Basic Services
- 941 Directory Services
- 945 NetWare Programming: Protocol Support
- 950 Visual AppBuilder
- 954 ALM Development
Novell Authorized Education Centers
The following Novell Authorized Education Centers (NAECs) offer developer training:
- Alternative Computer with sites in Mt. Laurel, NJ; Albany, NY; and Pittsburgh,
Allentown and Bluebell, PA offers courses 930, 940 and 945. Contact Jamie Anewalt at
1-800-321-1154.
- C-Trec in Houston, TX offers courses 930, 940, 941 and 945, and plans to teach 950 and
954. Contact Conni Templin at 1-713-871-8411.
- Clarity located in San Jose, CA offers courses 930, 940 and 945, and plans to teach 941,
950 and 954. Contact Kirstin Hills or Cyd Simerville at 1-800-729-9995.
- Professional Computer Development Corp. with sites in Norcross, GA; Shaumburg and
Mt. Prospect, IL; Livonia, MI; Edina, MN; Cincinnati and Maumee, OH; and Pittsburgh, PA
offers course 930. Contact Larry Guyette at 1-800-322-7232.
To obtain information on pricing, location, scheduling and course content for classes held
in the U.S. call 1-800-233-3382 or 1-801-429-5508. For information on classes in all other
locations, contact your local Novell office.
Novell, Inc. makes no representations or warranties with respect to any NetWare software and
specifically disclaims any express or implied warranties of merchantability, title or fitness for a
particular purpose. Distribution of any NetWare software is forbidden without the express
written consent of Novell, Inc. Further, Novell reserves the right to discontinue distribution of
any NetWare software. Novell is not responsible for lost profits or revenue, loss of use of the
software, loss of data, costs of re-creating lost data, the cost of any substitute equipment or
program or claims by any party other than you. Novell strongly recommends you make a backup
before any software is installed. Technical support for this software may be provided at the
discretion of Novell.
1994 Novell, Inc. All rights reserved. Novell, the N design, NetWare, DR DOS and
LANalyzer are registered trademarks; LAN WorkShop, NetWare SFT III, NetWare Loadable
Module, NLM, Global MHS, NetWare MHS, NetWare System Calls for DOS, NetWare
Runtime, Report Executive, NetWare Asynchronous Services Interface (NASI), NetWare
Management System, DeveloperNet Labs, UnixWare, AppWare, AppWare Foundation, ALM, Visual
AppBuilder, IPX and MacIPX are trademarks; and NetWire and Professional Developers'
Program are service marks of Novell, Inc. WordPerfect is a registered trademark of
Novell/WordPerfect, Inc. IBM and OS/2 are registered trademarks, and NetBIOS and SAA are
trademarks of International Business Machines Corporation. Microsoft is a registered trademark
and Windows and Visual Basic are trademarks of Microsoft Corporation. Macintosh is a
registered trademark of Apple Computer, Inc. CompuServe is a registered trademark of
CompuServe Corporation. NFS is a registered trademark of Sun Microsystems, Inc. UNIX is a
trademark of UNIX Systems Laboratories, Inc. in the USA and other countries. UNIX Systems
Laboratories is a wholly-owned subsidiary of Novell, Inc. WATCOM is a registered trademark
of WATCOM Systems, Inc.
Publisher: John Stewart
Editor: Niche Associates
Design: Creative Services, Provo
Feature Article: Ann Davis
Contributors: Belinda Adams, Phil Bench, Karl Bunnell, Jack Gumaer, Ray Maxwell, Dan
Stratton and Kevin White
Layout and Graphics: Niche Associates
Special thanks to the Developer Support, Developer Relations, Development, Marketing
Communications and Product Marketing staff who contributed time and valuable input.
1994 Novell, Inc. All rights reserved.
|