Skip to content

Building UNIX Applications

Chapter 3-2
Building UNIX Applications

Introduction

This chapter identifies the hardware and software requirements for developing HCL C API programs for Domino under UNIX and explains how to set up your UNIX environment. It covers the following topics:

Getting Started
Hardware and software requirements, Compiler installation, Environment settings for compiling the sample, Running HCL C API programs, and Testing the installation

Program Structure
Initialization and file-naming conventions

Toolkit Files
Platform-specific files supplied with the HCL C API Toolkit for Domino

Compatibility
Information on addressing, calling conventions, and data alignment

Compiling, Linking, Building shared libraries, and Debugging
Platform-specific information on compiler, linker, and debugger settings for C API applications

Porting HCL C API Programs for Domino to UNIX from Windows
Specific considerations when porting existing applications to run on UNIX systems

In addition to the information in this chapter, the chapter on Domino Canonical Format contains important considerations for developing C API applications for UNIX systems


Getting Started

This section describes the hardware and software requirements for each UNIX platform supported by the HCL C API for Domino.


Hardware and software requirements

Same Hardware requirements as those noted for the Domino server with addition of space to afford room for C API toolkit and compilation. Minimum software requirements are used for the build environment (for example, if Domino supports Linux version 9, then 9 is the build platform as you must always build on the lowest supported OS level)

Compiler installation

There are no special requirements for installation of the compilers or other tools.


Environment settings for compiling the sample

This section explains how to set up your UNIX environment to build and run HCL C API programs for Domino.

Summary

  • Make sure HCL Domino and the HCL C API for Domino are installed.
  • Set the environment variable LOTUS to the canonical Lotus directory, /opt/hcl, if necessary. All HCL software is installed in the canonical Lotus directory.
  • While developing HCL C API programs for Domino, set the environment variable Notes_ExecDirectory to specify the Domino executable directory.


The sections that follow define the following concepts:

  • The canonical Lotus directory
  • The Domino executable directory



The canonical Lotus directory

The canonical Lotus directory is the directory in which all Lotus products for UNIX are installed. A canonical Lotus directory is required because on some UNIX systems shared libraries are found in absolute file system locations.

Set the environment variable LOTUS to point to this directory:

  • /opt/hcl/domino for all UNIX platforms


If you use the C shell, your .cshrc file should contain the line:

setenv LOTUS /opt/hcl/domino for all UNIX platforms

For sh or ksh, your initialization file should contain the following:

LOTUS=/opt/hcl/domino; export LOTUS for all UNIX platforms

All Domino and Notes Client software should be installed in the canonical Lotus directory. Specifically,

  • The Domino program directories should reside in $LOTUS/notes.
  • The HCL C API Toolkit for Domino and Notes should reside in $LOTUS/notesapi.


All UNIX platforms support symbolic directory links. Therefore, Lotus products may physically reside anywhere in the file system, so long as a directory link in the canonical Lotus directory points to where the product actually resides. For example, the directory /opt/hcl/domino/notesapi may be a symbolic link to the directory where the HCL C API Toolkit for Domino and Notes physically resides.

The make files for HCL C API sample programs for Domino and Notes use $LOTUS to locate the directory where the HCL C API for Domino and Notes include files and object files reside.


The Domino executable directory

The Domino executable directory is the directory where the Domino executable program libraries reside. Relative to $LOTUS, the root of the Lotus tree, the Domino executable directory is:

$LOTUS/notes/latest/arch


Where

latest is a symbolic link to the release name (for example, 110001),

arch is the code name for the architecture of the UNIX platform (for example, ibmpow). It consists of up to three letters for the vendor (for example, ibm) and up to three letters for the CPU or machine type (for example, pow for POWER). For example, the Domino executable directory for Domino for IBM AIX Edition is:

$LOTUS/notes/latest/ibmpow



By convention, set the environment variable Notes_ExecDirectory to point to the Domino executable directory. If you use the C shell, your .cshrc file should contain the line:

setenv Notes_ExecDirectory your-Domino-executable-directory

For sh or ksh, your initialization file should contain the following:

Notes_ExecDirectory=your-Domino-executable-directory;
export Notes_ExecDirectory

Running HCL C API programs

This section explains how to set up your UNIX environment to run HCL C API programs for Domino.

Change the C API program with the owner, group, and file permission. Install the C API program executable file into the Domino executable directory, then create a sym link of tools/startup in $LOTUS/bin. For example,

