Skip to main content

Notes From Support:Transitioning from cc:Mail to Notes Mail using Agents

Bret H Swedeen (swedeen@us.ibm.com), GWA IT Architect, IBM
Bret Swedeen joined Lotus in the summer of 1997 as a Principal Knowledge Architect. Bret has worked in the computer industry for nearly 8 years doing everything from Notes phone support at Corporate Software to Notes consulting at Coopers & Lybrand. A Certified Netware Engineer (CNE) and Certified Lotus Professional (CLP) System Administrator and Application Developer, Bret has also written articles for the Lotus Notes Advisor, Database Advisor, LAN Times, and LAN Magazine. Most recently Bret authored the Lotus Notes 4.5 Administrator's Guide from Sybex publishing.

Summary:  This month's article focuses on a customer solution for moving from cc:Mail to Notes Mail by writing agents to ease the transition.

Date:  01 Jun 1998
Level:  Advanced
Activity:  702 views

[Editor's note: The From the Field column is brought to you by Lotus Support, and features technical articles based on our experiences with helping customers to find solutions in the field. This month's article focuses on a customer solution for moving from cc:Mail to Notes Mail by writing agents to ease the transition.]

This solution works with the Lotus tools available now for upgrading cc:Mail users to Notes 4.x. However, Domino 5.0 will include an integrated method for upgrading cc:Mail users to Notes 5.0.

Are you thinking about migrating from cc:Mail to Notes? If so, you've probably already taken a look at Lotus' cc:Mail-to-Notes migration tool (downloadable free of charge from the Lotus Web site). This tool helps administrators move individual cc:Mail users, or an entire post office, over to Notes. While this tool makes migration easy for the administrator, it works at the bits-and-bytes level, and individual users often have to perform additional tasks to complete the migration satisfactorily. Moreover, the migration tool does little to help acquaint former cc:Mail users with the new messaging world of Notes. Typically, that job is left to formal user training, or in some cases, helpful agents or SmartIcons.

Although a migration tool isn't expected to teach users a new e-mail package, the tool is expected to handle every aspect of migration. In some cases, however, the migration tool just can't do everything. Two such examples with the cc:Mail-to-Notes migration tool are as follows:

  • When the Notes administrator performs the migration, the system adds private mailing lists to a Notes database that attaches to a new e-mail message and appears in the user's InBox. Then, to gain access to the migrated mailing lists, users must open this message, detach the attachment, and add this database to their Notes workspace. Not a difficult task for most users; however, the burden of completing the migration of private mailing lists is on the user.

    Note: The issues of private mailing lists and Internet e-mail address conversion do not exist if the users run the migration (Release 4.11 or greater) from their workstation; however, if the Notes administrator controls every aspect of the migration from the Notes server, these issues remain.

  • The migration tool saves individual Internet e-mail addresses in cc:Mail (Release 6 and earlier) in a file called PRIVDIR.INI. When the Notes administrator executes the migration, the addresses in this file do not migrate. The workaround for this issue, once again, places the burden on the users, who must create Person documents in their Personal Address Book for each Internet e-mail address previously in their PRIVDIR.INI. And by the way, unless users know that the PRIVDIR.INI exists, they must create Person documents from memory.

Neither of these tasks is insurmountable for most users; however, in a perfect migration, users shouldn't have to worry about such issues.

One customer, in the quest for the perfect migration, dealt with these two issues during a recent cc:Mail-to-Notes migration project. Rather than have the users complete the migration for their private mailing lists and Internet e-mail addresses, the customer created two LotusScript agents that provided a one-button solution for both of these issues. The overall design, and actual code, of these two home-grown LotusScript agents are the focus of this report From the Field.

Note: The LotusScript Agents detailed in this report are for educational purposes and therefore not supported by Lotus Technical Support.

The customer's cc:Mail environment

The customer featured in this report migrated to Notes from a cc:Mail 2.x environment. The former cc:Mail setup had a single cc:Mail hub with four post offices, each supporting approximately 200 to 300 users. The migration project converted one post office per week and used the cc:Mail Message Transfer Agent (MTA) to temporarily support coexistence between the two messaging environments.

