

 0      General
 0.1        Introduction
 0.2        Version
 0.3        Copyright

 1      General GEAS questions
 1.1        What is GEAS?
 1.2        How do I compile GEAS?
 1.2.1      What is libuuid?
 1.3        Geas is running slowly.
 1.4        Can I use GEAS to develop web applications?
 1.5        
 1.6        Where's the documentation?
 1.7        How do I connect to GEAS over a network?
 1.8        Ok, so how do I configure this ORBit thing anyway?
 1.9        Does geas have a log?

 2      Debugging
 2.1        Debugging support
 2.1.1          Compile time options
 2.1.2          Run time options
 2.2        Error messages
 2.2.1          GEAS can't find a .conf file
 2.2.2          GEAS fails to run, and complains about a GCD file error
 2.2.3          Client says it can't log in
 2.2.4          GEAS complains about not finding a database
 2.2.5          GEAS can't connect to a database

 3      Database questions
 3.1        What is the difference between a GCD file and an SQL database
                creation script?
 3.2        How can I use an existing database?
 3.3        Can GEAS use other OODBs?

 4      Writing client applications
 4.1        How do I get a Java client to talk to GEAS?
 4.1.1      What about Java?

 5      Writing business classes
 5.1        What is the difference between a class and an object?
 5.2        What can I do with a class in GEAS?
 5.2.1      
 5.2.2.1    So how do I do 'has a' in GCD files?
 5.2.2      Isn't multiple inheritance bad?
 5.3        How do I make a new class?
 5.4        How do I set up 'C' methods in GEAS?
 5.5        How do I set up Python methods in GEAS?
 5.6        Do I have to use references, lists and lookups?

 6      CORBA questions
 6.1        How much CORBA do I need to know?
 6.2        What languages and ORBs can be used?
 6.3        
 6.3.1          Memory management rules
 6.3.2          Server side resources
 6.3.3          Client side resources
 6.3.3.1            GEAS::Query::Field
 6.4        Exception handling
 6.4.1          Python
 6.4.2          Java
 6.4.3          C
 6.5        What's a 'sequence' ?
 6.5.1          What's that weird array stuff in C?

----------------------------------------------------------------------
0 : General
----------------------------------------------------------------------

0.1) Introduction

   This FAQ covers a range of topics that seem to come up on a regular
basis. More detailed documentation is slowly being written, but for now,
many common issues are covered in this file.


0.2) Version

  Last modified: $Id: faq.txt,v 1.12 2001/08/23 23:30:58 ntiffin Exp $


0.3) Copyright

   GEAS FAQ - GNU Enterprise Application Server

   Copyright (C) 2001 Free Software Foundation

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  

   This file originally created by Andrew Murie on March 29, 2001
   andrewm@gnue.org

----------------------------------------------------------------------
1 : General GEAS questions
----------------------------------------------------------------------

1.1) What is GEAS?
    GEAS is the GNU Enterprise Application Server. It uses a relational
database to store data, but provides an OO API to clients.


1.2) How do I compile GEAS?

    Code is available in CVS, and released versions are available as a tarball
(see http://www.gnuenterprise.org/ and follow the 'Downloads' link.)
Alternatively, the latest code can be retrrieved from CVS, using
instructions also found on the GNUe web site. The file doc/INSTALL
provides reasonably detailed instructions.

    Run 'autogen.sh' (or 'configure' if autogen.sh is not present) with the
appropriate arguments to enable/disable features. In most cases, you will not
need an argument at all, because GEAS automatically checks which database
backends you have installed.

    This should warn you of any required libraries etc, which must be
installed. (If you find something is missing that is not detected by the
configure script, please email gnue-geas@lists.gnue.org with a description
of the problem, including your OS and which version you are running.)

    Type 'make' to compile the server.

    'make install' will copy a number of files to appropriate directories.
Full instructions on this are needed in the near future. The file INSTALL
will contain the most up to date installation instructions.


1.2.1) What is libuuid?

    This is one of the more common dependancies that people don't have
installed. Debian users can use apt-get to install the uuid-dev package.
Other users will need to locate an appropriate archive and install this
themselves. (libuuid is also provided by the e2fsprogs package.)

    TODO: Links to appropriate websites.


1.3) Geas is running slowly.

    That's not a question.


1.3.1) Fine. Why? And what can I do about it?

    A number of possible reasons exist. These include:
      A slow/overloaded computer.
      A slow network connection between GEAS and the client, or GEAS and the
          database.
      Heavy usage of the database by other applications.
      A small cache in GEAS. (Increase the 'maximumcache' entry in the config
          file.)
      Old code. (Recently, several changes have been made that drastically
          increase speed when handling large numbers of objects.)