% cp apiprog $LOTUS/notes/latest/ibmpow/apiprog

% cd $LOTUS/bin

% ln -s tools/startup apiprog

Change to the Domino data directory and start the C API program. For example,

% cd /local/notesdata

% /opt/hcl/bin/apiprog

Owner, group, and file permissions

UNIX is a Domino Server only platform. It is required that you run C API programs on UNIX under the same login as the server.

After compiling but before running a HCL C API program for Domino, make sure the executable file for the C API program has the same owner and group as other Domino binaries and also has the set group-id bit set.

By default, all Domino executable files have owner "root" and group "system" For example, a command to list the owner, group, and permissions of the Domino executable "server" for Domino for AIX would print something similar to the following:

% ls -l $LOTUS/notes/latest/ibmpow/server
-rwxr-xr-x 1 root system 14102624 June 25, 06:39 /opt/hcl/notes/latest/ibmpow/server

In this case, you must set the owner of your C API executable program to "root" and the group to "notes", The following commands show how to set the owner, group, and permissions of the C API sample program executable "intro" to the required values:

% cd $LOTUS/notesapi/samples/basic/intro
% su
Password: <enter the super user password>
# chown root intro
# chgrp system intro
# chmod 2555 intro
# exit
%
The Domino data directory

The Domino data directory is the directory containing server's notes.ini file, the Domino databases, and templates.

Under UNIX, the default Domino data directory is named /local/notesdata and it must reside on the local disk.

The initialization algorithm

When you invoke a program via /opt/hcl/bin/FOO it invokes our startup script which sets up the environment so that we can find our executables as well as our resources files required for Domino to run. This means that as long as you put your binary in /opt/hcl/notes/latest/ARCH and make the correct symbolic link as noted above then your executable will run fine. If you wish to locate your binary elsewhere, then you can use the startup script to directly invoke your executable and we will still be able to find our libraries and resource files. This is done with the syntax: /opt/hcl/notes/latest/ARCH/startup /full_path_to_my_executable/my_executable

Testing the installation

After installing Domino, the C compiler, the development files, the documentation, and the sample C API programs, follow these steps to build and test the sample C API program intro. Any problem building or executing an unmodified sample program indicates a problem in the environment.

  1. Verify that Domino for UNIX executes successfully in your environment. C API programs require that Domino is installed properly in the environment.
  2. Open an xterm window, or use rlogin or telnet to get a shell and a command prompt.
  3. Copy all the files under the intro directory to a directory under your home directory. Under the default installation of the HCL C API Toolkit for Domino and Notes, this sample directory is located under:

    /opt/hcl/domino/notesapi/samples/basic/intro
  4. Change to the directory where intro was copied and type ls to list the files in this directory.

    The .mak files in this directory are make files for the various operating environments. The C API kit includes multiple build support files for samples that can be built for multiple platforms.
  5. Build intro using the make file appropriate to your operating environment. For example, if you are developing on a Linux system, type the following command at the command prompt:

    make -f linux.mak

    The program should compile and link with no errors.
  6. Copy the database, intro.nsf, from the notedata directory in the C API kit to the Domino data directory. Under the default installation of the HCL C API Toolkit for Domino, this database is located under:

    /opt/hcl/domino/notesapi/notedata/intro.nsf
  7. Enter this at the command prompt:

    intro intro.nsf

    It should display the HCL C API for Domino and Notes release number followed by:

    The title for the database intro.nsf is...

    API Test Database (intro)

  8. Start Notes on a client machine. Open the database "intro.nsf" on the UNIX server.
  9. Check the database title by selecting File - Database - Properties. The title should be the same as the one printed by the intro sample: "API Test Database (intro)."


Program Structure

Program Initialization

C API programs for UNIX may use any of the following methods to initialize the Domino or Notes Client run-time system.

NotesMain

You can structure C API programs for UNIX as a subroutine named NotesMain. In this case, link with the bootstrap object file notes0.o. This object file provides the "main" program required by UNIX systems.

NotesMain uses the system's standard calling convention. The argument count provided to the subroutine is an integer.


AddInMain

HCL Domino Server add-in tasks are usually structured as a subroutine named AddInMain. This type of program must be linked with both platform-specific bootstrap object files notes0.o and notesai0.o. These object files provide the "main" program and perform server add-in initialization.

Like NotesMain, AddInMain uses the system's standard calling convention. The argument count provided to the subroutine is an integer.


