|Home||Switchboard||Unix Administration||Red Hat||TCP/IP Networks||Neoliberalism||Toxic Managers|
May the source be with you, but remember the KISS principle ;-)
Skepticism and critical thinking is not panacea, but can help to understand the world better
Configuring Sendmail on the Solaris 9 Platform
By Eric Rinker
The goal of this article is to impart a basic understanding of how to make changes to Sendmail on a machine running the Solaris 9 Operating System. This article is written for engineers with a reasonably good working knowledge of the standard principles of the UNIX operating system. To utilize this article, you need to know how to edit files and run programs, and you need root access.
How Email Works (Mail Transfer Agents)
Two categories of application deal with email: Mail User Agents (MUAs) and Mail Transfer Agents (MTAs).
Mail User Agents are applications that facilitate the creation, viewing, and disposal of email messages. Examples include mail or elm in a UNIX environment, and Eudora or Outlook in the Windows world. Netscape and Explorer are Internet browsers that can also double as MUAs.
Mail Transfer Agents transport email from one machine; typically, each machine uses only one MTA. Sendmail fills this role, while other MTAs out there include Exim, Postfix, and Qmail.
Evolution of Sendmail
Sendmail is one of the oldest and mostly widely used MTAs in the world. It is the default MTA for most UNIX distributions, including HP's HP-UX, IBM's AIX, and Sun Microsystems' Solaris OS. Sendmail's long life has made it complicated to configure and maintain, but it makes up for its drawbacks with its ability to do just about anything.
First appearing over 30 years ago, Sendmail has evolved into a robust, feature-rich method for transporting electronic mail from one location to another. Originally designed at a time when hard drives the size of washing machines supplied 64 kilobytes of usable storage, Sendmail used every trick in the book to conserve space. To make everything short and to the point, the Sendmail configuration file used such cryptic parameters as "Fw" for "Domains we receive mail for" and "DH" for "Who gets all local email." While there is a method to the madness, it is not readily apparent to the novice user. For backwards compatibility, these cryptic parameters are still present in the configuration file of today's Sendmail versions.
Over the years, as features were added to Sendmail, the configuration process became more and more complicated. To make it more administrator-friendly, Sendmail uses a m4-based compilation and configuration model. This layer between the administrator and the build and configuration process makes Sendmail easier to set up and maintain without requiring upgrades of older programs to handle new interaction methods.
This document couldn't possibly cover everything there is to know about Sendmail without being hundreds of pages long, and a bore to read. Instead, we focus on three commonly seen configurations: Mail Server, Incoming Relay, and Outgoing Only.
When modifying the behavior of Sendmail, the
/etc/mail/sendmail.cffile is not directly altered. Instead, a
.mcfile is altered and run through the m4 macro processor. Some example
.mcfiles are in
main.mcis the default setup system.
submit.mcconfigures Sendmail as an initial mail submission program.
subsidiary.mcrelays all mail on this system through another machine before the mail goes to its destination.
For our examples, we will copy the
new.mcand make our modifications like so:cd /usr/lib/mail/cf vi new.mc make new.cf cp new.cf /etc/mail/sendmail.cf /etc/init.d/sendmail restart
To begin with, common elements are shared in all three configurations. A minimal file contains the following:OSTYPE(`solaris8')dnl DOMAIN(`generic')dnl MAILER(`local')dnl MAILER(`smtp')dnl
OSTYPEmacro defines what system this file is on.
DOMAINmacro is used to pull in another file into the resulting sendmail.cf file.
MAILERmacros define which of the many different delivery methods this configuration file will use.
In this example, we are on a Solaris 8 or higher system, we are including the "generic" domain file, and we want to use both the local delivery system and the SMTP system.
The mail server is your typical server for incoming mail. It receives mail for user@domain, delivers it to the user's local mailbox, and processes mail in its queue for delivery to the outside world.
You only need to make one change: Add each domain that is to be considered a local account into
End result:OSTYPE(`solaris8')dnl MAILER(`local')dnl MAILER(`smtp')dnl
Incoming Relay is the common configuration for company email servers that are outside of the company firewall. Instead of storing the email, these relays pass it on to a predefined server inside the firewall that is the company's mail server. This setup is perfect for implementing filtering, since this machine doesn't handle the other duties of your typical mail server.
To configure Incoming Relay, we first need to add the relay server information. In this case, we are going to relay everything to
Next, we have to allow mail to be relayed through this machine. It's best to only relay mail for domains served by the internal servers. The following option tells sendmail to use the /etc/mail/relay-domains file as a list of domains allowed to send or receive mail through this server:FEATURE(`relay_entire_domain')dnl
We are done. This server will now relay for any domains in the /etc/mail/relay-domains file, except for local accounts, to
End result:OSTYPE(`solaris8')dnl DOMAIN(`solaris-antispam')dnl define(`SMART_HOST', 'relay.mydomain.com')dnl FEATURE(`relay_entire_domain')dnl MAILER(`local')dnl MAILER(`smtp')dnl
For security purposes, it's best not to set up an indiscriminate mail relay. Every machine needs to use an MTA to send email, and some programs require the ability to relay emails through an SMTP server. With these requirements, you can both relay mail for local services and secure your system from becoming an open relay by configuring Sendmail to attach only to the loop-back address.
To make Sendmail outgoing only, it needs to not accept mail from any remote hosts. To do this, we force it to use only the local loop-back address.DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')
No other options are required; Sendmail transports mail from the local machine to the outside world by default.
End result:OSTYPE(`solaris8')dnl DOMAIN(`solaris-generic')dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA') MAILER(`local')dnl MAILER(`smtp')dnl
Where to Go Next
For more information on options for a Relay server, see the sendmail.org tip Allowing controlled SMTP relaying in Sendmail 8.9 and later. Specifically, look at using the access_db option for a more robust anti-spam filtering relay server.
Now that you know how to make changes, you can decide what kinds of changes you want to make. Your first stop should be
/usr/lib/mail/READMEas it contains a good deal of information about Sendmail configuration, the m4 macros, and so on. Once you've exhausted that, you can check out some of the following resources.
The author would like to thank John Beck of Sun Microsystems for his help in reviewing this article.
Unless otherwise licensed, code in all technical manuals herein (including articles, FAQs, samples) is provided under this License.
Solaris Resources at Kempston
Configuring sendmail on Solaris 7 and Solaris 8 for use with a dial-up connection
This page covers the configuration of sendmail on Solaris 7 and Solaris 8 to send outgoing mail to an ISP using SMTP. A similar page describes the compilation, installation and configuration of fetchmail to collect incoming mail from an ISP's POP3 server.
If your ISP delivers incoming mail by means of SMTP, please also read configuring sendmail to accept incoming email.
Most dial-up systems send outgoing mail via a "smart host" operated by their ISP which handles delivery of mail to the destination. These instructions assume that a smart host will be used and do not cover configuration of sendmail to deliver directly to the destination through the use of MX records in the DNS. If you want to do this, or are interested in learning more about sendmail, consider buying the definitive "Bat" book: "sendmail" by Bryan Costales and Eric Allman, published by O'Reilly, ISBN 1-56592-222-0.
sendmail is controlled by its configuration file, /etc/mail/sendmail.cf, and Solaris provides two sample configuration files. The first is /etc/mail/main.cf which is for use on systems which act as mailhosts and provides all the sendmail rules needed to route mail on to the Internet. The second is /etc/mail/subsidiary.cf which is for use on systems which only route mail directly to hosts on the same domain and which send outbound mail to a designated smart host which relays the mail to its destination. The subsidiary.cf sample file is used as a basis for the configuration here and, as supplied with Solaris, is almost (but not quite) suitable for use on an intermittently connected dial-up system. Solaris also provides a mechanism for building a sendmail.cf file using m4 but this technique is not covered here.
Configuring sendmail for outgoing mail
You'll need a few items of information which are specific to you and your ISP in order to implement these instructions:
your email address or addresses your full name as you want it to appear on outgoing mail your ISP's domain (the part after the "@" sign in your email address) the name of your ISP's smart host for outgoing mail
For illustrative purposes, these instructions assume that your email address is firstname.lastname@example.org and that your ISP's smart host is named mail.zulu.com. Make sure that you replace these example names with your own details when editing the sendmail configuration file.
sendmail needs to be able to identify your fully qualified domain name (FQDN) and you may not have one!
If you own your own domain name, such as mydomain.com, there's no problem: your FQDN is hostname.mydomain.com where hostname is the name you chose for your Sun machine.
If you don't own a domain name, you'll need to invent one to make sendmail work properly. I suggest you use a domain name of .localdomain so that your FQDN is hostname.localdomain.
Your FQDN must be defined in /etc/inet/hosts. Check the contents of this file and amend it if necessary. It should contain (at least) the following line:
<local IP address> <host name> <your FQDN> loghost
For example, my system has the hostname gateway, a local IP address of 192.168.1.1 and I've invented an FQDN of gateway.localdomain. So, /etc/inet/hosts contains:
192.168.1.1 gateway gateway.localdomain loghost
Run the following script:
and this should produce output such as:
hostname gateway OK: fully qualified as gateway.localdomain
If it doesn't, there's something wrong with your hosts file and the script should identify what needs to be changed.
# cd /etc/mail # cp subsidiary.cf sendmail.cf.isp
where isp is the name of your ISP, so this file could be called sendmail.cf.zulu. This version of the file will be edited so that it causes sendmail to send outgoing mail via your ISP's smart host.
Insert a comment line at the start of the file so that you can easily recognise this version of sendmail.cf:
# Version of subsidiary.cf for use with ISP.
where ISP is the name of your Internet Service Provider.
The first change to be made tells sendmail where to send outgoing mail which is destined for addresses outside your own system. Look near the start of the file for the section headed:
################## # local info # ##################
A few lines after this heading are the lines:
# "Smart" relay host (may be null) DSmailhost.$m
Change the second of these lines so that it reads "DS" followed immediately by the name of your ISP's smart mail host. There mustn't be any spaces on this line. For example, if the name of the smart host is mail.zulu.com, this line should read:
It's likely that your system will have access to a Domain Name Service (DNS) only while it's connected to your ISP over a dial up link. If this is so, we have to tell sendmail not to try and do DNS lookups for outgoing email when sendmail first receives the mail.
Look for the section in the file headed:
############### # Options # ###############
and, within the Options section, the lines which read:
# name resolver options #O ResolverOptions=+AAONLY
Immediately after this point, insert the lines:
# Don't use DNS O ResolverOptions=-DNSRCH
The next two changes tell sendmail that outgoing mail destined for addresses outside your own domain shouldn't be sent immediately but should be placed in a queue for sending later. In sendmail's terminology, this email is classed as "expensive". The first change is to tell sendmail to "hold" expensive mail and this is done by changing the value of the HoldExpensive option from its default value of false to a value of true. Go back a little way in the file to near the start of the Options section, where you'll find the lines:
# avoid connecting to "expensive" mailers on initial submission? O HoldExpensive=False
Change the second of these lines so that it reads:
The second part of this change is done later in the file. Look for the section near the end of the file headed:
##################################### ### SMTP Mailer specification ### #####################################
Immediately after this are some mailer definitions (lines that start with an upper-case "M"). The "smtp" mailer is used to deliver outgoing mail to other machines (if any) on the local network whereas the "relay" mailer is used to deliver outgoing mail to the external smart host. The mailer definition for the "relay" mailer starts with:
Mrelay, P=[IPC], F=mDFMuXa8, S=11/31, R=61, E=\r\n, L=2040,
Edit this line to insert the character "e", meaning "expensive", after the "F=" string so that it reads:
Mrelay, P=[IPC], F=emDFMuXa8, S=11/31, R=61, E=\r\n, L=2040,
This change only affects outgoing mail which is to be routed via your ISP's smart host. Local mail, within your own system and within your own network, will be delivered immediately.
You also need to add a couple of rewriting rules to the sendmail configuration file to ensure that a valid return address is used in both the envelope sender field and in the 'From:' header on outgoing mail. There are two common possibilities here and you need to decide which applies to your ISP account. You may have a single email address, such as email@example.com, or your ISP may provide you with several email addresses, such as firstname.lastname@example.org, email@example.com, and so on. You may even have unlimited email addresses, such as <anything>@myhost.zulu.com.
In the first case, you will want to ensure that your single email address is used as the sender of outgoing mail, regardless of which unix user on your Solaris system sends the mail. In the second case, you may well decide to set up one login user on Solaris for each of your email user names and simply ensure that the correct domain name is used on outgoing mail. The edits for each of these cases are listed separately below.
A little further down the file, you'll find a line containing just "S11" and a line containing just "S31". The lines following each of these points are rewriting rules which determine how the sender address appears in, respectively, the envelope and 'From:' header on outgoing mail.
If you have a single email address:
Immediately after the "S11" line, insert a line which reads:
R$* $@ firstname.lastname@example.org
replacing email@example.com with your email address. This sets the envelope sender address on outgoing mail. Note that there must be one or more tab characters between the first and second fields on each such line inserted into the sendmail configuration file.
Immediately after the "S31" line, also insert a line which reads:
R$* $@ firstname.lastname@example.org
replacing email@example.com with your email address. This sets the address in the 'From:' header on outgoing mail.
Finally, you'll probably want to ensure that your real name appears in the 'From:' header on outgoing mail. This information is taken by sendmail from the name field in /etc/passwd and can be changed using the admintool program.
If you have several email addresses:
Immediately after the "S11" line, insert three lines which read:
R$- $@ $firstname.lastname@example.org R$- $+ $1 R$- $@ $email@example.com
replacing zulu.com with the domain name which should appear after the "@" sign on outgoing mail. These lines set the envelope sender address. Note that there must be one or more tab characters between the first and second fields on each such line inserted into the sendmail configuration file.
Immediately after the "S31" line, also insert three lines which read:
R$- $@ $firstname.lastname@example.org R$- $+ $1 R$- $@ $email@example.com
replacing zulu.com with the domain name which should appear after the "@" sign on outgoing mail. This sets the address in the 'From:' header.
Note that the full name inserted by sendmail in the 'From:' header of outgoing mail will be taken from the name field in the appropriate entry in /etc/passwd.
Run sendmail in rule testing mode to check that the changes which have been made to rewriting rules 11 and 31 have the expected effects.
To do this, type:
# /usr/lib/sendmail -C/etc/mail/sendmail.cf.isp -bt
If sendmail reports errors such as "invalid rewrite line", your edits to the sendmail configuration file are incorrect. Check your changes before proceeding.
If all is well, sendmail will respond with some text and a ">" prompt, expecting you to type a rule number followed by a space and an address. In reply to this, sendmail will report how the rewriting rule has transformed the address. Try rules 11 and 31 with several addresses and check the results are what is expected. When you've finished, exit sendmail by typing CONTROL and D.
The following is example output from my system after editing the sendmail configuration file for use with several addresses at Freeserve, where I have unlimited email addresses of the form <anything>@kempston.freeserve.co.uk:
# /usr/lib/sendmail -C/etc/mail/sendmail.cf.freeserve -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > 11 mike rewrite: ruleset 11 input: mike rewrite: ruleset 11 returns: mike @ kempston . freeserve . co . uk > 11 mike@localhost rewrite: ruleset 11 input: mike @ localhost rewrite: ruleset 11 returns: mike @ kempston . freeserve . co . uk > 11 jim@gateway rewrite: ruleset 11 input: jim @ gateway rewrite: ruleset 11 returns: jim @ kempston . freeserve . co . uk > 31 joe rewrite: ruleset 31 input: joe rewrite: ruleset 31 returns: joe @ kempston . freeserve . co . uk > 31 sally@localhost rewrite: ruleset 31 input: sally @ localhost rewrite: ruleset 31 returns: sally @ kempston . freeserve . co . uk > 31 sally@gateway rewrite: ruleset 31 input: sally @ gateway rewrite: ruleset 31 returns: sally @ kempston . freeserve . co . uk > #
Run sendmail again in rule testing mode to check that it correctly identifies the delivery agent to use for mail addressed within the local machine, to other machines on your local network (if any) and to addresses in the wider Internet.
To do this, type:
# /usr/lib/sendmail -C/etc/mail/sendmail.cf.isp -bt
As before, sendmail should respond:
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> >
This time, use the "/parse" command on different types of email address to check which mailer will be invoked by sendmail for each type of address. For example, suppose there's a user named "jim" on the local system. To check how sendmail will process mail addressed to "jim", type:
> /parse jim
This produces a number of lines of output showing the path this email address takes through sendmail's configuration file. The interesting line is the last, which reads:
mailer local, user jim
showing that sendmail would use its "local" mailer to deliver mail to jim. This mailer is not marked as expensive, so mail to jim would be delivered immediately.
If your Solaris system is standalone without being attached to a local network, skip this step. Otherwise, suppose that your local domain is kempston.net, your Solaris machine is called "sunbeam" and you have another machine on your local network called "penguin", perhaps running Linux. Type:
> /parse root@penguin
and check that the last line of the output is:
mailer esmtp, host penguin.kempston.net, user firstname.lastname@example.org
This indicates that sendmail would use its esmtp delivery agent across the local network to deliver mail to penguin. The esmtp mailer is not marked as expensive so this mail would also be delivered immediately.
Finally, try an address on the wider Internet:
> /parse email@example.com
This time, the last line of the output should read something like:
mailer relay, host mail.zulu.com, user firstname.lastname@example.org
This indicates that mail to non-local addresses will be delivered using the "relay" mailer which will send the mail to mail.zulu.com, the ISP's smart mail host. The "relay" mailer is the one we marked as "expensive" in sendmail.cf, and, since we also set HoldExpensive to True, such mail will not be processed immediately but will be queued for sending later, when the Solaris machine dials up your ISP.
Finally, type CONTROL and D to exit from sendmail's rule testing mode.
This file starts sendmail at boot time. Edit the file to replace:
/usr/lib/sendmail -bd -q15m &
in the "start" section with the line:
/usr/lib/sendmail -bd -X /var/log/mail.log -oL9 &
The option "-bd" starts sendmail as a daemon, listening for SMTP connections on port 25. The option "-q15m" in the default file causes sendmail to process its queue of outgoing mail every 15 minutes and this isn't appropriate when the system spends most of its time off-line. The remaining options are optional but are worth using until you're sure that sendmail is working properly. "-X /var/log/mail.log" logs all mail transactions to the specified file; and "-oL9" sets the logging level to the specified value.
Providing the tests in the preceding step were successful, activate the new sendmail configuration file by copying it and restarting sendmail:
# cp /etc/mail/sendmail.cf.isp /etc/mail/sendmail.cf # /etc/init.d/sendmail stop # /etc/init.d/sendmail start
If you've set up at least one user on your system apart from root, it's worth sending mail to that user to check that it's delivered immediately. Suppose you have a user named mike. Send a mail message to mike from the command line:
# mail mike From: root To: mike This is a test mail message .
Note the blank line after the headers and the full stop at the start of the final line which terminates the message.
Check that the mail queue is empty:
# mailq Mail queue is empty
Now switch user to mike and check that the mail message has been delivered:
# su - mike Sun Microsystems Inc. SunOS 5.8 Beta_Refresh February 2000 You have mail. $ mail From root Sat Jan 8 21:52:42 2000 Date: Sat, 8 Jan 2000 21:52:42 GMT From: Mike Mann <root> Message-Id: <200001082152.VAA00847@sunbeam.kempston.net> To: mike Content-Length: 29 This is a test mail message ? d $ exit #
Now send a mail message to an address outside your system. For example:
# mail email@example.com From: firstname.lastname@example.org To: email@example.com This is a test mail message .
and make sure that it's been queued by sendmail for later delivery:
# mailq Mail Queue (1 request) --Q-ID-- --Size-- -----Q-Time----- ------------Sender/Recipient------------ RAA01206 29 Sun Jan 9 17:48 root firstname.lastname@example.org
If you have a local network, it's also worth at this point, sending mail to one of your local machines and check that it's delivered immediately.
If you connect to your ISP by means of a dial up script, as described in Configuring PPP on Solaris 7 to connect to an ISP, edit the /dialup script so that it reads:
cp -p /etc/resolv.conf.isp /etc/resolv.conf cp -p /etc/asppp.cf.isp /etc/asppp.cf cp -p /etc/nsswitch.dns /etc/nsswitch.conf /etc/init.d/sendmail stop /etc/init.d/asppp start ping 126.96.36.199 sleep 30 /usr/lib/sendmail -bd -q1m -X /var/log/mail.log -oL9 &
The "sleep 30" waits for 30 seconds to give the dial up connection a chance to come up before sendmail is restarted. You may need to time how long it takes for the dial up process to complete and adjust this value accordingly. The "-q1m" option tells sendmail to process the outgoing mail queue when it starts and to run the queue once every minute while you're online in case there's any new mail to send.
Insert at the start of this file:
/etc/init.d/sendmail stop /etc/init.d/sendmail start
This simply stops sendmail and restarts it without the "-q1m" option so that it queues outgoing mail while your system is offline.
If you have an email address somewhere other than at the ISP you're connecting to with Solaris, it's worth sending a few test messages to ensure that all is well. When you receive the test messages sent by your Solaris system, check the headers (and particularly the 'From:' header) to make sure that they are correct. I'd recommend sending some messages composed with CDE's mail program and also by injecting them directly into sendmail. The following techniques are useful and the address to which the mail is sent is represented in these examples by email@example.com:
To send a minimal mail message with headers provided by sendmail:
# /usr/lib/sendmail firstname.lastname@example.org < /dev/null
To send a mail message with some headers provided by you and the rest by sendmail (note that there must be a blank line between the headers and the body of the message):
# /usr/lib/sendmail email@example.com From: sendmail_should_change_this To: firstname.lastname@example.org Subject: Test This is a test mail message [CTRL/D]
To send a message by talking to your local sendmail using TCP/IP:
# telnet localhost 25 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. 220 mailhost.zulu.com ESMTP Sendmail 8.9.1b+Sun/8.9.1; Sun, 21 Feb 1999 17:24:26 GMT HELO localhost 250 mailhost.zulu.com Hello localhost [127.0.0.1], pleased to meet you MAIL FROM: Me 250 Me... Sender ok RCPT TO: <email@example.com> 250 <firstname.lastname@example.org>... Recipient ok DATA 354 Enter mail, end with "." on a line by itself From: Me To: email@example.com Subject: Test This is a second test mail message . 250 RAA00498 Message accepted for delivery QUIT 221 mailhost.zulu.com closing connection Connection closed by foreign host. #
To make quite sure that it's all working correctly, send some mail messages while logged in as root and while logged in as an ordinary user.
# tail -f /var/log/mail.log
When you're sure that sendmail is working correctly, you may like to change the option "-oL9" in /etc/init.d/sendmail, /dialup and /hangup to change the amount of logging information which is written to /var/log/mail.log by changing "9" to some other digit.
Now that you've configured Solaris for outgoing mail, have a look at the corresponding page which describes the compilation, installation and configuration of fetchmail to collect incoming mail from an ISP's POP3 server.
If your ISP delivers incoming mail by means of SMTP, please also read configuring sendmail to accept incoming email.
Has this guide been useful?
I hope these instructions prove useful. If you have any comments or suggestions for improvement, or have found any technical errors, please email me at firstname.lastname@example.org
This page is copyright © email@example.com 2000. Reproduction is forbidden without the author's permission. You are welcome to link to these pages if you wish but please point to the pages at www.kempston.net: Solaris Resources at Kempston
|Home||Free Solaris||Connecting to an ISP|
|Configuring mail||Configuring modem dial up||Configuring a PPP server|
|Installing Software||Solaris FAQs and Software||Site Index|
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2018 by Dr. Nikolai Bezroukov. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) in the author free time and without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
|You can use PayPal to make a contribution, supporting development of this site and speed up access. In case softpanorama.org is down you can use the at softpanorama.info|
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.
Last modified: September 12, 2017