Notes for Porting and Modification

Porting Pine to Other Platforms

Substantial effort has gone into making Pine/Pico portable. There are still, of course, a number of machine dependencies. Some of the ports are well-tested and some are untested. In particular, the most heavily used ports are the Ultrix, NeXT, DOS, and PTX ports.

Each platform is given a three letter name (see the file doc/pine-ports). Make up a new one for your new port. We've attempted to bring all potential platform dependencies into three files: os-xxx.h, os-xxx.c, and makefile.xxx where xxx is the three letter name of the port. Thus any new port will hopefully just result in new versions of these files and some notes for the pine-ports file. There are actually nine new files needed, because there is a set of these files in the c-client, Pico, and Pine source directories. (As you can tell by reading this technical note, Pine originated on Unix systems. There are still probably many Unix dependencies built in, but these should be diminishing now that there are DOS, Windows, and VMS ports. Regrettably, the source code is full of instances of "ifdef DOS". Most of these are due to memory limit problems on DOS as opposed to actual system dependencies.

The makefiles are kept as simple and straight-forward as possible, because many previous attempts at automatically figuring out what to do seem to have become complex and ineffective in what they set out to do: which is to make compiling and installing the program easy. Each port is for a specific hardware/software platform, also because past attempts to generalize on versions of Unix or some CPU architecture don't seem to have gained much. Thus, there is a separate makefile for each platform that calls the appropriate compiler and linker with the appropriate flags. Most of these makefiles are pretty similar. The makefile also specifies which of the os-xxx.c and os-xxx.h files to use. It is the root from which all platform dependencies are selected. In most cases the makefile also defines a symbol named after the platform on which there can be dependencies in the source code, though we've tried to minimize relying on this where reasonable. Pine, Pico, and the C-client don't quite do everything the same (there are at least three separate authors involved). Basically, to build the source in one of the directories, run make -f makefile.xxx where xxx is the three-letter name of the platform. That's all the build script does. When starting a new port in the pine directory, there is a generic makefile called makefile.gen which should be a good starting point.

The file os-xxx.h is used for general platform dependent #include's and #defines. In the pine directory these .h files are located in the osdep subdirectory. All the include files that have been found to vary from one platform to another are also included here. In the case of Pico, there is only one os-xxx.h file called os-unx.h for most of the supported Unix ports and inside it are #ifdefs based on the platform specific symbol defined in the makefile. On the other hand, Pine now has a separate os-xxx.h file for each platform. There are a number of Pine configuration settings that are defined here, as well, such as the place it looks for certain files, defaults for the printer and folder names, the maximum screen size, and so on. For the Pine portion of the port, start by looking at the generic os-gen.h file and comparing it to some of the specific os-xxx.h files in osdep.

The os-xxx.c file contains functions that are potentially platform dependent. Again, the idea is to gather all the dependencies in one place. Pico uses the same strategy here as it uses with os-unx.h. That is, there is a single os-unx.c file for most of the Unix ports. Pine uses a complicated looking method to produce the os-xxx.c file from a set of included files. Each included file usually contains a single function and we've found that there are usually only a couple different implementations of each function in the ports we've done so far. Hopefully, coming up with an os-xxx.c for a new port will usually be a matter of including the right set of these already written functions. This is done by writing a new os-xxx.ic file in the osdep subdirectory. Start with the generic os-gen.ic, as you did with the os-gen.h file above.

We strongly encourage that no changes be made to the general source when porting and that all changes be contained in the three/nine system dependent files if possible. The object is to maintain source code integrity and assimilate ports to new platforms rapidly. The more conventional way to do this is with a large collection of #ifdefs. The problem with this is that adding a port for a new platform implies changing the source code for all the other platforms and thereby risks breaking them. (We readily admit that there are still too many ifdefs in the code, but we haven't had time to devote to fully cleaning that up.)

If you do port Pine to a new platform we hope that you will send us the changes required so that we may attempt to include it in a later release. Thanks!


Test Checklist

The following is a checklist of some things to check when testing a new port:

___
Sending mail, check that headers are correct
___
Sending mail with attachments
___
Sending mail with SMTP server
___
Sending mail without SMTP server
___
Sending mail with list of two SMTP servers, first one doesn't answer
___
Replying to and forwarding a message
___
Postponing messages under composition
___
Composer operations
___
Alternate editor, enable-alternate-editor-implicitly
___
Make sure local user names are expanded
___
Test spelling checker
___
Catching of SIGHUP while message is being composed
___
Setting of variables in .pinerc
___
New mail notification. Should happen with Pine idle to check timeouts
___
Reading mail (attachments, MIME, MIME with mailcap viewers)
___
Deleting, undeleting, expunging, sorting
___
Expunge to empty folder
___
Make sure that ~ expansion works in config files
___
Make sure that $VAR expansion works in config files
___
Save message to folder, check error conditions such as permission denied
___
Export message with FullHeaderMode on and off
___
Checkpointing (see the section on checkpointing)
___
Open IMAP and RIMAP folders
___
Default-fcc on remote IMAP server
___
Fcc-name-rule, fcc in addrbook (while composing)
___
Test opening bogus folders: invalid format, no permission
___
Open a USENET news group, list in folder-lister, read news, post news
___
Command line arguments
___
Change password
___
Lock keyboard
___
Address book operations (edit, delete, add, lists, whereis, composeto)
___
ReadOnly address book
___
Look at addrbook, change addrbook-sort-rule in Config, go back to addrbook screen
___
No permission to write in same directory as addrbook, should create addrbook.lu in a temp directory
___
Multiple address books
___
Address book loops from one addrbook to another and back
___
TakeAddr command with one address, with multiple addresses
___
TakeAddr command with ReadOnly address books
___
TakeAddr command with one of two address books ReadOnly
___
Send mail with empty address book
___
Config Screen operation, does pinerc get written?
___
Make sure SIGTSTP, ^Z works
___
Pinef
___
Sent-mail pruning (set back last-time-prune-questioned variable)
___
Printing using all three printer configurations, various screens
___
View help text and news
___
Folder list operations (rename, create, delete...)
___
Saved-msg-name-rule
___
Screen redrawing in various screens (^L)
___
Window resizing in various screens
___
Error messages for incorrect terminal types (try "foo" and "vt52")
___
Reading of /usr/local/lib/pine.conf
___
Fixing variables and features in /usr/local/lib/pine.conf.fixed
___
Flag command (check message status changed in mail folder)
___
Initial-keystroke-list
___
Aggregate operations (save, delete, export, takeaddr, ...)
___
Build xxx from scratch, build clean


[Previous] [Table of Contents]