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, AIX, NeXT, Windows, and Dec Unix 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 the files: {pico,pine}/osdep/os-xxx.h, {pico,pine}/osdep/os-xxx.ic, and {pico,pine}/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 separate dependencies in the c-client source, but that is handled in separate documentation there. Regrettably, the source code is also 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 most 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. When different "ports" are very similar, it is sometimes possible to use the same pine code (for example) with only a small change in the c-client or pico code. In those cases, that kind of dependency is reflected in the top-level build script. The build script can usually be used to invoke the various makes correctly. It may set some variables before running make so look to see what build does before trying a make in one of the subdirectories. This is especially true if LDAP is being included.

It is almost always easier to start with an existing port when trying to port to a new system. There is a port called gen (generic) which may be a good starting point. On the other hand, if another port is close to what you want, start with it instead.

The file pico/osdep/os-xxx.h contains most of the general platform dependent #include's and #defines. There are a number of Pine configuration settings that are defined in pine/osdep/os-xxx.h, 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. Start by looking at the generic pico/osdep/os-gen.h file and comparing it to some of the specific os-xxx.h files there.

The osdep/os-xxx.c files contain functions that are potentially platform dependent. Again, the idea is to gather all the dependencies in one place. We use a complicated looking method to produce the os-xxx.c files from a set of included files. Each included file usually contains a single implementation method and we've found that there are usually only two or three different methods 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 subdirectories. Starting with the generic os-gen.ic, as you did with the os-gen.h file above, may be a useful strategy.

We strongly encourage that no changes be made to the general source when porting and that all changes be contained in the 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.)

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
___
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