1.4) Can I use GEAS to develop web applications?

    Yes.


1.4.1) I was hoping for more detail. How?

    GEAS itself provides no user interface at all. It is possible to develop
a client in a range of languages (eg: Python, C, Java, PHP) that can run as
cgi-bin programs, and use HTML as the output display. Java applets can also
talk to GEAS, but the restrictions on what machines an applet can talk to
may limit this in specific installations. Also, the appropriate classes
(in the package org.omg. must be available on the client machine, and
these are not included in some earlier versions of the JRE.)

1.5) 


1.6) Where's the documentation?

    We had a volunteer working on that. Unfortunately, someone turned their
back for a moment, and he escaped. Until we track him down, the 'geas/doc'
directory contains a number of files describing GEAS, both the API, GCD file
format, and internals. It needs work, but it's a start. Volunteers to help
are always appreciated - provided you can read C you can help with this.
Even if you can't document some parts, you can help with providing direction
to the documentation, and ensure that what is being written is helpful.


1.7) How do I connect to GEAS over a network?

    Simply make sure the client can read a copy of the IOR file written by
the GEAS server. Additionally, it is important to ensure ORBit is configured
to use TCP/IP, and that the client can resolve the server's address
correctly. (See 1.8 and 2.3 for further information.)


1.8) Ok, so how do I configure this ORBit thing anyway?

Place the following lines in /etc/orbitrc (or in ~/.orbitrc, to control it
on a per-user basis.) To enable either UNIX sockets or TCP/IP set the
appropriate value to '1' and use '0' to disable. (Note: IPv6 is not yet
supported, but it will be eventually, hence the option.)

--- cut here ---
ORBIIOPUSock=0
ORBIIOPIPv4=1
ORBIIOPIPv6=0
--- cut here ---


1.9) Does GEAS have a log?

GEAS is an environmentally friendly system, and not so much as a small bush
has been removed from a rainforest to create it.

If you must have a log, GEAS can be configured to record every action to a
file, along with a timestamp and the ID of the user responsible.

In the configuration file, the option 'mainlog' sets a file to which all
data operations are recorded. Method calls are only logged in terms of
database operations.

The option 'logserverclasses' is used to determine if operations on GEAS
specific classes are logged as well. This covers the user data class, as
well as list handling and query handling classes. (Note: in either case,
operations on members of lists and results of queries are still logged.)

In the future, GEAS will allow more complex filtering of events, and running
multiple log files.


----------------------------------------------------------------------
2 : Debugging
----------------------------------------------------------------------

2.1) Debugging support

2.1.1) Compile time options

When running autogen.sh (or configure), the option --enable-debug turns on
extra debugging support. (Remember to type 'make' first.)

The option --enable-debug-security turns on extra debugging code in the
security system. As this prints information such as passwords, it can reduce
security. When security debugging is turned on, the user must respond with
'yes' to a warning message before the server will be activated. (This helps
prevent a server from being used with this potential security hole
accidentally.)


2.1.2) Run time options

If debugging has not been enabled, then there are no run time debugging
options. Normal activity logs will, of course, be useable.

The configuration file includes a 'debuglevel' option that sets the level of
debugging detail. Alternatively, the '-d' option allows the user to override
the configuration file.

The debug level may be set to any number between 0 and 10 inclusive.
Alternatively, the level may be set to 'off' (level 0), low (level 1), medium
(level 5) or high (level 10).

Example:
    geas-server -d low
    geas-server -d 4
    geas-server -d off


2.2) Error messages

2.2.1) GEAS can't find a .conf file

    The default location for the geas.conf file is specified with the
--sysconfdir option, when running 'autogen.sh'/'configure'. The default is
"prefix/etc"  (where prefix defaults to "/usr/local")

    eg:
        --sysconfdir="/etc/geas"

    Alternmatively, if the first option given to 'geas-server' is -c, this
specifies a different configuration file to load.

    eg:
        geas-server -c ./different-geas.conf


2.2.2) GEAS fails to run, and complains about a GCD file error

    Errors in the GCD file must be corrected before GEAS will run. The file
and line number of the error will be reported. The utility 'gcdverifier' can
be used to check a GCD file for errors, before attempting to install them.


2.2.3) Client says it can't log in

    First, check that the client is reading the correct IOR file for the
