Novell is now a part of Micro Focus

How to Write a Simple NLM Using Novell Script for NetWare

Articles and Tips: article

Joshua Parkin
Software Engineer
NamSys Inc.
jparkin@home.com

01 Jan 2001


This AppNote demonstrates how to write a simple NLM using Novell Script for NetWare and the Universal Component System.

Introduction

Novell Script for NetWare (NSN) was originally released with NetWare 5.0. Before that is was called NetBasic from HiTechSoft. NetBasic was the only other way to build server-side programs aside from using WatCom C or one of the other C compilers like Metrowerks Code Warrior. HiTechSoft also built components called NetWare Module Extensions (NMX) that you include in your programs, much like ActiveX components. These components allowed you to easily script and retrieve information from NetWare services such as SMTP and File and Print services, just to name a few. You could also design whole applications that included some semblance of a GUI using the WIN command. There was also a basic implementation of objects you could use for Internet scripts when run in conjunction with the NetWare Enterprise Web Server. NetBasic was widely used by system administrators who needed quick little custom applications to run on their server. The problem was that this language wasn't similar to anything used before. There were traces of C and Basic, and some Perl as well.

Novell bought NetBasic from HiTechSoft, did some massive redesign, and renamed it Novell Script for NetWare. Now NSN is 100 percent VBScript compatible, and the Universal Component System (UCS) has replaced the NMX component system. UCS objects called Universal Component Extensions (UCX) have been built by Novell to handle more NetWare services than the previous NMX objects. Another neat feature with UCS is that you can incorporate your favorite scripts (regardless of language) into your NSN projects. That means that if you have a Java Bean or a Perl script that you have been dying to piece together to make the ultimate app, you can now do it, all in the same program.

The important factor to remember here is that NSN is designed to work with Web pages and build server-side executables. This language is native to the NetWare platform. Most important, you can do this by using the language you already know. There is no need to completely learn another language. Novell has done a truly fantastic job at making this language similar to VBScript, but there are some new things to learn and some modifications to your existing applications that you may need to make to get them to run properly. That is not to say, however, that it is not worth your time. You can now build server-side apps that access the many functions of NetWare using the same code base as before. The changes needed (if any) are more for optimization rather than debugging.

In this AppNote, I will cover the Universal Component System and how to implement it, as well as some of the legacy scripts included for those who have come to know and love NetBasic. You already at least have a good grasp on Visual Basic and no doubt have done some work with VBScript with Web pages. Therefore I am going to handle the differences with NSN and Visual Basic/VBScript and give you some examples. I will also show you an easy way to build a simple client/server application using NSN and VB.

Universal Component System

The neatest feature in NSN is the Universal Component System (UCS). UCS has the ability to access components developed using your language of choice-such as C, C++, VB, Java, JavaScript, or PERL-on any machine on the network to be placed within your application. That is not to say that you cannot use NSN to develop your own objects-it is just that these are all available you. UCS works as a middle tier to interpret these components for use within your application. Components are then run through the UCS interpreter to be used in your application, as shown in Figure 1.

How UCS works as a middle tier.

UCS components (UCXes) can be stored in the NDS tree and passed to other OLE editors such as Visual Basic by using the UCX manager. The manager places these objects into the tree and handles the translations into your applications.

UCS refers to the whole system; UCX refers to just a component of the system. UCX components are the parts specifically designed for use with the UCS. Little conversion is needed; the components are therefore fast and efficient. UCX components that come with the current version of NSN include the following (more are being added all the time):


UCX Component
Description

Bindery

Use for searching bindery databases.

Btrieve

This component is used to manipulate a Btrieve database. This includes such features as add, modify, delete records.

Client Socket

Similar to the ActiveX Client Socket control. This allows your applications to connect to a server. Supports TCP/IP and SPX/IPX protocols.

COM Port

This component allows you to communicate with COM ports on the server.

Directory

This is the UCX component that connects to Novell Directory Services. This component allows you to manage, maintain and perform administrative functions to the NDS tree.

Document

Allows you to create HTML documents.

