In a previous developerWorks article, Introducing SMIT (see Resources), you learned how AIX® System Management Interface Tool (SMIT) can simplify virtually every aspect of the AIX system administration. This article shows you how to extend SMIT to do additional tasks. By extending SMIT, you can add tasks you do regularly that are not already defined, change existing tasks, or add tasks for your operator staff to do that would otherwise require a system programmer.
Let's begin by going over some of the internals of SMIT. Doing development on the SMIT application of a system can adversely affect the system. It's better to make your own development environment, construct your own extension, test it, and ultimately add it to the system's SMIT.
Note: Examples for this article were developed on an RS/6000® system running AIX 5L™ Version 5.2. Command examples used the Korn shell.
Before you begin, it is important to have an understanding of the terminology and underlying structure of the SMIT application. Here is a brief overview before you start with the actual programming:
SMIT and the character version smitty (or smit -c) is made up of three screen types:
- Menus -- This screen type gives choices of another menu, a dialog, or straight to the task.
- Dialog -- This screen type displays data entry fields required to execute the task.
- Selectors -- This screen type gathers the data required for the dialog to run a specific task.
A fourth screen, Command Status, displays the command, output, and status of the command. This screen is predefined.
These screens are defined by screen objects, which are stored in SMIT's database. The Object Data Manager (ODM) is used to manipulate the screen objects in the database. To extend SMIT, create a set of screen objects and add them to the SMIT database. The screen objects are defined in ascii files called stanzas. Stanzas are added to the SMIT database and further manipulated with a variety of ODM commands.
The ODM database files reside in the object repository. The SMIT ODM object repository is /usr/lib/objrepos. Files are owned by root, group system, and mode 664. In addition to SMIT, the system ODM database manages device configuration, product data for installation and update procedures, communications configuration information, and system resource information. Making changes to the system ODM database files can result in system problems. Therefore, it is strongly recommended that a copy of the SMIT ODM database be used for development and initial testing, using a non-root, non-group system user. Root privileges are needed for final testing and installation. It is also strongly recommended that you back up the system repository prior to making any changes to it. I'll give you examples of how to do this just prior to adding your changes to the system object repository.
The environmental variable ODMDIR specifies the ODM object repository for the ODM utilities. The default ODMDIR is /etc/objrepos. Set ODMDIR to point to your development object repository during development. SMIT uses /usr/lib/objrepos as it's repository unless a different path is specified on the command line with the -o flag.
ODM objects are divided into object classes. Object definitions of the same object class are stored in the same object repository file. The object repository file for a class has the same name as the class. Have a look at the various object classes in use on your system by using: $ ls -l /usr/lib/objrepos.
SMIT uses the following object classes:
sm_menu_optsm_name_hdrsm_cmd_hdrsm_cmd_opt
Table 1 shows the objects used to define each screen type. Later examples show how these fit together to form a SMIT command.
Table 1. Object classes used to define each screen type
| Screen type | Object class | Use of object (typical case) |
|---|---|---|
| Menu | sm_menu_opt | 1 for title of screen |
sm_menu_opt | 1 for first item | |
sm_menu_opt | 1 for second item | |
| ... | ... | |
sm_menu_opt | 1 for last item | |
| Selector | sm_name_hdr | 1 for title of screen and other attributes |
sm_cmd_opt | 1 for entry field or pop-up list | |
| Dialog | sm_cmd_hdr | 1 for title of screen and command string |
sm_cmd_opt | 1 for first entry field | |
sm_cmd_opt | 1 for second entry field | |
| ... | ... | |
sm_cmd_opt | 1 for last entry field |
Let's have a look at how the objects are structured and how they fit together when you invoke SMIT.
Create a development environment
Before you extend SMIT, you must first create a development environment. You do not want to adversely affect the system by developing your SMIT extensions in the system object repository. You can easily add your changes to the system object repository after you are done developing and testing them. Ideally, you would also have a development system you can do this work on, as not to impact the production environment.
Create or get a user account that is not a member of system group. Log in to this account and issue the following commands, as shown in Listing 1.
Listing 1. Creating a copy of the SMIT object repository
$ mkdir objrepos $ cp /usr/lib/objrepos/sm* ./objrepos $ ODMDIR=~/objrepos export ODMDIR |
You might wish to add the ODMDIR assignment to your .profile for the duration of this project. Otherwise, you need to remember to reassign ODMDIR every time you log in to work on this project.
Getting familiar with the SMIT object types
Let's now look at the screen definitions, as well as what's already defined in SMIT (see Listing 2). You should be able to see how these definitions correlate to what you see when you use SMIT.
Listing 2. Structure of the SMIT objects
$ odmshow sm_menu_opt
class sm_menu_opt {
char id_seq_num[17]; /* offset: 0xc ( 12) */
char id[65]; /* offset: 0x1d ( 29) */
char next_id[65]; /* offset: 0x5e ( 94) */
vchar text[1025]; /* offset: 0xa0 ( 160) */
vchar text_msg_file[1025]; /* offset: 0xa4 ( 164) */
long text_msg_set; /* offset: 0xa8 ( 168) */
long text_msg_id; /* offset: 0xac ( 172) */
char next_type[2]; /* offset: 0xb0 ( 176) */
char alias[2]; /* offset: 0xb2 ( 178) */
char help_msg_id[17]; /* offset: 0xb4 ( 180) */
vchar help_msg_loc[1025]; /* offset: 0xc8 ( 200) */
vchar help_msg_base[64]; /* offset: 0xcc ( 204) */
vchar help_msg_book[64]; /* offset: 0xd0 ( 208) */
};
/*
descriptors: 13
structure size: 0xd4 (212) bytes
data offset: 0x200032f0
population: 1750 objects (1749 active, 1 deleted)
*/
|
Listing 2 looks like a structure definition in C programming. Go ahead and have a look at sm_cmd_hdr, sm_cmd_opt, and sm_name_hdr.
Next, extract the already defined screen object definitions into text files, as shown in Listing 3.
Listing 3. Extract the defined screen object definitions into text files
$ odmget sm_menu_opt > sm_menu_opt.get $ odmget sm_cmd_hdr > sm_cmd_hdr.get $ odmget sm_cmd_opt > sm_cmd_opt.get $ odmget sm_name_hdr > sm_name_hdr.get |
In addition to being easier to scroll through and extract object definitions, it allows you to grep for specific fields to make sure you are not duplicating menu "next_id" or selector "id" fields, which must be unique.
Scroll through sm_menu_opt.get. Notice the following:
- The screen definitions are separated by blank lines. This is how they are delimited, and this is how you need to construct your own stanzas. The output of odmget is the same format that odmadd uses so, in theory, you could odmdelete all the entries in SMIT and use these text files to completely recreate it.
textis what appears next to the selector button or on the menu page for smitty.next_idis the object that is called when you execute the item. The "__ROOT__" id has a "next_id" of "top_menu." All the entries with id = "top_menu" appear when:- "next_type" = type of the next object
- "m" = menu
- "d" = dialog
- "n" = selector popup
- "i" = information
- The "id" field is the same for different screen definitions. Definitions with the same id field appear on the same menu. Note the objects with "top_menu" as their id. These are all on the first menu that comes up when you start smit (or smitty). The order in which they appear is set by the
id_seq_num.id_seq_numvalues, and they are not necessarily sequential; IBM left some space between them so that you can slide your own objects into menus without having to re-define all the objects on that menu.
Looking at sm_cmd_hdr.get, note cmd_to_exec. Some are simple commands, and others are complex shell scripts. When odmget extracts the scripts, it does escape "special" characters with "\". You don't need to include these escapes for your custom code, but you should expect that odmget adds them to your code, too.
Complete field descriptions of all the object classes can be found in the SMIT sections of "General Programming Concepts: Writing and Debugging Programs in the AIX 5L" documentation (see Resources).
By way of example, let's go through steps to create a new menu object within SMIT in your test object repository.
Step 1: What activity would you like to add to SMIT?
Say you regularly add and remove users, a task that could be done by operator staff. These users all have the same characteristics with the exception of their user name, user ID, and home directory (/home/username). Having an operator removing users is not a problem through SMIT, as there are only two lines on the dialog screen. However, the "Add a User" dialog has 49 selectors!
Figure 1. The "Add a User" dialog showing the first 17 selectors