server. An out of date or incorrect file will mean the client can't find the
server.

    Debugging network problems can be somewhat tricky, but the following
technique will solve the most common problems:

    Run this program (supplied with ORBit):
        ior-decode `cat geas-server.ior`

    (Note the backwards quote marks around the 'cat' command.) This will
print information about the connection to the server.

Example output:

  Tags known:
  TAG_INTERNET_IOP: 0x0
  TAG_MULTIPLE_COMPONENTS: 0x1
  TAG_ORBIT_SPECIFIC: 0xbadfaeca

  Object ID: IDL:GEAS/ConnectionFactory:1.0
  Profile count: 1

  Profile type: TAG_INTERNET_IOP
  Object endian: Little
  IIOP version: 1.0
  Host: geas.treshna.com
  Port: 3771
  Object key: ".....A.o.Q......8.N.r..."

or:

  Profile type: TAG_ORBIT_SPECIFIC
  Object endian: Little
  IIOP version: 1.0
  Socket path: /tmp/orbit-andrewm/orb-17552181161842507762
  IPv6 port: 0
  Object key: ".......z...D....J.N....."


If the client and server are on different machines, or the client is not
using ORBit, the first case (Profile Type: TAG_INTERNET_IOP) is required.
If there is no connection, ensure that the host can be reached from the
client machine, and that the client is also configured to use TCP/IP.

Running 'ping hostname' with the hostname _exactly_ as reported by
ior-decode will confirm that the hostname is resolving correctly, and that
there is a working network connection. (eg: ping
geas.gnuenterprise.com will reveal that there is no such machine
avaialble on the network.)

If the client and server both use ORBit, and both run on the same machine,
ensure that the indicated socket path can be accessed by both the client
and server. (This can be a problem if they are run as different users.)


2.2.4) GEAS complains about not finding a database

    The configuration file being read must define one and only one
database with the 'active' setting set to 'true'. (More are
technically possible, but only the first one marked as active will
ever be used.) (Of course editing the configuration file and
restarting the server will allow another database to be selected.)


2.2.5) GEAS can't connect to a database

    The first active database will be used: ie, if more than one database in
geas.conf has 'active' set to 'true' the first one will be used. If it is
not available, GEAS will not be able to work. To fix this, ensure that only
an available database is active.

    If this is not the case, there is most likely a problem with the
database configuration, which will need to be fixed.


----------------------------------------------------------------------
3 : Database questions
----------------------------------------------------------------------

3.1) What is the difference between a GCD file and an SQL database
     creation script?

    Essentially, GEAS takes a GCD file, and creates a set of tables that can
be used to represent the data structures described in the GCD files. A GCD
file also allows specifying relationships between classes - SQL requires
relationships to be constructed by performing a JOIN when executing a query.

   SQL does, however, support relational integrity, which GEAS does not
yet do - but this should be implemented in the future.


3.2) How can I use an existing database?

Code is being developed to enable GEAS to use existing database tables. This
has not been completed as yet.


3.3) Can GEAS use other OODBs?

GEAS can currently use either MySQL or PostgreSQL (relational databases.)
There is no reason why additional databases can't be supported, including
object oriented databases.


----------------------------------------------------------------------
4 : Writing client applications
----------------------------------------------------------------------

4.1) How do I get a Java client to talk to GEAS?

  A) Run 'idlj' to process the GEAS IDL files and build appropriate .java
     files. This should create a package called GEAS containing appropriate
     .java files.

  B) Write a Java program using these classes. Consult the JDK documentation
     and the example in the examples/java directory for more information.

  C) The client needs to read the 'geas-server.ior' file that the GEAS
     server creates.

  D) Use the CORBA.ORB.string_to_object() method to convert the string to
     a reference to a GEAS::ConnectionFactory object.

  E) The methods and attributes of each GEAS object is exactly as defined in
     the IDL files. All applications (in any language) obtain a
     ConnectionFactory instance from the object reference stored in the
     IOR file, and in turn use this to obtain references to all other objects.


4.1.1) What about Java?

    It is not the main development language for GNUe, but it
was useful for testing ORB issues (using different ORBs has helped isolate
and solve CORBA related problems) and a small amount of example code was
written in Java. For up to date documentation and examples, the Python code
continues to be the main language to use.


----------------------------------------------------------------------
5 : Writing business classes
----------------------------------------------------------------------

5.1) What is the difference between a class and an object?

First, read a decent book on object oriented programming. I suggest either
a C++ manual, the printed Python manual (the online docs tend to assume a
certain degree of previous OOP experience) or a Java manual.

  Class  : A class describes a particular type of thing in a computer
           program. For example, a 'person' class will have fields such as
           'name', 'date of birth', and other relevant information. It may
	   also have methods, where each method is a block of code that
	   may be executed. (eg: a method called calculateAge will use
	   the 'date of birth' field and the current date to work out how
	   old a person would be, given those two inputs.

           The only operation that may be performed on a class is to create
	   a new instance. (Of course, some languages allow classes to
	   have static members, but GEAS does not support this.)


  Object : An object is a specific instance of a class. Class 'person'
           describes what properties an instance of that class has. A specific
	   instance can be manipulated by a program.

	   A large range of oeprations may be performed on an object: data
	   fields may be accessed, methods may be executed, relationships
	   followed, and so on.


5.2) What can I do with a class in GEAS?

GEAS business classes support the following features:
   data fields  : These contain bytes of data in specific formats
   methods      : Code that implements business rules and operations
   lookups      : Read only access to data in lookup tables
   relationships: A class may contain references or lists of references
                  to other objects
   defaults     : Data fields may have default values, initialised at object
                  creation time
   inheritance  : An object may inherit from arbitrary classes (with some
                  restrictions)

5.2.1) How does inheritance work?

A class specifies one or more parent classes. An instance of the derived
class will then contain all members

A common assumption is that all people are addresses. This may be due to the
fact that every person you know is large enough to be mistaken for a house,
and thus leads to this common example:

  class address { text street; };
  class person : address { date dateofbirth };

In this case, class person contains two fields, one called 'street' and the
other called 'dateofbirth'.

Overriding of fields is not yet supported - if a field in a derived and a
base class have the same name, GEAS can easily get confused. In the future,
this should be dealt with.


5.2.1) What's wrong with that?

A person is not an address. A person has an address. Using 'has a' allows a
person to have a residential address and a mailing address. Using 'is a'
requires 'residential address' and 'mailing address' to be different
classes.



5.2.2.1) So how do I do 'has a' in GCD files?

Step 1: Create a data type that an object may posess.
Step 2: Create a field of that type.

eg:

    type address { text street; int number; ... other fields ... };
    class person { address residential,mailing;      };

this creates (in class person) the following fields:
    residential.street;
    residential.number;
    mailing.street;
    mailing.number

(On second thoughts, this may have been a less than perfect idea. It
may change in the future, to allow a class to be used as a member of
another class, or in relationships.)


5.2.2) Isn't multiple inheritance bad?

No. Every language feature can be used incorrectly. This is an argument for
only allowing competent programmers to write code. Removing every feature
that is hard to use would in fact require all programming languages to be
banned. (Some people may argue that this would be a good thing.  :)


5.3) How do I make a new class?

	http://www.gnuenterprise.org/~neilt/GNUeModuleGuide/main/businessobjects.html


5.4) How do I set up 'C' methods in GEAS?

    http://www.gnuenterprise.org/~neilt/GNUeModuleGuide/main/businessobjects.html


5.5) How do I set up Python methods in GEAS?

    http://www.gnuenterprise.org/~neilt/GNUeModuleGuide/main/businessobjects.html


5.6) Do I have to use references, lists and lookups?

	http://www.gnuenterprise.org/~neilt/GNUeModuleGuide/main/businessobjects.html


----------------------------------------------------------------------
6 : CORBA questions
----------------------------------------------------------------------

6.1) How much CORBA do I need to know?

    For working on GEAS, the answer is 'it depends'. Being able to read C is
the main requirement, and the code in 'servantlocator.h' is probably the
most complex CORBA related code - but this is only used to help connect an
incoming request to an object, so is not relevant for most parts of GEAS.

    For writing a new client, a small amount of basic knowledge will be
useful. All that is really needed is to know how to convert the IOR file to
an object reference (code that can be cut'n'pasted from existing examples in
C, Python and Java) and then be able to call methods in these objects.

   Writing a C client requires knowledge of the entire C mapping, and many
aspects are somewhat counterintuitive, due to mapping an OO system to a
non-OO language.

   For writing a GFD file to be handled by gnuef, you do not need to know
anything about CORBA. The small amount of CORBA code is in the GEAS driver
in gnuef. (If you're curious, have a look at
gnuef/src/drivers/geas/DBdriver.py and see just how little CORBA is actually
needed.)

   ORBit beginners documentation at http://icps.u-strasbg.fr/~genaud/ORBIT/
covers all you need to know about a simple client and server. CORBA has been
designed to make clients as simple as possible, while any complex code is
placed in a server: The simple client here demonstrates all you need to know
in order to use GEAS.

    The web site http://www.nd.edu/~rgarcia4/orbit/ contains additional
helpful information, that may be useful for developers wanting to learn more
about CORBA, to work on GEAS.

    The ORBit resources page at http://orbit-resource.sourceforge.net/ is
the main page for all ORBit web resources.

    Reading these pages (plus a little searching for information on servant
managers through http://www.google.com/) and playing with the examples was
how I learned enough CORBA to write GEAS. A solid understanding of OOP will,
of course, be useful as well.

    (Once the GNUe specific CORBA replacement is complete, there will
be no need to know about CORBA at all  :)


6.2) What languages and ORBs can be used?

    Any language with a CORBA binding may be used for writing GEAS clients.
Python and C are discussed in detail, and Java is mentioned in passing. For
other languages, please see the relevant documentation - most popular
languages have a standard binding between CORBA and the language, and most
ORBs include documentation on how to use them from supported languages.

    ORBit is used by the GEAS server, as it has a C binding, and a number of
GNUe developers prefer this. Any other ORB with a C binding could be used
with minimal changes.

    Clients may use any ORB that implements the IIOP standard. (Most CORBA
ORBs support this, and it is required by the standard.)


6.3) 


6.3.1) Memory management rules

    The following rules determine ownership of memoiry, and thus determine
what code must free memory.

    It applies to all functions supplied by CORBA (ie, CORBA_<function>() as
well as the IDL generated stub functions (GEAS_<classname>_<methodname>()
style functions used by clients) and all implementation functions (ie,
impl_GEAS_<classname>_<methodname>() in geas-skeleton.h).


    If a function allocates memory and then returns a pointer to that
memory, ownership passes to the caller of the function. (All memory
allocated must be either freed or returned, otherwise a memory leak will
occur.)

    If a pointer to a block of memory is passed to a function, that function
will not modify or free the memory. If necessary, a copy will be made. (In
the case of user created functions, the function should perform either a
bitwise copy or a deep copy as appropriate.) CORBA understands all data
structures that can be defined in an IDL file.


6.3.2) Server side resources

    Most server side resources are only held while in use. A cache exists to
maximise efficiency, but as resources are removed from the cache as
required, this will not cause any leaks.

    The GEAS::Query::Query and GEAS::ObjectList classes both contain a
'release()' method which clients must call once the resource is no longer
required. Failure to do so will cause the database to fill up with objects
that are no longer needed.

    (In the future, this will be automated, but for the time being, this
will remain a requirement for all clients.)


6.3.3) Client side resources

    In both Python and Java, support for memory management ensures that
memory is always freed appropriately. The only important thing to watch is
that you do not keep a reference to memory after it is not needed.

    In C, all memory management must be performed explicitly by the
developer. To complicate matters, there are different functionms to free
different types of memory.

GEAS::Connection        : CORBA_Object_release(obj,ev);
GEAS::ConnectionFactory : CORBA_Object_release(obj,ev);
GEAS::DataObject        : CORBA_Object_release(obj,ev);
GEAS::ObjectList        : CORBA_Object_release(obj,ev);
GEAS::Query::Query      : CORBA_Object_release(obj,ev);

GEAS::fieldlist         : CORBA_free(list);   [List of fields in a class]
GEAS::classnames        : CORBA_free(list);   [List of available classes]
GEAS::LookupOptions     : CORBA_free(list);   [List of options for a lookup]
GEAS::LoadDefinition    : CORBA_free(list);   [definition of list/reference]
GEAS::Query::Field      : CORBA_free(list);   [definition of list/reference]
GEAS::objectslist       : CORBA_free(list);   [list of object references]

CORBA::char             : CORBA_free(string); [ text string ]

Note: with the ObjectList and Query classes, you must release server side
resources, and then release client side resources.


6.3.3.1) GEAS::Query::Field

This structure contains members 'field' and 'value' which contain strings
(ie, 'char *' in C.) They may be set in any way you wish, but you must use
the appropriate function to free them, as well.

eg:
    If you use GEAS_Query_Field__alloc() then you must use CORBA_free()
and additionally, both 'field' and 'value' must be allocated using
CORBA_string_dup();

     GEAS_Query_Field *f = GEAS_Query_Field__alloc();
     f->field = CORBA_string_dup( "fieldname" );
     f->value = CORBA_string_dup( "value" );
     /* use 'f' */
     CORBA_free( f );

     If you use a statically allocated 'GEAS_Query_Field' instance, then it