DOS file manager

This component allows you to access the operating system. You can create, delete, and rename files with this control. It can also be used to list information of files and folders.

Environment

This allows you to set and maintain the NSN environment shell.

Error

This component displays the last error generated form the last UCS session.

Fax

This component allows you to implement fax capabilities into your programs be it a Web page or server-side script.

File I/O

This allows you to create a file object inside your programs to read and write to a file.

FTP File Manager

This allows access to all FTP functions inside of your application such as logging in and out, transferring and renaming files, getting and changing current and working directories.

LPT port

As it name states, allows you to write information to the printer port.

NDO

The NDO object is similar to the ADO object. This allows native connections to B2Systems, Oracle 8, and SQLIntegrator data stores on the NetWare platform.

NetWare File System Manager

This manager allows you to perform NetWare file system operations over the network.

Novell Script Pages

This component allows you to create Web pages similar to ASP pages on your Web server. This is automatically installed on your system when NSN is installed. Web servers can then be easily configured to handle the requests.

NWDir

This component allows you to extend and administer the NDS schema.

Power Supply

The power supply component allows you to read and set values to a UPS power supply.

Profile

Used when configuring .INI files

Queue

Allows queuing of different files for processing be it printing or otherwise.

Semaphore

Allows access to semaphores both global and local.

Server

This object retrieves information from the server. This information includes file usage statistics, who is logged on, just to name a few.

Server Socket

Similar to the Novell ActiveX component Server Socket. Allows connections using TCP/IP or IPX/SPX protocols.

SNMP

Reads the SNMP object and sends NetWare alerts.

Text Window

This component allows you to create and manage windows and menus on the server screen. Great for building a GUI to your server-side app.

Volume Manager

This allows you to retrieve information regarding the volumes on the server. Mounting, dismounting, and modifying user space restrictions functions are also included.

Zip

This component allows you to compress and decompress files.

Front Page Compatible

These components allows you to build Web pages using FrontPage and implement them on your Novell Web Server.

Novell is working to keep this system similar to VBScripting, and as a result more and more Front Page Compatible components are being added all the time. These are designed for use in your NSN Web pages. In the newest version, the following Front Page Compatible components are included:


Front Page Component
Description

AdRotator

The ad rotator automates the rotation of advertisements or announcements on your Web site.

Content Rotator

Changes the text of your Web pages.

Counter

Puts an operating counter on your Web page.

FileSystemObject

This object allows you to access the file system in your Web pages.

MyInfo

Keeps track of personal information of the Web site including the administrators contact information.

NextLink

Manages a list of URLs in the order you want them to be accessed.

PageCounter

Counts the number of times a Web page has been "hit".

PermissionChecker

Checks to see if a visitor has access to a certain Web page.

Tools

Provides some interesting functionality such as generates a random number, checks for plug-ins and more.

As you can see, NSN can be quite flexible-from use in Web page scripting to building server-side executables. Not only are your components easy to distribute through NDS, but you can also create many tools in many languages. This way you can pick the best tools for the job. You don't need a chainsaw to build a shelf, and a jigsaw won't cut down that 100 year-old tree. Using NSN and UCS allows you to leverage the best parts from each language and build that killer app you have always wanted to build, quickly and easily.

Advantages of NSN and UCS

One of the main advantages of UCS is the ability to add other language components to your application. As mentioned, you can add Java Beans, Perl scripts, and much more. This way, if you are familiar with a certain language, say Java, and you have already created some beans, you can reuse them in your scripts. This can include Web pages or server-side executables.

When building an NLM, you have to make sure that the NLM releases the server resources when they are not in use. There is the whole issue of thread management, handling multiple processors, and the end all be all-making sure you don't abend your server. This makes designing custom NLMs a daunting process. Quite honestly however, it is not so daunting when you use NSN because you don't have to worry about these problems. In fact, when used inside the NSN Shell, you pose the server very little threat. With that in mind, I still recommend developing on a separate server than on your main server. Things can happen, and you don't want to agitate everyone connected to your network because you had to down the server due to a bug in your program. It still happens.