main

You can structure the program as a standard C or C++ program with entry point main. In this case, the program must call the function NotesInitExtended to explicitly initialize the Domino run time system before calling any other HCL C API for Domino and Notes functions. When the program no longer needs to call any HCL C API functions for Domino and Notes, it must call the function NotesTerm to terminate the Domino run time system explicitly.

MainEntryPoint

You can structure the program as a shared object library with a main entry point named MainEntryPoint. In this case, the C API program is configured as an add-in to the software. Typically, the Notes client or Domino server software loads and calls the main entry point of this custom library in response to a Notes user's command or menu selection. In this case, the Domino run-time system is initialized before MainEntryPoint receives control. The Domino or Notes run-time system is terminated when the user exits Domino or Notes.

Under the LINUX environment the function definition of MainEntryPoint must use extern "C". This will prevent MainEntryPoint from being mangled. For further information please reference the "gcc/g++" online reference.


Naming Conventions

Platform-Specific File Directories

The platform-specific files supplied with the HCL C API Toolkit for Domino and Notes are in the library directory. The pathname for this directory depends on the platform:

AIX: $LOTUS/notesapi/lib/aix
Linux: $LOTUS/notesapi/lib/linux



Custom Libraries

Under Windows, custom libraries such as extension managers are in the form of dynamic link libraries (DLLs). Under UNIX, custom libraries are in the form of shared objects.

On all UNIX platforms, the filenames of shared objects must start with the characters "lib". Append to "lib" the name you want to give the file, followed by a platform-specific extension. The extensions used by the various UNIX platforms are as follows:

Platform File extension Typical Filename
AIX .a libfoo_r.a
Linux .so libfoo.so


Toolkit Files

This section describes the components of the HCL C API Toolkit for Domino and Notes that support building applications for UNIX platforms.


HCL C API Header Files for Domino

In the HCL C API Toolkit for Domino, support for all platforms is provided by the common include files in $LOTUS/notesapi/include. When compiling, the Domino header files require the use of the many compiler command-line switches which will be detailed below and are also in the PLAT_cmp.txt file included in the include directory of the SDK. For details, see "Compiling," below.

Be aware that the UNIX platform ID macro, "-DUNIX" also defines the W32 platform ID macro which stands for the Win32 APIs. If you need conditional compilation for 32-bit Windows, but not for UNIX, be sure to check that W32 is defined and UNIX is not defined, Alternatively you can use the NT platform ID macro for 32-bit Windows conditional compilation. There are 32 and 64 bit specific defines as well - please see the PLAT_cmp.txt or below for more info.

Header File Conflict

It is possible that a header file that is included with the compiler's software development kit may have the same name, but different contents, as a C API for Domino and Notes header file. If your API program requires the HCL C API header file for Domino and Notes but does not require the other file that has the same name, you may resolve the conflict including the HCL C API for Domino and Notes headers before the others during compilation. Alternatively, you may specify the full path of the header file in the #include statement in your source code. This alternative allows your program to include both files in a single source module.

It is also possible that a header file that is included with the compiler's software development kit may contain a definition that is also defined in a header file in the HCL C API Toolkit for Domino and the syntax of the definitions cause errors when compiling source code that includes both header files. In such cases it is recommended to keep code that requires each header file in a separate module.


HCL C API Library Files for Domino

Since the HCL C API for Domino is supplied as a shared object library on UNIX platforms, no separate library files are supplied with the HCL C API Toolkit for Domino and Notes. For details, see "Linking," below.


HCL C API Bootstrap Object Files for Domino

The bootstrap object files in the platform-specific subdirectories under $LOTUS/notesapi/lib are required to construct C API programs using the NotesMain entry point and to construct server add-in tasks. The file notes0.o provides the entry point and Domino run-time initialization for Domino applications. The file notesai0.o is used in conjunction with notes0.o to provide the entry point and run-time initialization for HCL Domino Server add-in tasks.


Compatibility

Data Structure Packing

On UNIX systems, most data structures passed between Domino and API applications are aligned on the appropriate data boundaries. However, some structures containing data that is stored directly in a Domino database are stored in Domino canonical format. You must convert this data using ODSReadMemory and ODSWriteMemory. For more information, see the "Domino Canonical Format" chapter.


Features Not Supported by Domino for UNIX

The following features of C API programs are not supported under UNIX due to design limitations in Domino:
  • Notes client menu add-ins
