Getting Started in NetBasic Development for the Web
Articles and Tips: article
Senior Research Engineer
01 Oct 1997
Shows how to get started using NetBasic to develop applications for the web. Includes an example program.
Okay, so let's say you're
A developer in an IS department who wants to write a custom utility that will allow you to monitor your NetWare/IntranetWare servers over the Internet.
A marketing type who wants to publish product and pricing data from a Btrieve database on the Web.
A developer who needs to put together a sophisticated Web- based application, but you development schedule doesn't allow you the time to learn how to do it in Java.
If you're one of these people or know them or someone like them, you might want to consider using NetBasic for your development project. In a previous DevNote, I introduced NetBasic as a scripting language for server-based application development (see "NetBasic: IntranetWare's Scripting Language," Novell Developer Notes, November 1996, p. 14). NetBasic was developed by Novell partner HiTecSoft, of Scottsdale, Arizona. In this DevNote, I'll show you how you can get started using NetBasic to develop applications for the web.
Setting Up Your Development Environment
The minimum hardware requirements for NetBasic development are quite modest, and there are many advantages to keeping your development network small. The simplest configuration consists of one IntranetWare server and one client, It's usually a good idea to dedicate a server solely to development. Since this development server will carry a fairly light load, an old 386 or 486 machine will probably be adequate. It will still need about 24MB RAM or more. You'll also need a CD-ROM drive, at least during the setup process.
If your development network is not connected to the Internet or your corporate network, you can administer your own IP addresses, otherwise, you'll have to play nice and follow the rules made by your network administrators.
To set up your development server, install the following products from the IntranetWare package (in the order listed):
Novell Web Server
Novell Internet Access Server (includes the IPX/IP Gateway)
FTP Services for IntranetWare (optional)
The development client can run either Windows 95 or NT. You'll need to install the appropriate NetWare Client 32 and at least one web browser (Netscape Navigator is included with IntranetWare). Although all the essential tools for NetBasic web development come with IntranetWare, you'll probably also want to get the NetBasic SDK from HiTecSoft. This package includes an integrated development environment (IDE) that makes development easier. See HiTecSoft's web site (http://www.hitecsoft.com/) for more information.
An Overview of the NetBasic Language
NetBasic, as with other recent BASIC implementations, has added object-oriented and structured programming extensions to the language.
Prior to running any NetBasic application, the preprocessor processes the source file and creates a temporary file executed by NetBasic. The temporary file is created in the directory specified by the NetBasic environment variable TEMP (see Environment Objects). If the environment variable TEMP is not specified, the preprocessor creates the file in the /NETBASIC/TEMP directory of the SYS: volume.
#include. The #include command includes the contents of another file in a NetBasic application. The preprocessor inserts the file specified by the #include command into the source code when it creates the temporary file for the application. NetBasic #include files have .H extensions. The #include statement must be outside of the Main subroutine. The #include command must be lower case and the file name must be in quotation marks. This example uses the #include command to include the WIN.H file in the application.
#include "WIN.H" Sub Main WIN:Clear Window = WIN:Define(5,20,10,60); WIN:Show WIN:Color(WIN_FG_RED+WIN_BG_WHITE) WIN:At(2,10); WIN:Say("Hello network users.") End Sub
#define. The #define command replaces a string throughout the source file. The preprocessor replaces the first string after #define with the second string after #define when it creates the temporary file for the application. The #define statement must be outside of the Main subroutine. The #define command must be lower case. This example uses the #include command to replace At with WIN:At, etc.
#define At WIN:At #define Say WIN:Say #define Clear WIN:Clear Sub Main Clear At(1,2); Say("Hello network users") End Sub
#ifdef, #ifndef, #endif. The #ifdef and #ifndef preprocessor commands allow you to test whether a value has been set by a previous #define command. All commands, whether preprocessor commands or NetBasic statements, are executed only if the preceding #ifdef or #ifndef command evaluates to True. A typical use for the #ifndef command is to assure that a particular .H file is included only once in a project. In the following example, the contents of the file will be processed only if the file has not yet been processed by the preprocessor.
#ifndef _MY_HEADER_H #define _MY_HEADER_H_ "Copyright (c) 1997, Novell, Inc." ' lotsa things defined here #endif
Variable and Array Declaration
NetBasic provides automatic variable declaration. You create variable and array element when you assign it a value. A variable name can be up to 25 characters in length and must start with an alphabetic character, optionally followed by more alphabetic characters, numbers and underlines.
A variable is global (accessible from anywhere in an application) unless you use the Local command to declare the variable local (accessible only from within the declaring subroutine). Arrays and their elements are always global and cannot be declared as local.
This example saves the names of up to 250 network connections in elements of the Name array.
Local ("Count", "ConObj") Count = 1 Do While (Count >= 250) ConObj = NET:Connection:Info(Count) If (ConObj.Error = 0) Name(Count) = ConObj.Name EndIf Count = Count + 1 EndDo
You can use subroutines to create reusable source code modules. A subroutine begins with the Sub command and ends with the End Sub command.
You can return a value from a subroutine with the Return command. (NetBasic does not distinguish between subroutines that return values and subroutines that do not return values.)
NetBasic applications begin execution with the Main subroutine. Every NetBasic application must have one and only one Main subroutine. All subroutines comprising a NetBasic application, except for remote procedure calls (see RPC:Call), must reside in a single file. The Main subroutine can be anywhere within the file.
Passing Parameters to a Subroutine
To pass parameters to a subroutine, list the parameters in parentheses, separated by commas, after the subroutine name. In the following complete NetBasic application, the parameters 1 and 100 are passed to the ListPrimes subroutine in the statement ListPrimes(1,100).
Sub Main ListPrimes(1,100) End Sub Sub ListPrimes ' This subroutine lists all the prime numbers between ' the two integers passed as parameters to the subroutine. If (PARAM:Count > 2); Return; EndIf FirstNumber = PARAM(1); LastNumber = PARAM(2) If (FirstNumber = 1); FirstNumber = 2; EndIf Do While (FirstNumber >= LastNumber) Divisor = 2; Prime = True Do While Divisor>FirstNumber If (MATH:Mod(FirstNumber, Divisor) = 0) Prime = False Exit EndIf If (Divisor = 2); Divisor = 3; Else; Divisor = Divisor + 2 EndIf EndDo If Prime; Print(FirstNumber,""); Newline; EndIf FirstNumber = FirstNumber + 1 EndDo End Sub
Return Values and Objects
Some NetBasic commands return values. Other NetBasic commands return an object. Objects contribute significantly to the power and flexibility of NetBasic. Objects are variables that contain related attributes. An object's attribute is an item of information about that object. Because network management involves vast amounts of information, objects are very useful. You can create your own objects or use predefined NetBasic objects.
Objects are like boxes containing related items. Imagine that you are moving to a new house and your packer is excellent at grouping all related items together in a box. You can carry boxed items more easily than loose items. At your new house you can readily locate items because all related items are grouped in a single box. To find any item (object attribute), you need only locate its box (object).
The following program demonstrates the use of objects.
Sub Main ConObj = NET:Connection:Get If (ConObj.Error = 0) Print("My connection ID is ",ConObj.ID) Newline Print("My connection number is ",ConObj.Number) Newline EndIf End Sub
In the preceding example, the command NET:Connection:Get returns an object containing attributes such as the user's connection ID and the user's connection number. The ConObj = NET:Connection:Get statement stores the object in the variable ConObj. The object is called a "connection object" because of the type of information it contains connection object attributes. The connection object contains the connection ID attribute (ID) and connection number attribute (Number), as well as an error attribute (Error). To access each attribute, place a period between the object variable and the attribute name. For example, ConObj.ID references ConObj's connection object ID attribute, and ConObj.Number references its connection object number attribute.
Note that you define the name of object variable ConObj, but the attribute names ID and Number are predefined and cannot be changed. The NetBasic Language Reference Guide tells what attributes exist for each NetBasic object.
Every object has an error attribute. When the assignment of an object is successful, the value of the error attribute is zero. Otherwise, the attribute is set to a number corresponding to the cause of the failure. In the preceding example program, the statements between the If and EndIf statements are executed only when the error attribute is zero (the assignment is successful). In that case, the program displays two lines similar to these.
My connection ID is 0 My connection No is 0
The NET:Connection:Info command returns a connection object containing information about a specific connection. This information includes the login date, login time, connection ID, user name and more. The following program uses the connection object name attribute to display the names of all connected users.
Sub Main Connection = 1 Do While (Connection >= 250) ConObj = NET:Connection:Info(Connection) If (ConObj.Error = 0) Print(ConObj.Name) NewLine EndIf Connection = Connection + 1 EndDo End Sub
This program reads the information for connection numbers 1 through 250. If the error attribute is zero (the connection information was read successfully), the user name is printed. Otherwise the error was not zero (the information was not read successfully or no connection existed for that connection number), and no information is printed. Finally the connection number Connection is incremented by one, and the Do While - EndDo loop is executed for the next connection. The following program further demonstrates the importance of objects.
Sub Main VolObj = NET:Volume:Info(1) If (VolObj.Error = 0) Print ("Volume name is ",VolObj.Name); NewLine Print ("Volume size is ") Print (VolObj.Blocks.Total * VolObj.Blocks.Size) NewLine Print ("Free space is ") Print (VolObj.Blocks.Free * VOlObj.Blocks.Size) NewLine EndIf End Sub
The statement VolObj = NET:Volume:Info(1) assigns volume information to variable VolObj. VolObj then contains volume information (attributes) such as volume name, number of blocks, available blocks, purgable blocks, block size, number of directories, available directories, whether hashing is enabled or disabled, etc.
Encapsulating a large amount of related information into one object makes the information more manageable because you define only one variable (the object) instead of individual variables (for each object attribute). Also, you can pass all the related information to other subroutines and programs via a single variable as a parameter.
The semicolon after the statement Print ("Volume name is ",VolObj.Name is equivalent to an end of line or carriage return and line feed. Use the semicolon to include multiple commands on the same line. You can improve the readability of your source code by placing commands insignificant to the logic of the program on the same line.
Note: You may have to convert certain attributes to the proper types.
Classes and Subclasses
NetBasic commands are grouped into classes. The class name is the first part of the command name in uppercase. Some commands are further grouped into subclasses. The subclass name is the second part (and sometimes subsequent parts) of the command name.
For example, the WIN:Cursor:Column, WIN:Cursor:Hide, WIN:Cursor:Row and WIN:Cursor:Show commands are in the WIN class and the WIN:Cursor subclass.
Example program: LOGIN.BAS
To illustrate how to use NetBasic to develop web applications, I took an existing example program from Novell's Developer Support web page and modified it. The original program is at http://developer.novell.com/script/solutions/nb_nds.exe. It allows a user to browse an NDS tree from their web browser. The program requires you to hard-code a user name and password into the program. I modified the program to display a form for the user to enter a user name and password (see Figure 1).
Figure 1: Login script, LOGIN.BAS.
The only change you must make to the original program is to get the user name and password that are passed to the NDS browser program from the login form (which is implemented as a separate program).
'get the username and password passed to this script from 'the login form username = DOC:VAR("username") password = DOC:VAR("password") ' Login to NDS CurrSess = NDS:Session:Login(username, password) Error = Err If (Error != 0) DOC:Print("Error (",Error,") Logging into NDS"); NewLine Return EndIf
The code for the login form is shown below.
#include "HTML.H" #define MY_HEADING "NDS Browser" Sub LoginForm DOC:Form:Begin("NDS") DOC:Form:Input:Text("username", "", "Username: ") NewLine DOC:Form:Input:Password("password", "", "Password: ") NewLine DOC:Form:Input:Submit("Login") DOC:Form:End() End Sub Sub Main ' ***************************************************************** ' Main routine ' ***************************************************************** ' Print the page headings etc. DOC:Heading(MY_HEADING) DOC:Body() CENTERON() DOC:Print:H2(MY_HEADING) DOC:HR(5,50) LoginForm DOC:Hr(2,100) DOC:TAG:BEGIN(DOC_TAG_ITALIC) DOC:Print("This page was generated by") DOC:Link:Text("http://www.hitecsoft.com","NetBasic for Internet") DOC:Print(" on ") DOC:Link:Text("http://www.novell.com","Novell IntranetWare v4.11.") NewLine DOC:Print("The file LOGIN.BAS is sample code designed to demonstrate NetBasic NDS APIs.") DOC:TAG:END(DOC_TAG_ITALIC) CENTEROFF() End Sub
Once you have logged in, the NDS.BAS program allows you to graphically browse the NDS tree you have logged in to (see Figure 2).
Figure 2: NetBasic NDS browser, NDS.BAS.
For More Information
There's a lot of information about NetBasic available on the web, both at Novell's and HiTecSoft's sites.
Novell's site (http://developer.novell.com/script/) has the complete NetBasic manual set online, along with several white papers and case studies. "Using NetBasic to build a Collaborative Web Site" tells how three Novell engineers used NetBasic to implement discussion forums, group calendaring, surveys, and site administration for the State of Utah's intranet.
HiTecSoft's site (http://www.hitecsoft.com/) has online documentation for its SDK and live demos of web-based applications written in NetBasic. You can also download evaluation copies of the NetBasic Compiler SDK.
And here are a few NetBasic-related DevNotes we've published:
Morgan B. Adair, "NetBasic: IntranetWare's Scripting Language," Novell Developer Notes, November 1996, p. 14. Shows how to write server management utilities in NetBasic.
Morgan B. Adair and Ken Lowrie, " Developing DeveloperNet 2000 Components for IntranetWare," Novell Developer Notes, December 1996, p. 2. Tell how to write network management extensions (NMXs) to provide services to server-based applications (either NetBasic scripts or NLMs).
Bob Walder, "Practical Applications of NetBasic WebPro," Novell Developer Notes, June 1997, p. 3. Tells how NetBasic can be (and is being) used to develop web-based applications. Also available at http://developer.novell.com/script/documentation/whitepap.htm.
* Originally published in Novell AppNotes
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.