Prior to the actual migration project, the customer conducted a migration pilot, using a small group of 20 users. The purpose of the pilot was to test the migration plan and shake out any problems that might exist. A byproduct of this pilot was the discovery of the private mailing list and Internet e-mail address-migration shortcomings.

The manner in which the migration tool handled the conversion of private mailing lists and Internet e-mail addresses was not necessarily a problem. The customer knew, however, that these two items would cause some confusion for certain users. Rather than frustrate those people, the customer quickly went to work at finding a way to overcome these issues.


Automating steps for the user: The private mailing list agent

Overcoming the issue with private mailing list conversion was simple because the hard part of list conversion was already done by the migration tool. The only thing left to do was to create a one-button solution so users didn't have to execute the steps manually. Keep in mind that, when a Notes administrator migrates a cc:Mail user or an entire post office, private mailing lists convert into Group documents and then appear in a new database derived from the Personal Address Book template. Since each user already has a Personal Address Book, the ideal one-button solution (or agent) should execute the following steps:

  1. Locate the message created by the migration tool that contained the database attachment of private mailing lists.
  2. Open the message.
  3. Detach the database attachment.
  4. Copy each Group document from the database and paste it into the pre-existing Personal Address Book.
  5. Delete the detached database.
  6. Delete the message.

It is one thing to create a list of steps to be automated; it is yet another to create the agent that actually executes these steps. The agent is supposed to act on a specific message and attachment. Therefore, the agent needs a way to distinguish this message and attachment from all others in the mail database. Fortunately, when the migration tool converts private mailing lists, it creates two useful pieces of information that are always the same:

  • The subject line for the message containing the attachment: "cc:Mail Migrated Private Mailing List is attached"
  • The file name of the attachment: CCPMLIST.NSF

Knowing the subject line of the message that contains the attachment and knowing the file name of that attachment provides the agent with nearly everything it needs to successfully find the message and work with the attachment. The agent also needs to know that the Personal Address Book for every user in the customer's environment has the file name NAMES.NSF. With these three pieces of information, the customer designed an agent to:

  1. Search through the InBox for a message with the subject line "cc:Mail Migrated Private Mailing List is attached." If the agent finds such a message, it removes the attachment (CCPMLIST.NSF) and saves it on the user's local disk drive. Otherwise, the agent informs the user that there are no private mailing lists.
  2. Open the detached database and copy each Group document to the user's pre-existing Personal Address Book.
  3. Delete the message and the detached database.

The following illustration shows a flowchart of the process the agent follows:


Figure 1. A flow chart of the private mailing list agent
A flow chart of the private mailing list agent

Transforming a process flow diagram into a useful agent resulted in the following LotusScript code:

Sub Initialize

	Dim db1 As NotesDatabase 
	Dim collection As NotesDocumentCollection
	Dim doc As NotesDocument 
	Dim object As NotesEmbeddedObject
	Dim session As New NotesSession
	Dim j As Integer
	Dim Subject As Variant
	Dim FoundIt As Integer
	Dim Pab As String
	Dim Comma As String
	Dim Position As Integer
	Comma = ","
	FoundIt = False
	Pab = session.GetEnvironmentString("NAMES", True)
	Position = Instr(1,Pab,Comma,1)
	If Position >0 Then
		Pab = Left$(Pab,Position -1)
	End If
	Dim db2 As New NotesDatabase("",Pab)
	Set db1 = session.CurrentDatabase
	Set collection = db1.AllDocuments
	Set doc = collection.GetLastDocument()
	Do While Not (doc Is Nothing)
		If doc.HasItem("Subject") Then
			Subject = doc.Subject
			If Subject(0) = ("cc:Mail Migrated Private Mailing 
			List is attached") Then
				FoundIt = True
				Set object = doc.GetAttachment( "ccpmlist.nsf" )
				Call object.ExtractFile( "c:\ccpmlist.nsf" )
				Call doc.Remove(True)
				Exit Do
			End If
		Set doc = collection.GetPrevDocument(doc)
		End If
	Loop
	If FoundIt = True Then
		Dim db3 As New NotesDatabase("","c:\ccpmlist.nsf")
		Set collection = db3.AllDocuments
		Set doc = collection.GetFirstDocument()
		While Not (doc Is Nothing)
			Call doc.CopyToDatabase(db2)
			Set doc = collection.GetNextDocument(doc)
		Wend
		Call db3.Remove
	Else
		Messagebox "You do not have any private mailing lists to extract."
	End If
End Sub	

The LotusScript code starts with several variable declarations and value assignments. These variables make it possible to work with the current mail database, Personal Address Book, and file attachment. After these variables are declared, a For loop begins in which the agent tests the subject of each document in the mail database. The agent compares the value of the subject line to the string "cc:Mail Migrated Private Mailing List is attached." If it finds a match, it assigns the variable FoundIt the value "True." The agent detaches the attachment, saves it to the local drive (C:\), and deletes the message. If none of the documents passes the subject-line test, the value of FoundIt remains "False."

Note: This script is specifically designed for a PC with a local "C:\" drive, and therefore won't work with Macintosh clients or other clients without a "C:\" drive.

After the For loop ends, the agent tests the value of FoundIt. If FoundIt equals "True," the agent copies each document from the detached database (CCPMLIST.NSF) to the user's Personal Address Book, and deletes the detached database. If, however, FoundIt does not equal "True," a message appears that informs the user that there are no private mailing lists to extract.

The customer used the private mailing list agent successfully throughout the migration project. However, in situations where the private mailing lists contained characters not supported by the migration tool, the agent failed. This failure was not the fault of the agent because attempts to extract the attached database manually also failed. The issue of unsupported characters is clearly documented in the migration tool's "User's Guide." Therefore, the customer was well aware of the character limitation and considered the agent extremely successful despite its occasional breakdown.


The extra mile: The Internet e-mail address agent

Next the customer wanted to extract Internet e-mail addresses contained in each user's personal PRIVDIR.INI file and place them in a Person document in the Personal Address Book.

The PRIVDIR.INI file is what cc:Mail (Release 6 and earlier) uses to store personal Internet e-mail addresses. Any user who has ever sent a message to an Internet e-mail address has one of these simple text files stored on the local hard drive. Since the file is stored locally, the migration tool can't access it when it runs from a Notes server. The workaround for this situation is to have each user manually perform the following steps:

  1. Find and open the PRIVDIR.INI file.
  2. Copy the Internet e-mail address in the file.
  3. Create a new Person document in the Personal Address Book.
  4. Paste the Internet e-mail address into the e-mail address field.
  5. Optionally fill in the first name, last name, and full name fields.
  6. Save the new Person document.
  7. Repeat steps 2 through 6 until no more Internet e-mail addresses remain in the PRIVDIR.INI file.

The customer felt that this manual user intervention was unnecessary and created a LotusScript agent to:

  1. Search the default directory location for the PRIVDIR.INI file (C:\WINDOWS\CCMAIL\CC1DIR).
  2. If the file is not found, increment the number in the CC1DIR directory name and search that directory (C:\WINDOWS\CCMAIL\CC2DIR). Continue directory-name number incrementing until finding the PRIVDIR.INI file or until reaching CC9DIR.
  3. If the file is not found, inform the user and stop running.
  4. If the file is found, open the file for reading.
  5. Ask the users if they want to enter a first and last name for each address as it's extracted.
  6. If the answer is No, extract each address, create a new Person document in the Personal Address Book, and stop running.
  7. If the answer is Yes, extract each address and allow the user to add a first and last name for each address.
  8. Take the additional information and create a new Person document in the Personal Address Book. The additional information helps fill in the following fields: First name, last name, full name, and e-mail address.
  9. Repeat steps 7 and 8 until no addresses remain.

The following illustration shows a flowchart of the process the agent follows:


Figure 2. A flow chart of the internet e-mail address agent
A flow chart of the internet e-mail address agent

The steps came together in the following LotusScript code:

Option Public
%INCLUDE "LSCONST.LSS"


Sub Initialize
   
Dim session As New NotesSession
Dim doc As NotesDocument   
Dim iEndOfFile As Integer
Dim iFileNum As Integer
Dim iReadLn As Integer
Dim iCharPos As Integer
Dim iRightNum As Integer
Dim iAnswer As Integer
Dim iCount As Integer
Dim iFileCount As Integer
Dim i As Integer
Dim tAtSign As String
Dim tFlatFileRecord As String
Dim tCharComp As String
Dim tInternetName As String
Dim tFormType As String
Dim tFirstName As String
Dim tLastName As String
Dim tPath As String
Dim tSubPath As String
Dim tFullPath As String
Dim tFileName As String
Dim tName As String
Dim tPab As String
Dim tComma As String
Dim iPosition As Integer
tComma = ","
tPab = session.GetEnvironmentString("NAMES", True)
iPosition = Instr(1,tPab,tComma,1)
If iPosition >0 Then
	tPab = Left$(tPab,iPosition -1)
End If
Dim db As New NotesDatabase("",tPab)
iFileNum = Freefile
tCompChar = "="
tAtSign = "@"
tFormType = "Person"
iCount = 0
iFileCount = 0
tPath = "U:\WINDOWS\CCMAIL\"
tSubPath = ""
On Error Goto EndOfFile
   
	For i = 1 To 10
     tFullPath = tPath + tSubPath + "*.*"
     tFileName = Dir$(tFullPath, 0)
     Do While tFileName <> ""
        If Instr(1, tFileName, "privdir.ini", 1) > 0 Then
          tName = tPath + tSubPath + tFileName
          iFileCount = 1
          Exit For
        End If
        tFileName = Dir$()
     Loop
     tSubPath = "cc" + Cstr(i) + "dir\"
	Next
   
	Open tName For Input As iFileNum
   
	iAnswer = Messagebox("Do you want to extract 
	and add old cc:Mail Internet addresses interactively? 
	Yes allows you to add a first and last name for 
	each address extracted. No simply extracts the 
	Internet addresses and adds them to your Personal Address Book", 
	MB_YESNO + MB_ICONQUESTION, "Interactive Mode?")   

     If iAnswer = IDYES Then     
          While Not Eof(iFileNum)
               Line Input #iFileNum, tFlatFileRecord 
               If Instr(1, tFlatFileRecord, tCompChar, 0) > 0 Then
                    iRightNum = Len(tFlatFileRecord) 
                    - Instr(1, tFlatFileRecord, tCompChar, 0)
                    tInternetName = Right(tFlatFileRecord, iRightNum)
                    If Instr(1, tInternetName, tAtSign, 0) Then               
                         tFirstName = Inputbox$
                         ("What is the FIRST NAME for " 
                         + tInternetName + "?")
                         tLastName = Inputbox$
                         ("What is the LAST NAME for " 
                         + tInternetname + "?")
                         Set doc = db.CreateDocument
                         doc.FirstName = tFirstName
                         If tLastName = "" Then
                              doc.LastName = iInternetName                              
                         Else
                              doc.LastName = tLastName
                              doc.FullName = tFirstName 
                              + " " + tLastName                              
                         End If
                         doc.MailAddress = tInternetName
                         doc.Type = tFormType
                         Call doc.Save( True, True )
                         iCount = iCount + 1
                    End If
               End If
          Wend
     Else
          While Not Eof(iFileNum)
               Line Input #iFileNum, tFlatFileRecord 
               If Instr(1, tFlatFileRecord, tCompChar, 0) < 0 Then
                    iRightNum = Len(tFlatFileRecord) 
                    - Instr(1, tFlatFileRecord, tCompChar, 0)
                    tInternetName = Right(tFlatFileRecord, iRightNum)
                    If Instr(1, tInternetName, tAtSign, 0) Then               
                         Set doc = db.CreateDocument
                         doc.LastName = tInternetName
                         doc.MailAddress = tInternetName
                         doc.Type = tFormType
                         Call doc.Save( True, True )
                         iCount = iCount + 1
                    End If
               End If
          Wend
     End If
     Messagebox ( "Process complete.  " + Cstr(iCount) 
     + " Internet addresses added to your Personal Address Book.")
     
EndOfFile:
     If iFileCount = 0 Then
          Messagebox "No Internet addresses were defined 
          in your cc:Mail account."
          Close #FileNum
          Exit Sub
     End If
     Close #iFileNum 
     
End Sub	

The LotusScript code starts with several variable declarations and value assignments. After the agent declares these variables, it begins a For loop. This loop repeats a maximum of ten times and searches several directories for the PRIVDIR.INI file. The first pass through the loop starts with U:\WINDOWS\CCMAIL. If a search of that directory is unsuccessful, the agent adds CC1DIR to the path, creating U:\WINDOWS\CCMAIL\CC1DIR. The agent then checks this directory. If this search is also unsuccessful, the agent increments the number found in the complete path name, and checks that directory (for example, U:\WINDOWS\CCMAIL\CC2DIR, U:\WINDOWS\CC:MAIL\CC3DIR, and so on). This process of incrementing and searching continues until the agent reaches U:\WINDOWS\CCMAIL\CC9DIR, at which point it searches this directory and the loop ends. If at any time the search is successful, the loop immediately ends.

Note: The U:\ drive is specific to the customer's environment. Other environments might use different drive and directory names.

After the loop ends, either by successfully finding the PRIVDIR.INI or repeating the maximum of ten times, the agent attempts to open the PRIVDIR.INI file. If the file is found, this attempt is successful and the script continues; however, if the file isn't found, this attempt causes an error that sends the script down to the section labeled EndofFile. This section displays a message for the user stating that there are no Internet e-mail addresses to extract. Then the script ends.

Successfully opening the PRIVDIR.INI file produces a message that asks the users whether they want to extract addresses interactively. Answering No causes the script to move quickly through the PRIVDIR.INI file, extracting each address and creating a new Person document in the Personal Address Book. In contrast, answering Yes causes the script to extract an address and then prompts the user for the first and last name associated with this address. The user-supplied values appear in the appropriate fields in the new Person document, which the agent then saves in the Personal Address Book. This process continues until the PRIVDIR.INI contains no addresses. When complete, a message appears indicating how many addresses were extracted.

The customer ran this agent flawlessly throughout the migration project, with users having no idea how much time was saved with this agent. Isn't that always the case?


Your results may vary

These two home-grown LotusScript agents were designed to make the transition to Notes a little easier for recently migrated cc:Mail users. These agents were the result of one customer's migration experience, and similar to the official cc:Mail-to-Notes migration tool, these additional agents can't be all things to all people. Therefore, the agents described in this article may not prove useful for everyone.

How will you know whether these agents will help your migration project? The only way to answer this question is to follow the lead of this article's featured customer: conduct a migration pilot. Look for ways to improve the migration process and ease the transition for your user community. If you keep these goals in mind, your project is bound for success.


Resources

About the author

Bret Swedeen joined Lotus in the summer of 1997 as a Principal Knowledge Architect. Bret has worked in the computer industry for nearly 8 years doing everything from Notes phone support at Corporate Software to Notes consulting at Coopers & Lybrand. A Certified Netware Engineer (CNE) and Certified Lotus Professional (CLP) System Administrator and Application Developer, Bret has also written articles for the Lotus Notes Advisor, Database Advisor, LAN Times, and LAN Magazine. Most recently Bret authored the Lotus Notes 4.5 Administrator's Guide from Sybex publishing.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Lotus
ArticleID=23459
ArticleTitle=Notes From Support:Transitioning from cc:Mail to Notes Mail using Agents
publish-date=06011998
author1-email=swedeen@us.ibm.com
author1-email-cc=htc@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers