/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

## On Mac OS and Linux

* Download cyrus-sasl tarball or clone git sources.

You can get the latest tarball from [here](ftp://ftp.cyrusimap.org/cyrus-sasl/).

Note: If you download the source tarball, the configure script is already present. If you have cloned the source from git. It will be missing the .configure script and that needs to be generated. The steps to generate it are not clear. You can overcome this issue by just copying the .configure script form the tarball onto the folder containing the git sources.

* Run configure

`./configure --disable-cram --disable-digest --disable-scram --disable-login --disable-otp --disable-passdss --disable-krb4 --disable-srp --without-des CFLAGS="-g"`

* Build the sources and install
    
    `make`

    `make install`

(On Mac) - The SASL library should now be available in _/usr/local/lib/sasl2_

    -rwxr-xr-x  1 root  admin    659 Dec 23 15:24 libanonymous.la
    -rwxr-xr-x  1 root  admin  22276 Dec 23 15:24 libanonymous.plugin
    -rwxr-xr-x  1 root  admin    706 Dec 23 15:24 libgssapiv2.la
    -rwxr-xr-x  1 root  admin  37052 Dec 23 15:24 libgssapiv2.plugin
    -rwxr-xr-x  1 root  admin    643 Dec 23 15:24 libplain.la
    -rwxr-xr-x  1 root  admin  22028 Dec 23 15:24 libplain.plugin
    -rwxr-xr-x  1 root  admin    665 Dec 23 15:24 libsasldb.la
    -rwxr-xr-x  1 root  admin  33916 Dec 23 15:24 libsasldb.plugin

## (On CentOS Linux) - 

* You need to download the "krb5-devel" rpm using command below. This will download `gssapi` directory and `gssapi.h` file under `/usr/include`.      
`yum install krb5-devel`

* Copy the `gssapi` directory and `gssapi.h file` into the plugin directory found under cyrus-sasl untar directory.
Example: 
    * `cp -r /usr/include/gssapi ~/cyrusSasl/cyrus-sasl-2.1.26/plugins`
    * `cp /usr/include/gssapi.h ~/cyrusSasl/cyrus-sasl-2.1.26/plugins`

* Remove the config cache file if any in cyrus-sasl directory
   * `rm -f ~/cyrusSasl/cyrus-sasl-2.1.26/config.cache`

* Run configure

`./configure --disable-cram --disable-digest --disable-scram --disable-login --disable-otp --disable-passdss --disable-krb4 --disable-srp --without-des CFLAGS="-g"`

* Build the sources and install
  * `make clean`
  * `make`
  * `make install`

(On CentOS Linux) The SASL library should now be available in _/usr/local/lib/sasl2_


     -rwxr-xr-x  1 root root   684 Mar 15 18:12 libanonymous.la     
     -rwxr-xr-x  1 root root 53751 Mar 15 18:12 libanonymous.so.3.0.0      
     -rwxr-xr-x  1 root root   704 Mar 15 18:12 libgs2.la       
     -rwxr-xr-x  1 root root 81808 Mar 15 18:12 libgs2.so.3.0.0      
     -rwxr-xr-x  1 root root   734 Mar 15 18:12 libgssapiv2.la       
     -rwxr-xr-x  1 root root 83549 Mar 15 18:12 libgssapiv2.so.3.0.0       
     -rwxr-xr-x  1 root root   668 Mar 15 18:12 libplain.la       
     -rwxr-xr-x  1 root root 54515 Mar 15 18:12 libplain.so.3.0.0       
     -rwxr-xr-x  1 root root   684 Mar 15 18:12 libsasldb.la        
     -rwxr-xr-x  1 root root 98219 Mar 15 18:12 libsasldb.so.3.0.0        

## On Win 64

* To build the base library and the plain plugin

Change the _PLUGINS_ variable in _plugins/NTMakefile_ to include only the PLAIN plugin. Then run `nmake /f NTMakefile CFG=Release`

The build will fail in sasldb but it would have already built the base library and PLAIN.

Use `nmake /f NTMakefile CFG=Debug` to get a debug build.Building Cyrus SASL