must not be freed, and the field/value members must be manually freed.

     char *value = "value";
     GEAS_Query_Field f;
     f.field = "fieldname";
     f.value = g_strdup( value );
     /* use 'f' */
     g_free( f.value );


6.4) Exception handling

GEAS does not use return values for indicating errors. Instead, the CORBA
exception mechanism is used, which is mapped to a language specific
implementation. For Python, C++ and Java, the native exception
handling system is used. In C, an extra data structure is used, and
all CORBA functions must be passed a pointer to this structure, for
storing exception information.

When raising an exception in a method, the return value is ignored.
Functions that return a pointer should return NULL, and other
functions may return any arbitrary value.


Example:

/* setup */
CORBA_Environment *ev = g_new0( CORBA_Environment , 1 );
CORBA_exception_init( ev ); /* ORBit specific */

/* function call */
GEAS_DataObject_getField( obj , "fieldname" , ev  );

/* test for exception */
if( ev->_major != CORBA_NO_EXCEPTION )
{
    /* handle exception - function in GEAS src code (src/exceptions.c) */
    switch( get_user_exception_id(ev) )
    {
        case GEAS_EXCEPTIONID_UnknownField:
	    /* handle this exception */
	    break;
        case GEAS_EXCEPTIONID_ServerError:
	    /* handle this exception */
	    break;
    }
}

/* create a new exception (GEAS function, also from src/exceptions.c) */
make_ServerError_exception( ev , "Just a dummy thing (%d)" , integer_var );

/* done */
CORBA_exception_free( ev ); /* ORBit specific */


6.4.1) Python

The standard Python try/catch system is used for CORBA exceptions as well.

Example:

  try:
      obj = con.newObject( "non-existant class" );
  catch GEAS.UnknownClass,ex:
      print "That class was not known (", ex.detail ,")"


6.4.2) Java

As for Python, Java's native exception handling mechanism is used. The
significant difference is that Java requires all possible exceptions to be
caught - if a method is marked in the IDL file as throwing an
exception, that exception must be handled, or a compile time error
will occur.


6.4.3) C

Each function has an additional argument, that is used to store information
about any exception that has occured. 

  CORBA_Environment ev;

  CORBA_exception_init( &ev );

  ... code that uses 'ev' ...

  CORBA_exception_free( &ev );


A single such variable may be used for the entire program, but after each
exception occurs, it _must_ be rest (by calling CORBA_exception_free() to free
the exception, and CORBA_exception_init() to reinitialise the storage area.

Assuming the name 'ev' is used: The variable 'ev._major' indicates the
type of exception that occured. It may be either CORBA_NO_EXCEPTION, if no
exception has occured, CORBA_USER_EXCEPTION if a GEAS specific exception has
occured, and CORBA_SYSTEM_EXCEPTION if a CORBA specified system exception
occured.

ev._repo_id describes the particular exception that occured.

Example:

    if( ev._major == CORBA_USER_EXCEPTION )
    {
        if( strcmp(ev->_repo_id,ex_GEAS_ServerError) == 0 )
	{
	    /* A GEAS::ServerError exception was thrown */
	}
    }


6.5) What's a 'sequence' ?

    A sequence is the CORBA term for an array.


6.5.1) What's that weird array stuff in C?

    In C, an array requires additional information to be stored that gives the
length of the array.

Example:

An array of strings:

   typedef struct
      {
         CORBA_unsigned_long _maximum,
         _length;
         CORBA_char **_buffer;
         CORBA_boolean _release;
      }
      CORBA_sequence_CORBA_string;

    The _maximum member gives the maximum number of entries, and thus the
number of entries required by the _buffer member. The _length determines
exactly how many of those entries are used.

    To create an array, these allocation functions are used:

    CORBA_sequence_CORBA_string__alloc();
    CORBA_sequence_CORBA_string_allocbuf( CORBA_unsigned_long length );


    The file geas.h contains all of the details on each structure used, and
should be checked if the exact function to use is unclear.


Example:

  CORBA_sequence_CORBA_string *array;
  array = CORBA_sequence_CORBA_string__alloc();
  array->_maximum = 3;
  array->_length  = 2;
  array->_buffer = CORBA_sequence_CORBA_string_allocbuf( array->_maximum = 3 );
  array->_buffer[0] = CORBA_string_dup( "First item" );
  array->_buffer[1] = CORBA_string_dup( "Second item" );

  /* use the array here */

  CORBA_free( array );