You need a menu option that has just one selector for the user name. Let the system pick the UID, and then hard code any other parameters. Also change the user's password so that they can log in (and be forced to change their password when they log in). Note that this is an example; you or your security policy might dictate additional parameters than are being used here.
The command line for creating such a user would look something like Listing 4.
Listing 4. The command that you want SMIT to be able to build and run
# mkuser pgrp='other' su='false' home='/home/user' shell='/usr/bin/ksh' user # passwd user |
Step 2: Is there something close already in SMIT?
No sense re-inventing the wheel. In this case, you know the "Add a User" dialog is close to what you want. Extract the screen definition from your sm_menu_opt.get file with the "text" field "Add a User", or with odmget -q "text = 'Add a User'" sm_menu_opt (see Listing 5).
Listing 5. Extracting the screen definition from your sm_menu_opt.get file
sm_menu_opt:
id_seq_num = "010"
id = "users"
next_id = "mkuser"
text = "Add a User"
text_msg_file = "smit.cat"
text_msg_set = 25
text_msg_id = 166
next_type = "d"
alias = ""
help_msg_id = "1800168"
help_msg_loc = ""
help_msg_base = ""
help_msg_book = ""
|
You see that the next_type is "d", (a dialog), and next_id is "mkuser". Run odmget -q "id = mkuser" sm_cmd_hdr (see Listing 6).
Listing 6. Extracting the screen definition from sm_cmd_hdr
sm_cmd_hdr:
id = "mkuser"
option_id = "user_add"
has_name_select = "n"
name = "Add a User"
name_msg_file = "smit.cat"
name_msg_set = 25
name_msg_id = 166
cmd_to_exec = "x() {\n\
LIST=\n\
SET_A=\n\
for i in \"$@\"\n\
do\n\
if [ \"$i\" = \"admin=true\" ]\n\
then\n\
SET_A=\"-a\"\n\
continue\n\
fi\n\
LIST=\"$LIST \\\"$i\\\"\"\n\
done\n\
eval mkuser $SET_A $LIST\n\
}\n\
x"
ask = "n"
exec_mode = ""
ghost = "n"
cmd_to_discover = "lsuser -D"
cmd_to_discover_postfix = ""
name_size = 0
value_size = 0
help_msg_id = "1800168"
help_msg_loc = ""
help_msg_base = ""
help_msg_book = ""
|
You see that "option_id" = "user_add". grep user_add sm_cmd_opt.get shows 49 entries, one for each of the selectors for this menu item. You only need the one that asks for the user name (see Listing 7).
Listing 7. Extracting the command definition from our sm_cmd_opt file
sm_cmd_opt:
id_seq_num = "01"
id = "user_add"
disc_field_name = "_rawname"
name = "User NAME"
name_msg_file = "smit.cat"
name_msg_set = 3
name_msg_id = 3
op_type = ""
entry_type = "t"
entry_size = 0
required = "+"
prefix = "--"
cmd_to_list_mode = ""
cmd_to_list = ""
cmd_to_list_postfix = ""
multi_select = "n"
value_index = 0
disp_values = ""
values_msg_file = ""
values_msg_set = 0
values_msg_id = 0
aix_values = ""
|
Put these in a file. This is your stanza file for adding your own objects. Comments can be added to your stanza file either with a "#" at the beginning of a line, or a "*" following an assignment. Make sure that only blank lines in the stanza file separate the screen definitions.
Step 3: Make your modifications
You do not need to include every field definition. Odmadd applies the default values (usually "" or 0).
Here are the changes you need to make to these object definitions to create your SMIT screens and commands:
sm_menu_opt:- id stays the same.
- seq_num needs to change. Let's have yours appear first, so make it "5."
- next_id needs to specify your next script, so lets call it "mkuser2."
- Text needs to differentiate this from the other, such as "Add a Simple User."
- next_type stays the same.
- Alias can stay.
- The rest of the lines can be removed. They are associated with the Message Facility for providing help messages, which is beyond the scope of this article.
Sm_cmd_hdr:- id needs to match what was called above and be unique, such as "mkuser2" [for example?]. Use
grep mkuser2 *.getto verify uniqueness. - option_add: need to specify another name or you'll get all 49, such as "user-add2."
- name: "Add a Simple User".
- has_name_select can be left at "n", meaning you can fastpath straight to it.
- Msg stuff can go away.
- cmd_to_exec: This is the command that is executed. You want to hard code the options (except for the user name), add code to check for successful completion of the
mkusercommand, and then change the password for the user. Do not be concerned about all the "\" escapes that odmget displays. You don't need to include them in your coding, because they appear when you do another odmget. Change the "LIST" line to:LIST="pgrp=other su=false home=/home/$i shell=/usr/bin/ksh". After the "eval" line, add the following in Listing 8.
Listing 8. Korn shell code needed to add "Changing Password" to your SMIT application# test for success, then change the password if [[ $? = 0 ]] then passwd $i fi
- id needs to match what was called above and be unique, such as "mkuser2" [for example?]. Use
sm_cmd_opt:- id: need to change to match sm_cmd_hdr.option_add. "user-add2".
Also, note required = "+." This displays a "+" next to your select box, indicating that an entry is required before proceeding.
Step 4: Installation and testing
When you are satisfied with your stanza file, add it to your development object repository. Make sure once again that you're not root and that ODMDIR points to your test directory (see Listing 9).
Listing 9. Check your identity and ODMDIR assignment, then add the stanza file to your development object repository
$ id uid=101(monroe) gid=3(sys) groups=4(adm) $ echo $ODMDIR /home/monroe/objrepos |
Add your stanzas to the object repository: $ odmadd stanza1.
Then verify that they got installed by extracting the individual objects with odmget (see Listing 10).
Listing 10. Extracting individual objects with odmget
$ odmget -q "next_id = mkuser2" sm_menu_opt $ odmget -q "id = mkuser2" sm_cmd_hdr $ odmget -q "id = "user_add2" |
Test by invoking SMIT, specifying no execute and the development repository: $ smit -x -o $ODMDIR. Drill down through Security & Users > Users. Note that you have your new entry -- "Add a Simple User" (see Figure 2).
Figure 2. Your new entry -- "Add a Simple User"

