Developer Links
SUPPORT FORUMS  
SAMPLE CODE & TIDS  
TEST/DEVELOPMENT KIT INFO
 
DEVELOPER LABS  
NOVELL SUPERLAB  
SUPPORT DOCUMENTS  
STRATEGIC/EXECUTIVE ISSUE TRACKING  
SYSOP PROGRAM  
     
Related Links
 
 
 
 
 
Related Links  
 

 
DEVELOPER SUPPORT HOME  

DECEMBER 1994 VOLUME 6 NUMBER 7

A NOVELL DEVELOPER SUPPORT PUBLICATION

INDEX


FROM THE COCKPIT

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


ARTICLES

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.


TECHNICAL INSIGHTS

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.


DEVELOPER NEWS

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

TELETIPS

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;
             }
      }}


DEVELOPER EDUCATION

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.