# 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