Your sm_menu_opt screen definition works. Select "Add a Simple User" (see Figure 3).
Figure 3. Selecting "Add a Simple User"

This is the command screen you developed; it has the correct screen title and only has one selector in the dialog. Add any name and press Enter. Because you are not root (and specified the no execute flag), the command doesn't run; it just appends what it would do to the smit.script file (see Listing 11).
Listing 11. SMIT correctly writes your code for this command to smit.script
#
# [Dec 04 2006, 14:28:05]
#
x() {
LIST=pgrp=other su=false home=/home/$i shell=/usr/bin/ksh
SET_A=
for i in "$@"
do
if [ "$i" = "admin=true" ]
then
SET_A="-a"
continue
fi
LIST="$LIST \"$i\""
done
eval mkuser $SET_A $LIST
if [ "$?" = "0" ]
then
passwd "$i"
fi
}
x bozo
|
Looks good. Now let's try it as root and actually create an account (see Listing 12).
Listing 12. Testing your extension by really creating an account (as root)
$ su # export ODMDIR=./objrepos # smit -o $ODMDIR |
Go ahead and add a user using your extension. Note that you are prompted to enter the user's password. Go ahead and do so (see Figure 4).
Figure 4. Command Status screen showing successful execution of your SMIT extension

Go back to "Change/Show Characteristics of a User" and display the one you just created (see Figure 5).
Figure 5. Change/Show Characteristics of a User

If there are further modifications you wish to make, make the changes to the stanza file and run odmadd again. It overwrites the entries you added earlier. Make sure you test your changes thoroughly.
When you're finished testing, remove the test user accounts you created on the system.
Installation into the production environment
Become root and set the ODMDIR variable to reflect SMIT's system database (see Listing 13).
Listing 13. Set the ODMDIR variable to reflect SMIT's system database
$ su # export ODMDIR=/usr/lib/objrepos |
The SMIT database repository is in /usr/lib/objrepos. It's highly advisable to back this up prior to doing the final installation. One way is shown in Listing 14.
Listing 14. Backing up the SMIT database repository
# cd /usr/lib # tar cvf objrepos.tar objrepos |
This creates a tar archive of the /usr/lib/objrepos directory that can easily be recovered if you need to revert back.
Add your screen objects, as defined by your stanza file, to the system object repository: # odmadd stanza and test again, using "smit" (no options). Have another administrator try out your changes. When you are satisfied, remove any test accounts that were created.
Finally, document what you have done, and save your stanza files. If a future AIX release updates the SMIT Object Repository, your changes might be lost and the files need to be re-installed.
Now you have successfully extended SMIT. You know how to develop, test, and install your extensions safely. You have a beginning knowledge of the SMIT object classes, their structure, and how they fit together. You can modify screen definitions that already exist to make SMIT do what you want. By developing more extensions, you can develop a greater understanding of the object classes.
There are all sorts of tasks that must be done frequently that can be made faster or easier by creating an extension to SMIT. By creating such extensions and adding SMIT help information as described in the Programming Concepts guide, you can free up your administrator time for other things.
Learn
- Introducing SMIT: The powerful AIX System Management Interface Tool (developerWorks, September 2006): Read this article for an introduction to SMIT.
- Object Data Manager (ODM) and SMIT chapters of General Programming Concepts: Writing and Debugging Programs: Read this guide for more information on ODM and SMIT.
- man page for the smit command (part of the bos.man.en_US.cmds fileset): This site provides information about the flags and arguments that can be used to modify SMIT's behavior.
- Setting Up and Maintaining Roles in AIX 5L Version 5.1 System Management Guide: Operating System and Devices: Visit this site to learn more about FastPaths.
- Object Data Manager (ODM) and SMIT chapters of General Programming Concepts: Writing and Debugging Programs: Read this guide.
- Search the AIX and UNIX library by topic:
- System administration
- Application development
- Performance
- Porting
- Security
- Tips
- Tools and utilities
- Java™ technology
- Linux®
- Open source
- AIX and UNIX: The AIX and UNIX developerWorks zone provides a wealth of information relating to all aspects of AIX systems administration and expanding your UNIX skills.
- New to AIX and UNIX: Visit the New to AIX and UNIX page to learn more about AIX and UNIX.
- AIX 5L Wiki: A collaborative environment for technical information related to AIX.
- Safari bookstore: Visit this e-reference library to find specific technical resources.
- developerWorks technical events and webcasts: Stay current with developerWorks technical events and webcasts.
- Podcasts: Tune in and catch up with IBM technical experts.
Get products and technologies
- IBM trial software: Build your next development project with software for download directly from developerWorks.
Discuss
- Participate in the developerWorks blogs and get involved in the developerWorks community.
-
Participate in the AIX and UNIX forums:
- AIX 5L -- technical forum
- AIX for Developers Forum
- Cluster Systems Management
- IBM Support Assistant
- Performance Tools -- technical
- Virtualization -- technical
- More AIX and UNIX forums
Doug Monroe is a UNIX System Administration consultant and instructor with DMA Inc. He holds a bachelor's degree in computer science from Oregon State University, and he has been supporting various flavors of UNIX since 1984. You can reach him at monroe@sqnt.com.