These are executable program libraries loaded and called by Notes when the user selects custom items from the File -Tools menu.
  • API programs such as IMPORTER
These are programs that load and call import/export libraries provided by Notes.
  • Notes/FX (Field Exchange)
This feature is only supported under Windows.


Compiling

Platform ID Macro

UNIX platforms require two macros. All UNIX platforms require the platform ID macro "UNIX", to distinguish them from PC-based environments. In addition, each UNIX platform has a platform-specific ID macro:

AIX64: AIX
AIX64

Linux64: LINUX
LINUX64


Compiler Switches and Options

The recommended compiler switches and options depend on the compiler you use. Please see the platform specific PLAT_cmp.txt files for more info

Linux64
To compile Domino C API applicaitons under Linux use the switches in linux64_cmp.txt


AIX64
To compile C API applications under AIX65, use the switches in aix64_cmp.txt

Linking

Stack Size
There are no special considerations for stack size for UNIX C API applications for Domino.

Linker Switches
The recommended linker switches depend on the linker you use.

Linux64
To link C API applications under Linux64, use the switches in linux_cmp.txt.

AIX64
To link executable C API applications under AIX64, use the switches in aix64_cmp.txt


Building shared libraries

Linker Switches

The recommended linker switches depend on the linker you use.

Linux64
To link C API applications under Linux, use the switches in linux64_cmp.txt.


AIX64
To link executable C API applications under AIX64, use the switches in aix64_cmp.txt:

Debugging

To build a version of an application for symbolic debugging, add the following flag to the compiler command:

-g Cause the compiler to generate additional information needed by the symbolic debugger.

You may want to avoid use of the -O flag, used to generate optimized code.



Porting HCL C API Programs for Domino to UNIX from Windows

Follow these steps to port your existing C API programs from Windows to UNIX.

Step 1: Avoid Features That Are Only Supported under Windows

Make sure your API program does not use any of the features listed in "Features Not Supported by Notes for UNIX" above. If it does, consider alternative solutions.


Step 2: Port Platform-Specific Code

Since most HCL C API functions for Domino and Notes are portable, most of the platform-specific code in a typical application appears in the system calls and the user interface.

Place portable C API code and non-portable system and UI code in separate modules. Define generic wrapper functions in the platform-dependent modules that can be called from the portable modules. Create a new platform-dependent module for each new platform you port to. This technique may help you maintain core code used for both the Windows and the UNIX versions of a program.

To help simplify porting, replace platform-dependent system calls, with standard C run-time functions.


Step 3: Use NotesInitExtended

If your program calls NotesInit (rather than NotesMain or AddinMain), change it to call NotesInitExtended instead.

Step 4: Perform Host/Canonical Conversion via ODS functions as needed

Read the "Domino Canonical Format" chapter in this guide. Find the places where your API program reads or writes any of the data types listed below, and modify these sections of your code to perform host/canonical conversion:

TYPE_COMPOSITE
TYPE_COLLATION
TYPE_OBJECT
TYPE_VIEW_FORMAT
TYPE_ICON
TYPE_SIGNATURE
TYPE_SEAL
TYPE_SEALDATA
TYPE_SEAL_LIST
TYPE_WORKSHEET_DATA
TYPE_USERDATA

This step has the greatest impact on C API programs that access rich text fields directly via the individual CD records. It also affects C API programs that access design notes, such as form, view, or macro notes. It does not affect C API programs that manipulate rich text via the high-level CompoundText* routines.

For all other data types, the Domino NSF subsystem performs the conversion automatically.


Step 5: Use Memcpy to avoid Bus Errors

Often, code ported to UNIX from Windows crashes at run time with the system error message "Bus Error." The most common cause is an attempt by a program to access an integral data type at an address that is not a multiple of the data type size, or to access a data structure at an address that is not to a multiple of the size of the data structure's largest simple element.

To avoid the most common causes of bus errors, find the places where the API program gets a pointer to a data structure from Domino. Use memcpy to copy the data structure into a local variable before accessing its members. Use the local variable, not the pointer provided by Domino, to access the structure members.

This step has an impact on a wide range of HCL C API programs for Domino. For example, when searching for notes in a database, Domino passes a pointer to a SEARCH_MATCH structure as one of the input arguments to the NSFSearch action routine. This SEARCH_MATCH pointer provided by Domino may not be aligned properly for the SEARCH_MATCH data type, since Domino data frequently resides in packed memory buffers.