Another advantage when writing these server-side scripts is that you can create them quickly. This is because of their object-oriented nature (being able to re-use code and the fact that there are already lots of objects to choose from). For example, you can quickly develop a printer queue administration program, or a volume-managing program, grabbing only the information you require.

In regards to using NSN in your Web pages, you will be able to access the power of the NetWare operating system in your Web pages. You can create Web pages to access printer queues or volume controls, and you can even create a simple Web application to send faxes or operate a simple Web-based FTP. When using NSN and the included UCX components, the power of the NetWare OS is at your command. In fact, HiTechSoft has already created a Web administrator using this same method. Their Web application allows you to do virtually anything NWADMIN does, all through your browser.

Differences and Similarities with VB/VBScript

As far as format, layout, and structure go, the languages are identical. They both have routines, functions, and event handlers that look and run like VB and VBScript. Objects have properties and are accessed the same way as in Visual Basic and VBScripting. If you are familiar with one, the other shouldn't be a problem. So what are the differences?

Well, remember that NSN was created from NetBasic. NetBasic had its own way of doing things, and some of that has changed. Novell provides legacy statements to save NetBasic users from having to convert their code.

Another point is that NSN was not geared with building a GUI front-end to your application. In this case it is different from VB. You can create windows, but you must code them the long way (define the window size via coordinates, etc.). Therefore, it can be assumed that NSN is designed mostly as a module builder like VBScript and not a GUI creator like VB. Some of the legacy statements (some will look more like VB than VBScript) still included in NSN are the following:


Command
Description/Syntax

Close

Closes open file(s)