The action routine must call memcpy to copy the SEARCH_MATCH structure from the address specified by the pointer to a local variable of type SEARCH_MATCH. The action routine must only use this local variable, not the pointer, to access the structure members. Using the pointer to access members of the SEARCH_MATCH structure may yield a bus error. See the example below.


Background

The reasons for bus errors stem from differences between Intel and RISC processors and compilers. Program code on Intel-architecture platforms can access any data type at any address. On other platforms, C source code that reads a 32-bit quantity, such as a long integer, from a particular memory address, causes the C compiler to emit a 32-bit load instruction. In this case, the memory address must be aligned on a 32-bit (4-byte) boundary. If the memory address is not properly aligned, the hardware will generate an interrupt. The kernel will trap this interrupt and send a BUS ERROR signal to the process running the program.

Generally, the following rules apply to all UNIX/RISC combinations:
  1. Any data type is aligned to an address that is a multiple of its own size.
  2. Any structure is aligned to the strictest alignment of all of its elements (that is, to a multiple of the size of its largest simple element or to the alignment of a contained structure if that is stricter).
  3. Any array of the data type is aligned to the alignment of its elements, and any element in the array is similarly aligned.
  4. Alignment is consistent unless compiler options or pragmas alter it.


Example

The code below shows how part of the sample program nsf_dump was modified to avoid a bus error. The original code caused a bus error at the line that accesses the NoteID member of the SEARCH_MATCH data structure.

Before porting to UNIX:

/************************************************************************

  FUNCTION:  DumpOneNote

  PURPOSE:  This is the action routine specified to NSFSearch

  INPUTS:   void far *Param         - not used
        SEARCH_MATCH far *pSearchMatch - information about the
                         note that was found
        ITEM_TABLE far *SummaryBuffer  - not used

*************************************************************************/

STATUS LNPUBLIC DumpOneNote( void far * Param,
         SEARCH_MATCH far *pSearchMatch,
         ITEM_TABLE far * SummaryBuffer )
{
  STATUS Error;
  char  szClass[LINELENGTH+1];
  DWORD  dwDumpCount;

  if (!(pSearchMatch->SERetFlags & SE_FMATCH))
    return( NOERROR );

  if (Error = GetNoteClassAndDumpCount( hDB,
              pSearchMatch->ID.NoteID, /* Bus Error Here !! */
              szClass,
              LINELENGTH,
              &dwDumpCount ))
  {
    return (Error);
  }
             
/* ... etc... */


After porting to UNIX:

/************************************************************************

  FUNCTION:  DumpOneNote

  PURPOSE:  This is the action routine specified to NSFSearch

  INPUTS:   void far *Param         - not used
        SEARCH_MATCH far *pSearchMatch - information about the
                         note that was found
        ITEM_TABLE far *SummaryBuffer  - not used

*************************************************************************/

STATUS LNPUBLIC DumpOneNote( void far * Param,
         SEARCH_MATCH far *pSearchMatch,
         ITEM_TABLE far * SummaryBuffer )
{
  SEARCH_MATCH SearchMatch;
  STATUS Error;
  char  szClass[LINELENGTH+1];
  DWORD  dwDumpCount;

  memcpy( (char*)&SearchMatch, (char*)pSearchMatch, sizeof(SEARCH_MATCH) );

  if (!(SearchMatch.SERetFlags & SE_FMATCH))
  {
    return( NOERROR );
  }

  if (Error = GetNoteClassAndDumpCount( hDB,
              SearchMatch.ID.NoteID,
              szClass,
              LINELENGTH,
              &dwDumpCount ))
  {
    return (Error);
  }
             
/* ... etc... */


Step 6: Remove Constructs not Supported by Your C Compiler

Remove from your code (or conditionally compile) any constructs that the C compiler on your UNIX system does not support.

For example, many programs developed using Microsoft C use the double forward slash ( // ) comment delimiter, a C and C++ convention that Microsoft supports for compatibility with its C++ compiler.

Step 7: Check All Explicit File Names

All file names should be in lowercase unless there is a good reason to do otherwise. Remember that file names in UNIX are case-sensitive. The biggest impact of this change is on documentation, with a smaller impact on source code.

Many programs and almost all documentation under DOS use all uppercase letters for file names. This helps to distinguish file names from other text in documentation, but under UNIX it is generally wrong because file names are in lowercase. ---