Close [(file#), (file#)]

A empty Close statement (no files mentioned) will close all open files that were opened in the application.

InKey$

Grabs the input from the keyboard (one keystroke only)

InKey$ (e.g. x = InKey$)

INP

Grabs an input (byte) from a port.

INP(port)

Input

Allows the user to prompt for input from the user. Can also use to read from files.

Input {Prompt as String,{; or ,} VariableList

Use of semicolon means keep the "?" on the same line as the question.

Open

Opens files for various reasons (input, output, append, etc.)

Open filename [FOR mode] [ACCESS access] [lock] as filenumber# [LEN = {length grabbed}]

Similar to the open statement in VB. Recommend use the FileScriptingObject UCX component instead of this method.

OUT

Send data out a certain I/O port.

OUT port, data

Sends a byte of data to the port. NOTE the data must be a numerical expression.

Print

Sends either to the server screen of a file.

Print file#, data

If no file number is mentioned, it will print the data to the screen.

Sound

Plays a sound through the server.

Sound frequency, duration

Can be used to play songs on the server (albeit bad) . Good for alerting users.

Wait

Suspends program for duration or waits for a keypress.

Wait [seconds]

If seconds is 0 or omitted then the program halts waiting for a keypress.

Logic statements such as ifelseend if, for..next, and doloop are all the same as VBScript.

Now what about Web pages? What are the differences there? What about Script tags? With Web pages you use the same <% %< that you do with VBScript. The only real difference is the @Language statement at the start of your Web page. With NSN is would look like this:

<% @Language=Nscript %<

Let's look at a simple 'hello world' Web page. Here is the VBScript version:

<% @Language=VBScript%<<
<HTML<<
<HEAD<<
<BODY<<
<%For x = 0 to 15%<<
<%for i = 0 to 3%<<
<H<%=i%<<Hello World<
<%next<
Next%>>
</BODY<<
</HTML<<

There you have a simple ASP page that prints Hello World 45 times while changing the size of the font... pretty straightforward. Now for the Novell Script version:

<% @Language=NScript%<<
<HTML<<
<HEAD<<
<BODY<<
<%For x = 0 to 15%<<
<%for i = 0 to 3%<<
<H<%=i%<<Hello World<
<%next<
Next%>>
</BODY<<
</HTML<<

The only difference is the @Language command. Actually, because of the way NSN is set up with the NetWare Enterprise Web Server, you can even leave out the @Language statement altogether. It's not recommended (bad form), but it is possible.Now here is where things get even more interesting. Since VB allows users to design forms and add controls, users of your program have a nice GUI to play with. With NSN you don't get that fun stuff. Instead you just script. I mentioned earlier that there is the possibility to add windows using the text window UCX component, but let's face it, that is a fair amount of work coding in dimensions for windows and menus, when one is used to using Visual Basic. If you wanted something to be displayed on the screen in VB, you just built a form, added the appropriate control, and then sent some data to it. This made the programs really easy to use. However, with NSN you don't have the ability to make your programs visually interesting (unless you are building a Web page but then you use HTML objects anyway). So when handling an output, we can send it to a printer, port, file or to the screen.

For the next example we are going to send it to the server screen using the Print command. In VB we are just going to use a message box.

Let's start with the VB program. This program will accept the input from a user using an input box and display it in a message box.

Private Sub Form_Load()

     Dim strTemp

     strTemp = InputBox("What is your name?")"
     MsgBox "Hello " "
End Sub

Using NSN the code would look like this:

dim strTemp

input "What is your name?", strTemp"
Print "Hello " + strTemp"

Both do the exact same thing but use different commands to accomplish it. When writing applications in VB, you will invariably use the graphical components like input and message boxes; however, in NSN they don't exist, yet.

Using Novell Script for NetWare

Now that I (hopefully) have perked your curiosity with NSN, you no doubt want to be able to write with it. Well, to start with there is no actual need for an integrated development environment for NSN. That is good, because I have yet to find one. You can create your basic files right on the server by using Novell's Edit. Do this by going to the system console and typing in Edit at the prompt. Inside Edit you can create your file and type in your code. It isn't very nice but it works.

You can also use Windows notepad. This works much in the same way as Novell's Edit and again isn't very nice. Remember the extension for server-side scripts is .BAS. All scripts need to located on the server to be executed.

If you want to be able to create applications, you can use any editor you want as long as it saves in plain text (you could even use WordPerfect but save in plain text). No extremely fancy markup codes can be saved with the program or you will receive an error message. You can also use InterDev or Elemental's DrumBeat to create the NSN Web pages. This is not a problem, but you don't get all the fancy helps that you get when developing to IIS.

NSN Shell

You can create an NSN shell by typing NSNSHELL at the server console. This runs the NSN interpreter and is great for debugging before you compile. In the NSN shell you can use DOS commands like CD and DIR to move around the server. You can even use commands like COPY and DEL to manipulate the files on the server.

From here you can run your precompiled NSN programs. To run an NSN program, simply move to the directory you stored your file in and enter the name at the DOS prompt. You can either enter the path then the file name, or just move to the directory and enter the file name. You don't have to enter the file extension. The shell is the safest place to play on the server. There is very little chance you can abend the server from inside the shell. You also don't have to worry about returning system resources promptly so that other server-side components you are running don't get bogged down. But as I mentioned before, you should be developing on a separate server aside from your main one.

Inside the shell you are able to run your application and see how it interacts with the user. Working inside the NSN shell also gives you good error codes for debugging purposes. It gives you line number, routine name, and what the error is. This is much better than just crashing the server or getting an "errors encountered" error code.

Project Files

If you want to compile your NSN programs to run on the server, you need to create a project file. Project files are simple ASCII files that you can easily create with any text editor. The project files are only used when you want to compile. The layout of a project file is much the same as an .INI file.

These are the most important application settings:

  • [Common]

  • [Compiler]

  • [Linker]

  • [NLMOpts]

  • [NLMLink]

Note: The square brackets are important and need to be there.

The [Common] Section

This section contains three keys:

  • Include is used by the compiler to find the components used in the application. Paths should be separated by a semi-colon.

  • Import is the path to the NSN compiler import (imp) directory.

  • Exepath is the path to the NSN compiler tools directory. This is used so that the compiler can find all the linker (nlmlinkx.exe) and pack (nlmpack.exe) programs.

The [Compiler] Section

This section gives the path(s) to the file(s) to be compiled in the application. Each file has to be specified in a different line. For example:

[Compiler]

     e:\nsn\user\test.bas

     e:\nsn\user\test2.bas

The [Linking] Section

This section describes what type of NLM you are creating. All of these are not required by all types of NLMs. The following keys are used:


Key
Used By UCX NLM
Used By Generic NLM

Program

X

X

NoLink X X

X

X

NoDefFile X X

X

X

EncryptionType X X

X

X

NLMType X X

X

X

ScreenName X

X

UnloadType X

X

NBClass X

X

NBMsg1 X

X

NBMsg2 X

X

NBCopyright X

X

NBExportAll X

X

NBExport# X

X

Program is used to define the message prefix that is displayed on the system console when your program sends a message to it during startup. This should be limited to 11 characters in length and could be anything you like but is intended to be your program name.

NoLink is used when you don't want to link your NLM at this moment in time. You can add custom linking scripting later. The line should be

NoLink=1

NoDefFile is a rarely used key. This key tells the compiler not to create a linker definition file.

EncryptionType tells the compiler either to encrypt the source file or not. There are only these two types of encryption currently supported. If you choose not to encrypt the file, your source code will be readily viewable in your executable. Use the following syntax:

EncryptionType=1  'use encryption'
EncryptionType=-1 'don't use encryption

NLMType tells the compiler what type of NLM to make either a UCX NLM or a Generic NLM. The syntax is:

NLMType=0 'generic NLM'
NLMType=1 'UCX NLM

ScreenName is the text that is displayed when the user presses <ALT< at the server console or the text displayed at the server menu <CTRL-ESC<.

UnloadType tells NSN how you want your NLM to act. The syntax is UnloadType=# where # is one of the values below.


Value Type
Description

0

Unload Immediate

1

Unload With Delay

2

Unload with Signal

3

Never Unload

NBClass is the UCX class name.

NBmsg1, NBmsg2, and NBCopyright are all displayed in the UCX Library when the UCX is loaded.

NBmsg1=string

NBmsg2=string

NBCopyright=string

NBExportAll tells the compiler to export all subroutines into UCX APIs.

NBExport# lets you choose which subroutines you want exported into UCX APIs. For example:

NBExport1=MAIN 'exports the main subroutine'
NBExport2=CONNECT 'exports the connect subroutine'
Now for the [NLMOpts] Tag

The following tags need to be included:

  • Description is displayed as the description of your NLM when it is loaded.

  • Name provides the module name of your NLM. There are naming rules when you want to build a UCX NLM (expected to be released shortly).

  • StackSize sets the size of the stack used by the main thread of your NLM. The recommendations are that if you have a generic NLM the size should be no less than 32KB but for UCX NLMs 16KB is appropriate.

  • ThreadName specifies the naming pattern in CLIB when a new thread is started.

  • Version is the version of the NLM. This has three parts-version, major, and minor. The syntax is Version=version,major,minor

    For minor instead of using a letter, use the corresponding number; for example, instead of using the letter b use the number 2. This is displayed when the NLM is first loaded.

  • Copyright is the copyright string to be displayed when the NLM is first loaded.

  • Map is used if you want a .MAP file generated by the linker program. The format is:

Map=0 'no map'
Map=1 'create a .MAP file
The [NLMLink] Tag

The key of the .PRJ file allows you to provide specific commands to the linker program on compilation. As of now the only thing you will find under this section is NLMOption key. This key is used to tell the linker what external components you want added to this package.

NLMOption1=Input {component name}

NLMOption2=Input {component name}

The NLMOptions commands must be in numbered sequential order. If they aren't, the components won't load properly and you may even miss some.

Building Your First NLM

Now you you have a basic understanding of NSN and UCS and know how to build a project file for your NLM. Now let's build a simple 'hello world' NLM. I know that as a developer you have created probably more than your share of 'hello world' applications, but it is a good starting point.

First you need to initiate the NSN shell. This shell gives you a secure spot to run your NSN scripts without much fear of abending the server. You do this by typing NSNINIT at the system console, followed by NSNSHELL to enter the shell.

You will then be in the NSN interactive shell. Here you type in simple DOS commands to move around the server. There is no editor in the NSN shell for your scripts, so you can use any script editor you choose.

With the editor you choose (I use Notepad), enter the following code:

Sub MAIN



Do While InKey << <q<<


     For i=1 To 10 

         Print "hello world""
     Next i



     For x=1 To 10

         Print "Hello World""
     Next x



     For y=1 To 10

         Print "HELLO WORLD""
     Next y



Loop



End Sub

I chose this code for two reasons. The first reason is to show you the format of the two standard looping commands, Do WhileLoop, and ForNext loop. They look the same as in VB. The second is to show you that you really should put an Exit command in your application. In this case I used the InKey command to monitor input from the keyboard waiting for the <Q< key to be pressed; otherwise, it continuously loops through the program.

To try it out, save the code on the server with a .BAS extension. Let's save the file as WROX2.BAS in a directory called WROX in the NSN directory on the server. Now run it. Go back to the NSN interactive shell on the server and make sure you are in the directory that you saved the file in. Run it by typing in wrox2 as the prompt. You should see Hello World scrolling rather quickly down your server screen. Press Q and it will all end. If all went well, you can compile.

Now, say you want to compile this application into an NLM. The project file should look like this:

[Common]

Import=E:\NSN\Sdk\Imp\

ExePath=E:\NSN\Sdk\Tools\



[Compiler]

File1=e:\NSN\WROX\WROX2.BAS



[Linker]

Program=Wrox2    

NoLink=0

NoDefFile=0

EncryptType=1

NLMType=0

ScreenName=Hello World

UnloadType=0



[NLMOpts]

Description=Hello World  

Name=Hi

StackSize=32

ThreadName=Hi__P

Version=1,0,1

Copyright=Free for all

Map=0

Let's look at this project file. There is no Include statement under the [Common] section. The reason is because we didn't include any objects in the code. It is just straight code. The Import and ExePath tags contain the path to the appropriate directories on the server.

Under the [Compiler] section you see the path to your .BAS file. In this case, you saved it in the WROX directory in the NSN directory on the server. The file was named WROX2.BAS.

In the [Linker] section you put the program name as Wrox2 (the name of the .BAS file). NoLink and NoDefFile are both set to 0. As you may recall, this causes the NLM to be linked and create a .DEF file. The code is being encrypted in the NLM type (EncryptType=1) and is making a standard NLM (NLMType=0). The program is displayed as Hello World on the server (screenname=Hello World) and the program unloads itself when it has completed running (UnloadType=0).

Note: We only used the parts of the project file that are used with the standard NLM; you are not making a UCX component and therefore did not include those parts.

[NLMOpts] contains the remainder of the options. The Description tag is what is displayed by the NetWare loader when the NLM is loaded. The name of the compiled NLM is Hi.NLM as dictated by Name tag. The main thread is set to the standard 32KB and the main thread name is named Hi_P (StackSize=32 and ThreadName=Hi_P). The version is 1.0.a (Version=1,0,1) with a Free for all statement regarding the copyright, and no map file is created when compiled.

Now, save your project file with the .BAS file on the server.

Next, you need to run the compiler program. The program is designed to be run from a Win32 client machine. So open up the MS-DOS Prompt window and go to the NSN\SDK\Tools directory. This directory contains all the parts needed to begin compiling. Type the following at the prompt:

NSNCOMP <location of project file<

The compiler will now run. You have just made your first NLM. That is all there is to it. You didn't have all the worries of someone who is building C NLMs-no dealing with releasing system resources efficiently, or anything to that end. It is a very quick way to build simple NLMs.

Conclusion

Using NSN you can now build server-side applications that access the many functions of NetWare using the same code base as before, allowing you to focus more on optimization rather than debugging. This AppNote covered the UCS and how to implement it, as well as some of the legacy scripts included for those who have come to know and love NetBasic. A follow-up AppNote will explain how to use UCXes in NSN scripts.

* Originally published in Novell AppNotes


Disclaimer

The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates